2011-07-01 8 views
5

Bir modelim var:django-taggit: Daha az db sorguları üretmenin bir yolu var mı?

class Entry(models.Model): 
    ... 
    tags = TaggableManager() 

Bir şablonda Entry.objects.all() üzerinde yinelemem, input.tags.all veritabanına bir tane daha sorgu üretir. Sorgu sayısını azaltmak mümkün mü? Select_related() gibi bir şey kullanarak (Ben işe yaramayacağını biliyorum, çünkü django-taggit birçoktomany ilişki kullanıyor, ama emin değilim tüm girdiler ile ilgili girişleri tüm isabetler 1 hit olarak seçilmelidir)?

+0

olası yinelenen [Django taggit önceden alma \ _related] (http://stackoverflow.com/questions/12926036/django-taggit-prefetch-related), ya da belki http://stackoverflow.com/questions/12204511/optimize etmek-django-sorgu-to-pull-yabancı-anahtar-ve-django-taggit-ilişki –

cevap

0

Select Reverse kullanmayı deneyin, tek bir sorgu ile many2many ilişkisinin bütünlüğünü almak için tasarlanmıştır.

2

Django 1.4'ten itibaren, tek bir sorguda bir queryset üzerinde bire çok ilişkileri almak için prefetch_related'u kullanabilirsiniz. Maalesef bu, django-taggit ile mükemmel bir şekilde çalışmaz, çünkü 'etiketler' özelliği gerçek bir ilişkiden ziyade bir yönetici ve bu nedenle prefetch_related bunun hakkında bir fikre sahip olamaz. Bunun yerine, tagged_items ilişkisini takip etmek gerekir:

entries = Entry.objects.prefetch_related('tagged_items__tag')

Ardından entry.tags.all ziyade yararlanarak daha başka bir sorgu çalışır, çünkü ön getirme işlemi etiketleri erişmek için şablon kodunda bazı benzer contortions geçmesi gerekir

Önceden alma: bölgesinin

{% for tagged_item in entry.tagged_items %} 
    <li>{{ tagged_item.tag.name }}</li> 
{% endfor %} 
+2

Sadece bir not - bu benim için bir GenericRelatedObjectManager hatasına neden oldu. Entry.tagged_items' i 'entry.tagged_items.all' olarak değiştirdim ve işe yaradı, ancak orijinal kod üzerinde SQL sorgularındaki herhangi bir gelişmeyle değil. Buraya karıştı. – Laurence

İlgili konular