diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 0bbf8cfade..2b61a0bfd4 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1192,8 +1192,7 @@ class Exists(Subquery): return sql, params -@deconstructible -class OrderBy(BaseExpression): +class OrderBy(Expression): template = '%(expression)s %(ordering)s' conditional = False diff --git a/docs/releases/3.2.2.txt b/docs/releases/3.2.2.txt index 47a541add0..d47da08d6c 100644 --- a/docs/releases/3.2.2.txt +++ b/docs/releases/3.2.2.txt @@ -9,4 +9,6 @@ Django 3.2.2 fixes several bugs in 3.2.1. Bugfixes ======== -* ... +* Prevented, following a regression in Django 3.2.1, :djadmin:`makemigrations` + from generating infinite migrations for a model with ``Meta.ordering`` + contained ``OrderBy`` expressions (:ticket:`32714`). diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 0585805a8b..dad9505ce0 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -2000,3 +2000,25 @@ class ExpressionWrapperTests(SimpleTestCase): group_by_cols = expr.get_group_by_cols(alias=None) self.assertEqual(group_by_cols, [expr.expression]) self.assertEqual(group_by_cols[0].output_field, expr.output_field) + + +class OrderByTests(SimpleTestCase): + def test_equal(self): + self.assertEqual( + OrderBy(F('field'), nulls_last=True), + OrderBy(F('field'), nulls_last=True), + ) + self.assertNotEqual( + OrderBy(F('field'), nulls_last=True), + OrderBy(F('field'), nulls_last=False), + ) + + def test_hash(self): + self.assertEqual( + hash(OrderBy(F('field'), nulls_last=True)), + hash(OrderBy(F('field'), nulls_last=True)), + ) + self.assertNotEqual( + hash(OrderBy(F('field'), nulls_last=True)), + hash(OrderBy(F('field'), nulls_last=False)), + )