Django Набор запросов Model.objects.all () не отличается - PullRequest
0 голосов
/ 05 мая 2020

У меня есть следующие модели 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).

Проблема, с которой я сталкиваюсь, заключается в том, что если у меня есть два профиля, Боб и Джим, и Боб создает награду под названием «Награда 1» и завершает ее, все в порядке. Если Джим затем завершает «Bounty 1», все работает нормально, за исключением случаев, когда я вызываю Bounty.objects.all () или Bob.created_bounties.all (), я получаю <QuerySet [<Bounty: Bounty 1>, <Bounty: Bounty 1>]> и queryset [0] == queryset [1].

База данных показывает только одну награду, и все выглядит так, как должно. Если я посмотрю на набор запросов SQL из Bounty.objects.all (), я вижу

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

Что, если я читаю справа, левое внешнее соединение является проблемой, потому что оно будет соответствовать как ProfileTrophys, так и т. вернуть награду дважды.

Любая помощь в том, почему это дублирование происходит в наборе запросов и что я делаю не так?

Изменить: я должен добавить, что все в приложении работает нормально, я заметил только потому, что объект Bounty дважды появляется на панели администратора, и это меня действительно беспокоило.

Изменить 2: Удаление создателя и original_completion из модели Bounty не влияет на проблему

1 Ответ

0 голосов
/ 05 мая 2020

Хорошо, получается, что это было связано с тем, что я упустил, мета-упорядочение было установлено на ["bounty_completions"], что вызывало необходимость вызова упорядочения в левом соединении.

...