-
Notifications
You must be signed in to change notification settings - Fork 766
How can I do nested mutations in graphene django? #1308
-
Hi guys I want to be able to perform a nested mutation (not sure if it's the correct term) here is my models
class User(AbstractUser):
email = models.EmailField(_('email address'), unique=True, blank=False, null=False)
username = None
first_name = None
last_name = None
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
# set custom manager
objects = UserManager()
def __str__(self):
return self.email
class customer(models.Model):
user = models.OneToOneField("users.User", verbose_name=_("customer user account"), on_delete=models.CASCADE)
# general info
first_name = models.CharField(_('customer first name'), max_length=100, help_text='customer first name')
last_name = models.CharField(_('customer last name'), max_length=100, help_text='customer last name')
# addresses info
addresses = models.ManyToManyField('users.address', verbose_name=_('customer addresses'), related_name='customer_addresses', blank=True)
default_shipping_address = models.ForeignKey('users.address', verbose_name=_('default shipping address'), on_delete=models.SET_NULL, null=True, blank=True, related_name='default_shipping')
class address(models.Model):
street_1 = models.CharField(_('street address 1'), max_length=250, help_text='street address one')
street_2 = models.CharField(_('street address 2'), null=True, blank=True, max_length=250, help_text='street address two')
postal_code = models.IntegerField(_('address zipcode'), help_text='address zipcode')
city = models.CharField(_('address city'), max_length=100, help_text='address city')
state = models.CharField(_('address state'), max_length=50, help_text='address state')
country = models.CharField(_('address country'), max_length=100, help_text='address country')
and this is my current implementation of creating a customer
class CreateCustomer(graphene.Mutation):
customer = graphene.Field(CustomerType)
class Arguments:
email = graphene.String(required=True)
first_name = graphene.String(required=True)
last_name = graphene.String(required=True)
password = graphene.String(required=True)
phone = graphene.String(required=True)
street_1 = graphene.String(required=False)
street_2 = graphene.String(required=False)
city = graphene.String(required=False)
state = graphene.String(required=False)
zipcode = graphene.String(required=False)
country = graphene.String(required=False)
def mutate(self, info, email, first_name, last_name, password, phone, street_1=None, street_2=None, city=None, state=None, zipcode=None, country=None):
user = User.objects.create_user(
email=email,
password = password
)
user.save()
current_customer = customer.objects.create(
user = user,
first_name = first_name,
last_name = last_name,
phone_number = phone,
email_address = email
)
if street_1:
customer_address = address.objects.create(
street_1 = street_1,
street_2 = street_2,
city = city,
state = state,
postal_code = zipcode,
country = country,
)
customer_address.save()
current_customer.addresses.add(customer_address)
current_customer.save()
return CreateCustomer(customer=current_customer)
I have a mutation for address, and user, I would like to be able to pass those mutations as arguments to the create customer class and my mutation would look something like this
mutation{
createCustomer(
firstName:"john",
user:createUser(
email:"john@example.com",
password:"password123",
),
addresses:createAddress(
street_1:"123 street name",
...rest of parameters
)
)
}
Beta Was this translation helpful? Give feedback.
All reactions
I find the graphene-django-cud package very helpful for reducing boilerplate in mutations, and allowing for things like nested fields in create/update. I believe it handles your original use-case. Check out the docs on that here: https://graphene-django-cud.readthedocs.io/en/latest/guide/nested-fields.html
Replies: 2 comments
-
I think that it is not possible with graphql, usually prefer to create many factory functions in a service because of it, is better to create the tests too
class CreateCustomer(graphene.Mutation): customer = graphene.Field(CustomerType) class Arguments: user_input = UserInput() address_input = AddressInput() def mutate(self, info, user_input, address_input): user_service_instance = UserService() created_user = user_service_instance.create_user_factory(user_input) if address_input: user_service_instance.update_address(address_input) return CreateCustomer(customer=created_user)
Beta Was this translation helpful? Give feedback.
All reactions
-
I find the graphene-django-cud package very helpful for reducing boilerplate in mutations, and allowing for things like nested fields in create/update. I believe it handles your original use-case. Check out the docs on that here: https://graphene-django-cud.readthedocs.io/en/latest/guide/nested-fields.html
Beta Was this translation helpful? Give feedback.