@aspitsin138

Почему не работает фильтр?

Перестал работать фильтр, ошибок нет, в лог get запрос отображается. Фильтр категорий работает, товаров нет.

import django_filters

from .models import Item, Category

class ItemFilter(django_filters.FilterSet):
    class Meta:
        model = Item
        fields = {
            'price': ['lt', 'gt'],
            'price_with_discount': ['lt', 'gt'],
            'rating': ['lt', 'gt'],
            'reviews': ['lt', 'gt'],
            'revenue': ['lt', 'gt'],
        }
		
class CategoryFilter(django_filters.FilterSet):
    class Meta:
        model = Category
        fields = {
            'quantity_of_purchased_sum': ['lt', 'gt'],
            'revenue_sum': ['lt', 'gt'],
        }


class Item(models.Model):
    url = models.CharField(unique=True, max_length=300, verbose_name="Ссылка на страницу товара")
    provider = models.ForeignKey(Provider, null=True, blank=True, verbose_name="Поставщик", on_delete=models.SET_NULL)
    name = models.CharField(max_length=300, null=True, blank=True, verbose_name="Название товара")
    image_url = models.CharField(max_length=300, null=True, blank=True, verbose_name="Ссылка на изображение")
    brand = models.ForeignKey(Brand, null=True, blank=True, verbose_name="Бренд", on_delete=models.SET_NULL)
    vendor_code = models.IntegerField(null=True, blank=True, verbose_name="Артикул")
    rating = models.IntegerField(null=True, blank=True, verbose_name="Рейтинг")
    reviews = models.IntegerField(null=True, blank=True, verbose_name="Количество отзывов")
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name="Цена без скидки")
    price_with_discount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True,
                                              verbose_name="Цена со скидкой")
    quantity = models.IntegerField(null=True, blank=True, verbose_name="Доступно")
    categories = models.ManyToManyField(Category, blank=True, verbose_name="Категории")
    quantity_of_purchased = models.IntegerField(null=True, blank=True, verbose_name="Количество покупок")
    revenue = models.DecimalField(max_digits=35, decimal_places=2, null=True, blank=True, verbose_name="Выручка")


class ItemListView(LoginRequiredMixin, SubscriptionRequiredMixin, FilterView):
    template_name = 'item_list.html'
    paginate_by = 10
    model = Item
    filterset_class = ItemFilter

    def get_queryset(self, **kwargs):
        qs = ItemFilter(self.request.GET, Item.objects.all()).qs
        return qs

    def get_context_data(self, **kwargs):
        table_headers = [
            {"id": "name", "name": "Товар"},
            {"id": "brand", "name": "Бренд"},
            {"id": "provider", "name": "Поставщик"},
            {"id": "rating", "name": "Рейтинг"},
            {"id": "reviews", "name": "Отзывы"},
            {"id": "price_with_discount", "name": "Цена"},
            {"id": "quantity", "name": "Доступно"},
            {"id": "categories", "name": "Категории"},
            {"id": "quantity_of_purchased", "name": "Куплено"},
            {"id": "revenue", "name": "Выручка"}
        ]

        ordering = self.request.GET.get('order_by', None)

        for header in table_headers:
            query = QueryDict(self.request.GET.urlencode(), mutable=True)

            if ordering == f"-{header['id']}":
                query["order_by"] = f"{header['id']}"
            elif ordering != header['id']:
                query["order_by"] = f"-{header['id']}"
            else:
                query["order_by"] = ""

            query['page'] = 1
            header['url'] = f"?{query.urlencode()}"

        if ordering:
            match_obj = re.match(r'-?(.+)', ordering)
            order_field = match_obj.groups()[0]
            order_field_index = next((index for (index, d) in enumerate(table_headers) if d["id"] == order_field), None)
            table_headers[order_field_index]["active"] = True
            table_headers[order_field_index]["down"] = ordering != order_field

        context = super().get_context_data(**kwargs)
        context['table_headers'] = table_headers
        return context

    def get_ordering(self):
        fields = [
            "id", "provider", "name", "brand", "vendor_code",
            "rating", "reviews", "price", "price_with_discount",
            "quantity", "categories", "quantity_of_purchased", "revenue"
        ]
        ordering = self.request.GET.get('order_by', 'id')

        match_obj = re.match(r'-?(.+)', ordering)

        if match_obj and (match_obj.groups()[0] in fields):
            field = match_obj.groups()[0]

            if field == ordering:
                return [F(field).asc(nulls_first=True)]
            else:
                return [F(field).desc(nulls_last=True)]

        return 'id'

{# Filters #}
        <form method="get">
        <div class="container text-center">
            <div class="row justify-content-around">
                
              <div class="col-2">
                
                {% min_max_field id="price" label="Цена без скидки" %}
                </div>
              <div class="col-2">
                {% min_max_field id="price_with_discount" label="Цена со скидкой" %}
              </div>
              <div class="col-2">
                {% min_max_field id="rating" label="Рейтинг" %}
              </div>
              <div class="col-2">
                {% min_max_field id="reviews" label="Количество отзывов" %}
              </div>
              <div class="col-2">
                {% min_max_field id="revenue" label="Выручка" %}
              </div>
              <div class="d-grid gap-2 d-md-flex justify-content-md-end">
                <input type="submit" class="btn btn-outline-dark" 
                style="--bs-btn-padding-y: .25rem; --bs-btn-padding-x: .5rem; --bs-btn-font-size: .75rem;"
                 value="Применить"/>
  • Вопрос задан
  • 81 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы