ركضت إلى …
Traceback (most recent call last):
[..]
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 393, in _clean_fields
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
File "/usr/local/lib/python3.7/site-packages/django_filters/widgets.py", line 201, in value_from_datadict
return value.split(',')
AttributeError: 'list' object has no attribute 'split'
ووجدت أن الرمز في ...
https://github.com/carltongibson/django-filter/blob/1f47e36b614724a8735e0457fa511dcaf5448481/django_filters/widgets.py#L195 -L202
... ليس قويًا فيما يتعلق بإرجاع قائمة super().value_from_datadict(data, files, name)
. أحتاج إلى تصحيح هذا الأمر أكثر ولكن ربما تعرف بالفعل ما الذي يحدث هنا؟
مرحباmoseb. هل يمكنك لصق كود FilterSet الذي تستخدمه؟ الأسطر القليلة الأخيرة من التتبع الخلفي كافية لتحديد سبب وصولك إلى هذا الاستثناء.
التتبع الكامل:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/wsgiref/handlers.py", line 137, in run
self.result = application(self.environ, self.start_response)
File "/usr/local/lib/python3.7/site-packages/django/contrib/staticfiles/handlers.py", line 65, in __call__
return self.application(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 141, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 75, in get_response
response = self._middleware_chain(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/utils/deprecation.py", line 94, in __call__
response = response or self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django_global_request/middleware.py", line 15, in __call__
return self.get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/usr/local/lib/python3.7/site-packages/django/template/response.py", line 106, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.7/site-packages/rest_framework/response.py", line 72, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.7/site-packages/rest_framework/renderers.py", line 733, in render
context = self.get_context(data, accepted_media_type, renderer_context)
File "/usr/local/lib/python3.7/site-packages/rest_framework/renderers.py", line 710, in get_context
'filter_form': self.get_filter_form(data, view, request),
File "/usr/local/lib/python3.7/site-packages/rest_framework/renderers.py", line 642, in get_filter_form
html = backend().to_html(request, queryset, view)
File "/usr/local/lib/python3.7/site-packages/rest_framework_filters/backends.py", line 52, in to_html
return super().to_html(request, queryset, view)
File "/usr/local/lib/python3.7/site-packages/django_filters/rest_framework/backends.py", line 105, in to_html
return template.render(context, request)
File "/usr/local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 171, in render
return self._render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 937, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/site-packages/crispy_forms/templatetags/crispy_forms_tags.py", line 199, in render
c = self.get_render(context).flatten()
File "/usr/local/lib/python3.7/site-packages/crispy_forms/templatetags/crispy_forms_tags.py", line 118, in get_render
actual_form.form_html = helper.render_layout(actual_form, node_context, template_pack=self.template_pack)
File "/usr/local/lib/python3.7/site-packages/crispy_forms/helper.py", line 308, in render_layout
template_pack=template_pack
File "/usr/local/lib/python3.7/site-packages/crispy_forms/layout.py", line 140, in render
return self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
File "/usr/local/lib/python3.7/site-packages/crispy_forms/layout.py", line 104, in get_rendered_fields
for field in self.fields
File "/usr/local/lib/python3.7/site-packages/crispy_forms/layout.py", line 104, in <genexpr>
for field in self.fields
File "/usr/local/lib/python3.7/site-packages/crispy_forms/utils.py", line 148, in render_field
html = template.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 171, in render
return self._render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 163, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 937, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/defaulttags.py", line 309, in render
return nodelist.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 937, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/defaulttags.py", line 309, in render
return nodelist.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 937, in render
bit = node.render_annotated(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 904, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.7/site-packages/django/template/defaulttags.py", line 302, in render
match = condition.eval(context)
File "/usr/local/lib/python3.7/site-packages/django/template/defaulttags.py", line 876, in eval
return self.value.resolve(context, ignore_failures=True)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 671, in resolve
obj = self.var.resolve(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 796, in resolve
value = self._resolve_lookup(context)
File "/usr/local/lib/python3.7/site-packages/django/template/base.py", line 837, in _resolve_lookup
current = getattr(current, bit)
File "/usr/local/lib/python3.7/site-packages/django/forms/boundfield.py", line 74, in errors
return self.form.errors.get(self.name, self.form.error_class())
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 180, in errors
self.full_clean()
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 381, in full_clean
self._clean_fields()
File "/usr/local/lib/python3.7/site-packages/django/forms/forms.py", line 393, in _clean_fields
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
File "/usr/local/lib/python3.7/site-packages/django_filters/widgets.py", line 201, in value_from_datadict
return value.split(',')
AttributeError: 'list' object has no attribute 'split'
[12/Jul/2019 13:49:06] "GET /XXXXXXXX/?ordering=first_name HTTP/1.1" 500 59
إنه من تصفح قائمة حيث يقوم django-rest-framework بإنشاء الكود.
مرحباmoseb. هل يمكنك لصق كود FilterSet الذي تستخدمه؟
لأكون صادقًا ، لم أجد أيًا في هذا المجال من الكود ، حتى الآن. قد يكون كل ذلك بواسطة DRF. لست متأكدا بعد.
أدرك أن تقرير الخطأ الخاص بي ليس مثاليًا ولكنه أفضل ما لدي الآن. آسف!
يجب أن يكون عرض واجهة برمجة التطبيقات إما filterset_class
أو filterset_fields
، أو إذا كنت تستخدم إصدارًا أقدم من مرشح django ، filter_class
و filter_fields
.
لقد اكتشفت استخدام filter_class
- لذا أعتقد أنك ساعدتني للتو في العثور على أن الترحيل إلى django-filter 2.0 لم يتم بشكل صحيح حتى نهايته. رائع!
هل هناك شيء يمنع django-filter من اكتشاف بقايا الطعام قبل 2.x والتحذير منها ، من الناحية المفاهيمية؟ هل يحذر ولكن فاتني؟ هل رمز التحذير بشأن هذه إضافة مرحب بها لطلب السحب؟
أزال الإصدار 2.0 الكثير من تحذيرات الإيقاف الحالية ، لذلك قد تحاول تشغيل مجموعة الاختبار الخاصة بك مقابل v1.0 ثم v1.1 من django-filter.
على افتراض أن هذا سيحل نفسه عند التحديث. عد إذا لم يكن كذلك.
يوجد عرض توضيحي قابل لإعادة الإنتاج للمشكلة الآن على https://github.com/moseb/django-filter-issue-1103-demo. يرجى النظر في إعادة فتح هذه المشكلة. شكرا لك!
آه ، هذا مرتبط بعدم توافق ModelMultipleChoiceFilter
مع مزيج CSV ، بالإضافة إلى in
lookup. قضيتان منفصلتان ولكن مرتبطتان هنا.
لا يجب أن تحتاج إلى بحث in
لحقول m2m ، لأن مرشح الاختيار من متعدد يوفر بالفعل سلوكًا مشابهًا.
مرحبا!
آه ، هذا مرتبط بعدم توافق
ModelMultipleChoiceFilter
مع مزيج CSV ، بالإضافة إلىin
lookup. قضيتان منفصلتان ولكن مرتبطتان هنا.
هل توجد تذاكر حالية على GitHub لهذه المشكلات؟
يبدو أن جعل BaseCSVWidget.value_from_datadict
أكثر قوة كما هو مذكور أعلاه وحده لن يحل المشكلة؟ (لم أفهم المشكلة تمامًا حتى الآن).
لا يجب أن تحتاج إلى بحث
in
لحقول m2m ، لأن مرشح الاختيار من متعدد يوفر بالفعل سلوكًا مشابهًا.
يسمح in
بالتحقق من قيم متعددة تزيد عن exact
. إذا لم أتمكن من استخدام ìn
، كيف يمكنني التحقق من القيم المتعددة؟
ملاحظة: هل يمكننا إعادة فتح هذه التذكرة؟
يبدو أن جعل
BaseCSVWidget.value_from_datadict
أكثر قوة كما هو مذكور أعلاه وحده لن يحل المشكلة؟ (لم أفهم المشكلة تمامًا حتى الآن).
ربما. إذا كانت القيمة قائمة بالفعل ، فيجب أن تمضي قدمًا وتعيد تلك القائمة. ومع ذلك ، لا أعتقد أنه من المنطقي خلط سلوك CSV مع عنصر واجهة المستخدم SelectMultiple
.
يسمح
in
بالتحقق من قيم متعددة تزيد عنexact
. إذا لم أتمكن من استخدامìn
، كيف يمكنني التحقق من القيم المتعددة؟
ينشئ ModelMultipleChoiceFilter
استعلام OR من كائنات Q. لذلك ، إذا كان لديك سلسلة استعلام مثل /api/mymodel?m2m=a&m2m=b
، فسينتهي بك الأمر باستخدام مرشح مثل
MyModel.objects.filter(Q(m2m='a') | Q(m2m='b'))
مع الإصدار 2.1 ، يتم الآن تطبيق lookup_expr
على كل كائن Q ، لذلك ينتهي بك الأمر مع
MyModel.objects.filter(Q(m2m__in='a') | Q(m2m__in='b'))
ما ورد أعلاه غير صالح وقد ينكسر ، ومع ذلك فمن المنطقي أن contains
وعمليات البحث الأخرى التي تهدف إلى العمل مع قيم فردية.
لذلك ، باختصار ، كل ما عليك فعله هنا هو استخدام exact
للبحث عن حقل m2m الخاص بك.
أعتقد أن ما يجب فعله هنا هو:
BaseCSVWidget
متوافقًا مع SelectMultiple
بإرجاع القيمة إذا كانت قائمة بالفعل. أو إذا لم يكن متوافقًا ، فيجب على الأقل تقديم خطأ مفيد في init.Meta.fields
للمتر المربع. إنشاء بحث in
عن ModelMultipleChoiceFilter
أمر غير منطقي. يجب علينا أيضًا اختبار ما يحدث لعمليات البحث الأخرى مثل isnull
، والتي تتوقع قيمة منطقية.نعم ، لا يزال هذا لا يبدو وكأنه خطأ ولكن كيف يعمل كل شيء تحت التوثيق على ما أعتقد ...
لقد حصلت للتو على هذا الخطأ وتفسيره مدفون في هذا الموضوع ، لذا لتلخيص وحفظ بحث طويل عن القراء في المستقبل:
الحقول ManyToMany
المعلنة في مجموعات العرض ' filterset_fields
يجب ألا تحتوي على in
تحذير في وقت التشغيل سيكون موضع تقدير كبير.
marcosox فكرة جيدة. سعيد لإلقاء نظرة على العلاقات العامة مضيفا ذلك!
التعليق الأكثر فائدة
لقد حصلت للتو على هذا الخطأ وتفسيره مدفون في هذا الموضوع ، لذا لتلخيص وحفظ بحث طويل عن القراء في المستقبل:
الحقول
ManyToMany
المعلنة في مجموعات العرض 'filterset_fields
يجب ألا تحتوي علىin
تحذير في وقت التشغيل سيكون موضع تقدير كبير.