Django-filter: рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХреЛрдИ рдлрд╝рд┐рд▓реНрдЯрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧред рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 6 рдирд╡ре░ 2015  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: carltongibson/django-filter

рдкреНрд░рд┐рдп рд╕рд╛рдерд┐рдпреЛ,

рдХреНрдпрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдлрд╝рд┐рд▓реНрдЯрд░ рдлрд╝реАрд▓реНрдб рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдореЗрдЯрд╛.рдлрд╝реАрд▓реНрдб рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЛрдИ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ?

рдпрджрд┐ рдРрд╕рд╛ рдХреЛрдИ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рдХрд░рдиреЗ рдХреЗ рд╕рд░реНрд╡реЛрддреНрддрдо рддрд░реАрдХреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдк рдХреНрдпрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрдВрдЧреЗ?

рд╕рд╛рджрд░,
рдПрдВрдбреНрд░рд┐рдпреБрд╕

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдУрд╡рд░рд░рд╛рдЗрдбрд┐рдВрдЧ 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

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреЗрдЬрд┐рдиреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рдмреА/рд╕реА рдбреЗрдЯрд╛ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ)ред рдРрд╕рд╛ рдХреБрдЫ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

        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

рд╕рднреА 6 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рд╣рд╛рдп @ рдПрдВрдбреНрд░рд┐рдпрд╕-рд╕реЗрдиреБрд▓рд┐рд╕ред 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']

рдореИрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдУрд╡рд░рд░рд╛рдЗрдбрд┐рдВрдЧ 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

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреЗрдЬрд┐рдиреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рдмреА/рд╕реА рдбреЗрдЯрд╛ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ)ред рдРрд╕рд╛ рдХреБрдЫ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

        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__ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рдпрд╛ рдЬреЛ рднреА рдЕрдиреНрдп рд╡рд┐рдзрд┐ рдареАрдХ рд╣реИ (рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдЖрдк рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдареАрдХ рд╣реИрдВ)ред

рдореИрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдУрд╡рд░рд░рд╛рдЗрдбрд┐рдВрдЧ 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

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдкреЗрдЬрд┐рдиреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ (рдмреА/рд╕реА рдбреЗрдЯрд╛ рдХреЛрдИ рдирд╣реАрдВ рд╣реИ)ред рдРрд╕рд╛ рдХреБрдЫ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

        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

рдЖрдкрдиреЗ рдореЗрд░рд╛ рджрд┐рди рдмрдирд╛ рджрд┐рдпрд╛!

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

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

chromakey picture chromakey  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

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

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

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

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