2

I have 2 models connected with 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)

I want to query only name and title fields form Person and Card models.

I tried several approaches but none of them worked.

1st try

Person.objects.filter(slug=slug).only('name', 'card__title')

but generated query doesn't include card__title:

SELECT "core_person"."id", "core_person"."name" FROM "core_person" 
WHERE "core_person"."slug" = some-name

2nd try

Person.objects.filter(slug=slug).select_related('card').only('name')

but generated query includes all fields from 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

3rd try

Person.objects.filter(slug=slug).select_related('card').only('name', 'card__title')

but it throws weird exception:

django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'card'. Choices are: card

Desired result

Is there a way to receive a query like below not using .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
VeGABAU
  • 158
  • 1
  • 13
  • Why do you need this? – knbk Jul 14 '16 at 16:19
  • What is the problem with `.values()` ? – Gocht Jul 14 '16 at 16:22
  • 1
    @Gocht I need model instance not dict – VeGABAU Jul 14 '16 at 16:27
  • @knbk because in reality `Card` model has ~10 large fields which I don't need in this query and if I fetch them it makes query slower – VeGABAU Jul 14 '16 at 16:30
  • 1
    `.only()` worked for me. Try getting only one user, I guess `slug` is unique: `Person.objects.only('card__title').get(slug=slug)` – Gocht Jul 14 '16 at 16:44
  • @Gocht it executes, you are right, but if I write `person = Person.objects.only('card__title').get(slug=slug)` and then try to get the value like `person.card.title` django executes 2nd query to actually get the card. I want to avoid 2nd query with `select_related()`. But thanks for your time and help. – VeGABAU Jul 14 '16 at 17:20
  • Once again `Person.objects.select_related('card').only('card__title').get(slug=slug)` works. – Gocht Jul 14 '16 at 17:21
  • @Gocht strange, because I'm getting the exception `django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'card'. Choices are: card`. Have you changed anything in models and which django version do you use? – VeGABAU Jul 14 '16 at 17:32
  • Well I was trying with FK, you don't need select related to 1to1 relation https://docs.djangoproject.com/es/1.9/topics/db/examples/one_to_one/ – Gocht Jul 14 '16 at 17:34
  • @Gocht well, if I replace `OneToOneField` with `ForeignKey` I get `AttributeError: 'ManyToOneRel' object has no attribute 'attname'` exception. Can you please post code you are using on pastebin? Sorry didn't get why select_related is not needed for 1to1. – VeGABAU Jul 14 '16 at 17:59
  • This is an example of the code I am testing with http://pastebin.com/vpyUmhi7 – Gocht Jul 14 '16 at 19:17
  • @Gocht in your code you're actually doing it the opposite way. You call a manager on a model which has FK field (in my case it's `Card` not `Person`). As a result you get not `Person` instance but `Card`. But in my case it still solves the problem. Thanks a lot for your time and help! – VeGABAU Jul 14 '16 at 20:00
  • Good for you, cheers! – Gocht Jul 14 '16 at 20:05
  • Does this answer your question? [Selecting specific fields using select\_related in Django](https://stackoverflow.com/questions/35524259/selecting-specific-fields-using-select-related-in-django) – Qumber Nov 25 '20 at 14:19

0 Answers0