Code

Opened 5 years ago

Closed 5 years ago

Last modified 3 years ago

#10710 closed (fixed)

Invalid results with only() when model has two foreign keys to other models that inherit from a single abstract parent

Reported by: mrts Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: defer only, efficient-admin
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Given the models:

from django.db import models

class Base(models.Model):
    name = models.CharField(max_length=10)
    lots_of_text = models.TextField()

    class Meta:
        abstract = True

    def __unicode__(self):
        return self.name

class A(Base):
    a_field = models.CharField(max_length=10)

class B(Base):
    b_field = models.CharField(max_length=10)

class C(Base):
    a = models.ForeignKey(A)
    b = models.ForeignKey(B)
    is_published = models.BooleanField()

the following occurs:

# all ok here:
>>> from somewhere.models import A, B, C
>>> results = C.objects.all().select_related()
>>> results[0].a.id
2
>>> results[0].a.lots_of_text
u'Sed ut perspiciatis unde omnis iste natus error...'

# bizarre things happen: `id` and `lots_of_text` are swapped
>>> results = C.objects.all().only('name', 'a', 'b').select_related()
>>> results[0].a.lots_of_text
2
>>> results[0].a.id
u'Sed ut perspiciatis unde omnis iste natus error...'

# no luck in deferring two relations with only():
>>> C.objects.all().only('name', 'a', 'b').select_related().only('a__name', 'b__name')
Traceback (most recent call last):
...
FieldDoesNotExist: A has no field named 'b'

# deferring a single relation with only works:
>>> C.objects.all().only('name', 'a', 'b').select_related().only('a__name')
[<C_Deferred_b_is_published_lots_of_text_name: c1>, ...]

Attachments (0)

Change History (7)

comment:1 Changed 5 years ago by mrts

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from limit() behaves erratically in a queryset where the model has two foreign keys to only() behaves erratically in a queryset where the model has two foreign keys

comment:2 Changed 5 years ago by mrts

  • Summary changed from only() behaves erratically in a queryset where the model has two foreign keys to invalid results with only() when model has two foreign keys to other models that inherit from a single abstract parent

comment:3 Changed 5 years ago by mrts

  • Summary changed from invalid results with only() when model has two foreign keys to other models that inherit from a single abstract parent to Invalid results with only() when model has two foreign keys to other models that inherit from a single abstract parent

comment:4 Changed 5 years ago by mtredinnick

(In [10383]) Fixed deferred fields and select_related() interaction.

Loading related models when some fields were deferred was resulting in
incorrect offsets being used into the results row, causing the wrong data to be
assigned to attributes.

Refs #10710. This fixes the first of two bugs reported there.

comment:5 Changed 5 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

The second problem here was fixed in r10384.

comment:6 Changed 5 years ago by mrts

  • Keywords only, efficient-admin added; only removed

comment:7 Changed 3 years ago by jacob

  • milestone 1.1 deleted

Milestone 1.1 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.