Django related_name默认语法

时间:2018-08-06 07:05:00

标签: django django-models

根据documentation,相关名称必须唯一。再次根据documentation,默认值(如果开发人员未明确设置)为FOO_set,其中FOO是源模型名称。

因此,如果我有两个外键(当然是指向两个不同的模型),那么(默认)相关的名称会不会相似?

2 个答案:

答案 0 :(得分:6)

假设您有一个模型C,其中ForeignKey分别为AB,例如:

class A(models.Model):
    pass

class B(models.Model):
    pass

class C(models.Model):
    a = models.ForeignKey(A, on_delete=models.CASCADE)
    b = models.ForeignKey(B, on_delete=models.CASCADE)

然后确实有两个c_set ,但是它们在不同型号上。因此A对象有一个c_set,而B对象有一个c_set,但是没有混淆,因为对象的类型决定了我们在谈论哪种关系。 / p>

通常,指定具有更好命名法的related_name=...参数是有意义的。

答案 1 :(得分:3)

我想扩展一下威廉·范昂塞姆(Willem Van Onsem)的出色回答。在他的示例中,类C与类A和B有关。因此,A和B具有属性c_set,但它们是不同的类。因此,具有相同名称的属性c_set存在于不同的范围(名称空间)中。

但是如果关系具有不同的性质怎么办。让我们看一下不同的例子。想象一个运动队的应用程序。我们有个人和团队班。一个人可以为团队效力或指导团队。这些模型如下所示:

class Person(models.Model):
    name = models.CharField(max_length=255, unique=True)


class Team(models.Model):
    name = models.CharField(max_length=255, unique=True)
    place = models.CharField(max_length=255)
    players = models.ManyToManyField('Person')
    coaches = models.ManyToManyField('Person')

现在,这应该为Person类创建一个属性team_set

person = Person.objects.get(pk=1)
# now we want to get the teams where the person participates
person.team_set.all()

有问题!应该使用哪个关系-playerscoaches? Django不允许这样做,并要求明确声明相关名称。

我们可以通过声明相关名称来解决此问题,例如:

players = models.ManyToManyField('Person', related_name='plays_in_teams')
coaches = models.ManyToManyField('Person', related_name='trains_teams')

更改后,我们可以查询以下团队:

person.plays_in_teams.all()
person.trains_teams.all()

这显示了相关名称的有用性。它们有助于创建人类可读的查询并提高代码的可维护性。