#36644: Enable using an empty order_by() to disable implicit primary key 
ordering
in first()
-------------------------------------+-------------------------------------
     Reporter:  Lily                 |                    Owner:  Mridul
         Type:  New feature          |                   Status:  assigned
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

 * cc: Jake Howard (added)

Comment:

 For folks checking the forum thread, when Tom Carrick summarized the
 options discussed [https://github.com/django/new-
 features/issues/71#issuecomment-3325381421 here], this was "option 2", to
 which I did not see specific objections afterward.
 ----
 > This will interact with ​default orderings (`Meta.ordering`), which will
 need some careful handling.

 I think that looks like this:

 {{{#!diff
 diff --git a/django/db/models/query.py b/django/db/models/query.py
 index b404fd1875..4d1218ea89 100644
 --- a/django/db/models/query.py
 +++ b/django/db/models/query.py
 @@ -1135,9 +1135,13 @@ class QuerySet(AltersData):

      def first(self):
          """Return the first object of a query or None if no match is
 found."""
 +        # RemovedInDjango70Warning: replace with:
 +        # if self.ordered or not self.query.default_ordering:
          if self.ordered:
              queryset = self
          else:
 +            if not self.query.default_ordering:
 +                warnings.warn(..., RemovedInDjango70Warning,
 skip_file_prefixes=django_file_prefixes())
 self._check_ordering_first_last_queryset_aggregation(method="first")
              queryset = self.order_by("pk")
          for obj in queryset[:1]:
 @@ -1148,9 +1152,13 @@ class QuerySet(AltersData):

      def last(self):
          """Return the last object of a query or None if no match is
 found."""
 +        # RemovedInDjango70Warning: replace with:
 +        # if self.ordered or not self.query.default_ordering:
          if self.ordered:
              queryset = self.reverse()
          else:
 +            if not self.query.default_ordering:
 +                warnings.warn(..., RemovedInDjango70Warning,
 skip_file_prefixes=django_file_prefixes())
 self._check_ordering_first_last_queryset_aggregation(method="last")
              queryset = self.order_by("-pk")
          for obj in queryset[:1]:
 diff --git a/tests/queries/test_qs_combinators.py
 b/tests/queries/test_qs_combinators.py
 index e329d0c4f0..79cfb78dd7 100644
 --- a/tests/queries/test_qs_combinators.py
 +++ b/tests/queries/test_qs_combinators.py
 @@ -416,7 +416,7 @@ class QuerySetSetOperationTests(TestCase):
          base_qs = Author.objects.order_by()
          qs1 = base_qs.filter(name="a1")
          qs2 = base_qs.filter(name="a2")
 -        self.assertEqual(qs1.union(qs2).first(), a1)
 +        self.assertEqual(qs1.union(qs2).order_by("pk").first(), a1)

      def test_union_multiple_models_with_values_list_and_order(self):
          reserved_name = ReservedName.objects.create(name="rn1", order=0)
 }}}

 I think this will need a deprecation (notice the edited test). We will be
 enforcing some more explicitness for users who must to clear an ordering
 for the sake of doing a union but then need to add it back to retain the
 prior behavior of `first()`, but I think that trade-off is worth it.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36644#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/01070199c297964f-f14562e5-6982-44b3-8140-7204f1b3af3f-000000%40eu-central-1.amazonses.com.

Reply via email to