Skip to content

Commit

Permalink
Support graphene-django-extensions nested ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
MrThearMan committed Sep 4, 2024
1 parent 3b20992 commit 0630c7c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ omit = [
"docs/*",
".venv/*",
".tox/*",
"example_project/*",
]
exclude_lines = [
"if TYPE_CHECKING:",
Expand Down
29 changes: 21 additions & 8 deletions query_optimizer/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,7 @@ def paginate_prefetch_queryset(self, queryset: QuerySet, filter_info: GraphQLFil
remote_field = field.remote_field
field_name = remote_field.name if isinstance(field, models.ManyToManyField) else remote_field.attname

order_by: list[str] = (
# Use the `order_by` from the filter info, if available
[x for x in filter_info.get("filters", {}).get("order_by", "").split(",") if x]
# Use the model's `Meta.ordering` if no `order_by` is given
or copy(queryset.model._meta.ordering)
# No ordering if neither is available
or []
)
order_by = self.get_prefetch_ordering(filter_info, model=queryset.model)

pagination_args = validate_pagination_args(
after=filter_info.get("filters", {}).get("after"),
Expand Down Expand Up @@ -271,6 +264,26 @@ def paginate_prefetch_queryset(self, queryset: QuerySet, filter_info: GraphQLFil
)
)

def get_prefetch_ordering(self, filter_info: GraphQLFilterInfo, model: type[Model]) -> list[str]:
"""Get the ordering for prefetch querysets."""
order_info: str | list[str] = filter_info.get("filters", {}).get("order_by", "")

# 'Graphene-django' uses a comma-separated string for ordering.
if isinstance(order_info, str):
order_info = order_info.split(",")
# 'Graphene-django-extensions' uses a list of enums.
elif isinstance(order_info, list): # pragma: no cover
order_info = [str(x) for x in order_info]

return (
# Use the `order_by` from the filter info, if available
[x for x in order_info if x]
# Use the model's `Meta.ordering` if no `order_by` is given
or copy(model._meta.ordering)
# No ordering if neither is available
or []
)

def filter_queryset(self, queryset: QuerySet, filter_info: GraphQLFilterInfo) -> QuerySet:
"""Run all filtering based on the object type matching the queryset's model."""
# Run filtering hooks on object types if they exist.
Expand Down

0 comments on commit 0630c7c

Please sign in to comment.