рд╕рд┐рддрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рдирд╛, 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' рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ 'рдЯреЗрд╕реНрдЯ' рдЯреИрдЧ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рдПрдЧрд╛)ред
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
рд╕реЗ рдирд┐рдХрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдирд╡реАрдирддрдо рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдЙрджрд╛рд╣рд░рдг: