Returns True if the QuerySet is ordered and the ordering is deterministic. This requires that the ordering includes a field (or set of fields) that is unique and non-nullable. For queries involving a GROUP BY clause, the model's default ordering is ignored.
(self)
| 2007 | |
| 2008 | @property |
| 2009 | def totally_ordered(self): |
| 2010 | """ |
| 2011 | Returns True if the QuerySet is ordered and the ordering is |
| 2012 | deterministic. This requires that the ordering includes a field |
| 2013 | (or set of fields) that is unique and non-nullable. |
| 2014 | |
| 2015 | For queries involving a GROUP BY clause, the model's default |
| 2016 | ordering is ignored. Ordering specified via .extra(order_by=...) |
| 2017 | is also ignored. |
| 2018 | """ |
| 2019 | if not self.ordered: |
| 2020 | return False |
| 2021 | ordering = self.query.order_by |
| 2022 | if not ordering and self.query.default_ordering: |
| 2023 | ordering = self.query.get_meta().ordering |
| 2024 | if not ordering: |
| 2025 | return False |
| 2026 | opts = self.model._meta |
| 2027 | pk_fields = {f.attname for f in opts.pk_fields} |
| 2028 | ordering_fields = set() |
| 2029 | for part in ordering: |
| 2030 | # Search for single field providing a total ordering. |
| 2031 | field_name = None |
| 2032 | if isinstance(part, str): |
| 2033 | field_name = part.lstrip("-") |
| 2034 | elif isinstance(part, F): |
| 2035 | field_name = part.name |
| 2036 | elif isinstance(part, OrderBy) and isinstance(part.expression, F): |
| 2037 | field_name = part.expression.name |
| 2038 | if field_name: |
| 2039 | if field_name == "pk": |
| 2040 | return True |
| 2041 | # Normalize attname references by using get_field(). |
| 2042 | try: |
| 2043 | field = opts.get_field(field_name) |
| 2044 | except exceptions.FieldDoesNotExist: |
| 2045 | # Could be "?" for random ordering or a related field |
| 2046 | # lookup. Skip this part of introspection for now. |
| 2047 | continue |
| 2048 | # Ordering by a related field name orders by the referenced |
| 2049 | # model's ordering. Skip this part of introspection for now. |
| 2050 | if field.remote_field and field_name == field.name: |
| 2051 | continue |
| 2052 | if field.attname in pk_fields and len(pk_fields) == 1: |
| 2053 | return True |
| 2054 | if field.unique and not field.null: |
| 2055 | return True |
| 2056 | ordering_fields.add(field.attname) |
| 2057 | |
| 2058 | # Account for members of a CompositePrimaryKey. |
| 2059 | if ordering_fields.issuperset(pk_fields): |
| 2060 | return True |
| 2061 | # No single total ordering field, try unique_together and total |
| 2062 | # unique constraints. |
| 2063 | constraint_field_names = ( |
| 2064 | *opts.unique_together, |
| 2065 | *(constraint.fields for constraint in opts.total_unique_constraints), |
| 2066 | ) |