python - 如何覆盖 Graphite 烯中的 DjangoModelFormMutation 字段类型?

标签 python django graphql graphene-python

我正在构建一个简单的配方存储应用程序,该应用程序使用 GraphQL 的 Graphene 包。到目前为止,我已经能够在我的突变中非常轻松地使用 Django Forms,但是我的模型字段之一实际上是一个枚举,我想在 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',)

我已经创建了这个 Graphite 烯枚举UnitEnum = Enum.from_enum(Unit)但是我无法让 Graphite 烯拾取它。我尝试将其添加到 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)

我真的不喜欢这样,但想不出更好的方法来处理这个问题。我在此处搜索另一个 Graphite 烯 django 问题时遇到了这个想法 https://github.com/graphql-python/graphene-django/issues/481#issuecomment-412227036 .

我觉得必须有更好的方法来做到这一点。

关于python - 如何覆盖 Graphite 烯中的 DjangoModelFormMutation 字段类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55213100/

相关文章:

python - 传递一次参数,多次使用

python - Django: activate() 没有显示效果

python - 如何确保调试配置中没有 pdb 调用?

javascript - 无法从 json 对象获取数据

html - 如何在 Django 中将 CSS 链接到 HTML?

python - 尽管两个查询集在 shell 中打印出相同的内容,但 Django 的 assertQuerysetEqual() 方法还是失败了?

python - csv DictReader 上的 "Doing work"失败

javascript - 使用 Apollo 客户端进行 useMutation 后未触发 useEffect

javascript - 如何将 2 个点表示法字符串合并到 GraphQL 查询字符串

javascript - 如何从 graphql 模式中获取所有类型的列表?