graphene-django-cud
graphene-django-cud copied to clipboard
Any way to generate InputTypes without writing a mutation class?
Hi, I'm wondering if this library exposes any way to generate an InputType
for a model in an ad-hoc way.
I was able to get this working by subclassing DjangoCreateMutation
to create the InputType and add it to the registry, then accessing it below. However don't want to actually expose these mutations - I'm concerned that the mutations created might be included in the schema by another developer on the team accidentally. We really only want the InputType generated by these mutations.
In the docs it mentions
Here, the owner field will now be of type CreateUserInput!, which has to have been created before, typically via a CreateUserMutation
Is there another way to take advantage of the auto-generated InputType
without creating unused subclasses of DjangoCreateMutation
?
Here's an example - I'm building a custom mutation that
Example payload from client
mutation CustomFormSubmitMut {
customFormSubmit(input: {
additionalItem: "extra string that the backend does something with"
dog {
name: "fido"
owner {
firstName: "alex"
}
}
}) {
wasCreated
}
}
I was able to get that to work using the following python code. The types are what I expect - they're auto generated from the models and use the names that I assign.
# NOTE: needed because it creates an additional InputType for User model for
# use only in the CustomFormSubmitMutation.
class CustomFormCreateUserMutation(DjangoCreateMutation):
class Meta:
model = User
type_name = "CustomSubmitUserInput"
# NOTE: needed because it creates an additional InputType for Dog model for
# use only in the CustomFormSubmitMutation.
class CustomFormCreateDogMutation(DjangoCreateMutation):
class Meta:
model = Dog
type_name = "CustomFormDogInput"
foreign_key_extras = {"owner": {"type": "CustomSubmitUserInput"}}
class CustomFormInputType(graphene.InputObjectType):
# NOTE:
dog = CustomFormDogMutation._meta.InputType(required=True)
# NOTE: this illustrates why we don't want Dog as the root of the mutation
# you can imagine that maybe this custom form also has other, non-related models at the root
additional_item = graphene.String(required=True)
class CustomFormSubmitMutation(graphene.Mutation):
class Arguments:
input = CustomFormInputType(required=True)
was_created = graphene.Boolean()
@classmethod
def mutate(cls, root, info, input): # noqa VNE003
# custom mutate method handler - e.g. get_or_create() on both models, do something
# with the `additional_item` in the input, etc.
return CustomFormSubmitMutation(was_created=True)
I tried to manually call the utils that DjangoCreateMutation
calls but got a few errors related to the registry. I probably needed to add the lines below, but I'm concerned with how fragile my approach here is
# django_graphene_cud/mutations/create.py
model_fields = get_input_fields_for_model(
model,
fields,
exclude,
tuple(auto_context_fields.keys()) + optional_fields,
required_fields,
many_to_many_extras,
foreign_key_extras,
many_to_one_extras,
one_to_one_extras=one_to_one_extras,
parent_type_name=input_type_name,
field_types=field_types,
ignore_primary_key=ignore_primary_key,
)
for name, field in custom_fields.items():
model_fields[name] = field
InputType = type(input_type_name, (InputObjectType,), model_fields)