كيف أفعل مساواة في تصفية مستطيل Django؟
-
22-08-2019 - |
سؤال
في مقاييس Django Model ، أرى أن هناك أ __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)
المحلول
يمكن كائنات س يمكن أن يكون مساعدة لهذه المشكلة. لم أستخدمها مطلقًا ، لكن يبدو أنه يمكن نفيها ودمجها مثل تعبيرات Python العادية.
تحديث: لقد جربته للتو ، يبدو أنه يعمل بشكل جيد:
>>> 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>, ...]
نصائح أخرى
يبدو أن استعلامك يحتوي على سلبي مزدوج ، فأنت تريد استبعاد جميع الصفوف التي لا تكون فيها x 5 ، وبعبارة أخرى تريد تضمين جميع الصفوف التي يكون فيها x 5. أعتقد أن هذا سوف يقوم بالخدعة.
results = Model.objects.filter(x=5).exclude(a=true)
للإجابة على سؤالك المحدد ، لا يوجد "لا يساوي" ولكن هذا ربما يرجع ذلك إلى أن Django لديه كل من "مرشح" و "استبعاد" الأساليب المتاحة حتى تتمكن دائمًا من تبديل جولة المنطق للحصول على النتيجة المرجوة.
ال field=value
بناء الجملة في الاستعلامات هو اختصار ل field__exact=value
. هذا يعني ذلك يضع Django مشغلي الاستعلام على حقول الاستعلام في المعرفات. يدعم Django المشغلين التاليين:
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
أنا متأكد من خلال الجمع بين هذه الكائنات Q AS ديف فوغت يقترح واستخدام filter()
أو exclude()
كما يقترح جيسون بيكر ستحصل على ما تحتاجه بالضبط لأي استفسار محتمل.
من السهل إنشاء بحث مخصص مع Django 1.7. هناك __ne
مثال بحث في وثائق Django الرسمية.
تحتاج إلى إنشاء البحث نفسه أولاً:
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)
في Django 1.9/1.10 هناك ثلاثة خيارات.
-
results = Model.objects.exclude(a=true).filter(x=5)
يستخدم
Q()
أشياء و ال~
المشغل أو العاملfrom django.db.models import Q object_list = QuerySet.filter(~Q(a=True), x=5)
سجل أ وظيفة البحث المخصصة
from django.db.models import Lookup from django.db.models.fields import Field @Field.register_lookup class NotEqual(Lookup): lookup_name = 'ne' def as_sql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return '%s <> %s' % (lhs, rhs), params
ال
register_lookup
تمت إضافة ديكور في Django 1.8 وتمكين البحث المخصص كالمعتاد:results = Model.objects.exclude(a=True, x__ne=5)
أثناء وجودك مع النماذج ، يمكنك التصفية مع =
, __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')
قرار التصميم المعلق. وفي الوقت نفسه ، الاستخدام exclude()
تتبع قضية Django لديه ملحوظ الدخول #5763، بعنوان "Queryset ليس لديه" مشغل مرشح "غير متساوٍ. إنه أمر رائع لأنه (اعتبارًا من أبريل 2016) تم "افتتاحه منذ 9 سنوات" (في عصر Django Stone) ، "مغلق منذ 4 سنوات" ، و "آخر 5 أشهر".
اقرأ من خلال المناقشة ، إنه مثير للاهتمام. في الأساس ، يجادل بعض الناس __ne
يجب إضافة بينما يقول آخرون exclude()
أكثر وضوحا وبالتالي __ne
ينبغي ليس تضاف.
(أنا أتفق مع السابق ، لأن الحجة الأخيرة تكافئ تقريبًا لقول أن بيثون لا ينبغي أن يكون !=
لأنه لديه ==
و not
سابقا...)
يجب أن تستخدم filter
و exclude
مثله
results = Model.objects.exclude(a=true).filter(x=5)
باستخدام استبعاد وتصفية
results = Model.objects.filter(x=5).exclude(a=true)
آخر جزء من التعليمات البرمجية سوف يستبعد جميع الكائنات حيث x! = 5 و A صحيحة. جرب هذا:
results = Model.objects.filter(a=False, x=5)
تذكر أن = تسجيل الدخول في السطر أعلاه هو تعيين خطأ للمعلمة A والرقم 5 للمعلمة x. لا يتحقق من المساواة. وبالتالي ، لا توجد حقًا أي طريقة لاستخدام! = رمز في مكالمة استعلام.
ما تبحث عنه هو كل الأشياء التي لديها إما a=false
أو x=5
. في Django ، |
بمثابة OR
المشغل بين Querysets:
results = Model.objects.filter(a=false)|Model.objects.filter(x=5)
results = Model.objects.filter(a = True).exclude(x = 5)أجيال هذا SQL:
select * from tablex where a != 0 and x !=5يعتمد SQL على كيفية تمثيل الحقل الحقيقي/الخاطئ ، ومحرك قاعدة البيانات. رمز Django هو كل ما تحتاجه.
قيم Django-Model (الكشف: مؤلف) يوفر تنفيذًا غير متساوي البحث ، كما في هذا الجواب. كما يوفر الدعم النحوي لها:
from model_values import F
Model.objects.exclude(F.x != 5, a=True)
احترس من الكثير من الإجابات غير الصحيحة لهذا السؤال!
منطق جيرارد صحيح ، على الرغم من أنه سيعيد قائمة بدلاً من QuerySet (والتي قد لا تكون مهمة).
إذا كنت بحاجة إلى مجموعة QuerySet ، فاستخدم س:
from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))