使用django ORM连接三个或更多表

时间:2012-12-28 15:43:44

标签: django join orm

我设计的模型使得所有模型在auth_user表上都具有一对一的关系,即User。为了您的快速参考,我粘贴下面的图片

enter image description here

现在我想选择与BasicDetails,Department和Project表中的用户名相关的所有数据。以下查询未获取结果。

User.objects.select_related().get(username='user1')

有人可以帮我吗?

-Vikram

1 个答案:

答案 0 :(得分:1)

你应该使用prefetch_related来提高效率,因为你的关系是反向的(你想从User访问其他记录而不是相反):

u = User.objects.prefetch_related('project_set', 'department_set', 'basicdetails_set').get(username='user1')

这不会生成单个查询,但Django将使用缓存技术来有效地产生较少的数据库开销。如果我没记错的话,它将产生4个查询(4个表中的单个连接可能会更慢,具体取决于记录数,索引等)。好处是在后续请求中不会生成任何queres。例如,获取用户的项目:

u.project_set.all() #hits the db
u.project_set.all() #cached version, no db hit

有关详细信息,请参阅此处https://docs.djangoproject.com/en/dev/topics/db/queries/#one-to-one-relationships

编辑:什么是project_set

如果您的项目模型定义如下

class Project(models.Model):
    ...
    user = models.ForeignKey(User)

然后你可以Project.objects.get(pk=1).user来访问与项目实例相关联的用户,但是你会如何做相反的事情(得到某个用户的所有项目)? Django将自动包含一个' _set'为方便起见,为了其他型号的财产。因此,我们可以像这样得到某个用户的项目:

u = User.objects.get(pk=1)
user_objects = u.project_set.all()

但是,如果要为此反向关系显式设置名称,django允许您使用related_name关键字参数定义ForeignKey,如下所示:

class Project(models.Model):
    ...
    user = models.ForeignKey(User, related_name='projects')

现在代替.project_set您可以使用.projects来访问用户的项目:

u = User.objects.get(pk=1)
user_objects = u.projects.all()