rti*_*dru 9 python django relay graphql graphene-python
我在我们的GraphQL服务器上将django-graphene与Relay一起使用。该实现在类中强加了全局ID要求,该要求覆盖并隐藏Django的ID字段。graphene.relay.Node
结果,我可以这样查询:
{
allBatches(id:"QmF0Y2hOb2RlOjE=") {
edges {
node {
id
pk
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
并获得以下响应:
{
"data": {
"allBatches": {
"edges": [
{
"node": {
"id": "QmF0Y2hOb2RlOjE=",
"pk": 1
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我失去的是能够按对象本身的原始ID(或PK)字段进行过滤的功能:
{
allBatches(id:1) {
edges {
node {
id
pk
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,我根本无法通过ID过滤对象。我可以想到两种可能的解决方法:1.防止django-graphene-relay劫持和遮蔽该id字段,也许强迫它使用其他字段名称,例如gid
2.查找一种将其包括pk为特殊字段的方法可作为属性和过滤器使用
我在1上没有取得任何进展,因为看起来django-graphene(似乎是中继标准)强加了对该字段的限制id。我看到它id已在多个地方用作魔术字符串,并且似乎没有改变字段名称的标准方法。
在2上,我可以使该属性Mixin像这样工作:
class PKMixin(object):
pk = graphene.Field(type=graphene.Int, source='pk')
Run Code Online (Sandbox Code Playgroud)
但是,我无法通过过滤进行django-filter工作,因为的FilterSet没有pk声明字段,并因以下错误而中断
'Meta.fields'包含未在此FilterSet上定义的字段:pk
我尝试了以下方法:
class PKFilteringNode(Node):
@classmethod
def get_node_from_global_id(cls, info, global_id, only_type=None):
# So long as only_type is set; if we detect that the global_id is a pk and not a global ID;
# then coerce it to be a proper global ID before fetching
if only_type:
try:
int(global_id)
global_id = cls.to_global_id(only_type._meta.name, global_id)
return super(PKFilteringNode, cls).get_node_from_global_id(info, global_id, only_type)
except ValueError:
pass
return super(PKFilteringNode, cls).get_node_from_global_id(info, global_id, only_type)
Run Code Online (Sandbox Code Playgroud)
现在我可以让GraphQL做到这一点:
{
batchA: batch(id: "QmF0Y2hOb2RlOjE=") {
id
name
}
batchB: batch(id: 1) {
id
name
}
}
{
"data": {
"batchA": {
"id": "QmF0Y2hOb2RlOjE=",
"name": "Default Batch"
},
"batchB": {
"id": "QmF0Y2hOb2RlOjE=",
"name": "Default Batch"
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我非常担心这会破坏某些下游的缓存水平?同样,这仍然不允许通过ID进行过滤,因为过滤取决于
DjangoFilterConnectionField
我现在被困住了。我有几个问题:
https://github.com/graphql-python/graphene-django/issues/349
您是否尝试过解决方案 2 但使用 id 作为源?
class PKMixin(object):
pk = graphene.Field(type=graphene.Int, source='id')
Run Code Online (Sandbox Code Playgroud)
另外,如果您只想获取单个记录,则无论如何都不应该通过连接字段。您应该batchByPk在模式上定义类似字段的内容。
最后要注意的是,目前 graphene-django 还DjangoFilterConnectionField没有以有效的方式实现,所以你可能根本不想使用它。
| 归档时间: |
|
| 查看次数: |
688 次 |
| 最近记录: |