Applies standard ordering to QuerySet. :param model: The Model this queryset is based on. :param table: ``pypika_tortoise.Table`` to keep track of the virtual SQL table (to allow self referential joins) :param orderings: What columns/order to order by
(
self,
model: type[Model],
table: Table,
orderings: Iterable[tuple[str, str | Order]],
annotations: dict[str, Term | Expression],
fields_for_select: Collection[str] | None = None,
)
| 189 | return field_name, order_type |
| 190 | |
| 191 | def resolve_ordering( |
| 192 | self, |
| 193 | model: type[Model], |
| 194 | table: Table, |
| 195 | orderings: Iterable[tuple[str, str | Order]], |
| 196 | annotations: dict[str, Term | Expression], |
| 197 | fields_for_select: Collection[str] | None = None, |
| 198 | ) -> None: |
| 199 | """ |
| 200 | Applies standard ordering to QuerySet. |
| 201 | |
| 202 | :param model: The Model this queryset is based on. |
| 203 | :param table: ``pypika_tortoise.Table`` to keep track of the virtual SQL table |
| 204 | (to allow self referential joins) |
| 205 | :param orderings: What columns/order to order by |
| 206 | :param annotations: Annotations that may be ordered on |
| 207 | :param fields_for_select: Contains fields that are selected in the SELECT clause if |
| 208 | .only(), .values() or .values_list() are used. |
| 209 | |
| 210 | :raises FieldError: If a field provided does not exist in model. |
| 211 | """ |
| 212 | # Do not apply default ordering for annotated queries to not mess them up |
| 213 | if not orderings and self.model._meta.ordering and not annotations: |
| 214 | orderings = self.model._meta.ordering |
| 215 | |
| 216 | for ordering in orderings: |
| 217 | field_name = ordering[0] |
| 218 | if field_name in model._meta.fetch_fields: |
| 219 | raise FieldError( |
| 220 | "Filtering by relation is not possible. Filter by nested field of related model" |
| 221 | ) |
| 222 | |
| 223 | related_field_name, __, forwarded = field_name.partition("__") |
| 224 | if related_field_name in model._meta.fetch_fields: |
| 225 | related_field = cast(RelationalField, model._meta.fields_map[related_field_name]) |
| 226 | related_table = self._join_table_by_field(table, related_field_name, related_field) |
| 227 | self.resolve_ordering( |
| 228 | related_field.related_model, |
| 229 | related_table, |
| 230 | [(forwarded, ordering[1])], |
| 231 | {}, |
| 232 | ) |
| 233 | elif field_name in annotations: |
| 234 | term: Term |
| 235 | if not fields_for_select or field_name in fields_for_select: |
| 236 | # The annotation is SELECTed, we can just reference it in the following cases: |
| 237 | # - Empty fields_for_select means that all columns and annotations are selected, |
| 238 | # hence we can reference the annotation. |
| 239 | # - The annotation is in fields_for_select, hence we can reference it. |
| 240 | term = Field(field_name) |
| 241 | else: |
| 242 | # The annotation is not in SELECT, resolve it |
| 243 | annotation = annotations[field_name] |
| 244 | if isinstance(annotation, Term): |
| 245 | term = annotation |
| 246 | else: |
| 247 | term = annotation.resolve( |
| 248 | ResolveContext( |
no test coverage detected