Django Graphene Relay order_by(OrderingFilter)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django Graphene Relay order_by(OrderingFilter)相关的知识,希望对你有一定的参考价值。
我有一个带有中继器和过滤器的石墨烯接口。它工作得很好,但我想添加order_by选项。我的对象看起来像:
class FooGQLType(DjangoObjectType):
class Meta:
model = Foo
exclude_fields = ('internal_id',)
interfaces = (graphene.relay.Node,)
filter_fields = {
"id": ["exact"],
"code": ["exact", "icontains"],
}
connection_class = ExtendedConnection
class Query(graphene.ObjectType):
foo = DjangoFilterConnectionField(FooGQLType)
ExtendedConnection应该不相关,但:
class ExtendedConnection(graphene.Connection):
class Meta:
abstract = True
total_count = graphene.Int()
def resolve_total_count(root, info, **kwargs):
return root.length
这使我可以像foo(code_Icontains:"bar")
一样进行查询。根据the Graphene documentation,我应该为此在FilterSet中使用OrderingFilter。我觉得有点烦人,因为过滤器应该是自动的,但是如果我这样做的话:
class FooGQLFilter(FilterSet):
class Meta:
model = Foo
order_by = OrderingFilter(
fields=(
('code', 'code'),
('lastName', 'last_name'),
('otherNames', 'other_names'),
)
)
我收到需要提供fields
或exclude
的错误:
AssertionError: Setting 'Meta.model' without either 'Meta.fields' or 'Meta.exclude' has been deprecated since 0.15.0 and is now disallowed. Add an explicit 'Meta.fields' or 'Meta.exclude' to the FooGQLFilter class.
因此,如果我添加一个fields = []
使其静音,则它将编译。但是,当我在以下位置使用它时:
foo = DjangoFilterConnectionField(FooGQLType, filterset_class=FooGQLFilter)
我的常规过滤器,例如code_Icontains
消失了。我可以在那儿再次添加它们,但这很愚蠢。快速查看源代码,看起来Relay或django-filters已经创建了FilterSet类(很有意义),用这种方法覆盖它显然不是一个好主意。
如何在我的石墨烯中继过滤对象上添加orderBy过滤器?我觉得这应该很简单,但我正在努力解决。
[我也看到了用DjangoFilterConnectionField
子类化connection_resolver
的示例,该示例以某种方式注入order_by,但告诉我没有orderBy参数。
我已经修改了a GitHub issue中关于此主题的解决方案:
from graphene_django.filter import DjangoFilterConnectionField
from graphene.utils.str_converters import to_snake_case
class OrderedDjangoFilterConnectionField(DjangoFilterConnectionField):
"""
Adapted from https://github.com/graphql-python/graphene/issues/251
Substituting:
`claims = DjangoFilterConnectionField(ClaimsGraphQLType)`
with:
```
claims = OrderedDjangoFilterConnectionField(ClaimsGraphQLType,
orderBy=graphene.List(of_type=graphene.String))
```
"""
@classmethod
def connection_resolver(cls, resolver, connection, default_manager, max_limit,
enforce_first_or_last, filterset_class, filtering_args,
root, info, **args):
filter_kwargs = {k: v for k, v in args.items() if k in filtering_args}
qs = filterset_class(
data=filter_kwargs,
queryset=default_manager.get_queryset(),
request=info.context
).qs
order = args.get('orderBy', None)
if order:
if type(order) is str:
snake_order = to_snake_case(order)
else:
snake_order = [to_snake_case(o) for o in order]
qs = qs.order_by(*snake_order)
return super(DjangoFilterConnectionField, cls).connection_resolver(
resolver,
connection,
qs,
max_limit,
enforce_first_or_last,
root,
info,
**args
)
要使用它,只需修改以下查询:
claims = DjangoFilterConnectionField(ClaimsGraphQLType)
到
claims = OrderedDjangoFilterConnectionField(ClaimsGraphQLType,
orderBy=graphene.List(of_type=graphene.String))
然后您可以查询:
{ claims(status: 2, orderBy: "-id") { id } }
或
{ claims(status: 2, orderBy: ["creationDate", "lastName"]) { id } }
以上是关于Django Graphene Relay order_by(OrderingFilter)的主要内容,如果未能解决你的问题,请参考以下文章
Django Graphene Relay order_by (OrderingFilter)
使用 Django GraphQL JWT 和 Graphene Relay 进行身份验证和授权
如何使用 Graphene-Django Relay 中的外键关系更新模型?
如何使用 GraphQL、Graphene 和 Relay 改变现有数据?