summaryrefslogtreecommitdiff
path: root/django/db/models/sql/query.py
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-02-17 18:47:57 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-02-17 18:47:57 +0000
commitda6570bf082620205737c82cd7deb7185daaf538 (patch)
tree0d19599ca9923f974512bb7453072a553ada28e6 /django/db/models/sql/query.py
parent2d0588548e52c78e5213d262a5c4e5df1da3450e (diff)
queryset-refactor: Model inheritance support.
This adds both types of model inheritance: abstract base classes (ABCs) and multi-table inheritance. See the documentation and tests / examples for details. Still a few known bugs here, so don't file tickets (I know about them). Not quite ready for prime-time usage, but it mostly works as expected. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7126 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/sql/query.py')
-rw-r--r--django/db/models/sql/query.py26
1 files changed, 21 insertions, 5 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 7d95e1d603..7b70e4d1b2 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -389,8 +389,13 @@ class Query(object):
aliases.append(col.alias)
elif self.default_cols:
table_alias = self.tables[0]
- result = ['%s.%s' % (qn(table_alias), qn(f.column))
- for f in self.model._meta.fields]
+ root_pk = self.model._meta.pk.column
+ seen = {None: table_alias}
+ for field, model in self.model._meta.get_fields_with_model():
+ if model not in seen:
+ seen[model] = self.join((table_alias, model._meta.db_table,
+ root_pk, model._meta.pk.column))
+ result.append('%s.%s' % (qn(seen[model]), qn(field.column)))
aliases = result[:]
result.extend(['(%s) AS %s' % (col, alias)
@@ -742,7 +747,7 @@ class Query(object):
opts = self.model._meta
alias = self.join((None, opts.db_table, None, None))
- field, target, unused, join_list, = self.setup_joins(parts, opts,
+ field, target, opts, join_list, = self.setup_joins(parts, opts,
alias, (connector == AND))
col = target.column
alias = join_list[-1][-1]
@@ -850,11 +855,21 @@ class Query(object):
name = opts.pk.name
try:
- field, direct, m2m = opts.get_field_by_name(name)
+ field, model, direct, m2m = opts.get_field_by_name(name)
except FieldDoesNotExist:
names = opts.get_all_field_names()
raise TypeError("Cannot resolve keyword %r into field. "
"Choices are: %s" % (name, ", ".join(names)))
+ if model:
+ # The field lives on a base class of the current model.
+ alias_list = []
+ for int_model in opts.get_base_chain(model):
+ lhs_col = opts.parents[int_model].column
+ opts = int_model._meta
+ alias = self.join((alias, opts.db_table, lhs_col,
+ opts.pk.column))
+ alias_list.append(alias)
+ joins.append(alias_list)
cached_data = opts._join_cache.get(name)
orig_opts = opts
@@ -899,6 +914,7 @@ class Query(object):
nullable=field.null)
joins.append([alias])
else:
+ # Non-relation fields.
target = field
break
else:
@@ -1242,7 +1258,7 @@ class UpdateQuery(Query):
def add_update_values(self, values):
from django.db.models.base import Model
for name, val in values.items():
- field, direct, m2m = self.model._meta.get_field_by_name(name)
+ field, model, direct, m2m = self.model._meta.get_field_by_name(name)
if not direct or m2m:
# Can only update non-relation fields and foreign keys.
raise TypeError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field)