Django-filter: التصفية الافتراضية عند عدم تمرير معلمات عامل التصفية في request.GET

تم إنشاؤها على ٦ نوفمبر ٢٠١٥  ·  6تعليقات  ·  مصدر: carltongibson/django-filter

أعزائي،

هل هناك خيار لتعيين حقل المرشح الافتراضي والقيمة لاستخدامهما إذا لم يتم العثور على معلمة أحددها في Meta.fields في كائن الطلب؟

إذا لم يكن هناك مثل هذا الخيار ، فماذا تقترح كأفضل طريقة للقيام بذلك؟

يعتبر،
أندريوس

التعليق الأكثر فائدة

أنا استخدم 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

ال 6 كومينتر

مرحبًا @ andrius-senulis. تم إنشاء مرشح django أعلى نماذج 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

انت صنعت يومي!

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات