Django-filter: السماح لتجاوز استرداد مجموعة استعلام في FilterSet

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

قد يكون العنوان مربكًا بعض الشيء. سيكون من الجيد أن يكون لديك طريقة filter تسمى كل مرة يتم فيها استرداد مجموعة الاستعلام ويتم تطبيق التصفية للحقول. نعم ، يمكنني تجاوز خاصية qs ، أولاً الحصول على مجموعة استعلام تمت تصفيتها ثم تطبيق الإعدادات المسبقة. ولكن ليس من الواضح ما إذا كان هذا قد يكون له بعض الآثار الجانبية والبيانات التي تم تمريرها للتصفية يمكن الوصول إليها بأمان.

هناك حالة الاستخدام الخاصة بي.
أقوم بتصفية مجموعة استعلام بواسطة علاقة M2M (كما في queryset.filter(items__field="foo") ). ومع ذلك ، أريد الحصول على العناصر التي تم جلبها مسبقًا والتي تمت تصفيتها بواسطة هذا الحقل أيضًا.

بمعنى آخر ، يبدو الفلتر الخاص بي كما يلي:

# In my filterset
def filter_items_by_field(self, queryset, name, value):
        queryset = queryset.all().filter(
            items__field=value,
        )
        prefetched_items = Prefetch(
            'items',
            Item.objects..filter(
                field=value,
            ),
        )
        return queryset.prefetch_related(prefetched_items)

# In my vieset
def get_queryset(self):
        queryset = super().get_queryset()
        # This should be applied everytime
        prefetched_items = Prefetch(
            'items',
            Item.objects..filter(
                another_field=some_value,
            ),
        )
        return queryset.prefetch_related(prefetched_items)

عامل تصفية واحد مثل هذا يعمل كما هو متوقع. ومع ذلك ، قد يكون لدي عدة مرشحات filter_items_by_* + أحتاج إلى تطبيق نفس التصفية لمجموعة طلبات البحث من الجلب المسبق لجميع عوامل التصفية. والفلاتر المتعددة ليست مشكلة ، لأنها حصرية في حالتي. لكن عامل التصفية + عام سيؤدي إلى استثناء.

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

لدي حل مؤقت لهذه المشكلة: كل filter_items_by_* ينفذ تصفية إلزامية على الجلب المسبق.
وفي filter_queryset (بعد تطبيق التصفية) ، إذا لم يتم جلب items مسبقًا (ما هو سيء لأنني أتفحص attrs المحمية لمجموعة طلبات البحث) ، فأنا أطبق الجلب المسبق مع التصفية الإلزامية. لكن يجب أن تكون هناك طريقة أفضل للتعامل مع مثل هذه المواقف.

آمل أن يكون نموذجي واضحًا بدرجة كافية.

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

مرحبًا @ Alexx-G. لا يزال الإصدار 2.0 يمثل مخرجًا ، ولكن ستكون هناك بعض التغييرات على واجهة برمجة التطبيقات التي تتناول هذا السؤال تحديدًا. باختصار،

  • ستحتاج إلى تجاوز طريقة .filter_queryset() . ستكون السمة .qs مسؤولة بشكل أساسي عن استدعاء .filter_queryset() وتخزين نتيجتها مؤقتًا.
  • يمكنك الحصول على قيم التصفية للجلب المسبق من self.form.cleaned_data .

ال 4 كومينتر

مرحبًا @ Alexx-G. أعتقد أن هذا يمكن أن يكون ممكنًا مع بعض التنسيق بين مجموعة المرشحات وفئات التصفية ذات الصلة. في الأساس، فإن مرشح إلحاق Prefetch مثلا لفي parent filterset. عندئذٍ يقوم FilterSet.qs باستدعاء prefetch_related عندما يكون ذلك مناسبًا.

ومع ذلك ، ما هي حالة استخدام هذا؟ أود أن أزعم أنه من المحتمل أن يكون هناك أماكن أكثر ملاءمة للتعامل مع الجلب المسبق.

أعتقد أن هذا يمكن أن يكون ممكنًا مع بعض التنسيق بين مجموعة المرشحات وفئات التصفية ذات الصلة.

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

ومع ذلك ، ما هي حالة استخدام هذا؟ أود أن أزعم أنه من المحتمل أن يكون هناك أماكن أكثر ملاءمة للتعامل مع الجلب المسبق.

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

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

مرحبًا @ Alexx-G. لا يزال الإصدار 2.0 يمثل مخرجًا ، ولكن ستكون هناك بعض التغييرات على واجهة برمجة التطبيقات التي تتناول هذا السؤال تحديدًا. باختصار،

  • ستحتاج إلى تجاوز طريقة .filter_queryset() . ستكون السمة .qs مسؤولة بشكل أساسي عن استدعاء .filter_queryset() وتخزين نتيجتها مؤقتًا.
  • يمكنك الحصول على قيم التصفية للجلب المسبق من self.form.cleaned_data .

شكرا جزيلا لجهودكم!

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