python - 如何覆盖石墨烯中的 DjangoModelFormMutation 字段类型?
问题描述
我正在构建一个简单的配方存储应用程序,该应用程序使用用于 GraphQL 的 Graphene 包。到目前为止,我已经能够在我的突变中非常轻松地使用 Django Forms,但是我的模型字段之一实际上是一个 Enum,我想在 Graphene/GraphQL 中公开它。
我的枚举:
class Unit(Enum):
# Volume
TEASPOON = "teaspoon"
TABLESPOON = "tablespoon"
FLUID_OUNCE = "fl oz"
CUP = "cup"
US_PINT = "us pint"
IMPERIAL_PINT = "imperial pint"
US_QUART = "us quart"
IMPERIAL_QUART = "imperial quart"
US_GALLON = "us gallon"
IMPERIAL_GALLON = "imperial gallon"
MILLILITER = "milliliter"
LITER = "liter"
# Mass and Weight
POUND = "pound"
OUNCE = "ounce"
MILLIGRAM = "milligram"
GRAM = "gram"
KILOGRAM = "kilogram"
我的模型:
class RecipeIngredient(TimeStampedModel):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name='ingredients')
direction = models.ForeignKey(RecipeDirection, on_delete=models.CASCADE, null=True, related_name='ingredients')
quantity = models.DecimalField(decimal_places=2, max_digits=10)
unit = models.TextField(choices=Unit.as_tuple_list())
我的表格:
class RecipeIngredientForm(forms.ModelForm):
class Meta:
model = RecipeIngredient
fields = (
'recipe',
'direction',
'quantity',
'unit',
)
我的突变:
class CreateRecipeIngredientMutation(DjangoModelFormMutation):
class Meta:
form_class = RecipeIngredientForm
exclude_fields = ('id',)
我已经创建了这个石墨烯枚举UnitEnum = Enum.from_enum(Unit)
,但是我无法让石墨烯把它捡起来。我已经尝试将它CreateRecipeIngredientMutation
作为常规字段添加到unit = UnitEnum()
该突变上的输入类中。到目前为止,我得到的最接近的是不久前的这个Github issue。在 iPython shell 中玩过这个类之后,我想我可以做到CreateRecipeIngredientMutation.Input.unit.type.of_type = UnitEnum()
,但这感觉很糟糕。
解决方案
我想出了一个可行但不漂亮的解决方案。我使用了https://github.com/hzdg/django-enumfields包来帮助解决这个问题。
我创建了自己的表单域:
class EnumChoiceField(enumfields.forms.EnumChoiceField):
def __init__(self, enum, *, coerce=lambda val: val, empty_value='', **kwargs):
if isinstance(enum, six.string_types):
self.enum = import_string(enum)
else:
self.enum = enum
super().__init__(coerce=coerce, empty_value=empty_value, **kwargs)
并在我的 Django 表单中使用它。然后在我的自定义 AppConfig 中,我这样做了:
class CoreAppConfig(AppConfig):
name = 'myapp.core'
def ready(self):
registry = get_global_registry()
@convert_form_field.register(EnumChoiceField)
def convert_form_field_to_enum(field: EnumChoiceField):
converted = registry.get_converted_field(field.enum)
if converted is None:
raise ImproperlyConfigured("Enum %r is not registered." % field.enum)
return converted(description=field.help_text, required=field.required)
最后在我的模式中:
UnitEnum = Enum.from_enum(Unit)
get_global_registry().register_converted_field(Unit, UnitEnum)
我真的不喜欢这个,但想不出更好的方法来处理这个问题。我在这里搜索另一个石墨烯 django 问题时遇到了这个想法https://github.com/graphql-python/graphene-django/issues/481#issuecomment-412227036。
我觉得必须有更好的方法来做到这一点。
推荐阅读
- chatbot - 无法使用 Botium CLI 从 QnAMaker 导入 convos 和话语
- replace - 替换python中的坏字符
- java - 如何为 ZipInputStream.getNextEntry 编写 Junit
- amazon-web-services - 来自 lambda 函数的多域
- java - 一旦输入扫描仪存储数据,以保存在各种阵列中。爪哇
- java - 如何在集成中使用执行器进行并行处理
- ssl - 如何在标准应用引擎中限制 1.2 版本的 SSL/TLS 协议以用于谷歌管理的 ssl
- java - 如何使用并行性来加速 URL GET 请求?
- javascript - 指向新屏幕的单元格中的 Ag-grid 按钮
- javascript - javascript中的独立离线反向地理编码库