Я действительно должен неправильно понимать что-то с полем GenericRelation
из структуры типов контента Django.
Чтобы создать минимальный самостоятельный пример, я буду использовать пример примера опросов из учебника. Добавьте общее поле внешнего ключа в модель Choice
и создайте новую модель Thing
:
class Choice(models.Model):
...
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
thing = GenericForeignKey('content_type', 'object_id')
class Thing(models.Model):
choices = GenericRelation(Choice, related_query_name='things')
С чистым db, синхронизированными таблицами и создайте несколько экземпляров:
>>> poll = Poll.objects.create(question='the question', pk=123)
>>> thing = Thing.objects.create(pk=456)
>>> choice = Choice.objects.create(choice_text='the choice', pk=789, poll=poll, thing=thing)
>>> choice.thing.pk
456
>>> thing.choices.get().pk
789
До сих пор так хорошо - отношение работает в обоих направлениях от экземпляра. Но из набора запросов обратное отношение очень странно:
>>> Choice.objects.values_list('things', flat=1)
[456]
>>> Thing.objects.values_list('choices', flat=1)
[456]
Почему обратное отношение снова возвращает id из Thing
? Я ожидал вместо этого первичный ключ выбора, эквивалентный следующему результату:
>>> Thing.objects.values_list('choices__pk', flat=1)
[789]
Те запросы ORM генерируют SQL следующим образом:
>>> print Thing.objects.values_list('choices__pk', flat=1).query
SELECT "polls_choice"."id" FROM "polls_thing" LEFT OUTER JOIN "polls_choice" ON ( "polls_thing"."id" = "polls_choice"."object_id" AND ("polls_choice"."content_type_id" = 10))
>>> print Thing.objects.values_list('choices', flat=1).query
SELECT "polls_choice"."object_id" FROM "polls_thing" LEFT OUTER JOIN "polls_choice" ON ( "polls_thing"."id" = "polls_choice"."object_id" AND ("polls_choice"."content_type_id" = 10))
Документы Django, как правило, превосходны, но я не могу понять, почему второй запрос или найти какую-либо документацию по этому поведению - кажется, что он полностью возвращает данные из неправильной таблицы?