Django-如何使用单个查询集在用户的关系模型中获取所有相关对象

时间:2019-05-07 10:01:07

标签: django django-models django-rest-framework django-templates django-views

我想用单个查询集获取用户的所有对象, 但是我不知道... 请帮助我

示例: 我有一个2关系模型到用户模型, 我可以在下面用这些代码获取对象

User.objects.get(id=1).profile
User.objects.get(id=1).groups

但是我如何只用单个查询集获得用户的所有对象...

2 个答案:

答案 0 :(得分:1)

使用here中所述的select_relatedprefetch_related

user = User.objects.select_related('profile').prefetch_related('groups').get(id=1)
user.profile  # does not query the database again
user.groups  # does not query the database again

但是请注意,由于user <-> groups是m2m关系,因此在任何情况下都会两次访问数据库。如果您仅获取一个特定用户,则添加prefetch_related并不会带来任何改变。如果遍历用户列表,确实会有所不同,因为只需要一个查询就可以提取所有与m2m相关的组,而不是每个用户一个查询:

users = User.objects.select_related('profile').prefetch_related('groups')\
     .filter(is_staff=True)
for user in users:  # 2 queries
    print(user.profile)
    for group in user.groups:  # no database query
        print(group.name)

答案 1 :(得分:0)

您可以使用以下格式的双下划线访问查询集中的ManyToMany,Foreign字段数据。

columnname.referred.table__reference_column


class DigitalApplicationsAndPlatform(models.Model):    
    digital_area = models.ForeignKey(MasterDigitalProductsAreas, on_delete=models.CASCADE)    
    keywords = models.ManyToManyField("MasterKeyword", blank=True, related_name="digital_keyword")

查询集:

m = models.DigitalApplicationsAndPlatform.objects.filter(id=1).values('digital_product', 'digital_area__digital_area', 'keywords__keyword')

由于关键字字段具有ManyToMany关系,因此上面的查询集将具有digital_product,digital_area__digital_area的多个值。

结果:

<QuerySet [{'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10000ft Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10K Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': '_10,000ft Insights_'}, {'digital_product': '10,000ft Insights', 'digital_area__digital_area': 'Productivity & Collaboration', 'keywords__keyword': "_10K' Insights_"}]>

以上查询对性能有影响。每当您尝试访问相关的模型数据时,Django都会访问数据库。

m =    models.DigitalApplicationsAndPlatform.objects.filter(id=1).select_related('digital_area').prefetch_related('keywords').values('digital_product',    'digital_area__digital_area', 'keywords__keyword')

您可以使用以下提示来通过上面的查询集来解决它。

  • select_related-用于外键和OneToOne字段。
  • prefetch_related-用于多对多和反向查找

下面的官方文档将给您一些有关访问相关数据的想法。

https://docs.djangoproject.com/en/2.2/topics/db/queries/#lookups-that-span-relationships