how to use custom register mutation with django-graphql-auth

Viewed 849

django-graphql-auth is an awesome package, but the documentation doesn't say much about models association to a custom user model.

I am looking for a away to make use of this package with a custom Register Mutation for both user types Applicant and Employer


class User(AbstractUser):
    email = models.EmailField(blank=False,
                              max_length=255,
                              verbose_name="email address")
    is_applicant = models.BooleanField(default=False)
    is_employer = models.BooleanField(default=False)

    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"


class Applicant(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    fullname = models.CharField(max_length=255, null=True)


class Employer(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    company_name = models.CharField(max_length=225, null=True)

Mutation goal to achieve:

mutation {
  registerApplicant(
    input: {
      email: "new_applicant@email.com",
      username: "new_applicant",
      password1: "createsuperpassword",
      password2: "createsuperpassword",
      isApplicant: true,
      applicant {
        fullname: "New Applicant"
      }
    }
  ) {
    success,
    errors,
    token,
    refreshToken
  }
}

mutation {
  registerEmployer(
    input: {
      email: "new_employer@email.com",
      username: "new_employer",
      password1: "createsuperpassword",
      password2: "createsuperpassword",
      isEmployer: true,
      employer {
        fullname: "New Employer"
      }
    }
  ) {
    success,
    errors,
    token,
    refreshToken
  }
}

1 Answers

You could do this whole process with only graphql_jwt, at first you would need to define input; like this:

class ApplicantInfoInput(graphene.InputObjectType):
    email = graphene.String(required=True)
    username = graphene.String(required=True)
    password1 = graphene.String(required=True)
    password2 = graphene.String(required=True)
    is_applicant = graphene.Boolean(required=True)
    fullname = graphene.String(required=True)

Then the mutation class should look something like this:

from graphql_jwt.shortcuts import get_token, create_refresh_token
from ..models import User, Applicant

class UserCreateMutation(graphene.Mutation):
    user = graphene.Field(UserType)
    success = graphene.Boolean()
    token = graphene.String()
    refresh_token = graphene.String()

    class Arguments:
        input = ApplicantInfoInput(required=True)

    @staticmethod
    def mutate(root, info, input=None):
        try:
            user = User.objects.get(username=input.username)
        except User.DoesNotExist as e:
            user = None

        if user:
            raise Exception('User Already Exists!')
        else:
            user_instance = Applicant(fullname=input.fullname)
            user_instance.user.email = input.email
            user_instance.user.set_password(input.password1)
            user_instance.user.is_applicant = True
            user_instance.save()
            token = get_token(user_instance)
            refresh_token = create_refresh_token(user_instance)
            return UserCreateMutation(user=user_instance,
                                      token=token,
                                      refresh_token=refresh_token,
                                      success=True)
Related