Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How can I do nested mutations in graphene django? #1308

Answered by sjdemartini
isaacfink asked this question in Q&A
Discussion options

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
 )
 )
}
You must be logged in to vote

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

Comment options

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)
You must be logged in to vote
0 replies
Comment options

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

You must be logged in to vote
0 replies
Answer selected by firaskafri
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /