Fixed #12768 -- Fixed QuerySet.raw() regression on FK with custom db_column.

This commit is contained in:
Matt Johnson 2015-07-22 11:54:42 -07:00 committed by Tim Graham
parent 71df9b7de4
commit e063ac2fae
4 changed files with 23 additions and 4 deletions

View File

@ -1196,11 +1196,11 @@ class RawQuerySet(object):
""" """
Resolve the init field names and value positions Resolve the init field names and value positions
""" """
model_init_names = [f.attname for f in self.model._meta.fields model_init_fields = [f for f in self.model._meta.fields if f.column in self.columns]
if f.attname in self.columns]
annotation_fields = [(column, pos) for pos, column in enumerate(self.columns) annotation_fields = [(column, pos) for pos, column in enumerate(self.columns)
if column not in self.model_fields] 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 return model_init_names, model_init_order, annotation_fields
def __iter__(self): def __iter__(self):

View File

@ -14,3 +14,7 @@ Bugfixes
* Added a system check warning if the old ``TEMPLATE_*`` settings are defined * Added a system check warning if the old ``TEMPLATE_*`` settings are defined
in addition to the new ``TEMPLATES`` setting. 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`).

View File

@ -23,6 +23,10 @@ class Book(models.Model):
opening_line = models.TextField() opening_line = models.TextField()
class BookFkAsPk(models.Model):
book = models.ForeignKey(Book, primary_key=True, db_column="not_the_default")
class Coffee(models.Model): class Coffee(models.Model):
brand = models.CharField(max_length=255, db_column="name") brand = models.CharField(max_length=255, db_column="name")

View File

@ -5,7 +5,7 @@ from datetime import date
from django.db.models.query_utils import InvalidQuery from django.db.models.query_utils import InvalidQuery
from django.test import TestCase, skipUnlessDBFeature 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): 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')) list(Book.objects.raw('SELECT id FROM (SELECT * FROM raw_query_book WHERE paperback IS NOT NULL) sq'))
except InvalidQuery: except InvalidQuery:
self.fail("Using a subquery in a RawQuerySet raised 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])