From baaf29895c41cfafcd130d5a8f5ab548e5e9c308 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 11 May 2009 10:10:03 +0000 Subject: 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. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10738 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/sql/query.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'django/db/models/sql') diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index bafa1e93ea..394e30ba97 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -778,7 +778,9 @@ class BaseQuery(object): qn2 = self.connection.ops.quote_name aliases = set() only_load = self.deferred_to_columns() - proxied_model = opts.proxy and opts.proxy_for_model or 0 + # Skip all proxy to the root proxied model + proxied_model = get_proxied_model(opts) + if start_alias: seen = {None: start_alias} for field, model in opts.get_fields_with_model(): @@ -1301,7 +1303,10 @@ class BaseQuery(object): opts = self.model._meta root_alias = self.tables[0] seen = {None: root_alias} - proxied_model = opts.proxy and opts.proxy_for_model or 0 + + # Skip all proxy to the root proxied model + proxied_model = get_proxied_model(opts) + for field, model in opts.get_fields_with_model(): if model not in seen: if model is proxied_model: @@ -1376,6 +1381,13 @@ class BaseQuery(object): alias = root_alias alias_chain = [] for int_model in opts.get_base_chain(model): + # Proxy model have elements in base chain + # with no parents, assign the new options + # object and skip to the next base in that + # case + if not int_opts.parents[int_model]: + int_opts = int_model._meta + continue lhs_col = int_opts.parents[int_model].column dedupe = lhs_col in opts.duplicate_targets if dedupe: @@ -1720,7 +1732,9 @@ class BaseQuery(object): raise MultiJoin(pos + 1) if model: # The field lives on a base class of the current model. - proxied_model = opts.proxy and opts.proxy_for_model or 0 + # Skip the chain of proxy to the concrete proxied model + proxied_model = get_proxied_model(opts) + for int_model in opts.get_base_chain(model): if int_model is proxied_model: opts = int_model._meta @@ -2423,3 +2437,11 @@ def add_to_dict(data, key, value): data[key].add(value) else: data[key] = set([value]) + +def get_proxied_model(opts): + int_opts = opts + proxied_model = None + while int_opts.proxy: + proxied_model = int_opts.proxy_for_model + int_opts = proxied_model._meta + return proxied_model -- cgit v1.3