首先,这是我的模特。每个字符串有1到3个表演者,每个表演者链接到几个字符串:
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
获取所有字符串,其中任何Performer外键都指向该字符串,如下所示:
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'
此外,我还尝试使用相关名称的过滤器,但这给了我同样的错误。有没有办法根据所有指向相同类型的外键字段之一获取_set?
答案 0 :(得分:3)
通过在related_name
,performer
,performer2
关系中提供performer3
,您可以覆盖related_name
类的默认Performer
链接是string_set
。现在要获得每个关系的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个或更多String
{{ 1}}与此Performer
有关系的对象。这会使事情变得更加麻烦。
请记住,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()