django-фильтр не фильтрует запрос

#python-3.x #django #django-rest-framework #django-views #django-filter

#python-3.x #django #django-rest-framework #django-представления #django-filter

Вопрос:

Я применил библиотеку django-filter в своем проекте, если она не фильтрует элементы. если я посещу URLадрес http://127.0.0.1:8000/products/?q=amp;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 %}
 

Комментарии:

1. Поделитесь шаблоном, в котором вы отображаете элементы.

2. @WillemVanOnsem взгляните.

3. Вы FilterMixin никогда не экспортируете что-то вроде a product_list , так что это будет исходный набор запросов.

4. переменная @WillemVanOnsem FilterMixin contaxt object_list выдает что-то вроде этого <products.views.ProductFilter object at 0x05DB4A90>

5. да, но это никак не влияет на product_list … Кроме того, даже если бы это было правдой, это не то, как вы фильтруете с помощью набора фильтров, вам нужно получить доступ к .qs набору фильтров.

Ответ №1:

Вы FilterMixin никогда не экспортируете что-то вроде a 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 

Комментарии:

1. вы не определили f и не задали запрос, это может быть context['object_list'] = qs context_object_name = self.get_context_object_name(qs)

2. @RahulVerma: да, это просто qs .