diff options
| author | Matt Johnson <mdj2@pdx.edu> | 2015-07-22 11:54:42 -0700 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-07-23 18:07:38 -0400 |
| commit | e063ac2fae007a2eecaeab5ce17064c31230ce29 (patch) | |
| tree | 981151d26d168b54bdef160b2c97a5bc7072ace3 | |
| parent | 71df9b7de4bcb760e756d119685636e101898816 (diff) | |
Fixed #12768 -- Fixed QuerySet.raw() regression on FK with custom db_column.
| -rw-r--r-- | django/db/models/query.py | 6 | ||||
| -rw-r--r-- | docs/releases/1.8.4.txt | 4 | ||||
| -rw-r--r-- | tests/raw_query/models.py | 4 | ||||
| -rw-r--r-- | tests/raw_query/tests.py | 13 |
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]) |
