لدي عرض ، 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
، أرى أن الفلاتر لم يتم تعيينها:
ولكن بعد ذلك إذا قمت بإجراء 127.0.0.1:8000?page=1
، أرى أن الفلاتر قد تمت تهيئتها بشكل صحيح:
حاول استخدام قيمة منطقية 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/
على الرغم من تقديم الفلتر بالقيم الصحيحة ، لم يكن للفلتر أي تأثير حيث لا يزال بإمكاني رؤية الحسابات التي تم تعليقها أو التخلي عنها.
علاوة على ذلك ، عندما أزور الصفحة 2 بالضغط على الزر 2
في الأسفل ، أحصل على http://127.0.0.1:8000/?page=2
مع إعادة ضبط المرشحات على Unknown
.
هل ترى أي سبب لماذا؟
آسف - لا شيء واضح يتبادر إلى الذهن.
بالنسبة إلى المشكلة الأولى ، أوصي بالنظر في استعلام 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
.
هل data
فارغ للصفحتين الأولى والثانية؟
هذا غير قابل للعنونة كما هو. إغلاق معلّق معلومات كافية لتحديد مشكلة.
نفس المشكلة هنا بعد الترقية إلى 2.0. يجب أن تكون الصفحة الافتراضية أو عامل التصفية الفارغ موجودًا في عنوان URL للحصول على النتائج. هل هذا على الأقل موثق في مكان ما؟
ما زلت بحاجة إلى مزيد من المعلومات لتتمكن من التكاثر ...
page
؟ ألا يتعلق هذا بترقيمك للصفحات بدلاً من عامل تصفية Django؟
ما هي المعلومات المطلوبة بالضبط؟ الترقية إلى 2.0 تؤدي إلى السلوك الموصوف. يؤدي الرجوع إلى الإصدار 1.1.0 إلى إعادة كل شيء إلى طبيعته. لقد حاولت تبسيط العرض والمرشحات إلى الحد الأدنى قدر الإمكان ، واستمر السلوك ، لذلك يبدو أنه من السهل إلى حد ما إعادة إنتاجه.
moorchegue ، بسيط لحالة الاختبار أو مشروع اختبار يوضح المشكلة.
يبدو أيضًا أن المشكلة تتعلق بكل ما يوفر منطق ترقيم الصفحات. نعم ، قد يكون هناك بعض عدم التوافق مع الإصدار الجديد ، ولكن تصحيح الأخطاء في الحزم الأخرى خارج النطاق. تحتاج إلى إظهار خطأ في عامل تصفية Django حتى يكون هناك أي شيء يمكننا القيام به هنا.
حسنًا ، المشكلة هنا هي طريقة is_valid()
المقدمة كجزء من # 788.
يؤدي هذا تلقائيًا إلى إرجاع False
عندما يكون data
هو None
.
في طريقة العرض ، نقوم بعد ذلك بتعيين object_list
إلى qs.none()
.
ومن هنا جاء السلوك المرصود.
في اختبار لهذا لا هو الفشل لأن قالب اختبار يستخدم filter.qs
بدلا من object_list
.
يتمثل العمل الفوري في تعيين 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
شكرا.
التعليق الأكثر فائدة
نعم - بدأت العلاقات العامة ولكن اضطررت إلى تعليق عملي مفتوح المصدر. يجب أن أكون قادرًا على المتابعة من حيث توقفت قريبًا.