From ee596888e1149864e7828f5cf63c0eda395744c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anssi=20K=C3=A4=C3=A4ri=C3=A4inen?= Date: Wed, 20 Jan 2016 11:05:48 +0200 Subject: [PATCH] Fixed #26092 -- Fixed QuerySet.order_by() regression with an M2M through model. --- django/db/models/sql/compiler.py | 2 +- docs/releases/1.9.2.txt | 3 +++ tests/m2m_through/models.py | 1 + tests/m2m_through/tests.py | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 47a85bb9a4..3b804dc0b0 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -555,7 +555,7 @@ class SQLCompiler(object): # If we get to this point and the field is a relation to another model, # append the default ordering for that model unless the attribute name # of the field is specified. - if field.is_relation and path and opts.ordering and name != field.attname: + if field.is_relation and opts.ordering and getattr(field, 'attname', None) != name: # Firstly, avoid infinite loops. if not already_seen: already_seen = set() diff --git a/docs/releases/1.9.2.txt b/docs/releases/1.9.2.txt index 71ca0dbea2..71709d0fb8 100644 --- a/docs/releases/1.9.2.txt +++ b/docs/releases/1.9.2.txt @@ -41,3 +41,6 @@ Bugfixes * Fixed CSRF cookie check on POST requests when ``USE_X_FORWARDED_PORT=True`` (:ticket:`26094`). + +* Fixed a ``QuerySet.order_by()`` crash when ordering by a relational field of + a ``ManyToManyField`` ``through`` model (:ticket:`26092`). diff --git a/tests/m2m_through/models.py b/tests/m2m_through/models.py index c25303f6f5..dab3be5164 100644 --- a/tests/m2m_through/models.py +++ b/tests/m2m_through/models.py @@ -65,6 +65,7 @@ class CustomMembership(models.Model): class Meta: db_table = "test_table" + ordering = ["date_joined"] class TestNoDefaultsOrNulls(models.Model): diff --git a/tests/m2m_through/tests.py b/tests/m2m_through/tests.py index badaeb4b87..40753e0fe1 100644 --- a/tests/m2m_through/tests.py +++ b/tests/m2m_through/tests.py @@ -198,6 +198,20 @@ class M2mThroughTests(TestCase): attrgetter("name") ) + def test_order_by_relational_field_through_model(self): + CustomMembership.objects.create(person=self.jim, group=self.rock) + CustomMembership.objects.create(person=self.bob, group=self.rock) + CustomMembership.objects.create(person=self.jane, group=self.roll) + CustomMembership.objects.create(person=self.jim, group=self.roll) + self.assertQuerysetEqual( + self.rock.custom_members.order_by('custom_person_related_name'), + [self.jim, self.bob], lambda x: x + ) + self.assertQuerysetEqual( + self.roll.custom_members.order_by('custom_person_related_name'), + [self.jane, self.jim], lambda x: x + ) + def test_query_first_model_by_intermediate_model_attribute(self): Membership.objects.create( person=self.jane, group=self.roll,