Django 反向关系

5 投票
3 回答
12046 浏览
提问于 2025-04-18 02:36

我正在为一个应用程序设置网络服务,下面是我有的模型:

class Parent(models.Model):
    ...
class Child(models.Model):
    parent = models.ForeignKey(Course)
    ...

这些模型之间的关系是一对多(一个父对象,多个子对象)。

现在,我想要获取所有的父对象以及它们各自的子对象,并将这些信息作为JSON请求发送出去。

有没有办法做到这一点,而不需要先获取所有的“子对象”,再一个个检查它们与特定父对象的关系呢?

我觉得这样做在处理非常大的数据库时会非常低效,而且“子对象”不会在其他“父对象”中重复出现。

非常感谢!

3 个回答

0

是的,在Django中你可以使用:

parentInstance.child_set.all()

这里的 parentInstance 是你在 Parent 数据库中的一个特定父对象。这样做会高效地返回与这个父对象相关的所有子对象。为了将结果变成JSON格式的响应,你可以尝试这样做:

import json

from django.http import HttpResponse

response_data = {}
response_data[str(parentInstance)] = parentInstance.child_set.all()
return HttpResponse(json.dumps(response_data), content_type="application/json"

这个内容来源于 这里

2

为什么你需要进行迭代呢?即使Django没有给你提供一种特殊的反向语法,你也可以这样做:

Child.objects.filter(parent=my_parent)

但是,简单在谷歌上搜索一下你问题的标题就会发现,确实有一种特殊的语法可以处理反向关系:

my_parent.child_set.all()
18

在Django中,每个关系都会自动在模型中添加一个反向关系。比如说,当你使用ForeignKeyManyToManyField时,这个反向关系会包含多个对象。在这种情况下,默认的属性名称会被设置为<model>_set,所以这里就是child_set。这个child_set是一个管理器,你可以用它来处理,比如说遍历所有的子对象:

for child in parent.child_set.all():
    do_something()

你也可以通过related_name属性来指定反向关系使用的属性名称:

class Child(models.Model):
    parent = models.ForeignKey(Parent, related_name='children')

for child in parent.children.filter(some_field=True):
    do_something()

想了解更多,可以查看文档中关于反向关系的内容反向关系是如何实现的

撰写回答