๋ณ์ ์ผ๋ก ๋ณด๋ฉด django-taggit ์ django-filter๋งํผ ์ธ๊ธฐ๊ฐ ์์ผ๋ฉฐ Django์์ ํ๊ทธ๋ฅผ ์ง์ ํ๊ธฐ ์ํ ์ต๊ณ ์ ์๋ฃจ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. 2010๋ ๋ถํฐ ์ฌ์ฉ๋์์ผ๋ฉฐ ์ ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ฉฐ ์ฌ๋ฌ ๋ช ์ ์ ๊ธฐ ๊ธฐ๊ณ ์๊ฐ ์์ต๋๋ค.
django-taggit ํํฐ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ธ์?
๋ด๊ฐ ์ด๊ฒ์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
tags = django_filters.ModelMultipleChoiceFilter(
name='tags__name',
to_field_name='name',
conjoined=True,
distinct=True,
queryset=Tag.objects.all(),
)
ํ์ง๋ง ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์๋๋ก ํ ์๋ ์์ต๋๋ค('TeSt' ํ๊ทธ์ ๋ํ ํํฐ๋ 'test' ํ๊ทธ๊ฐ ์๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผ ํจ).
TaggitFilter
์ ์ผ๋ฐ ModelMultipleChoiceFilter
์ด๋ป๊ฒ ๋ค๋ฆ
๋๊น?
๋ํ ๋จ์ํ ์กฐํ์ ํ๋ ์ด๋ฆ์ ๊ฒฐํฉํ์ฌ ์ฌ๊ธฐ ์ lookup_expr
์ง์์ ์ถ๊ฐํ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค.
ModelMultipleChoiceFilter
๊ฒฝ์ฐ URL์ field_name=tag1&field_name=tag2
์ฌ์ผ ํ์ง๋ง ํ๊ทธ๊ฐ ๋ง์ URL์ด ๋งค์ฐ ๊ธธ์ด์ง ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ณต์ ํ ์ ์๋ URL์๋ ์ ํฉํ์ง ์์ต๋๋ค.
ํ๊ทธ๋ ์ผ๋ จ์ ๊ท์น์ ์ฌ์ฉํ์ฌ django-taggit์ ์ํด ์ฒ๋ฆฌ๋์ด ๋ชจ๋ ํ๊ทธ๋ฅผ ํฌํจํ๋ ๋จ์ผ ๋ฌธ์์ด์ ์ ๋ฌํ ์ ์์ต๋๋ค.
์ด์จ๋ lookup_expr
์ ModelMultipleChoiceFilter
๋ ํ์คํ ๋์์ด ๋ ๊ฒ์
๋๋ค!
๊ฐ๋จํ ์ดํด๋ณด๋ฉด Taggit์ TagsField
๋ฅผ ์ฌ์ฉํ ์ ์์ด์ผ ํจ์ ์ ์ ์์ต๋๋ค. ์ด๊ฒ์ 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+ ํ ๋ฆฌํ์คํธ๊ฐ ๋ํ๋๋ฉด ๊ธฐ์๊ฒ ์๊ฐํ์ง๋ง, ๊ทธ ์ธ์๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๊ฒ์ผ๋ก ๋ง๋ฌด๋ฆฌํ๊ฒ ์ต๋๋ค.
์๊ฒ ์ต๋๋ค. ์ถฉ๋ถํ ๊ณต์ ํฉ๋๋ค. ModelMultipleChoiceFilter
lookup_expr
์ง์์ ์ด๋ป์ต๋๊น?
@stantond PR์ ๋ณด๋
๋๋ ํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๋ถํํ๋ ์ ๋ ์๋ จ๋ ๊ฐ๋ฐ์๊ฐ ์๋๋ผ ๋๋ฌ๊ฑฐ๋ฆฌ๋ PM์ ๋๋ค!
+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
ํ๋๋ฅผ ์ฌ์ฉํ์ธ์. 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
์์ ์ถ์ถ๋ฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์์ ์: