默认情况下,石墨烯附带的relay.ConnectionField
实现不会对查询进行分页。(可以选择使用“first”或“last”对连接进行分页。)如果连接具有大量节点,则这是不切实际的。一次强制分页不超过 100 个节点的合适方法是什么?
问问题
674 次
2 回答
3
不幸的是,石墨烯不支持默认值。我为这种情况建立了自己的装饰器。设置DEFAULT_PAGE_SIZE
和MAX_PAGE_SIZE
适当。也可以调整以从装饰器本身接收这些值,但我将它与 Django 和 ergo Django 的设置一起使用。
DEFAULT_PAGE_SIZE = 10
MAX_PAGE_SIZE = 100
def limited_pagination(func):
'''
Decorator for limiting the `first` and `last` pagination parameters. Uses
DEFAULT_PAGE_SIZE and MAX_PAGE_SIZE settings. Raises an exception when
values are invalid.
'''
def wrapper(*args, **kwargs):
if 'first' in kwargs and 'last' in kwargs:
raise RuntimeError('Use either `first` or `last`, not both.')
for key in ('first', 'last'):
if key in kwargs:
try:
value = int(kwargs[key])
except ValueError:
raise ValueError('`{}` must be an integer.'.format(key))
if value < 0:
raise ValueError('`{}` must be 0 or greater.'.format(key))
elif value > MAX_PAGE_SIZE:
raise ValueError(
'`{}` must not be greater than {}.'.format(
key, MAX_PAGE_SIZE
)
)
kwargs[key] = value
break # Break out of for loop to skip `else` branch.
else:
kwargs['first'] = DEFAULT_PAGE_SIZE
result = func(*args, **kwargs)
return result
return wrapper
使用示例:
@limited_pagination
def resolve_whatever(self, info):
return [1, 2, 3, 4, 5]
于 2018-01-19T16:25:41.527 回答
1
对于那些寻找 django 解决方案的人,graphene-django 有RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST
和RELAY_CONNECTION_MAX_LIMIT
设置:https ://docs.graphene-python.org/projects/django/en/latest/settings/#relay-connection-enforce-first-or-last 。您只需要启用RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST
,并确保DjangoConnectionField
在 Query 声明中使用。
例如:
# settings
GRAPHENE = {
'RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST': True,
'RELAY_CONNECTION_MAX_LIMIT': 50,
}
# model
class Category(models.Model):
name = models.CharField(max_length=100)
# graphql type
class CategoryType(graphene_django.DjangoObjectType):
class Meta:
model = Category
fields = ("id", 'name')
interfaces = (graphene.relay.Node,)
# query
class Query(graphene.ObjectType):
categories = graphene_django.DjangoConnectionField(CategoryType)
def resolve_categories(root, info, **kwargs):
return Category.objects.all().order_by("id")
于 2021-05-17T22:03:24.947 回答