Opened 16 years ago

Closed 16 years ago

Last modified 13 years ago

#10955 closed (fixed)

`select_related()` doesn't work with proxy models.

Reported by: Tai Lee Owned by: Jacob
Component: Database layer (models, ORM) Version: dev
Severity: Keywords: proxy model select_related
Cc: Armin Ronacher Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I get a traceback if I call get() on a queryset for a proxy model which is using select_related(), or simply no objects if I try to access the queryset itself.

# models

class Country(models.Model):
	name = models.CharField(max_length=50, unique=True)

class State(models.Model):
	name = models.CharField(max_length=50)
	country = models.ForeignKey(Country)

	def __unicode__(self):
		return self.name

class StateProxy(State):
	class Meta:
		proxy = True

# interactive shell

>>> country = Country.objects.create(name='Australia')
>>> state = State.objects.create(name='New South Wales', country=country)

>>> State.objects.select_related()
[<State: New South Wales>]

>>> StateProxy.objects.select_related()
[]

# should have got [<State: New South Wales>]

>>> StateProxy.objects.get(name='New South Wales')
<StateProxy: New South Wales>

>>> StateProxy.objects.select_related().get(name='New South Wales')
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/path/to/django/db/models/manager.py", line 120, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/path/to/django/db/models/query.py", line 269, in get
    num = len(clone)
  File "/path/to/django/db/models/query.py", line 68, in __len__
    self._result_cache = list(self.iterator())
  File "/path/to/django/db/models/query.py", line 207, in iterator
    for row in self.query.results_iter():
  File "/path/to/django/db/models/sql/query.py", line 276, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/path/to/django/db/models/sql/query.py", line 2301, in execute_sql
    sql, params = self.as_sql()
  File "/path/to/django/db/models/sql/query.py", line 384, in as_sql
    self.pre_sql_setup()
  File "/path/to/django/db/models/sql/query.py", line 571, in pre_sql_setup
    self.fill_related_selections()
  File "/path/to/django/db/models/sql/query.py", line 1361, in fill_related_selections
    lhs_col = int_opts.parents[int_model].column
AttributeError: 'NoneType' object has no attribute 'column'

# should have got <StateProxy: New South Wales>

Attachments (3)

10955-proxy_select_related-r10643.diff (1.5 KB ) - added by Tai Lee 16 years ago.
10955_proxy_select_related_r10697.diff (9.6 KB ) - added by Clément Nodet 16 years ago.
initial patch, fixes select_related + filter on proxy, and type issue on subproxy
10955_proxy_select_related_no_manager_fix_r10697.diff (8.2 KB ) - added by Clément Nodet 16 years ago.
patch without manager fix (covered by #10953)

Download all attachments as: .zip

Change History (12)

by Clément Nodet, 16 years ago

initial patch, fixes select_related + filter on proxy, and type issue on subproxy

comment:1 by Clément Nodet, 16 years ago

Has patch: set

There was a possible bug on subproxy (proxy of proxy) manager creation, giving the following results on the API tests:

>>> MyPersonProxy.objects.all() 
[<MyPerson: Bazza del Frob>, <MyPerson: Foo McBar>, <MyPerson: homer>]

bypassed that by forcing manager inheritance (of abstract and concrete managers) from the model base (before skipping proxy for populating fields), but not sure this is the needed behaviour here.

Patch mostly adresses proxy skipping when joining fields (traversing multiple levels of nested proxies) and ancestors chain when populating select fields on proxy models. Added also some regression tests on proxy + model inheritance, subproxy select_related().filter(...), and ForeignKey( proxy / subproxy )

comment:2 by Alex Gaynor, 16 years ago

I have a patch on another issue (I forget the number) that solves the manager issue.

by Clément Nodet, 16 years ago

patch without manager fix (covered by #10953)

comment:3 by Clément Nodet, 16 years ago

@Alex:

I suppose #10953 , attached a new patch with no modifications in django.models.base.ModelBase

comment:4 by Armin Ronacher, 16 years ago

Owner: changed from nobody to Armin Ronacher

comment:5 by Armin Ronacher, 16 years ago

The patch for this and #10953 is attached to my github repo: http://github.com/mitsuhiko/django/tree/ticket-10953

comment:6 by Jacob, 16 years ago

Owner: changed from Armin Ronacher to Jacob
Status: newassigned

comment:7 by Armin Ronacher, 16 years ago

Cc: Armin Ronacher added

comment:8 by Jacob, 16 years ago

Resolution: fixed
Status: assignedclosed

(In [10738]) Fixed #10953, #10955: proxies of proxies now work correctly, though I still don't quite understand why you'd want to do such a thing. Thanks, Armin Ronacher.

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