์ฌ๋ฌ๋ถ ๋ชจ๋์๊ฒ,
Meta.fields์์ ์ ์ํ ๋งค๊ฐ๋ณ์๊ฐ ์์ฒญ ๊ฐ์ฒด์์ ๋ฐ๊ฒฌ๋์ง ์์ ๊ฒฝ์ฐ ์ฌ์ฉํ ๊ธฐ๋ณธ ํํฐ ํ๋ ๋ฐ ๊ฐ์ ์ค์ ํ๋ ์ต์ ์ด ์์ต๋๊น?
๊ทธ๋ฌํ ์ต์ ์ด ์๋ค๋ฉด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ผ๋ก ๋ฌด์์ ์ ์ํ์๊ฒ ์ต๋๊น?
๋ฌธ์ ์ธ์ฌ,
์๋๋ฆฌ์ฐ์ค
์๋
ํ์ธ์ @andrius-senulis์
๋๋ค. django-filter๋ ์ผ๋ฐ django ์์ ์์ ๊ตฌ์ถ๋์์ผ๋ฏ๋ก ์ด ์ง๋ฌธ์ "๋ฐ์ด๋ ์์์ ๊ธฐ๋ณธ ํ๋ ๊ฐ์ ์ด๋ป๊ฒ ์ ๊ณตํฉ๋๊น?"๋ก ์์ฝํ ์ ์์ต๋๋ค. ์ด SO ๋ต๋ณ ์ ๋ฐ๋ผ ์์์ clean_<field_name>
๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ๊ธฐ๋ณธ๊ฐ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ถํํ๋ ๊ธฐ๋ณธ ์์ ํด๋์ค๋ ์ง์ ๋
ธ์ถ๋์ง ์์ผ๋ฏ๋ก ํ์ ํด๋์ค๋ก ๋ง๋ค๊ณ ํด๋น ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค (ํธ์ง ์ฐธ์กฐ). ์ฆ, ํํฐ์๋ ๊ธฐ๋ณธ ์์ ํ๋๊ฐ ์์ผ๋ฏ๋ก ํ๋๋ฅผ ํ์ ๋ถ๋ฅํ๊ณ clean()
๋ฉ์๋๋ฅผ ์ฌ์ ์ํ ์ ์์ต๋๋ค. ์กฐ๊ธ ๋ฒ๊ฑฐ๋กญ์ต๋๋ค. ์,
class DecimalDefaultField(forms.DecimalField):
def clean(self, value):
if value is None:
return 4.0
return super(DecimalDefaultField, self).clean(value)
class NumberDefaultFilter(filters.NumberFilter):
field_class = DecimalDefaultField
class MyFilterSet(FilterSet):
some_field = NumberDefaultFilter(name='some_field')
...
๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฌํ๊ณ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ๋ ๊ฒ์ ๋๋ค.
def your_view(request):
data = request.GET.copy()
data.setdefault('some_field', 'some_value')
f = YourFilterSet(data, queryset=YourModel.objects.all())
...
ํธ์งํ๋ค:
์ค์ ๋ก FilterSet.Meta
๊ธฐ๋ณธ ์์์ ์ ๊ณตํ ์ ์์ผ๋ฉฐ ์ด๋ ๋ด๋ถ์ ์ผ๋ก ํ์ ๋ถ๋ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ clean_<field name>
๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
class MyForm(forms.Form):
clean_some_field(self, value):
...
class MyFilterSet(FilterSet):
class Meta:
model = MyModel
form = MyForm
fields = ['some_field']
FilterView๋ฅผ ์ฌ์ฉํฉ๋๋ค. get_filterset_kwargs ์ฌ์ ์๊ฐ ์ ์๊ฒ ํจ๊ณผ์ ์ ๋๋ค.
class MyFilterView(FilterView):
filterset_class = filters.MyFilter
# ...
def get_filterset_kwargs(self, filterset_class):
kwargs = super(MyFilterView, self).get_filterset_kwargs(filterset_class)
if kwargs["data"] is None:
kwargs["data"] = {"is_very_interesting": False}
return kwargs
ํธ์ง: ์๋ฅผ ๋ค์ด ํ์ด์ง ๋งค๊น์ ์ฌ์ฉํ ๋ ์ด๊ฒ์ ์ ์ฉ๋์ง ์์ต๋๋ค(b/c ๋ฐ์ดํฐ๋ ์์์ด ์๋). ๋ค์๊ณผ ๊ฐ์ด ์๋ํ ์ ์์ต๋๋ค.
if kwargs["data"] is None:
kwargs["data"] = {"is_very_interesting": False}
elif "is_very_interesting" not in kwargs["data"]:
kwargs["data"] = kwargs["data"].copy()
kwargs["data"]["is_very_interesting"] = False
__init__
์ฌ์ฉํ๋ฉด ํจ๊ณผ์ ์ด์์ต๋๋ค. (์ด๊ฒ์ djangorestframework-filters
์ด์ง๋ง ๋ฐ๋๋ผ django-filter
์ ๊ฐ๋ค๊ณ ์๊ฐํฉ๋๋ค):
class MyFilter(filters.FilterSet):
foo = ...
def __init__(self, data, *args, **kwargs):
if not data.get('foo'):
data = data.copy()
data['foo'] = 'bar'
super().__init__(data, *args, **kwargs)
__init__
ํ๋ ๋ฐฉ๋ฒ์ ๊ถ์ฅ๋์ง ์์ผ๋ฉฐ ๋งํฌ์ ์ค๋ช
๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ํ์ง ์์์ต๋๋ค... https://django-filter.readthedocs.io/en/master/guide/tips.html # ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐ๊ฐ ์ฌ์ฉ
get_filterset_kwargs
์ FilterView
๊ฐ ์ ์๊ฒ ํจ๊ณผ์ ์ด์์ต๋๋ค.
__init__
์ ๊ถ์ฅ๋์ง ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๊ธฐ๋ณธ ์์/ํํฐ ๊ฐ์ ์ ๊ณตํ๋ ๊ฒ์ ํผ๋์ค๋ฝ๊ฑฐ๋ ๋ถ์ ์ ์ธ ์ํฅ์ ์ค ์ ์๋ ๋์ ์ต๊ด์ด๋ผ๋ ์ ์์ ๊ถ์ฅ๋์ง ์์ต๋๋ค. __init__
๋๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ํตํด ๊ตฌํํ๋ ๊ฒ์ด ์ข์ต๋๋ค(ํจ๊ณผ์ ๋ํด ๊ด์ฐฎ๋ค๋ฉด).
FilterView๋ฅผ ์ฌ์ฉํฉ๋๋ค. get_filterset_kwargs ์ฌ์ ์๊ฐ ์ ์๊ฒ ํจ๊ณผ์ ์ ๋๋ค.
class MyFilterView(FilterView): filterset_class = filters.MyFilter # ... def get_filterset_kwargs(self, filterset_class): kwargs = super(MyFilterView, self).get_filterset_kwargs(filterset_class) if kwargs["data"] is None: kwargs["data"] = {"is_very_interesting": False} return kwargs
ํธ์ง: ์๋ฅผ ๋ค์ด ํ์ด์ง ๋งค๊น์ ์ฌ์ฉํ ๋ ์ด๊ฒ์ ์ ์ฉ๋์ง ์์ต๋๋ค(b/c ๋ฐ์ดํฐ๋ ์์์ด ์๋). ๋ค์๊ณผ ๊ฐ์ด ์๋ํ ์ ์์ต๋๋ค.
if kwargs["data"] is None: kwargs["data"] = {"is_very_interesting": False} elif "is_very_interesting" not in kwargs["data"]: kwargs["data"] = kwargs["data"].copy() kwargs["data"]["is_very_interesting"] = False
๋น์ ์ ๋ด ํ๋ฃจ๋ฅผ ๋ง๋ค์์ต๋๋ค!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
FilterView๋ฅผ ์ฌ์ฉํฉ๋๋ค. get_filterset_kwargs ์ฌ์ ์๊ฐ ์ ์๊ฒ ํจ๊ณผ์ ์ ๋๋ค.
ํธ์ง: ์๋ฅผ ๋ค์ด ํ์ด์ง ๋งค๊น์ ์ฌ์ฉํ ๋ ์ด๊ฒ์ ์ ์ฉ๋์ง ์์ต๋๋ค(b/c ๋ฐ์ดํฐ๋ ์์์ด ์๋). ๋ค์๊ณผ ๊ฐ์ด ์๋ํ ์ ์์ต๋๋ค.