У меня есть 2 модели, связанные с OneToOneField
:
class Person(TimeStampedModel, StatusModel):
name = models.CharField(max_length=300)
slug = models.SlugField(max_length=300)
class Card(TimeStampedModel, StatusModel):
title = models.CharField(max_length=300)
year = models.IntegerField()
comment = models.TextField(blank=True)
featured = models.BooleanField(default=False)
person = models.OneToOneField(Person, on_delete=models.CASCADE)
Я хочу запрашивать только поля name
и title
из моделей Person
и Card
.
Я пробовал несколько подходов, но ни один из них не работал.
Первая попытка
Person.objects.filter(slug=slug).only('name', 'card__title')
но сгенерированный запрос не включает card__title
:
SELECT "core_person"."id", "core_person"."name" FROM "core_person"
WHERE "core_person"."slug" = some-name
Вторая попытка
Person.objects.filter(slug=slug).select_related('card').only('name')
но сгенерированный запрос включает все поля из Card
:
SELECT "core_person"."id", "core_person"."name", "core_card"."id",
"core_card"."title", "core_card"."year", "core_card"."comment",
"core_card"."featured"
FROM "core_person"
LEFT OUTER JOIN "core_card" ON ("core_person"."id" = "core_card"."person_id")
WHERE "core_person"."slug" = some-name
3-я попытка
Person.objects.filter(slug=slug).select_related('card').only('name', 'card__title')
но выдает странное исключение:
django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'card'. Choices are: card
Желаемый результат
Есть ли способ получить запрос, как показано ниже, без использования .values()
?
SELECT "core_person"."id", "core_person"."name", "core_card"."id",
"core_card"."title"
FROM "core_person"
LEFT OUTER JOIN "core_card" ON ("core_person"."id" = "core_card"."person_id")
WHERE "core_person"."slug" = some-name
.values()
? - person Gocht   schedule 14.07.2016Card
имеет ~ 10 больших полей, которые мне не нужны в этом запросе, и если я их извлеку, запрос замедлится - person VeGABAU   schedule 14.07.2016.only()
работал на меня. Попробуйте получить только одного пользователя, я думаю,slug
уникален:Person.objects.only('card__title').get(slug=slug)
- person Gocht   schedule 14.07.2016person = Person.objects.only('card__title').get(slug=slug)
, а затем попытаюсь получить значение, подобноеperson.card.title
, django выполнит второй запрос, чтобы фактически получить карту. Я хочу избежать второго запроса сselect_related()
. Но спасибо за ваше время и помощь. - person VeGABAU   schedule 14.07.2016Person.objects.select_related('card').only('card__title').get(slug=slug)
работает. - person Gocht   schedule 14.07.2016django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'card'. Choices are: card
. Изменили ли вы что-нибудь в моделях и какую версию django вы используете? - person VeGABAU   schedule 14.07.2016OneToOneField
наForeignKey
, я получу исключениеAttributeError: 'ManyToOneRel' object has no attribute 'attname'
. Не могли бы вы опубликовать код, который вы используете на pastebin? Извините, не понял, почему select_related не нужен для 1to1. - person VeGABAU   schedule 14.07.2016Card
, а неPerson
). В результате получается неPerson
экземпляр, аCard
. Но в моем случае это все еще решает проблему. Большое спасибо за ваше время и помощь! - person VeGABAU   schedule 14.07.2016