Django Фильтры - Редактировать набор запросов на основе слаг из URL - PullRequest
1 голос
/ 19 апреля 2020

Итак, у меня есть простая модель, которая называется Pages. Каждая страница принадлежит определенной категории, поскольку это отношение ForeignKey, страница может принадлежать только одной категории.

Помимо категорий, мы также используем теги для дополнительной фильтрации различных страниц.

Мы используем представление категорий для отображения всех страниц, принадлежащих к определенной категории, easy peasy.

Дело в том, что мы используем django -фильтры для фильтрации страниц, выбирая различные теги. Список тегов увеличивается на количество страниц. Поэтому я хотел бы показывать только связанные теги для категории.

urls.py

path('<slug:category_slug>/', views.PageByCategoryView.as_view(), name='page_by_category'),

views.py

class PageByCategoryView(FilterView):
    logger.info("Category view is called")
    model = Page
    filterset_class = PageByCategoryFilter
    strict = False
    queryset = Page.published_objects.all()
    template_name = 'pages/page_by_category.html'

filters.py

   class PageByCategoryFilter(django_filters.FilterSet):
        tags = django_filters.ModelMultipleChoiceFilter(
            queryset=Tag.objects.filter(page__category_id='2'), <-- actually works!
            conjoined=True,
            widget=forms.CheckboxSelectMultiple()
        )

        class Meta:
            model = Page
            fields = [
                'tags__slug'
            ]

Таким образом, теги, используемые в фильтре, на самом деле фильтруются по page__category_id = 2, это именно то, чего я хочу достичь, хотя я хочу сделать это динамически. Я пытался определить qs следующим образом:

@property
def qs(self):
        queryset = super(PageByCategoryFilter, self).qs
        current_category = self.request.GET.get('category_slug')
        if current_category:
            logger.info("Current category is in url")
            return queryset.filter(category__slug=current_category)
        return queryset

Это просто не работает, как я могу получить current_category из URL?

Хорошо, что я сделал ниже на самом деле работает, но выглядит вроде хаки sh .. У кого-нибудь есть лучший ответ по решению этой проблемы?

def category_filter(request):
    path = request.path
    category_slug = re.sub('\/+', r'', path)
    current_category = category_slug
    return Tag.objects.filter(page__category__slug=current_category).distinct()

С наилучшими пожеланиями,

Кевин

1 Ответ

0 голосов
/ 19 апреля 2020

Ваша исходная функция просмотра должна иметь возможность принимать параметр category_slug, в котором передается фрагмент категории URL, например в этом примере из Django документов (обратите внимание, как num объявляется как int в URL, а затем передается в качестве аргумента page):

В urls.py

    path('blog/page<int:num>/', views.page),

В функции просмотра

def page(request, num=1):
    ...

Если вы используете Django REST, вы сможете получить параметр URL вашего атрибута kwargs member, примерно так :

In urls.py

url('^purchases/(?P<username>.+)/$', PurchaseList.as_view()),

На ваш взгляд, классы:

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        This view should return a list of all the purchases for
        the user as determined by the username portion of the URL.
        """
        username = self.kwargs['username']  # this is what you're after
        return Purchase.objects.filter(purchaser__username=username)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...