Django-filter: في البحث

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

مرحبا،

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

هل هذا سلوك طبيعي ومتوقع أم أفعل شيئًا خاطئًا هنا؟ شكرا.

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

آه ، يجب أن تجري التصفية باستخدام ?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 .

ال 9 كومينتر

مرحبًا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 .

نعم ، هذا منطقي. شكرا. ليس لدي المزيد من الأسئلة.

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

القضايا ذات الصلة

chromakey picture chromakey  ·  5تعليقات

GuillaumeCisco picture GuillaumeCisco  ·  3تعليقات

jnegro picture jnegro  ·  3تعليقات

gsvr picture gsvr  ·  3تعليقات

ses4j picture ses4j  ·  4تعليقات