Skip to content

Commit

Permalink
Refactor Paginated to be used similarly to how Connection is used
Browse files Browse the repository at this point in the history
  • Loading branch information
bellini666 committed Oct 20, 2024
1 parent 89074b1 commit 9705ab0
Show file tree
Hide file tree
Showing 9 changed files with 751 additions and 91 deletions.
85 changes: 78 additions & 7 deletions docs/guide/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type Fruit {

input OffsetPaginationInput {
offset: Int! = 0
limit: Int! = -1
limit: Int = null
}

type Query {
Expand Down Expand Up @@ -107,7 +107,7 @@ class Fruit:

@strawberry.type
class Query:
fruits: OffsetPaginated[Fruit] = strawberry_django.field()
fruits: OffsetPaginated[Fruit] = strawberry_django.offset_paginated()
```

Would produce the following schema:
Expand All @@ -118,7 +118,7 @@ type Fruit {
}

type PaginationInfo {
limit: Int!
limit: Int = null
offset: Int!
}

Expand All @@ -130,7 +130,7 @@ type FruitOffsetPaginated {

input OffsetPaginationInput {
offset: Int! = 0
limit: Int! = -1
limit: Int = null
}

type Query {
Expand Down Expand Up @@ -159,6 +159,77 @@ query {
> OffsetPaginated follow the same rules for the default pagination limit, and can be configured
> in the same way as explained above.
### Customizing queryset resolver

It is possible to define a custom resolver for the queryset to either provide a custom
queryset for it, or even to receive extra arguments alongside the pagination arguments.

Suppose we want to pre-filter a queryset of fruits for only available ones,
while also adding [ordering](./ordering.md) to it. This can be achieved like:

```python title="types.py"

@strawberry_django.type(models.Fruit)
class Fruit:
name: auto
price: auto


@strawberry_django.order(models.Fruit)
class FruitOrder:
name: auto
price: auto


@strawberry.type
class Query:
@straberry.offset_paginated(OffsetPaginated[Fruit], order=order)
def fruits(self, only_available: bool = True) -> QuerySet[Fruit]:
queryset = models.Fruit.objects.all()
if only_available:
queryset = queryset.filter(available=True)

return queryset
```

This would produce the following schema:

```graphql title="schema.graphql"
type Fruit {
name: String!
price: Decimal!
}

type FruitOrder {
name: Ordering
price: Ordering
}

type PaginationInfo {
limit: Int!
offset: Int!
}

type FruitOffsetPaginated {
pageInfo: PaginationInfo!
totalCount: Int!
results: [Fruit]!
}

input OffsetPaginationInput {
offset: Int! = 0
limit: Int = null
}

type Query {
fruits(
onlyAvailable: Boolean! = true
pagination: OffsetPaginationInput
order: FruitOrder
): [FruitOffsetPaginated!]!
}
```

### Customizing the pagination

Like other generics, `OffsetPaginated` can be customized to modify its behavior or to
Expand Down Expand Up @@ -195,7 +266,7 @@ class FruitOffsetPaginated(OffsetPaginated[Fruit]):

@strawberry.type
class Query:
fruits: FruitOffsetPaginated = strawberry_django.field()
fruits: FruitOffsetPaginated = strawberry_django.offset_paginated()
```

Would produce the following schema:
Expand All @@ -206,7 +277,7 @@ type Fruit {
}

type PaginationInfo {
limit: Int!
limit: Int = null
offset: Int!
}

Expand All @@ -220,7 +291,7 @@ type FruitOffsetPaginated {

input OffsetPaginationInput {
offset: Int! = 0
limit: Int! = -1
limit: Int = null
}

type Query {
Expand Down
3 changes: 2 additions & 1 deletion strawberry_django/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from . import auth, filters, mutations, ordering, pagination, relay
from .fields.field import connection, field, node
from .fields.field import connection, field, node, offset_paginated
from .fields.filter_order import filter_field, order_field
from .fields.filter_types import (
BaseFilterLookup,
Expand Down Expand Up @@ -60,6 +60,7 @@
"mutation",
"mutations",
"node",
"offset_paginated",
"order",
"order_field",
"ordering",
Expand Down
Loading

0 comments on commit 9705ab0

Please sign in to comment.