Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added field.attname to Options.name_map

The change also removed allow_explicit_fk from sql/query.py.
  • Loading branch information...
commit c21e86ab9e3e5ebd6d245d038cb0cb352cd84c3a 1 parent 31e6d58
@akaariai akaariai authored
View
7 django/db/models/options.py
@@ -404,12 +404,13 @@ def init_name_map(self):
for f, model in self.get_all_related_objects_with_model():
cache[f.field.related_query_name()] = (f, model, False, False)
for f, model in self.get_m2m_with_model():
- cache[f.name] = (f, model, True, True)
+ cache[f.name] = cache[f.attname] = (f, model, True, True)
for f, model in self.get_fields_with_model():
- cache[f.name] = (f, model, True, False)
+ cache[f.name] = cache[f.attname] = (f, model, True, False)
for f in self.virtual_fields:
if hasattr(f, 'related'):
- cache[f.name] = (f.related, None if f.model == self.model else f.model, True, False)
+ cache[f.name] = cache[f.attname] = (
+ f.related, None if f.model == self.model else f.model, True, False)
if app_cache_ready():
self._name_map = cache
return cache
View
29 django/db/models/sql/query.py
@@ -1091,8 +1091,7 @@ def build_filter(self, filter_expr, branch_negated=False, current_negated=False,
try:
field, sources, opts, join_list, path = self.setup_joins(
- parts, opts, alias, can_reuse, allow_many,
- allow_explicit_fk=True)
+ parts, opts, alias, can_reuse, allow_many,)
if can_reuse is not None:
can_reuse.update(join_list)
except MultiJoin as e:
@@ -1237,15 +1236,14 @@ def _add_q(self, q_object, used_aliases, branch_negated=False,
len(q_object.children))
return target_clause
- def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
+ def names_to_path(self, names, opts, allow_many):
"""
Walks the names path and turns them PathInfo tuples. Note that a
single name in 'names' can generate multiple PathInfos (m2m for
example).
'names' is the path of names to travle, 'opts' is the model Options we
- start the name resolving from, 'allow_many' and 'allow_explicit_fk'
- are as for setup_joins().
+ start the name resolving from, 'allow_many' is as for setup_joins().
Returns a list of PathInfo tuples. In addition returns the final field
(the last used join field), and target (which is a field guaranteed to
@@ -1258,17 +1256,9 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
try:
field, model, direct, m2m = opts.get_field_by_name(name)
except FieldDoesNotExist:
- 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:
- available = opts.get_all_field_names() + list(self.aggregate_select)
- raise FieldError("Cannot resolve keyword %r into field. "
- "Choices are: %s" % (name, ", ".join(available)))
+ available = opts.get_all_field_names() + list(self.aggregate_select)
+ raise FieldError("Cannot resolve keyword %r into field. "
+ "Choices are: %s" % (name, ", ".join(available)))
# Check if we need any joins for concrete inheritance cases (the
# field lives in parent, but we are currently in one of its
# children)
@@ -1314,7 +1304,7 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
return path, final_field, targets
def setup_joins(self, names, opts, alias, can_reuse=None, allow_many=True,
- allow_explicit_fk=False, outer_if_first=False):
+ outer_if_first=False):
"""
Compute the necessary table joins for the passage through the fields
given in 'names'. 'opts' is the Options class for the current model
@@ -1329,9 +1319,6 @@ def setup_joins(self, names, opts, alias, can_reuse=None, allow_many=True,
If 'allow_many' is False, then any reverse foreign key seen will
generate a MultiJoin exception.
- The 'allow_explicit_fk' controls if field.attname is allowed in the
- lookups.
-
Returns the final field involved in the joins, the target field (used
for any 'where' constraint), the final 'opts' value, the joins and the
field path travelled to generate the joins.
@@ -1345,7 +1332,7 @@ def setup_joins(self, names, opts, alias, can_reuse=None, allow_many=True,
joins = [alias]
# First, generate the path for the names
path, final_field, targets = self.names_to_path(
- names, opts, allow_many, allow_explicit_fk)
+ names, opts, allow_many)
# Then, add the path to the query's joins. Note that we can't trim
# joins at this stage - we will need the information about join type
# of the trimmed joins.
View
3  tests/lookup/tests.py
@@ -470,7 +470,8 @@ def test_error_messages(self):
self.fail('FieldError not raised')
except FieldError as ex:
self.assertEqual(str(ex), "Cannot resolve keyword 'pub_date_year' "
- "into field. Choices are: author, headline, id, pub_date, tag")
+ "into field. Choices are: author, author_id, headline, "
+ "id, pub_date, tag")
try:
Article.objects.filter(headline__starts='Article')
self.fail('FieldError not raised')
Please sign in to comment.
Something went wrong with that request. Please try again.