summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnson <mdj2@pdx.edu>2015-07-22 11:54:42 -0700
committerTim Graham <timograham@gmail.com>2015-07-23 18:07:38 -0400
commite063ac2fae007a2eecaeab5ce17064c31230ce29 (patch)
tree981151d26d168b54bdef160b2c97a5bc7072ace3
parent71df9b7de4bcb760e756d119685636e101898816 (diff)
Fixed #12768 -- Fixed QuerySet.raw() regression on FK with custom db_column.
-rw-r--r--django/db/models/query.py6
-rw-r--r--docs/releases/1.8.4.txt4
-rw-r--r--tests/raw_query/models.py4
-rw-r--r--tests/raw_query/tests.py13
4 files changed, 23 insertions, 4 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 96ecdbc1f4..c147928759 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -1196,11 +1196,11 @@ class RawQuerySet(object):
"""
Resolve the init field names and value positions
"""
- model_init_names = [f.attname for f in self.model._meta.fields
- if f.attname in self.columns]
+ model_init_fields = [f for f in self.model._meta.fields if f.column in self.columns]
annotation_fields = [(column, pos) for pos, column in enumerate(self.columns)
if column not in self.model_fields]
- model_init_order = [self.columns.index(fname) for fname in model_init_names]
+ model_init_order = [self.columns.index(f.column) for f in model_init_fields]
+ model_init_names = [f.attname for f in model_init_fields]
return model_init_names, model_init_order, annotation_fields
def __iter__(self):
diff --git a/docs/releases/1.8.4.txt b/docs/releases/1.8.4.txt
index e6606cb37f..81b00c1800 100644
--- a/docs/releases/1.8.4.txt
+++ b/docs/releases/1.8.4.txt
@@ -14,3 +14,7 @@ Bugfixes
* Added a system check warning if the old ``TEMPLATE_*`` settings are defined
in addition to the new ``TEMPLATES`` setting.
+
+* Fixed ``QuerySet.raw()`` so ``InvalidQuery`` is not raised when using the
+ ``db_column`` name of a ``ForeignKey`` field with ``primary_key=True``
+ (:ticket:`12768`).
diff --git a/tests/raw_query/models.py b/tests/raw_query/models.py
index 1e5e176bcf..2a888088ef 100644
--- a/tests/raw_query/models.py
+++ b/tests/raw_query/models.py
@@ -23,6 +23,10 @@ class Book(models.Model):
opening_line = models.TextField()
+class BookFkAsPk(models.Model):
+ book = models.ForeignKey(Book, primary_key=True, db_column="not_the_default")
+
+
class Coffee(models.Model):
brand = models.CharField(max_length=255, db_column="name")
diff --git a/tests/raw_query/tests.py b/tests/raw_query/tests.py
index 2027a32d2b..94f21f9a71 100644
--- a/tests/raw_query/tests.py
+++ b/tests/raw_query/tests.py
@@ -5,7 +5,7 @@ from datetime import date
from django.db.models.query_utils import InvalidQuery
from django.test import TestCase, skipUnlessDBFeature
-from .models import Author, Book, Coffee, FriendlyAuthor, Reviewer
+from .models import Author, Book, BookFkAsPk, Coffee, FriendlyAuthor, Reviewer
class RawQueryTests(TestCase):
@@ -274,3 +274,14 @@ class RawQueryTests(TestCase):
list(Book.objects.raw('SELECT id FROM (SELECT * FROM raw_query_book WHERE paperback IS NOT NULL) sq'))
except InvalidQuery:
self.fail("Using a subquery in a RawQuerySet raised InvalidQuery")
+
+ def test_db_column_name_is_used_in_raw_query(self):
+ """
+ Regression test that ensures the `column` attribute on the field is
+ used to generate the list of fields included in the query, as opposed
+ to the `attname`. This is important when the primary key is a
+ ForeignKey field because `attname` and `column` are not necessarily the
+ same.
+ """
+ b = BookFkAsPk.objects.create(book=self.b1)
+ self.assertEqual(list(BookFkAsPk.objects.raw('SELECT not_the_default FROM raw_query_bookfkaspk')), [b])