Django-filter: (2.0) يقوم FilterView دائمًا بإرجاع QuerySet الفارغة لمجموعة FilterSet غير المنضمة.

تم إنشاؤها على ٢٩ يونيو ٢٠١٨  ·  19تعليقات  ·  مصدر: carltongibson/django-filter

لدي عرض ، AccountList ، والذي يحاول عرض جدول django_table2. شفرة مصدر العرض:

class AccountList(SingleTableMixin, FilterView):
    model = Account
    table_class = AccountTable
    template_name = 'accounts/account_list.html'
    context_table_name = 'object_list'
    ordering = ['vps']

    filterset_class = AccountFilter

هذا العرض يستخدم حاليًا مجموعة المرشحات هذه (من django_filters):

import django_filters
from accounts.models import Account

class AccountFilter(django_filters.FilterSet):
    class Meta:
        model = Account
        fields = ['is_suspended', 'is_abandoned']

    is_suspended = django_filters.BooleanFilter(name='is_suspended', initial='False')
    is_abandoned = django_filters.BooleanFilter(name='is_abandoned', initial='False')

    def __init__(self, data=None, *args, **kwargs):
        # if filterset is bound, use initial values as defaults
        if data is not None:
            # get a mutable copy of the QueryDict
            data = data.copy()

            for name, f in self.base_filters.items():
                initial = f.extra.get('initial')

                # filter param is either missing or empty, use initial as default
                if not data.get(name) and initial:
                    data[name] = initial

        super().__init__(data, *args, **kwargs)

باستخدام هذا النموذج:

{% if filter %}
    <form action="" method="get" class="form form-inline">
        {{ filter.form.as_p }}
        <input type="submit" />
    </form>
{% endif %}

{% render_table object_list %}

{% endblock %}

هذا هو بلدي من urls.py الخاص بي

path('', login_required(AccountList.as_view())),

عندما أزور صفحتي ، 127.0.0.1:8000 ، أرى أن الفلاتر لم يتم تعيينها:
enter image description here

ولكن بعد ذلك إذا قمت بإجراء 127.0.0.1:8000?page=1 ، أرى أن الفلاتر قد تمت تهيئتها بشكل صحيح:

enter image description here

ما الذي يجعل عوامل التصفية الخاصة بي لا تحتوي على القيمة الافتراضية عندما لا يكون لدي صفحة = 1 ملحقة بعنوان url الخاص بي؟

Bug

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

نعم - بدأت العلاقات العامة ولكن اضطررت إلى تعليق عملي مفتوح المصدر. يجب أن أكون قادرًا على المتابعة من حيث توقفت قريبًا.

ال 19 كومينتر

حاول استخدام قيمة منطقية False فعلية بدلاً من قيمة السلسلة 'False' .

لذلك عندما حاولت ما يلي:

is_suspended = django_filters.BooleanFilter(name='is_suspended', initial=False)
is_abandoned = django_filters.BooleanFilter(name='is_abandoned', initial=False)

هذه هي الطريقة التي يتم بها عرض المرشحات على 127.0.0.1:8000/

image

على الرغم من تقديم الفلتر بالقيم الصحيحة ، لم يكن للفلتر أي تأثير حيث لا يزال بإمكاني رؤية الحسابات التي تم تعليقها أو التخلي عنها.

علاوة على ذلك ، عندما أزور الصفحة 2 بالضغط على الزر 2 في الأسفل ، أحصل على http://127.0.0.1:8000/?page=2 مع إعادة ضبط المرشحات على Unknown .

image

هل ترى أي سبب لماذا؟

آسف - لا شيء واضح يتبادر إلى الذهن.

بالنسبة إلى المشكلة الأولى ، أوصي بالنظر في استعلام SQL الناتج. تأكد من تطبيق المرشحات suspended و abandoned بالفعل.
بالنسبة للإصدار الثاني ، سأفحص البيانات الواردة. من المحتمل أنه تم توفير قيمة غير صالحة لمرشحات suspended و abandoned عند تغيير الصفحات.

أدخلت بعض بيانات الطباعة ووجدت ما يلي:

def __init__(self, data=None, *args, **kwargs):
    if data is not None:        # 1
        data = data.copy()

        for name, f in self.base_filters.items():
            initial = f.extra.get('initial')   

            # filter param is either missing or empty, use initial as default
            if not data.get(name) and initial:
                data[name] = initial

    super(BaseFilterSet, self).__init__(data, *args, **kwargs)

لذلك يبدو أن data هو None . هل ستعرف سبب عدم تمرير العرض المستند إلى الفصل الدراسي الخاص بي على data إلى AccountFilter ؟

