【问题标题】:Overwrite django choices output in graphene覆盖石墨烯中的 django 选择输出
【发布时间】:2017-06-13 17:07:15
【问题描述】:

我正在与graphenegraphene-django 合作,我对IntegerField 的选择有疑问。 graphene 创建一个Enum,如果值为1,则输出为“A_1”;如果值为 2,则为“A_2”,依此类推。示例:

# model
class Foo(models.Model):
    score = models.IntegerField(choices=((1, 1), (2, 2), (3, 3), (4, 4), (5, 5)))

# query

query {
    foo {
       score
    }
}

# response 

{
  "data": {
    "foo": {
      "source": "A_1"
    }
  }
}

我找到了一个转换选项值的函数。

def convert_choice_name(name):
    name = to_const(force_text(name))
    try:
        assert_valid_name(name)
    except AssertionError:
        name = "A_%s" % name
    return name

assert_valid_name 有这个正则表达式:

r'^[_a-zA-Z][_a-zA-Z0-9]*$'

因此,无论以数字开头,它都会将其转换为“A_...”。

我怎样才能覆盖这个输出?

【问题讨论】:

    标签: python django graphene-python


    【解决方案1】:

    您可以在 Graphene-Django 模型中将 convert_choices_to_enum 设置为 False,这会将它们保留为整数。

    class FooType(DjangoObjectType):
        class Meta:
            model = Foo
            convert_choices_to_enum = False
    

    有更多关于设置here的信息。

    【讨论】:

      【解决方案2】:

      我自己刚刚碰到这个,另一种方法是将您的字段定义在 Meta 之外(使用 only_fields)只是一个 graphene.Int ,然后您可以提供自己的解析器函数并返回该字段的值, 最终会是一个数字。

      我的代码 sn-p(问题字段是 resource_type,即 Enum):

      class ResourceItem(DjangoObjectType):
          class Meta:
              model = Resource
              only_fields = (
                  "id",
                  "title",
                  "description",
                  "icon",
                  "target",
                  "session_reveal",
                  "metadata",
                  "payload",
              )
      
          resource_type = graphene.Int()
      
          def resolve_resource_type(self, info):
              return self.resource_type
      

      【讨论】:

        【解决方案3】:

        代码cmets说

        GraphQL 将 Enum 值序列化为字符串,但在内部是 Enums 可以用任何类型的类型表示,通常是整数。

        因此,对于您的特定情况,您将无法轻松地将在线值替换为整数。但是,字符串(“A_1”)表示的实际值是否在内部和客户端仍然是整数(来自字段的描述值)可能并不重要。

        一般来说,您可以通过定义一个枚举类并添加到DjangoObjectType 的定义中来将自动生成的字段替换为选项。这是一个使用文档枚举示例的示例...

        class Episode(graphene.Enum):
            NEWHOPE = 4
            EMPIRE = 5
            JEDI = 6
        
            @property
            def description(self):
                if self == Episode.NEWHOPE:
                    return 'New Hope Episode'
                return 'Other episode'
        

        然后您可以将其添加到您的 DjangoObjectType

        class FooType(DjangoObjectType):
            score = Episode()
            class Meta:
                model = Foo
        

        或者,如果您想获得更多花哨,您可以从Foo._meta.get_field('score').choices 中的字段选择动态生成枚举字段。见graphene_django.converter.convert_django_field_with_choices

        【讨论】:

          猜你喜欢
          • 2021-09-19
          • 2018-01-11
          • 2020-09-01
          • 2019-12-20
          • 2019-08-08
          • 2021-09-25
          • 2020-09-05
          • 2017-08-20
          • 2020-09-03
          相关资源
          最近更新 更多