python - كيف أقوم بعمل غير متساوٍ في تصفية بحث Django؟




django-models django-queryset (8)

في نموذج Django QuerySets ، أرى أن هناك __gt و __lt للقيم المقارنة ، ولكن هل هناك __ne / != / <> ( لا يساوي ؟)

أرغب في التصفية باستخدام لا يساوي:

مثال:

Model:
    bool a;
    int x;

انا اريد

results = Model.objects.exclude(a=true, x!=5)

!= ليس بناء صحيح. حاولت __ne ، <> .

انتهى بي الأمر باستخدام:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)

في انتظار قرار التصميم. في الوقت نفسه ، استخدم exclude()

يحتوي تعقب قضية جانغو على الإدخال الرائع رقم 5763 ، المعنون "Queryset ليس لديه عامل تصفية مرشح" غير متساوٍ " . إنه أمر لافت للنظر لأنه (اعتبارًا من أبريل 2016) "تم فتحه منذ 9 سنوات" (في عصر الحجر في Django) ، "مغلق قبل 4 سنوات" ، و "آخر تغيير منذ 5 أشهر".

قراءة من خلال المناقشة ، من المثير للاهتمام. في الأساس ، يقول بعض الناس __ne ينبغي أن يضاف في حين أن آخرين يقولون exclude() أكثر وضوحا ، وبالتالي لا ينبغي أن يضاف __ne .

(أنا أتفق مع السابق ، لأن الحجة الأخيرة مكافئة تقريبًا للقول أن Python لا يجب أن يكون != لأنه يحتوي على == not بالفعل ...)


الجزء الأخير من التعليمة البرمجية سيؤدي إلى استبعاد كل الكائنات حيث x! = 5 و a هو True. جرب هذا:

results = Model.objects.filter(a=False, x=5)

تذكر أن علامة = في السطر أعلاه تقوم بتعيين False للمعلمة a والرقم 5 إلى المعلمة x. إنه لا يتحقق من المساواة. وبالتالي ، ليس هناك أي طريقة لاستخدام الرمز! = في استدعاء الاستعلام.


بينما مع Models ، يمكنك التصفية مع = ، __gt ، __gte ، __lt ، __lte ، لا يمكنك استخدام ne ، != أو <> . ومع ذلك ، يمكنك تحقيق تصفية أفضل على استخدام كائن Q.

يمكنك تجنب تسلسل QuerySet.filter() و QuerySet.exlude() ، واستخدام هذا:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')

ربما يمكن أن تكون عناصر Q مساعدة لهذه المشكلة. لم أستخدمها أبدًا ، لكن يبدو أنها يمكن أن تُفسد وتُجمع كثيرًا مثل تعبيرات بيثون العادية.

تحديث: لقد جربته للتو ، يبدو أنه يعمل جيدًا:

>>> from myapp.models import Entry
>>> from django.db.models import Q

>>> Entry.objects.filter(~Q(id = 3))

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

ما تبحث عنه هي كل الكائنات التي تحتوي إما a=false أو x=5 . في دجانجو ، | يعمل كمشغل OR بين مجموعات الاستعلام:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

من السهل إنشاء بحث مخصص مع Django 1.7. هناك مثال للبحث __ne في وثائق رسمية جانغو .

تحتاج إلى إنشاء البحث نفسه أولاً:

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, qn, connection):
        lhs, lhs_params = self.process_lhs(qn, connection)
        rhs, rhs_params = self.process_rhs(qn, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params

ثم تحتاج إلى تسجيله:

from django.db.models.fields import Field
Field.register_lookup(NotEqual)

والآن يمكنك استخدام البحث __ne في استعلاماتك مثل:

results = Model.objects.exclude(a=True, x__ne=5)

يجب عليك استخدام filter exclude مثل هذا

results = Model.objects.exclude(a=true).filter(x=5)

Django-model-values (الكشف: author) تطبيقًا لعملية البحث NotEqual ، كما في هذه الإجابة . كما يوفر الدعم النحوي له:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)






django-queryset