diff --git a/django/db/models/query.py b/django/db/models/query.py index 9323e9b36b..5567b3227d 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -615,7 +615,24 @@ class QuerySet(object): clone = self._clone() clone.query.add_immediate_loading(fields) return clone + + ################################### + # PUBLIC INTROSPECTION ATTRIBUTES # + ################################### + def ordered(self): + """ + Returns True if the QuerySet is ordered -- i.e. has an order_by() + clause or a default ordering on the model. + """ + if self.query.extra_order_by or self.query.order_by: + return True + elif self.query.default_ordering and self.query.model._meta.ordering: + return True + else: + return False + ordered = property(ordered) + ################### # PRIVATE METHODS # ################### diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index fa58060916..6c08fe079e 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -268,6 +268,12 @@ There's no way to specify whether ordering should be case sensitive. With respect to case-sensitivity, Django will order results however your database backend normally orders them. +.. versionadded:: 1.1 + +You can tell if a query is ordered or not by checking the +:attr:`QuerySet.ordered` attribute, which will be ``True`` if the +``QuerySet`` has been ordered in any way. + ``reverse()`` ~~~~~~~~~~~~~ diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py new file mode 100644 index 0000000000..5699b60241 --- /dev/null +++ b/tests/regressiontests/queries/tests.py @@ -0,0 +1,27 @@ +import unittest +from models import Tag, Annotation +from django.db.models import Count + +class QuerysetOrderedTests(unittest.TestCase): + """ + Tests for the Queryset.ordered attribute. + """ + + def test_no_default_or_explicit_ordering(self): + self.assertEqual(Annotation.objects.all().ordered, False) + + def test_cleared_default_ordering(self): + self.assertEqual(Tag.objects.all().ordered, True) + self.assertEqual(Tag.objects.all().order_by().ordered, False) + + def test_explicit_ordering(self): + self.assertEqual(Annotation.objects.all().order_by('id').ordered, True) + + def test_order_by_extra(self): + self.assertEqual(Annotation.objects.all().extra(order_by=['id']).ordered, True) + + def test_annotated_ordering(self): + qs = Annotation.objects.annotate(num_notes=Count('notes')) + self.assertEqual(qs.ordered, False) + self.assertEqual(qs.order_by('num_notes').ordered, True) + \ No newline at end of file