Django-filter: Фильтр для Django-Taggit (запрос)

Созданный на 16 авг. 2016  ·  11Комментарии  ·  Источник: carltongibson/django-filter

Судя по звездам, django-taggit примерно так же популярен, как django-filter, и я считаю, что это

Что вы думаете о фильтре django-taggit?

Самое близкое, что у меня есть, это:

tags = django_filters.ModelMultipleChoiceFilter(
        name='tags__name',
        to_field_name='name',
        conjoined=True,
        distinct=True,
        queryset=Tag.objects.all(),
    )

Но я не могу сделать это без учета регистра (фильтр для тега TeSt должен возвращать результаты с тегом test).

Самый полезный комментарий

Рабочий пример с последними библиотеками:

from taggit.forms import TagField
from django_filters.views import FilterView

class TagFilter(django_filters.CharFilter):
    field_class = TagField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')
        super().__init__(*args, **kwargs)


class MyFilter(django_filters.FilterSet):
    tags = TagFilter(field_name='tags__name')

    class Meta:
        model = MyModel

Все 11 Комментарий

Чем TaggitFilter будет отличаться от обычного ModelMultipleChoiceFilter ?

Кроме того, я почти уверен, что мы могли бы добавить сюда поддержку lookup_expr , просто присоединив имя поля к поиску.

С ModelMultipleChoiceFilter URL-адрес должен быть field_name=tag1&field_name=tag2 , но может быть значительное количество тегов, что делает URL-адрес очень длинным. Не идеален, например, для URL-адреса, которым можно поделиться.

Теги обрабатываются django-taggit с использованием набора правил , позволяющих передавать одну строку, содержащую все теги.

Тем не менее, lookup_expr в ModelMultipleChoiceFilter определенно будут полезны!

Быстрый взгляд показывает, что у вас должна быть возможность использовать TagsField Taggit. Это даст вам их поведение при синтаксическом анализе csv.

class TagsFilter(CharFilter):
    field_class = taggit.forms.TagsField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')


class MyFilterSet(FilterSet):
    tags = TagsFilter(name='tags__name')

    class Meta:
        model = MyModel
GET http://localhost/api/my-model?tags=a,b,c,d

Предостережение здесь в том, что здесь используется поиск in , который не является решением без учета регистра, которое вы ищете.

Я более или менее не хочу добавлять специальный фильтр для Django Taggit, хотя это может быть отличный пакет.

В конечном итоге создать фильтры на уровне проекта не так уж и сложно. Достойная суть будет долгим. (Google отлично подходит для этого.)

С удовольствием посмотрю на пул-реквест A +, если он появится, но если не считать этого, я собираюсь закрыть это как выходящее за рамки.

Хорошо, достаточно честно. А как насчет поддержки lookup_expr в ModelMultipleChoiceFilter ?

@stantond Рад посмотреть на пиар. _Покажи мне Cödz_ 😀

Хотел бы я - к сожалению, я не опытный разработчик, а неуклюжий личный менеджер!

+1

Рабочий пример с последними библиотеками:

from taggit.forms import TagField
from django_filters.views import FilterView

class TagFilter(django_filters.CharFilter):
    field_class = TagField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')
        super().__init__(*args, **kwargs)


class MyFilter(django_filters.FilterSet):
    tags = TagFilter(field_name='tags__name')

    class Meta:
        model = MyModel

Используйте поле slug тега вместо поля name чтобы не учитывать регистр. Taggit по умолчанию уменьшает символы в нижнем регистре.

Обратите внимание, что мы можем расширить решение в https://github.com/carltongibson/django-filter/issues/460#issuecomment -507218839 с настраиваемым полем, если мы хотим поддерживать фильтр по одному тегу, содержащему один или несколько пробелов.

from django import forms
from django.utils.translation import gettext as _

from taggit.utils import parse_tags


class TagField(forms.CharField):

    def clean(self, value):
        value = super().clean(value)

        if "," not in value and '"' not in value and value:
            return [value]

        try:
            return parse_tags(value)
        except ValueError:
            raise forms.ValidationError(
                _("Please provide a comma-separated list of tags.")
            )

Код извлекается из taggit/forms.py .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги