首页 > 解决方案 > Django 使用 Ajax 进行动态过滤

问题描述

我想使用带有 Ajax 的输入字段的值来动态过滤我的 querySet。

现在我正在尝试这样的事情:

模板:

<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)

查询:

$('.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() 缺少 1 个必需的位置参数:'query'”错误。我假设在发布请求函数中调用 get_queryset 函数不是解决这个问题的方法。

在 Django 中使用 Ajax 动态过滤的最佳方法是什么?

标签: javascriptjquerydjango

解决方案


您的问题是该方法ListView.get_queryset()通常是在没有任何额外参数的情况下定义的,因此当 Django 隐式调用它时,它不会将任何值传递给query您在那里添加的新额外参数。

因此,要么直接使用self.request.POST.get('query', '')inget_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

推荐阅读