#15790: only() broken for proxy models
-----------------------------+---------------------------------------------
Reporter: | Owner: nobody
michal.modzelewski@… | Status: new
Type: Bug | Component: Database layer (models, ORM)
Milestone: | Severity: Release blocker
Version: SVN | Triage Stage: Unreviewed
Keywords: proxy only |
Has patch: 0 |
-----------------------------+---------------------------------------------
Usage of deferred fields with proxy models is broken.
For example when using the following models
{{{
class Item(models.Model):
name = models.CharField(max_length=15)
text = models.TextField(default="xyzzy")
value = models.IntegerField()
other_value = models.IntegerField(default=0)
class Proxy(Item):
class Meta:
proxy = True
}}}
we create an item with
{{{
>>> proxy = Proxy.objects.create(name="proxy", value=42)
}}}
Now depending on whether we call only() with 'id' or not we get different
behaviour.
Without 'id' we get an endless loop.
{{{
>>> deferredproxy = Proxy.objects.only('value').get(pk=proxy.pk)
>>> deferredproxy.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
deferredproxy.name
File "/home/michal/.local/lib/python2.7/site-
packages/django/db/models/query_utils.py", line 100, in __get__
cls._base_manager.filter(pk=instance.pk).only(name).using(
File "/home/michal/.local/lib/python2.7/site-
packages/django/db/models/base.py", line 426, in _get_pk_val
return getattr(self, meta.pk.attname)
File "/home/michal/.local/lib/python2.7/site-
packages/django/db/models/query_utils.py", line 100, in __get__
cls._base_manager.filter(pk=instance.pk).only(name).using(
...
File "/home/michal/.local/lib/python2.7/site-
packages/django/db/models/base.py", line 426, in _get_pk_val
return getattr(self, meta.pk.attname)
RuntimeError: maximum recursion depth exceeded
}}}
With 'id' we get the wrong value when accessing a deferred field.
{{{
>>> deferredproxy = Proxy.objects.only('id', 'value').get(pk=proxy.pk)
>>> deferredproxy.name
3
}}}
This value happens to be the object id.
{{{
>>> proxy.id
3
}}}
Comparing the objects returned with examples using the base model.
{{{
>>> Proxy.objects.only('other_value').get(pk=proxy.pk).__dict__
{'_state': <django.db.models.base.ModelState object at 0x89bd58c>,
'other_value': 3}
>>> Item.objects.only('other_value').get(pk=proxy.pk).__dict__
{'_state': <django.db.models.base.ModelState object at 0x89bd80c>, 'id':
3, 'other_value': 0}
>>> Proxy.objects.only('name', 'text', 'value',
'other_value').get(pk=proxy.pk).__dict__
{'text': u'proxy', '_state': <django.db.models.base.ModelState object at
0x89bda8c>, 'name': 3, 'value': u'xyzzy', 'other_value': 42}
>>> Item.objects.only('name', 'text', 'value',
'other_value').get(pk=proxy.pk).__dict__
{'name': u'proxy', 'text': u'xyzzy', '_state':
<django.db.models.base.ModelState object at 0x89bdcec>, 'value': 42,
'other_value': 0, 'id': 3}
}}}
'id' is missing from the !__dict!__ for the proxy models, and all the
values are shifted.
--
Ticket URL: <http://code.djangoproject.com/ticket/15790>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.