Django-filter: Django-Taggit рдХреЗ рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ (рдЕрдиреБрд░реЛрдз)

рдХреЛ рдирд┐рд░реНрдорд┐рдд 16 рдЕрдЧре░ 2016  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: carltongibson/django-filter

рд╕рд┐рддрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рдирд╛, django-taggit django-filter рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИ, рдФрд░ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ Django рдореЗрдВ рдЯреИрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЬрд╛рдиреЗ-

рдЖрдк django-taggit рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реИрдВ?

рдореБрдЭреЗ рдЗрд╕рдХреЗ рд╕рдмрд╕реЗ рдХрд░реАрдм рдорд┐рд▓рд╛ рд╣реИ:

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

рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рдХреЗрд╕-рдЕрд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ (рдЯреИрдЧ '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 рдХреЗ рд▓рд┐рдП рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИред

рдЯреИрдЧ рдХреЛ рдирд┐рдпрдореЛрдВ рдХреЗ рдПрдХ рд╣реИ , рдЬрд┐рд╕рд╕реЗ рд╕рднреА рдЯреИрдЧ рд╡рд╛рд▓реЗ рдПрдХрд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рднрд▓реЗ рд╣реА, lookup_expr рдореЗрдВ ModelMultipleChoiceFilter рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдорджрджрдЧрд╛рд░ рд╣реЛрдЧрд╛!

рдПрдХ рддреНрд╡рд░рд┐рдд рд░реВрдк рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЯреИрдЧрдЧрд┐рдЯ рдХреЗ TagsField рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЖрдкрдХреЛ рдЙрдирдХрд╛ рд╕реАрдПрд╕рд╡реА рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╡реНрдпрд╡рд╣рд╛рд░ рджреЗрдЧрд╛ред

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 рдЯреИрдЧрдЧрд┐рдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд┐рд▓реНрдЯрд░ рдирд╣реАрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдкреИрдХреЗрдЬ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЕрдВрддрддрдГ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрддрд░реАрдп рдлрд╝рд┐рд▓реНрдЯрд░ рдмрдирд╛рдирд╛ рдЗрддрдирд╛ рдХрдард┐рди рдирд╣реАрдВ рд╣реИред рдПрдХ рд╕рднреНрдп рд╕рд╛рд░ рдПрдХ рд▓рдВрдмрд╛ рд░рд╛рд╕реНрддрд╛ рддрдп рдХрд░реЗрдЧрд╛ред (Google рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред)

рдпрджрд┐ рдХреЛрдИ рдЖрддрд╛ рд╣реИ рддреЛ A+ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЛ рджреЗрдЦрдХрд░ рдЦреБрд╢реА рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЙрд╕рд╕реЗ рдХрдо рдореИрдВ рдЗрд╕реЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред

рдареАрдХ рд╣реИ рдкрд░реНрдпрд╛рдкреНрдд рдареАрдХ рд╣реИред lookup_expr рдореЗрдВ ModelMultipleChoiceFilter рд╕рдорд░реНрдерди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

@stantond рдПрдХ рдкреАрдЖрд░ рдХреЛ

рдХрд╛рд╢ рдореИрдВ рдХрд░ рдкрд╛рддрд╛ - рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореИрдВ рдПрдХ рдХреБрд╢рд▓ рдбреЗрд╡рд▓рдкрд░ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд▓рдбрд╝рдЦрдбрд╝рд╛рддрд╛ рд╣реБрдЖ рдкреНрд░рдзрд╛рди рдордВрддреНрд░реА рд╣реВрдВ!

+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

рдХреЗрд╕ рдЕрд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП name рдлрд╝реАрд▓реНрдб рдХреЗ рдмрдЬрд╛рдп рдЯреИрдЧ рдХреЗ slug рдлрд╝реАрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЯреИрдЧрдЧрд┐рдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрд▓рдЧ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рд╣рдо рдПрдХ рдпрд╛ рдЕрдзрд┐рдХ рд╡реНрд╣рд╛рдЗрдЯрд╕реНрдкреЗрд╕ рд╡рд╛рд▓реЗ рдПрдХрд▓ рдЯреИрдЧ рджреНрд╡рд╛рд░рд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрд╕реНрдЯрдо рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде 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 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

blueyed picture blueyed  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Alexx-G picture Alexx-G  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

nhuzaa picture nhuzaa  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

GuillaumeCisco picture GuillaumeCisco  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

loganknecht picture loganknecht  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