2013-07-30 71 views
3

E.g我有一個模型Cat,它有一個與Life相反的ForeignKey如何過濾Django QuerySet的相關字段'all'或'none'

class Life(models.Model): 
    state = models.CharField(choices=('alive', 'dead', 'unknown') 
    cat = models.ForeignKey('animals.Cat', related_name="lives") 


class Cat(models.Model): 
    name = models.CharField(max_length=12) 
    cat_type = models.CharField(choices=('normal', 'schroedinger') 
    ... 

如何獲得CatQuerySet A S已沒有失去他們的生活?即有所有他們的生活無論是在國家「活着」或者是cat_type「薛定諤」,並有沒有自己的生活狀態「死」)

回答

1

我的天堂「T使用一段時間這個API,但我相信這會完成這項工作:

from django.db.models import Q 

normal_and_alive = Q(cat_type="normal") & ~Q(lives__state__in=["dead", "unknown"]) 
schroedinger_and_not_dead = Q(cat_type="schroedinger") & ~Q(lives__state="dead") 

cats = Cat.objects.filter(normal_and_alive | schroedinger_and_not_dead) 

見Django的文檔的文檔爲complex lookups with the Q() object

撇開:這將只執行一個數據庫查詢

0
cats = Cat.objects.filter(id=-1) # make it an empty queryset 

temp = Cat.objects.filter(cat_type='normal') 
for one in temp: 
    cats |= one.lives.filter(state='alive') # set union 

temp = Cat.objects.filter(cat_type='schroedinger') 
for one in temp: 
    cats |= one.lives.exclude(state='dead') 

return cats 

新的答案:

cats = Cat.objects.filter(id=-1) # make it an empty queryset 

temp = Cat.objects.filter(cat_type='normal') 
for one in temp: 
    if len(one.lives.exclude(state='alive')) == 0: 
     cats |= Cat.objects.filter(id=one.id) 

temp = Cat.objects.filter(cat_type='schroedinger') 
for one in temp: 
    if len(one.lives.filter(state='dead')) == 0: 
     cats |= Cat.objects.filter(id=one.id) 

return cats 
+0

這會導致多少數據庫匹配? 2,3,貓的數量+2? – Kimvais

+0

我不太確定,如果將狀態字段移動到Cat,可能會有很少的命中 – metaphy

+0

Life()'記錄的查詢集,你不能這樣做,因爲它基本上是'Cat.objects.all()| Life.objects.all()'。它不工作,因爲他們在不同的表 – metaphy

相關問題