Opened 16 years ago

Closed 16 years ago

Last modified 13 years ago

#10695 closed (fixed)

defer() uses the same cached value for all models

Reported by: jbronn Owned by: Malcolm Tredinnick
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: defer qs
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

While trying to get defer() to work with GeoQuerySets I ran into some strange issues. I eventually figured out that that problem was not isolated to GeoDjango. Here a toy model that demonstrates the problem:

from django.db import models

class City(models.Model):
    name = models.CharField(max_length=30)
    def __unicode__(self): 
        return self.name

Creating two cities, and showing what happens when the QuerySet is evaluated:

>>> c = City.objects.create(name='Pueblo')
>>> c = City.objects.create(name='Houston')
>>> City.objects.all()
[<City: Pueblo>, <City: Houston>]

However, when evaluating a QuerySet with the name field deferred, this is what's returned:

>>> City.objects.defer('name')
[<City_Deferred_name: Pueblo>, <City_Deferred_name: Pueblo>]

Notice how it shows "Pueblo" for both records, when the second one should be "Houston." The same thing happens with slicing:

>>> qs = City.objects.defer('name')
>>> qs[0].name
u'Pueblo'
>>> qs[1].name
u'Pueblo'

My gut tells me that when DeferredAttribute is cached it is somehow cached for all of the other attributes. However, I cannot pinpoint how and/or where this is happening.

Attachments (8)

defer.diff (7.6 KB ) - added by Alex Gaynor 16 years ago.
defer_v2.diff (8.4 KB ) - added by jbronn 16 years ago.
defer_v3.diff (8.8 KB ) - added by jbronn 16 years ago.
defer.2.diff (9.6 KB ) - added by Alex Gaynor 16 years ago.
add tests and code to make it work properly with foreing keys
defer.3.diff (9.6 KB ) - added by Alex Gaynor 16 years ago.
defer.4.diff (9.1 KB ) - added by Alex Gaynor 16 years ago.
defer.5.diff (9.2 KB ) - added by Alex Gaynor 16 years ago.
defer.6.diff (9.2 KB ) - added by Alex Gaynor 16 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 by Alex Gaynor, 16 years ago

Triage Stage: UnreviewedAccepted

by Alex Gaynor, 16 years ago

Attachment: defer.diff added

comment:2 by Alex Gaynor, 16 years ago

Has patch: set

comment:3 by Alex Gaynor, 16 years ago

An alternate approach would be to put the pk in the class name, however that would mean creating O(n) classes, which strikes me as silly and wasteful of memory, given that this approach works.

by jbronn, 16 years ago

Attachment: defer_v2.diff added

by jbronn, 16 years ago

Attachment: defer_v3.diff added

by Alex Gaynor, 16 years ago

Attachment: defer.2.diff added

add tests and code to make it work properly with foreing keys

by Alex Gaynor, 16 years ago

Attachment: defer.3.diff added

by Alex Gaynor, 16 years ago

Attachment: defer.4.diff added

comment:4 by Malcolm Tredinnick, 16 years ago

Owner: changed from mtreddinick to Malcolm Tredinnick
Status: newassigned

I'm not convinced about this patch yet (Alex: work on getting one patch right, instead of submitting 14 really quick ones). All that instance.__dict__ stuff looks a bit ugly. But I see where you're going. Will work on it a bit over the weekend.

by Alex Gaynor, 16 years ago

Attachment: defer.5.diff added

by Alex Gaynor, 16 years ago

Attachment: defer.6.diff added

comment:5 by Malcolm Tredinnick, 16 years ago

Resolution: fixed
Status: assignedclosed

Fixed in r10382.

comment:6 by Jacob, 13 years ago

milestone: 1.1

Milestone 1.1 deleted

Note: See TracTickets for help on using tickets.
Back to Top