Перечисления в Django и Graphene всегда приводят к нулю
У меня возникли некоторые проблемы при попытке использовать перечисления с Django и Graphene. Несмотря на то, что значения перечисления сохраняются в SQLite и извлекаются должным образом, это приводит к ошибке. Ниже приведен пример ошибки.
{
"message": "Cannot return null for non-nullable field DjangoObject.vanillaEnum.",
"locations": [
{
"line": 10,
"column": 5
}
]
},
Я использую Django 2.0.3 и Graphene 2.0.1 с Anaconda3 5.0.0 и Python 3.6.4. Мне удалось воспроизвести ошибку, используя тривиальный пример, который доступен на моей учетной записи GitHub.
в models.py
Я определил Python Enum
и модель Django, которая использует это перечисление. Модели здесь работают как задумано (AFAIK) без каких-либо графеновых зависимостей. База данных SQLite по умолчанию также имеет правильные значения.
models.py
import enum
from django.db import models
@enum.unique
class VanillaEnum(enum.Enum):
RED = enum.auto()
BLUE = enum.auto()
GREEN = enum.auto()
@classmethod
def choices(cls):
return tuple((x, x) for x in cls)
class DjangoModel(models.Model):
name = models.CharField(max_length=20)
vanilla_enum = models.CharField(choices=VanillaEnum.choices(), default=VanillaEnum.GREEN, max_length=20)
def __str__(self):
return f'name={self.name}, vanilla_enun={self.vanilla_enum}'
Далее в schema.py
Я определил два перечисления. Один использует graphene.Enum.from_enum
преобразовать VanillaEnum
в то, что якобы графен может использовать. Второй - это enum, использующий graphene.Enum
, Второе перечисление - мой контрольный пример, который должен работать. Но это все равно приводит к той же ошибке, что и выше.
Затем я определил два объекта, нативный объект Graphene, который использует оба перечисления в качестве полей, и объект Django-Graphene, который сопоставлен с моделью.
schema.py
import graphene
from graphene_django import DjangoObjectType
from djangographeneenum.models import DjangoModel, VanillaEnum
ConvertedEnum = graphene.Enum.from_enum(VanillaEnum)
class GrapheneEnum(graphene.Enum):
RED = 1
BLUE = 2
GREEN = 3
class GrapheneObject(graphene.ObjectType):
name = graphene.String()
converted_enum = graphene.Field(ConvertedEnum)
graphene_enum = graphene.Field(GrapheneEnum)
def __str__(self):
return f'name={self.name}, converted_enum={self.converted_enum}, graphene_enum={self.graphene_enum}'
class DjangoObject(DjangoObjectType):
class Meta:
model = DjangoModel
class Query(graphene.ObjectType):
graphene_object = graphene.Field(GrapheneObject)
django_model = graphene.List(DjangoObject)
def resolve_graphene_object(self, info):
graphene_object = GrapheneObject(name='Abc', converted_enum=ConvertedEnum.RED, graphene_enum=GrapheneEnum.BLUE)
print(f'graphene_object: {graphene_object}')
return graphene_object
def resolve_django_model(self, info):
django_model = DjangoModel.objects.get_or_create(name='RED Model', vanilla_enum=VanillaEnum.RED)
print(f'django_model: {django_model}')
django_model = DjangoModel.objects.get_or_create(name='BLUE Model', vanilla_enum=VanillaEnum.BLUE)
print(f'django_model: {django_model}')
django_model = DjangoModel.objects.get_or_create(name='GREEN Model', vanilla_enum=VanillaEnum.GREEN)
print(f'django_model: {django_model}')
objects_all = DjangoModel.objects.all()
for x in objects_all:
print(f'django_model: {x}')
return objects_all
Ниже приведен частичный вывод. Перечисления в нативном объекте Графен оба отображаются как null
, А для сопоставленной модели Django весь объект null
а не только поле enum.
"data": {
"grapheneObject": {
"name": "Abc",
"convertedEnum": null,
"grapheneEnum": null
},
"djangoModel": [
null,
null,
null,
null
]
}
Итак, что мне не хватает?