From fcad6c48f07bdc6346c065849a87f0f02afb6f94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Anssi=20K=C3=A4=C3=A4ri=C3=A4inen?= <akaariai@gmail.com>
Date: Tue, 17 Jul 2012 12:24:56 +0300
Subject: [PATCH] Fixed #17497 -- Corrected FieldError message in add_fields()

The erroneous message was user visible in values_list() calls.

Thanks to ojii for report and review, and to antoviaque for the patch.
---
 django/db/models/sql/query.py         | 13 +++++++++----
 tests/modeltests/many_to_one/tests.py | 14 +++++++++++++-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 8fbba3dbc9..118bc1e14f 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1655,10 +1655,15 @@ class Query(object):
         except MultiJoin:
             raise FieldError("Invalid field name: '%s'" % name)
         except FieldError:
-            names = opts.get_all_field_names() + self.extra.keys() + self.aggregate_select.keys()
-            names.sort()
-            raise FieldError("Cannot resolve keyword %r into field. "
-                    "Choices are: %s" % (name, ", ".join(names)))
+            if name.find(LOOKUP_SEP) != -1:
+                # For lookups spanning over relationships, show the error
+                # from the model on which the lookup failed.
+                raise
+            else:
+                names = sorted(opts.get_all_field_names() + self.extra.keys()
+                               + self.aggregate_select.keys())
+                raise FieldError("Cannot resolve keyword %r into field. "
+                                 "Choices are: %s" % (name, ", ".join(names)))
         self.remove_inherited_models()
 
     def add_ordering(self, *ordering):
diff --git a/tests/modeltests/many_to_one/tests.py b/tests/modeltests/many_to_one/tests.py
index 257025583b..fd849df051 100644
--- a/tests/modeltests/many_to_one/tests.py
+++ b/tests/modeltests/many_to_one/tests.py
@@ -3,7 +3,7 @@ from __future__ import absolute_import
 from copy import deepcopy
 from datetime import datetime
 
-from django.core.exceptions import MultipleObjectsReturned
+from django.core.exceptions import MultipleObjectsReturned, FieldError
 from django.test import TestCase
 from django.utils.translation import ugettext_lazy
 
@@ -424,3 +424,15 @@ class ManyToOneTests(TestCase):
         notlazy = unicode(lazy)
         article = reporter.article_set.get()
         self.assertEqual(article.headline, notlazy)
+
+    def test_values_list_exception(self):
+        expected_message = "Cannot resolve keyword 'notafield' into field. Choices are: %s"
+
+        self.assertRaisesMessage(FieldError,
+                                 expected_message % ', '.join(Reporter._meta.get_all_field_names()),
+                                 Article.objects.values_list,
+                                 'reporter__notafield')
+        self.assertRaisesMessage(FieldError,
+                                 expected_message % ', '.join(['EXTRA',] + Article._meta.get_all_field_names()),
+                                 Article.objects.extra(select={'EXTRA': 'EXTRA_SELECT'}).values_list,
+                                 'notafield')