首页 > 解决方案 > Django Model.objects.all() 查询集不明显

问题描述

我有以下 Django 3.0 模型:

class Profile(models.Model):
    id = ShortUUIDField(primary_key=True, unique=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

class Bounty(models.Model):
    id = ShortUUIDField(primary_key=True, unique=True)
    creator = models.ForeignKey('Profile', related_name="created_bounties", on_delete=models.SET_NULL, null=True, blank=True)
    original_completion = models.OneToOneField('ProfileTrophy', related_name="original_bounty",on_delete=models.SET_NULL, null=True, blank=True)
    name = models.CharField(max_length=50)

class ProfileTrophy(models.Model):
    id = ShortUUIDField(primary_key=True, unique=True)
    profile = models.ForeignKey('Profile', related_name="bounty_completions", on_delete=models.CASCADE)
    bounty = models.ForeignKey('Bounty', related_name="bounty_completions", on_delete=models.CASCADE)
    name = models.CharField(max_length=50, null=True, blank=True)

所以前提是有个人资料和赏金。配置文件可以创建赏金(存储为赏金的创建者)。配置文件可以完成一个赏金,它被存储为一个 ProfileTrophy(完成赏金的奖杯),他们可以完成他们创建的赏金或其他人创建的赏金(赏金可以有许多完成,但创建者的原始存储在 original_completion 中)。

我遇到的问题是,如果我有两个配置文件 Bob 和 Jim,并且 Bob 创建一个名为“Bounty 1”的赏金并完成它,一切都很好。如果 Jim 然后完成“Bounty 1”,一切正常,除了当我调用 Bounty.objects.all() 或 Bob.created_bounties.all() 时,我得到<QuerySet [<Bounty: Bounty 1>, <Bounty: Bounty 1>]>和 queryset[0]==queryset[1]。

数据库只显示一个赏金,一切看起来都应该如此。如果我查看 Bounty.objects.all() 的查询集 SQL,我会看到

SELECT "core_bounty"."id" FROM "core_bounty" LEFT OUTER JOIN "core_profiletrophy" ON ("core_bounty"."id" = "core_profiletrophy"."bounty_id")

如果我正在阅读,那么左外连接就是问题所在,因为它会匹配两个 ProfileTrophys 并因此返回赏金两次。

关于为什么在查询集中发生这种重复以及我做错了什么的任何帮助?

编辑:我应该补充一点,应用程序中的所有内容都可以正常工作,我只是注意到,因为 Bounty 对象在管理仪表板中出现了两次,这真的让我很困扰。

编辑 2:从 Bounty 模型中删除 creator 和 original_completion 对问题没有影响

标签: pythondjangodjango-models

解决方案


好的,事实证明它与我遗漏的东西有关,元排序设置为 ["bounty_completions"] 这导致排序需要在左连接中调用。


推荐阅读