﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15790	only() broken for proxy models	michal.modzelewski@…	Michał Modzelewski	"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."	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed	proxy only	michal.modzelewski@…	Ready for checkin	1	0	0	0	0	0
