如何让Strawberry泛型分页类继承StrawberryContainer适配strawberry-django
实现方案
1. 改造通用分页类型
继承StrawberryContainer标记协议,同时保留原有的泛型逻辑即可,完整代码如下:
from typing import Generic, List, TypeVar, Optional import strawberry from strawberry.types.base import StrawberryContainer T = TypeVar('T') @strawberry.type class CursorPaginationResult(Generic[T], StrawberryContainer): rows: List[T] next: Optional[str] # 建议调整为可选类型,无下一页时返回None更符合常规逻辑
不需要额外重写特殊方法,StrawberryContainer本身是标记型协议,继承后strawberry-django就会自动识别这是一个包装了泛型类型的容器,自动解析内层的T类型,不会出现类型推导错误。
2. 自定义Field逻辑对齐
你写的CustomStrawberryDjangoField逻辑无需大改,只需要确保get_result方法最终返回的是CursorPaginationResult实例即可,参考实现如下:
from strawberry_django.fields.field import StrawberryDjangoField class CustomStrawberryDjangoField(StrawberryDjangoField): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 自动注入分页参数 self.arguments.extend([ strawberry.Argument(name="limit", type=int, default=10), strawberry.Argument(name="cursor", type=str, default=None) ]) def get_result(self, source, info, **kwargs): limit = kwargs.pop("limit") cursor = kwargs.pop("cursor") # 此处实现你自己的游标分页查询逻辑 queryset = self.get_queryset(source, info, **kwargs) # 基于cursor过滤、排序、分页 rows = list(queryset[:limit+1]) # 多查一条判断是否有下一页 next_cursor = str(rows[-1].id) if len(rows) > limit else None rows = rows[:limit] return CursorPaginationResult(rows=rows, next=next_cursor)
3. 使用方式
和你预期的用法完全一致,无需调整:
# 先定义你的业务类型 @strawberry.type class Item: id: strawberry.ID # 其他字段... @strawberry.type class TestQuery: items: CursorPaginationResult[Item] = CustomStrawberryDjangoField()
内容的提问来源于stack exchange,提问作者cbergmiller
相关产品推荐
相关产品推荐

