How to make Graphene Input Class variables optional?
Asked Answered
P

3

13

In a GraphQL update mutation I want to be able to pass in the values for a child object but I want each of those values to be optional.

So I have created an Input Class like this:

class CityCouncilInput(graphene.InputObjectType):
  mayor = graphene.String()
  treasurer = graphene.String()

Now, I want to be able to pass in either values for both the mayor and treasurer or just one of them.

Pleas know that my code works fine if ALL of the values are passed in. I just want those field values to be optional. How do I do that?

Robert

Pattison answered 24/8, 2017 at 22:35 Comment(0)
U
10

You can try

class CityCouncilInput(graphene.InputObjectType):
  mayor = graphene.String(required=False, default=None)
  treasurer = graphene.String(required=False, default=None)
Utopian answered 25/8, 2017 at 4:53 Comment(1)
default_value for recent versions of grapheneApodictic
S
2

I think the easiest is to define a default argument for the mutation function

Assuming you have the following model, where your values can be blank (Note: I assumed both mayor and treasurer would be allowed to be blank but not NULL - otherwise I guess you can pass None as a default argument):

class CityCouncil(models.Model):
    mayor = models.TextField(max_length=1000, blank=True)
    treasurer = models.CharField(max_length=1000, blank=True)

Then to create the city council this should work:

class createCityCouncil(graphene.Mutation):
    mayor = graphene.String()
    treasurer = graphene.String()

    class Arguments:
        mayor = graphene.String()
        treasurer = graphene.String()

    def mutate(self, mayor="", treasurer=""):

        council = CityCouncil(mayor=mayor, treasurer=treasurer)
        council.save()

        return createCityCouncil(
            mayor=council.mayor, 
            treasurer=council.treasurer
        )

Similarly, when performing an update mutation, you can pass in optional arguments and selectively update the property on your object with setattr).

class updateCityCouncil(graphene.Mutation):
    mayor = graphene.String()
    treasurer = graphene.String()

    class Arguments:
        mayor = graphene.String()
        treasurer = graphene.String()

    def mutate(self, info, id, **kwargs):
        this_council=CityCouncil.objects.get(id=id)
        if not this_council:
            raise Exception('CityCouncil does not exist')

        for prop in kwargs:
            setattr(this_council, prop, kwargs[prop])

        this_council.save

        return updateCityCouncil(
            mayor=this_council.mayor, 
            treasurer=this_council.treasurer
        )
Secondary answered 5/9, 2018 at 21:38 Comment(0)
L
1

You may just have to run an if statement in your mutate function to have the capability of updating either field and the code for the class updateCityCouncil mutation is as below (PS: Take note of assumptions of a model named CityCouncil and the GraphQL type for the Model):

    class CityCouncilType(DjangoObjectType):
        class Meta:
            model = CityCouncil

    class CityCouncilInput(graphene.InputObjectType):
        id = graphene.Int()
        mayor = graphene.String()
        treasurer = graphene.String()

    class updateCityCouncil(graphene.Mutation):
        class Arguments:
            id = graphene.Int(required=True)
            input = CityCouncilInput(required=True)

        ok = graphene.Boolean()
        council = graphene.Field(CityCouncilType)

        @staticmethod
        def mutate(root, info, id, input=None):
            ok = False
            this_council = CityCouncil.objects.get(pk=id)
            if this_council:
                ok = True
                if input.mayor is not None:
                    this_council.mayor = input.mayor
                if input.treasurer is not None:
                    this_council.treasurer = input.treasurer
                this_council.save()
                return updateCityCouncil(ok=ok, council=this_council)
            return updateCityCouncil(ok=ok, council=None)
Lucianolucias answered 10/5, 2020 at 8:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.