graphene-django 将 models.BigInteger() 转换为 graphene.Integer()

Posted

技术标签:

【中文标题】graphene-django 将 models.BigInteger() 转换为 graphene.Integer()【英文标题】:graphene-django converts models.BigInteger() to graphene.Integer() 【发布时间】:2018-01-19 07:30:22 【问题描述】:

我正在使用石墨烯-django。

我正在尝试从 models.BigInteger() 字段中检索数据,但是当我在 graphiQL 中进行查询时出现错误


  "errors": [
    
      "message": "Int cannot represent non 32-bit signed integer value: 2554208328"
    
  ],
  "data": 
    "match": null
  

有谁知道我如何强制石墨烯给我数据?

【问题讨论】:

【参考方案1】:

我最终使用了自定义标量。如果它在graphene-django中自动转换为更好的标量会更好,但这是我解决这个问题的方法。我用自定义 BigInt 标量编写了一个 converter.py 文件,如果我们有一个大于 MAX_INT 的数字,它使用浮点数而不是整数

# converter.py
from graphene.types import Scalar
from graphql.language import ast
from graphene.types.scalars import MIN_INT, MAX_INT

class BigInt(Scalar):
    """
    BigInt is an extension of the regular Int field
        that supports Integers bigger than a signed
        32-bit integer.
    """
    @staticmethod
    def big_to_float(value):
        num = int(value)
        if num > MAX_INT or num < MIN_INT:
            return float(int(num))
        return num

    serialize = big_to_float
    parse_value = big_to_float

    @staticmethod
    def parse_literal(node):
        if isinstance(node, ast.IntValue):
            num = int(node.value)
            if num > MAX_INT or num < MIN_INT:
                return float(int(num))
            return num

然后

# schema.py
from .converter import BigInt
class MatchType(DjangoObjectType):
    game_id = graphene.Field(BigInt)
    class Meta:
        model = Match
        interfaces = (graphene.Node, )
        filter_fields = 

【讨论】:

【参考方案2】:

您可以注册新的转换器:

    import graphene
    from graphene_django.converter import convert_django_field

    @convert_django_field.register(models.BigIntegerField)
    def convert_bigint_to_float(field, registry=None):
        return graphene.Float(description=field.help_text, required=not field.null)

这是它在 graphene-django 本身中的使用方式。

【讨论】:

【参考方案3】:

这是来自石墨烯源代码(但我猜还没有发布): https://github.com/graphql-python/graphene/blob/485b1ed325287fd721b13aac8b4ec872d6295c6a/graphene/types/scalars.py#L85

class BigInt(Scalar):
"""
The `BigInt` scalar type represents non-fractional whole numeric values.
`BigInt` is not constrained to 32-bit like the `Int` type and thus is a less
compatible type.
"""

@staticmethod
def coerce_int(value):
    try:
        num = int(value)
    except ValueError:
        try:
            num = int(float(value))
        except ValueError:
            return None
    return num

serialize = coerce_int
parse_value = coerce_int

@staticmethod
def parse_literal(ast):
    if isinstance(ast, IntValueNode):
        return int(ast.value)

我认为另一个答案中的代码实际上可能更好,但想链接这个以防万一

【讨论】:

以上是关于graphene-django 将 models.BigInteger() 转换为 graphene.Integer()的主要内容,如果未能解决你的问题,请参考以下文章

具有多对多和直通表的 Graphene-django

Graphene-django - 使用枚举变异类型

graphene-django:查询所有模型字段而不是请求的字段

graphene-django:没有“Meta.fields”或“Meta.exclude”的“Meta.model”自 0.15.0 以来已被弃用,现在已被禁止

graphene-django 中的自定义参数

如何将 Angular/Apollo 客户端与 graphene-django 集成?