مرحبا،
أنا أستخدم django-filter مع إطار عمل django-rest-framework ، هذا لا يعمل ، إنه لا يُرجع شيئًا:
import django_filters
from rest_framework import filters
from ..models import MyModel
class MyModelFilter(filters.FilterSet):
my_field = django_filters.CharFilter(lookup_expr='in')
class Meta:
model = MyModel
لكن هذا يعمل ويعمل كما هو متوقع:
from django_filters import filters as df_filters
from rest_framework import filters
from ..models import MyModel
class CharInFilter(df_filters.BaseInFilter, df_filters.CharFilter):
pass
class MyModelFilter(filters.FilterSet):
my_field = CharInFilter()
class Meta:
model = MyModel
هل هذا سلوك طبيعي ومتوقع أم أفعل شيئًا خاطئًا هنا؟ شكرا.
مرحبًاmaxtepkeev. نعم - هذا هو السلوك المتوقع. المرشحات ليست "مدركة للتعبير" ولن تغير سلوكها وفقًا لـ lookup_expr
.
يمكنك إما إنشاء فئة عامل التصفية يدويًا كما فعلت في المثال الثاني ، أو يمكنك إنشاء عوامل تصفية تلقائيًا باستخدام بنية نمط القاموس لـ Meta.fields
. داخليًا ، يفعل نفس الشيء كما في المثال الخاص بك.
على سبيل المثال ،
class MyModelFilter(Filters.FilterSet):
class Meta:
model = MyModel
fields = {
'my_field': ['exact', 'in', ...],
}
مرحبًا @ rpkilby
شكرا على الرد.
IMHO ليس واضحًا جدًا من الوثائق ، لذلك ربما يمكنك إضافة المزيد من المعلومات حول ذلك في المستندات.
أيضًا ، المثال الثاني مع Meta.fields
لا يعمل معي لسبب ما.
maxtepkeev نرحب بأي علاقات عامة في المستندات!
أعتقد أن المشكلة الأساسية هي أن CharFilter يتوقع (يتلقى؟) قيمة واحدة فقط ، وليس قائمة ؛ هذا يأتي من كيفية تعيين عنصر واجهة المستخدم للبيانات من GET
QueryDict
- كل _that_ هو نماذج Django الداخلية ، وهو أمر غير واضح لكثير من الناس. ربما نحتاج إلى بعض _القراءة الخلفية_ لشرح الآليات ...
carltongibson سأحاول العمل على هذا لاحقًا الليلة. يمكن إعادة صياغة هذا في قسم حول المشاكل الشائعة و / أو النظرية.
maxtepkeev فيما يلي المستندات الخاصة بخلط BaseInFilter
مع أنواع المرشحات الأخرى ، ولكن ليس من الواضح تمامًا كيفية الوصول إلى هناك. على سبيل المثال ، إذا كنت تريد البحث في المستندات حول كيفية استخدام CharFilter
بشكل صحيح مع lookup_expr='in'
، فمن المحتمل أنك لن تجد هذا القسم.
هل ما زلت تواجه مشكلات في بناء جملة Meta.fields
؟ ربما آخر نموذج / كود التصفية و traceback؟
rpkilby نعم ، كان من الصعب العثور عليه ، لكني قرأت هذا القسم وبعد ذلك قمت بتطبيق حل عملي الحالي ، على سبيل المثال:
from django_filters import filters as df_filters
from rest_framework import filters
from ..models import MyModel
class CharInFilter(df_filters.BaseInFilter, df_filters.CharFilter):
pass
class MyModelFilter(filters.FilterSet):
my_field = CharInFilter()
class Meta:
model = MyModel
لا يزال Meta.fields
لا يعمل بالنسبة لي ، فهو لا ينتج عنه أي عمليات تتبع أو أخطاء أو أي شيء آخر ، إنه يقوم فقط بإرجاع مجموعة نتائج فارغة ، وهذه هي الطريقة التي أحاول استخدامها:
from rest_framework import filters
from ..models import MyModel
class MyModelFilter(filters.FilterSet):
class Meta:
model = MyModel
fields = {
'my_field': ['in'],
}
كما قلت سابقًا ، أنا أستخدم django-filter مع إطار عمل django-rest ، فأنا أستخدم بناء جملة ?my_field=Option1,Option2
في عنوان URL الذي يعمل بشكل صحيح مع الحل الحالي ولكن لا يعمل مع Meta.fields
.
آه ، يجب أن تجري التصفية باستخدام ?my_field__in=Option1,Option2
. يكون هذا أكثر منطقية عندما يكون لديك عمليات بحث متعددة. على سبيل المثال ،
class ProductFilter(filterset.Filter):
class Meta:
model = Product
fields = {'price': ['exact', 'in', 'lt', 'gt'], }
سينتج فلاتر price
و price__in
و price__lt
و price__gt
.
بالطبع ، سيئتي ، إنها تعمل الآن.
ولكن إذا لم يعجبني الجزء __in
، فإن الخيار الوحيد هو استخدام فئة مخصصة كما أفعل في الوقت الحالي ، أليس كذلك؟
نعم ، ولا بأس إذا كان لديك مرشح واحد فقط لهذا الحقل. إذا كان لديك عدة مرشحات لحقل ما ، فستحتاج إلى استخدام بعض إستراتيجيات التسمية للتمييز بينها. على سبيل المثال ، price__in
، price__lt
، price__gt
.
نعم ، هذا منطقي. شكرا. ليس لدي المزيد من الأسئلة.
التعليق الأكثر فائدة
آه ، يجب أن تجري التصفية باستخدام
?my_field__in=Option1,Option2
. يكون هذا أكثر منطقية عندما يكون لديك عمليات بحث متعددة. على سبيل المثال ،سينتج فلاتر
price
وprice__in
وprice__lt
وprice__gt
.