覆盖石墨烯中的django选择输出

时间:2017-01-27 22:05:19

标签: python django graphene-python

我正在使用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 _...”。

如何覆盖此输出?

3 个答案:

答案 0 :(得分:6)

代码评论说

  

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

因此,对于您的特定情况,您将无法轻松地用整数替换线上值。但是,如果字符串(“A_1”)表示的实际值在内部和客户端(从字段的描述值中)仍然是整数,则可能无关紧要。

通常,您可以通过定义枚举类并添加到DjangoObjectType的定义来替换字段的自动生成字段。以下是使用文档Enum example ...

的示例
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

答案 1 :(得分:1)

刚刚碰到这个问题,另一种方法是将您在Meta之外的字段(使用only_fields定义为graphene.Int,那么您可以提供自己的解析器函数,只需返回字段的值,该值将以数字结尾。

我的代码段(问题字段为resource_type,即枚举):

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

答案 2 :(得分:1)

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

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

有关设置here的更多信息。