Loading django/db/models/query.py +3 −3 Original line number Diff line number Diff line Loading @@ -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): Loading docs/releases/1.8.4.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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`). tests/raw_query/models.py +4 −0 Original line number Diff line number Diff line Loading @@ -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") Loading tests/raw_query/tests.py +12 −1 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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]) Loading
django/db/models/query.py +3 −3 Original line number Diff line number Diff line Loading @@ -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): Loading
docs/releases/1.8.4.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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`).
tests/raw_query/models.py +4 −0 Original line number Diff line number Diff line Loading @@ -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") Loading
tests/raw_query/tests.py +12 −1 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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])