【问题标题】:django - how do I join the results of multiple models having foreign key the same user?django - 如何加入具有相同用户外键的多个模型的结果?
【发布时间】:2012-01-14 03:31:04
【问题描述】:
我有多个模型指向同一个用户,如下所示:
class Model1(moldels.Model):
user = models.ForeignKey(User)
title = models.CharField()
...
class Model2(moldels.Model):
user = models.ForeignKey(User)
...
class Model3(moldels.Model):
user = models.ForeignKey(User)
...
如何在Model1 上的title 字段上进行搜索/过滤,并加入来自具有相同用户的其他模型的结果。只有 Moldel1 将为同一用户返回多个结果。 Model2 和 Model3 将始终为每个用户返回一个结果(例如一个头像和一个配置文件)。 - 谢谢!
【问题讨论】:
标签:
django
django-models
django-views
django-queryset
【解决方案1】:
这取决于您所说的“加入”是什么意思。您可以通过模型的user 和related_name(默认情况下:<lowercase class name>_set)从其他任何地方访问一个,例如:
model1_instance.user.model2_set.all()
或者您可以使用用户实例直接访问每个:
user.model1_set.all()
user.model2_set.all()
user.model3_set.all()
您也可以通过用户查询这些模型,使用查询遍历:
User.objects.filter(model1__title='some title')
最后,对于只有一个实例的模型,例如每个用户一个配置文件,您应该使用OneToOneField 而不是ForeignKey。如果你这样做,那么你可以在任何反向关系上使用select_related OneToOneField(真正的 SQL JOIN),例如:
User.objects.filter(model1__title='some title').select_related('model2', 'model3')
但是,select_related不适用于反向外键关系或多对多关系。为此,您必须等到 Django 1.4 与 prefetch_related 一起发布。
【解决方案2】:
如果你想得到一个查询集,这是不可能的。您无法获取各种模型的查询集。
但我认为你想要这样的东西:
objs1 = Model.objects.filter(title__icontains='YOUR FILTER')
users = objs1.values('user').distinct()
objs2 = Model2.objects.filter(user__in=users)
objs3 = Model3.objects.filter(user__in=users)
objs = list(objs1)
objs.extend(list(objs2))
objs.extend(list(objs3))
return objs