2016-04-26 86 views
1

首先,這裏是我的模型。每串有從1到3的表演,每個表演掛幾串:嘗試獲取多個外鍵集合時,Django查詢集合給出attribute_error

class Performer(models.Model) : 
    name = models.CharField(max_length=60, default="None") 
    description = models.TextField(null=True, default=None) 

class String(models.Model) : 
    index = models.IntegerField(null=True, default=None) 
    step = models.IntegerField(null=True, default=None) 
    process = models.CharField(max_length=100,null=True, default=None) 
    description = models.TextField(null=True, default=None) 
    performer = models.ForeignKey(Performer, related_name='performer', on_delete=models.CASCADE, null=True, default=None) 
    performer2 = models.ForeignKey(Performer, related_name='performer2', on_delete=models.CASCADE, null=True, default=None) 
    performer3 = models.ForeignKey(Performer, related_name='performer3', on_delete=models.CASCADE, null=True, default=None) 

我需要設置與單個表演所有字符串。但是,如果我嘗試使用string_set得到任何地方的表演外鍵指向字符串像這樣所有字符串:

p = Performer.objects.get(name="smth")# so p is a performer object 
s = p.string_set.all() 

我得到這個問題:

AttributeError: 'Performer' object has no attribute 'string_set' 

而且我tryed使用具有相關名稱的過濾器,但是這給了我相同的錯誤。有沒有一種方法可以從任何指向相同類型的外鍵字段之一獲取_set?

回答

3

通過在每個performerperformer2performer3關係提供related_name您覆蓋從Performer類是string_set連接默認related_name。現在拿到String對於這些關係,你就必須讓他們像下面這樣:

p = Performer.objects.get(name="smth")# so p is a performer object 
p.performer.all() #first one which would actually be a queryset 
p.performer1.all() #second one which would actually be a queryset 
p.performer2.all() #third one which would actually be a queryset 

這將是唯一的,如果你有真正的單String和相互關聯的單一Performer但是你應該記住像p.performer1.all()這樣的查詢實際上可以返回2個或更多與這個Performer有關係的對象String。這會讓事情變得更加繁瑣。

請記住,ForeignKey創建一個一對多的關係...

的模型結構,你會提供有做過濾,你想的問題。更好的模型設計看起來像下面這樣:

class Performer(models.Model) : 
    name = models.CharField(max_length=60, default="None") 
    description = models.TextField(null=True, default=None) 
    strings = models.ManyToManyField(String, related_name='performers') 

class String(models.Model) : 
    index = models.IntegerField(null=True, default=None) 
    step = models.IntegerField(null=True, default=None) 
    process = models.CharField(max_length=100,null=True, default=None) 
    description = models.TextField(null=True, default=None) 

這種設計可以讓你執行:

p = Performer.objects.get(name="smth")# so p is a performer object 
s = p.strings.all() 
+0

感謝您的想法與manyToManyField,我心底先試試吧.. –

+0

但我可以執行「s.performers.all()」其中s是單個字符串對象與這些模型? –

+0

是的,你可以。但請記住,它的多對多關係如此's.performers.all()'也會返回一個查詢集,而不是一個對象 – canufeel