-
Notifications
You must be signed in to change notification settings - Fork 769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
offset pagination support for relay connection #809
Comments
I've archive this by #563, but no one come to review. |
Our team would find #563 really helpful, is there anything we can do to help get it merged? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Not stale! This is a very common requirement and @NateScarlet's PR provides it. |
I have written a blog to address this issue. It can be achieved using "first" and "last" arguments only |
This is actually very easy to implement considering the underlying pagination in Graphene Django is an offset pagination. from graphql_relay.connection.arrayconnection import cursor_to_offset, offset_to_cursor
from graphene_django.filter import DjangoFilterConnectionField
class OffsetConnectionField(DjangoFilterConnectionField):
def __init__(self, *args, **kwargs):
kwargs.setdefault("offset", graphene.Int())
super().__init__(*args, **kwargs)
@classmethod
def connection_resolver(
cls,
resolver,
connection,
default_manager,
queryset_resolver,
max_limit,
enforce_first_or_last,
root,
info,
**args
):
"""
Check parameter compatibility for `offset`.
Using offset with before could lead to negative indexing which is not supported by Relay so we forbid it altogether.
"""
offset = args.get("offset")
before = args.get("before")
if offset is not None:
assert before is None, (
"You can't provide a `before` at the same time as an `offset` value to properly paginate the `{}` connection."
).format(info.field_name)
return super().connection_resolver(
resolver,
connection,
default_manager,
queryset_resolver,
max_limit,
enforce_first_or_last,
root,
info,
**args
)
@classmethod
def resolve_connection(cls, connection, args, iterable, max_limit=None):
"""
Take the offset out of the argument and if it is not `None` convert it to a `after` cursor.
"""
offset = args.pop("offset", None)
after = args.get("after")
if offset:
if after:
offset += cursor_to_offset(after) + 1
# input offset starts at 1 while the graphene offset starts at 0
args["after"] = offset_to_cursor(offset - 1)
return super().resolve_connection(connection, args, iterable, max_limit) and you just need to use # cookbook/graphql/category.py
import graphene
from cookbook.models import Category, Ingredient
class CategoryNode(DjangoObjectType):
class Meta:
model = Category
interfaces = (graphene.relay.Node, )
class Query(graphene.ObjectType):
category = graphene.relay.Node.Field(CategoryNode)
all_categories = OffsetConnectionField(CategoryNode) ** Note ** |
I think you can make a cursor by base64 encoding page offset like below
It's not a robust solution but possible anyway. |
Hi all, I have a use case to paginate results based on an offset. I figured I would be able to add "offset" into my graphQL query to achieve this. (source: https://graphql.org/learn/pagination/)
Specifically, I want to implement fetching page 3 results of a list, where each page has a size of 20. Doing this query throws "unknown argument "offset" on field allEntityA"
I have already trasnformed my Django model into a type
relay.Node
)How can I achieve jumping from page 1 to 3 without using cursor navigation?
The text was updated successfully, but these errors were encountered: