Django динамическая фильтрация с помощью Ajax

Я хочу динамически фильтровать мой querySet, используя значение поля ввода с помощью Ajax.

Прямо сейчас я пытаюсь сделать что-то вроде этого:

Шаблон:

<div class="card mt-3">
        <div class="card-body">
        <form action="" form="get">
            <input data-url="{% url 'klantbeheer' %}" class="zoekklanten" name="q" type="text" placeholder="Zoek op contactnaam...">
        </form>
        {% if object_list %}
                <div class="single-table">
                    <div class="table-responsive">
                        <table class="table text-center">
                            <thead class="text-uppercase bg-dark">
                                <tr class="text-white">
                                    <th scope="col">Bedrijfsnaam</th>
                                    <th scope="col">Contactnaam</th>
                                    <th scope="col">Locatie</th>
                                    <th scope="col">Actie</th>
                                </tr>
                            </thead>
                            <tbody>
                                {% for user in object_list %}
                                <tr>
                                    <td>{{ user.bedrijfsNaam }}</td>
                                    <td>{{ user.contactNaam }}</td>
                                    <td>{{ user.adres }}</td>
                                    <td>
                                        <a href="{% url 'klantupdaten' user.id  %}"><i class="fas fa-edit"></i></a>
                                        <a href="#" data-url="{% url 'klantverwijderen' user.id %}" class="deletegebruiker" data-bs-toggle="modal" data-bs-target="#dynamic-modal"><i class="fas fa-trash-alt"></i></a>
                                    </td>
                                </tr>
                                {% endfor %}
                            </tbody>
                        </table>
                    </div>
                </div>
            {% else %}
            <p>Geen gebruikers gevonden</p>
                <p>
                    <a href="{% url 'klantaanmaken' user.id %}" class="btn btn-primary">Maak klant aan</a>
                </p>
            {% endif %}
        </div>
    </div>

Вид:

class ManageUserView(SuperUserRequired, ListView):
    model = User
    template_name = 'webapp/klant/beheerklant.html'


    #Query based upon contactName
    def get_queryset(self, query):
        

        #Contactnaam bevat QUERY EN superuser is vals.
        object_list = self.model.objects.filter(contactNaam__icontains=query).exclude(is_superuser=True)
        
        return object_list

    def post(self, request, *args, **kwargs):
        query = self.request.POST.get('query', '')
        print(query)
        self.get_queryset(query)

Jquery:

$('.zoekklanten').on('keyup', function(){
    var url = $(this).data('url')
    var query = $(this).val();

    $.ajax({
        url:url,
        type:'POST',
        data:{
            'query':query
        },
        dataType: 'json',
            beforeSend: function(xhr, settings){
                if(!csrfSafeMethod(settings.type) && !this.crossDomain){
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            },
            success: function(result){
            },
            error: function(data){
            }

     })})

Я получаю ошибку "get_queryset() missing 1 required positional argument: 'query'". Я предполагаю, что вызов функции get_queryset внутри функции запроса к посту не является правильным решением.

Какой лучший способ динамической фильтрации с помощью Ajax в Django?

Ваша проблема в том, что метод ListView.get_queryset() обычно определяется без дополнительного параметра, поэтому, когда он вызывается Django неявно, он не передает никакого значения новому дополнительному параметру query, который вы туда добавили.

Так что либо используйте self.request.POST.get('query', '') в get_queryset() непосредственно, а не передавайте его туда как параметр, либо добавьте значение по умолчанию к параметру.

Однако использование пользовательского ввода и передача его непосредственно в SQL запрос является рискованным, так как это может привести к SQL инъекции (даже если Django пытается санировать значение).

def get_queryset(self, query=None):
    # either set default value for `query` here^
    if not query:
        return super().get_queryset()

    # or take the value from `POST` here instead of passing it as a parameter to the method
    query = self.request.POST.get('query')
    object_list = self.model.objects.filter(contactNaam__icontains=query).exclude(is_superuser=True)
    
    return object_list
Вернуться на верх