【问题标题】:How to use a custom id with Graphene and Relay?如何在 Graphene 和 Relay 中使用自定义 id?
【发布时间】:2019-05-02 19:52:58
【问题描述】:

我已经实现了 graphql,并且正在迁移到中继。我已经为每个表都有一个 uuid,它被命名为“id”。我发现我的应用程序this github thread 谈到可能会更改规范,但感觉就像一个兔子洞。

有没有一种简单的方法可以将我自己的自定义 ID 与中继一起使用?

【问题讨论】:

    标签: graphene-python


    【解决方案1】:

    如果您已经实现了默认中继端点,那么您应该有一些 TableNameNode 类,其中包含一个 Meta 嵌套类和一个单独的 Query 类。

    class ExampleTableNameNode(DjangoObjectType):
        class Meta:
            model = ExampleTableName
            interface = (relay.Node,)
    
    class Query(object):
        example_table_name = relay.Node.Field(ExampleTableNameNode)
        all_example_table_names = DjangoFilterConnectionField(ExampleTableNameNode)
    
        def resolve_example_table_name(self, info, **kwargs):
            pass
    
        def resolve_all_example_table_names(self, info, **kwargs):
            pass
    

    interface = (relay.Node,) 定义了 1) 如何生成 id 以及 2) 如何使用它们来获取数据。如果我们创建一个 relay.Node 子类来重新定义这两个特性,那么我们可以使用我们的自定义 id。

    class CustomNode(relay.Node): 
        class Meta:
            name = 'Node'
    
        @staticmethod
        def to_global_id(type, id):
            #returns a non-encoded ID
            return id
    
        @staticmethod
        def get_node_from_global_id(info, global_id, only_type=None):
            model = getattr(Query,info.field_name).field_type._meta.model
            return model.objects.get(id=global_id)
    

    这里我们实现了两个函数,to_global_id 和 get_node_from_global_id。 model = ... 这行从 graphql 查询表名到实际模型有点神奇。如果这不起作用,您只需要制作一个字典,从 example_table_name 之类的东西转到实际的 ExampleTableName django 模型。

    一旦你这样做了,你必须像这样用CustomNode 替换对relay.Node 的两个引用。

    class ExampleTableNameNode(DjangoObjectType):
        class Meta:
            model = ExampleTableName
            interface = (CustomNode,)
    
    class Query(object):
        example_table_name = CustomNode.Field(ExampleTableNameNode)
        all_example_table_names = DjangoFilterConnectionField(ExampleTableNameNode)
    
        def resolve_example_table_name(self, info, **kwargs):
            pass
    
        def resolve_all_example_table_names(self, info, **kwargs):
            pass
    

    答案在graphene docs。我在实现石墨烯和中继时阅读了它们,但是有很多东西要立即学习,很容易通过自定义节点部分阅读,并且以后不记得您需要执行自定义节点解决方案。

    【讨论】:

    • 虽然此代码有助于解决问题,但需要将其复制到大型项目的每个模式文件中——这是多余的。也尝试将其放入全局查询聚合器架构中,但这会提供循环导入,因为在每个查询中都使用了 CustomNode,并且每个查询都被导入以聚合到全局架构中。有什么办法可以避免多次复制粘贴?
    猜你喜欢
    • 2020-05-19
    • 2018-05-15
    • 2019-11-06
    • 2019-12-20
    • 2017-10-15
    • 2020-05-20
    • 2020-05-19
    • 2019-06-17
    • 2020-04-14
    相关资源
    最近更新 更多