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 namereverse 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

例如,现在可用的字段是:

nameemailsalary

要查找员工,我们可以这样简单地查询:

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 啥是反向关系?的主要内容,如果未能解决你的问题,请参考以下文章

Django 反向关系

Django:prefetch_related() 是不是遵循反向关系查找?

来自 ForeignKey 的 django 反向关系查询

使用反向关系在 django 模型中获取 n 个项目

每日一学:啥是反向代理

Django - 遵循反向关系的两种不同方法