diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-03-12 12:41:58 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-03-12 12:41:58 +0000 |
| commit | 428450b7a90d92239b170160e5926f83085fa476 (patch) | |
| tree | 85f47ae81a123d27c141f0ee4f31409292333793 /django/db/models/sql | |
| parent | f3ed30f377051c3fef3d184241ed5271fbe61854 (diff) | |
queryset-refactor: Refactored the way values() works so that it works properly
across inherited models.
Completely by accident, this also allows values() queries to include fields
from related models, providing it is crossing a single-valued relation
(one-to-one, many-to-one). Many-to-many values() fields still aren't supported,
since that requires actual thinking. So this refs #5768.
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7230 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/sql')
| -rw-r--r-- | django/db/models/sql/query.py | 35 | ||||
| -rw-r--r-- | django/db/models/sql/subqueries.py | 2 |
2 files changed, 23 insertions, 14 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 491e5b2f5b..f0e2318a74 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -916,7 +916,8 @@ class Query(object): if subtree: self.where.end_subtree() - def setup_joins(self, names, opts, alias, dupe_multis, allow_many=True): + def setup_joins(self, names, opts, alias, dupe_multis, allow_many=True, + allow_explicit_fk=False): """ Compute the necessary table joins for the passage through the fields given in 'names'. 'opts' is the Options class for the current model @@ -939,9 +940,17 @@ class Query(object): try: field, model, direct, m2m = opts.get_field_by_name(name) except FieldDoesNotExist: - names = opts.get_all_field_names() - raise FieldError("Cannot resolve keyword %r into field. " - "Choices are: %s" % (name, ", ".join(names))) + for f in opts.fields: + if allow_explicit_fk and name == f.attname: + # XXX: A hack to allow foo_id to work in values() for + # backwards compatibility purposes. If we dropped that + # feature, this could be removed. + field, model, direct, m2m = opts.get_field_by_name(f.name) + break + else: + names = opts.get_all_field_names() + raise FieldError("Cannot resolve keyword %r into field. " + "Choices are: %s" % (name, ", ".join(names))) if not allow_many and (m2m or not direct): for join in joins: for alias in join: @@ -1102,17 +1111,17 @@ class Query(object): """ return not (self.low_mark or self.high_mark) - def add_local_columns(self, columns): + def add_fields(self, field_names): """ - Adds the given column names to the select set, assuming they come from - the root model (the one given in self.model). + Adds the given (model) fields to the select set. The field names are + added in the order specified. """ - for alias in self.tables: - if self.alias_map[alias][ALIAS_REFCOUNT]: - break - else: - alias = self.get_initial_alias() - self.select.extend([(alias, col) for col in columns]) + alias = self.get_initial_alias() + opts = self.get_meta() + for name in field_names: + u1, target, u2, joins = self.setup_joins(name.split(LOOKUP_SEP), + opts, alias, False, False, True) + self.select.append((joins[-1][-1], target.column)) def add_ordering(self, *ordering): """ diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py index 374109d355..5fb42de85b 100644 --- a/django/db/models/sql/subqueries.py +++ b/django/db/models/sql/subqueries.py @@ -160,7 +160,7 @@ class UpdateQuery(Query): query = self.clone(klass=Query) alias = '%s0' % self.alias_prefix query.change_alias(query.tables[0], alias) - self.add_local_columns([query.model._meta.pk.column]) + self.add_fields([query.model._meta.pk.name]) # Now we adjust the current query: reset the where clause and get rid # of all the tables we don't need (since they're in the sub-select). |
