Django - sorgu sonuçlarını sınırlama


Yanıtlar:


304

Django querysets tembeldir. Bu, bir sorgunun veritabanına yalnızca sonucu özellikle istemeniz durumunda vuracağı anlamına gelir.

Bu nedenle, bir sorgunun sonucunu yazdırana veya gerçekten kullanana kadar, veritabanı erişimi olmadan daha fazla filtre uygulayabilirsiniz.

Aşağıda gördüğünüz gibi, kodunuz yalnızca son 10 öğeyi getirmek için yalnızca bir sql sorgusu yürütür.

In [19]: import logging                                 
In [20]: l = logging.getLogger('django.db.backends')    
In [21]: l.setLevel(logging.DEBUG)                      
In [22]: l.addHandler(logging.StreamHandler())      
In [23]: User.objects.all().order_by('-id')[:10]          
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]

Bunu mongoDB'de denedim ve SELECT'in desteklenmediğini söylüyor. MongoDB'de nasıl yapılır?
winux

@winux Bu Django'ya özgü olduğu için, Django'yu özel olarak Mongo / NoSQL tipi veritabanlarıyla çalışacak şekilde ayarlamanız gerekebilir. Bu, standart Django ORM kurulumu ile ilgili olarak benim deneyimimde tipik bir kurulum değil.
anonim korkak

38

Aslında ben LIMIT 10bu yüzden dilimleme Python değil veritabanında gerçekleşecek veritabanına verileceğini düşünüyorum .

Daha fazla bilgi için sınırlayıcı-sorgu kümelerine bakınız .


Dilimlemeden sonra filtre uygulayamayacağınız için, filtreleme gerektiren sorgu kümeleri için de işe yaramayacağını unutmayın.
Mike 'Pomax' Kamermans

2
Bu yüzden önce dilimlemek yerine süzün. Bağlantı için teşekkürler Davor!
Vyachez

13

Görünüşe göre sorudaki çözüm artık Django 1.7 ile çalışmıyor ve bir hata veriyor: "Bir dilim alındıktan sonra sorgu yeniden sıralanamıyor"

Belgelere göre Python dilim sözdiziminin “adım” parametresini zorlayan https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets Sorguyu değerlendirir. Bu şekilde çalışır:

Model.objects.all().order_by('-id')[:10:1]

Yine de sınır SQL veya Python dilimleri tüm sonuç dizisi idam yürütülürse merak ediyorum. Uygulama hafızasına dev listeler almak iyi değildir.


Bu çözüm bile django> = 1.8 test edilmiş durumda çalışmaz.
sonus21

3

Evet. Sınırlı bir nesne alt kümesi almak istiyorsanız, aşağıdaki kodla yapabilirsiniz:

Misal:

obj=emp.objects.all()[0:10]

0 başlangıcı isteğe bağlıdır, bu nedenle

obj=emp.objects.all()[:10]

Yukarıdaki kod ilk 10 örneği döndürür.


1

Diğer faydalı cevaplara bir ekleme ve gözlem olarak, [:10]dilimleme olarak yapmanın listenin ilk 10 öğesini döndüreceğini fark etmek önemlidir. , son 10 değil ...

Son 10'u almak için [-10:]bunun yerine yapmalısınız ( buraya bakın ). Bu , öğeleri tersine çevirmek için order_by('-id')ile kullanmaktan kaçınmanıza yardımcı olacaktır -.


1
Bunu denedim ve "Negatif indeksleme desteklenmiyor."
bparker

@DarkCygnus Product.objects.filter(~Q(price=0))[-5:]bana aynı hataya neden oluyor: "Negatif indeksleme desteklenmiyor."
bersam

Bu django'da bir queryset üzerinde çalışmaz: code.djangoproject.com/ticket/13089 Queryset'i bir listeye dönüştürürseniz çalışır.
valem
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.