Django 啥是反向关系?
Posted
技术标签:
【中文标题】Django 啥是反向关系?【英文标题】:Django What is reverse relationship?Django 什么是反向关系? 【发布时间】:2013-06-24 02:44:09 【问题描述】:谁能告诉我反向关系是什么意思? 我已经开始使用 Django,并且在文档中的很多地方我都看到了“反向关系”。它到底是什么意思?为什么有用?引用this post 与related_name 有什么关系?
【问题讨论】:
【参考方案1】:这是related_name上的文档
假设您有 2 个模型
class Group(models.Model):
#some attributes
class Profile(models.Model):
group = models.ForeignKey(Group)
#more attributes
现在,您可以从配置文件对象执行profile.group
。但是如果你想要给定group
对象的配置文件对象,你会怎么做呢?这就是related name
或reverse relationship
的用武之地。
Django,默认情况下给你一个默认的related_name
,它是ModelName(小写),后跟_set
- 在这种情况下,它将是profile_set
,所以group.profile_set
。
但是,您可以通过在 ForeignKey
字段中指定 related_name
来覆盖它。
class Profile(models.Model):
group = models.ForeignKey(Group, related_name='profiles')
#more attributes
现在,您可以按如下方式访问外键:
group.profiles.all()
【讨论】:
所以我们可以访问、编辑、查询等来自组对象的所有配置文件对象属性,或者您是否知道 group_id?【参考方案2】:为了更清晰的画面,你可以假设当我们使用反向关系时,它会在引用的模型中添加一个额外的字段:
例如:
class Employee(models.Model):
name = models.CharField()
email = models.EmailField()
class Salary(models.Model):
amount = models.IntegerField()
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='salary')
在 Salary 模型中使用 related_name 后,现在您可以假设 Employee 模型将多一个字段:salary
。
例如,现在可用的字段是:
name
、email
和 salary
要查找员工,我们可以这样简单地查询:
e = Employee.objects.filter(some filter).first()
要查看他们的薪水,我们可以通过以下方式查看
e.salary
(现在我们可以在员工模型中使用薪金属性或字段)。这将为您提供该员工的薪水实例,您可以通过写e.salary.amount
找到金额。这将为您提供该员工的薪水。
在多对多关系的情况下,我们可以使用.all()
,然后对其进行迭代。
【讨论】:
【参考方案3】:在 Django 2.0 中,您将按如下方式定义 ForeignKey
mainclient = models.ForeignKey( MainClient, on_delete=model.CASCADE, related_name='+')
related_name='+'
将取消 Django 设置的默认反向关系,因此在前面的示例中,您将无法使用 group.profiles.all()
查询配置文件。
【讨论】:
为什么需要这样做? 如果您有一个 Status 对象和一个 TransactionHistory 对象,其中有两个从 TransactionHistory 到 Status 的关系,请将它们称为 from_status 和 to_status。当然,您可以为 Status 中的反向关系赋予唯一的名称,以便您可以访问 Status.transactionHistoriesFromStatuses 和 Status.transactionHistoriesToStatuses,但是如果您的业务逻辑永远不会使用反向关系,那么简单地使用“+”来删除是合理的反向关系。以上是关于Django 啥是反向关系?的主要内容,如果未能解决你的问题,请参考以下文章