جلالة الملك. يجب دائمًا تقديم الوسيطة data بواسطة FilterView .

https://github.com/carltongibson/django-filter/blob/b1f1c6592ef64a2172ec39040607a9c0b0714140/django_filters/views.py#L39 -L46

هل data فارغ للصفحتين الأولى والثانية؟

هذا غير قابل للعنونة كما هو. إغلاق معلّق معلومات كافية لتحديد مشكلة.

نفس المشكلة هنا بعد الترقية إلى 2.0. يجب أن تكون الصفحة الافتراضية أو عامل التصفية الفارغ موجودًا في عنوان URL للحصول على النتائج. هل هذا على الأقل موثق في مكان ما؟

ما زلت بحاجة إلى مزيد من المعلومات لتتمكن من التكاثر ...

page ؟ ألا يتعلق هذا بترقيمك للصفحات بدلاً من عامل تصفية Django؟

ما هي المعلومات المطلوبة بالضبط؟ الترقية إلى 2.0 تؤدي إلى السلوك الموصوف. يؤدي الرجوع إلى الإصدار 1.1.0 إلى إعادة كل شيء إلى طبيعته. لقد حاولت تبسيط العرض والمرشحات إلى الحد الأدنى قدر الإمكان ، واستمر السلوك ، لذلك يبدو أنه من السهل إلى حد ما إعادة إنتاجه.

moorchegue ، بسيط لحالة الاختبار أو مشروع اختبار يوضح المشكلة.

يبدو أيضًا أن المشكلة تتعلق بكل ما يوفر منطق ترقيم الصفحات. نعم ، قد يكون هناك بعض عدم التوافق مع الإصدار الجديد ، ولكن تصحيح الأخطاء في الحزم الأخرى خارج النطاق. تحتاج إلى إظهار خطأ في عامل تصفية Django حتى يكون هناك أي شيء يمكننا القيام به هنا.

حسنًا ، المشكلة هنا هي طريقة is_valid() المقدمة كجزء من # 788.

https://github.com/carltongibson/django-filter/blob/1dde11c70eedeac32f6de92c426deb289e1aebd8/django_filters/filterset.py#L202 -L206

يؤدي هذا تلقائيًا إلى إرجاع False عندما يكون data هو None .

في طريقة العرض ، نقوم بعد ذلك بتعيين object_list إلى qs.none() .

https://github.com/carltongibson/django-filter/blob/1dde11c70eedeac32f6de92c426deb289e1aebd8/django_filters/views.py#L80 -L83

ومن هنا جاء السلوك المرصود.

في اختبار لهذا لا هو الفشل لأن قالب اختبار يستخدم filter.qs بدلا من object_list .

https://github.com/carltongibson/django-filter/blob/1dde11c70eedeac32f6de92c426deb289e1aebd8/tests/templates/tests/book_filter.html#L3 -L5

يتمثل العمل الفوري في تعيين strict = False على مجموعة عوامل التصفية الخاصة بك. ينتج عن هذا أن معلمات التصفية غير الصالحة الفعلية ستؤدي إلى تصفية جزئية بدلاً من إظهار نتائج فارغة ، ولكن يجب أن تكون قابلة للتطبيق في الوقت الحالي. (الأفضل هو تجاوز المنطق get المنطق بالطبع ...)

سيكون لدينا تفكير وتحسين التعامل مع الحالة غير المقيدة.

جلالة الملك. النقص الأساسي هنا هو التباين بين object_list للعرض و FilterSet .qs . سيؤدي إعادة السلوك الصارم إلى FilterSet.qs إلى إصلاح ذلك.

بالإضافة إلى ذلك ، لا توجد معالجة صارمة / غير صارمة للواجهة الخلفية DRF.

سأعمل على حفظ هذا الأمر.

rpkilby هل هناك أي تقدم في هذه القضية؟

نعم - بدأت العلاقات العامة ولكن اضطررت إلى تعليق عملي مفتوح المصدر. يجب أن أكون قادرًا على المتابعة من حيث توقفت قريبًا.

لاحظ أن الحل يجب أن يكون تعيين strict = False على سليلك FilterMixin (على الأرجح View .

لا يمكنك فقط تغيير الشرط لإرجاع qs في حالة النموذج غير المحدود؟

على سبيل المثال

-        if self.filterset.is_valid() or not self.get_strict():
+        if not self.filterset.is_bound or self.filterset.is_valid() or not self.get_strict():

https://github.com/carltongibson/django-filter/pull/1007

شكرا.

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