django-filter 不过滤查询

Posted

技术标签:

【中文标题】django-filter 不过滤查询【英文标题】:django-filter not filtering the query 【发布时间】:2021-04-02 12:34:39 【问题描述】:

如果没有过滤项目,我在我的项目中应用了 django-filter 库。 如果我访问 url http://127.0.0.1:8000/products/?q=&category=electronics 它应该提供唯一的电子产品,但它提供所有可用的产品。我做错了什么?它应该过滤类别明智或产品标题明智和价格明智。

class ProductFilter(FilterSet):     # by using django-filters
    title = CharFilter(field_name='title', lookup_expr='icontains', distinct=True)
    category = CharFilter(field_name='categories__title', lookup_expr='icontains', distinct=True)
    category_id = CharFilter(field_name='categories__id', lookup_expr='icontains', distinct=True)
    min_price = NumberFilter(field_name='price', lookup_expr='gte', distinct=True)
    max_price = NumberFilter(field_name='price', lookup_expr='lte', distinct=True)

    class Meta:
        model = Product
        fields = ['category', 'title', 'description', 'min_price', 'max_price']


class FilterMixin(object):
    filter_class = ProductFilter
    search_ordering_param = 'ordering'

    def get_queryset(self, *args, **kwargs):
        try:
            qs = super(FilterMixin, self).get_queryset(*args, **kwargs)
            return qs
        except:
            raise ImproperlyConfigured("You must have a queryset in order to use the FilterMixin")

    def get_context_data(self, *args, **kwargs):
        context = super(FilterMixin, self).get_context_data(*args, **kwargs)
        qs = self.get_queryset()
        ordering = self.request.GET.get(self.search_ordering_param)
        if ordering:
            qs = qs.order_by(ordering)
        filter_class = self.filter_class
        print(filter_class)
        if filter_class:
            f = filter_class(self.request.GET, queryset=qs)
            context['object_list'] = f
        return context


class ProductListView(FilterMixin, ListView):
    queryset = Product.objects.all()
    filter_class = ProductFilter
    

    def get_context_data(self, *args, **kwargs):
        context = super(ProductListView, self).get_context_data(*args, **kwargs)
        context['filter_form'] = ProductFilterForm(data=self.request.GET or None)
        return context

模板文件-

% extends 'base.html' %
% load crispy_forms_tags %
% load static %

% block content %

<div class='col-sm-2'>
<form method="GET" action="% url 'products:product-list' %">
 filter_form|crispy 
<input type='hidden' name='q' value=' request.GET.q ' />
<input type='submit' value='Apply Filter' class='btn btn-default'>

</form>

<a href="% url 'products:product-list' %">Clear Filters</a>
</div>




<div class='col-sm-12'>
<h3>All Products <small>*<a href="% url 'categories:category-list'%">Categories</a>*</small></h3>
% if product_list %


     <div class="row">

     % for product in product_list %
         <div class="col">
           % include 'products/snippets/card.html' with instance=product %
         </div>
     % endfor %

      % else %
        <p>No product found!!</p>
    % endif %

 </div>

</div>

% endblock %

【问题讨论】:

共享您呈现项目的模板。 @WillemVanOnsem 看看。 你的 FilterMixin 永远不会导出像 product_list 这样的东西,所以这将是原始查询集。 @WillemVanOnsem FilterMixin contaxt 变量object_list 给出类似&lt;products.views.ProductFilter object at 0x05DB4A90&gt; 是的,但这对product_list 没有影响...此外,即使这是真的,这不是您使用过滤器集进行过滤的方式,您需要访问过滤器集的.qs 【参考方案1】:

您的FilterMixin 永远不会导出类似product_list 的内容,因此这将是原始查询集,而不是您使用FilterSet 过滤的查询集。

您可以通过以下方式轻松更新:

def get_context_data(self, *args, **kwargs):
    context = super().get_context_data(*args, **kwargs)
    qs = context['object_list']
    if self.filter_class:
        qs = self.filter_class(self.request.GET, queryset=qs).qs
    ordering = self.request.GET.get(self.search_ordering_param)
    if ordering:
        qs = qs.order_by(ordering)
    context['object_list'] = qs
    context_object_name = self.get_context_object_name(qs)
    if context_object_name is not None:
        context[context_object_name] = qs
    return context

【讨论】:

你没有定义f ,查询集可能是context['object_list'] = qs context_object_name = self.get_context_object_name(qs) @RahulVerma:是的,就是qs

以上是关于django-filter 不过滤查询的主要内容,如果未能解决你的问题,请参考以下文章

如何使用`django-filters`编写将在整数字段上使用范围过滤器的GraphQL查询?

python测试开发django-169.过滤器django-filter 入门使用

Python测试开发django-169.过滤器django-filter 入门使用

django-filter使用分页

Django(69)最好用的过滤器插件Django-filter

如何在ListAPIView中使用django-filter对过滤结果进行排序