Как я могу использовать пагинацию для моего класса (DetailView) с помощью get_context_data?

Как я могу получить пагинацию для текущего кода? Я не могу изменить DetailView на View или ListView, поэтому в этом классе я получаю фильтр продуктов.

class CategoryDetailView(DetailView):
    model = Category
    queryset = Category.objects.all()
    context_object_name = 'category'
    template_name = 'category_products.html'
    ...


def get_context_data(self, **kwargs):

    context = super().get_context_data(**kwargs)
    ...
    products = Product.objects.filter(id__in=[pf_['product_id'] for pf_ in pf])
    context['category_products'] = products
    return context

Обычно выбирают представление на основе классов, которое наиболее удобно для выполнения работы. Вы можете рассматривать свое представление как ListView из Product, которые относятся к определенной категории. Поступая таким образом, вы делаете более удобным получение связанных Product, и менее удобным получение соответствующих Category, но последнее проще.

Мы можем реализовать представление как:

from django.shortcuts import get_object_or_404

class CategoryDetailView(ListView):
    model = Product
    context_object_name = 'category_products'
    template_name = 'category_products.html'
    paginate_by = 1
    # …

    def get_queryset(self):
        qs = super().get_queryset().filter(
            category__slug=self.kwargs['slug']
        )
        if 'search' in self.request.GET:
            qs = qs.filter(title__icontains=self.request.GET['search'])
        elif request.GET:
            qs = qs.filter(
                features__value__in=[v for _, vs in self.request.GET.lists() for v in vs]
        )
        if 'sort' in self.request.GET:
            qs = qs.order_by(self.request.GET['sort'])
        return qs

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['category'] = get_object_or_404(Category, pk=self.kwargs['pk'], slug=self.kwargs['slug'])
        return context

Таким образом, get_queryset здесь реализует расширенный запрос, который вы реализовали, и мы добавляем category, переопределяя get_queryset. Затем этот набор запросов будет автоматически постранично разбиваться по логике ListView.

Однако я бы посоветовал упростить логику, обычно расширенная фильтрация только увеличивает вероятность ошибок. Кроме того, упорядочивание по произвольному параметру создает уязвимость безопасности, например, можно попытаться отфильтровать по some_foreignkey__some_secure_field, чтобы раскрыть данные. Таким образом, вы можете захотеть проверить, что order находится в списке допустимых значений.

Вернуться на верх