Description
I am trying to build an API for a transportation system which has different kind of users (Driver, Customer, SystemAdmin and Authorizer). For this purpose I created an AbstractUser
and use inheritance relationship for the all of the above different users.
For adding JWT to the model, I have read the official tutorial, but whenever I want to create a new user like the following I faced to the error:
mutation {
register(
email: "[email protected]",
username: "new_user",
password1: "supersecretpassword",
password2: "supersecretpassword",
) {
success,
errors,
token,
refreshToken
}
}
Steps to Reproduce
- Here is my model:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class Usermodel(AbstractUser, models.Model):
phone_no = models.CharField(
max_length=11,
blank=True,
verbose_name="Phone Number"
)
USERNAME_FIELD = "username" # e.g: "username", "email"
EMAIL_FIELD = "email" # e.g: "email", "primary_email"
def __str__(self):
return self.username
class Driver(Usermodel, models.Model):
national_id = models.CharField(
max_length=10,
blank=True,
verbose_name="National ID"
)
profile_picture = models.ImageField(
blank=True,
null=True
)
STATUS_CHOICES = [
('1', 'Free'),
('2', 'Busy')
]
driver_status = models.CharField(
max_length=1,
choices=STATUS_CHOICES
)
rating = models.FloatField(
default=-1
)
ranking = models.IntegerField(
default=-1
)
class Meta:
verbose_name = 'Driver'
verbose_name_plural = 'Drivers'
class Authorizer(Usermodel, models.Model):
class Meta:
verbose_name = 'Authorizer'
verbose_name_plural = 'Authorizers'
class Customer(Usermodel, models.Model):
class Meta:
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
class Administrator(Usermodel, models.Model):
class Meta:
verbose_name='Adminsitrator'
verbose_name_plural='Administrators'
- users schema
import graphene
from graphene import Mutation, ObjectType, InputObjectType
from .models import Driver, Authorizer, Customer, Administrator
from graphene_django.types import DjangoObjectType
class DriverType(DjangoObjectType):
class Meta:
model = Driver
class AuthorizerType(DjangoObjectType):
class Meta:
model = Authorizer
class Query(ObjectType):
driver = graphene.Field(
DriverType,
id = graphene.ID()
)
authorizer = graphene.Field(
AuthorizerType,
id = graphene.ID()
)
all_drivers = graphene.List(DriverType)
all_authorizers = graphene.List(AuthorizerType)
def resolve_all_drivers(self, info, **kwargs):
return Driver.objects.all()
def resolve_driver(self, info, **kwargs):
id = kwargs.get('id')
if id is not None:
return Driver.objects.get(pk=id)
def resolve_authorizer(self, info, **kwargs):
id = kwargs.get('id')
if id is not None:
return Driver.objects.get(pk=id)
def resolve_all_authorizers(self, info, **kwargs):
return Authorizer.objects.all()
class DriverInput(InputObjectType):
first_name = graphene.String()
last_name = graphene.String()
email = graphene.String()
username = graphene.String()
phone_no = graphene.String()
national_id = graphene.String()
password = graphene.String()
class AuthorizerInput(InputObjectType):
first_name = graphene.String()
last_name = graphene.String()
email = graphene.String()
username = graphene.String()
phone_no = graphene.String()
password = graphene.String()
class CreateDriver(Mutation):
class Arguments:
driver_data = DriverInput()
driver = graphene.Field(DriverType)
def mutate(self, info, driver_data=None):
driver = Driver(
first_name=driver_data.first_name,
last_name=driver_data.last_name,
email=driver_data.email,
username=driver_data.username,
phone_no=driver_data.phone_no,
national_id=driver_data.national_id,
password=driver_data.password
)
driver.save()
return CreateDriver(
driver=driver
)
class UpdateDriver(Mutation):
class Arguments:
id = graphene.ID()
driver_data = DriverInput()
driver = graphene.Field(DriverType)
def mutate(self, info, id, driver_data=None):
#TODO: Error handling if the id not exists
driver = Driver.objects.get(pk=id)
driver.first_name = driver_data.first_name
driver.last_name = driver_data.last_name
driver.email = driver_data.email
driver.username = driver_data.username
driver.phone_no = driver_data.phone_no
driver.national_id = driver_data.national_id
driver.password = driver_data.password
driver.save()
return UpdateDriver(driver=driver)
class AuthorizerInput(InputObjectType):
first_name = graphene.String()
last_name = graphene.String()
email = graphene.String()
username = graphene.String()
phone_no = graphene.String()
password = graphene.String()
class CreateAuthorizer(Mutation):
class Arguments:
authorizer_data = AuthorizerInput()
authorizer = graphene.Field(AuthorizerInput)
def mutate(self, info, authorizer_data=None):
authorizer = Authorizer(
firstname=authorizer_data.first_name,
last_name=authorizer_data.last_name,
email=authorizer_data.email,
username=authorizer_data.username,
phone_no=authorizer_data.phone_no,
password=authorizer_data.password
)
authorizer.save()
return CreateAuthorizer(authorizer=authorizer)
class UpdateAuthorizer(Mutation):
class Arguments:
id = graphene.ID()
authorizer_data = AuthorizerInput()
authorizer = graphene.Field(AuthorizerType)
def mutate(self, info, id, authorizer_data=None):
authorizer = Authorizer.objects.get(pk=id)
authorizer.first_name = authorizer_data.first_name
authorizer.last_name = authorizer_data.last_name
authorizer.email = authorizer_data.email
authorizer.username = authorizer_data.username
authorizer.password = authorizer_data.password
authorizer.save()
return UpdateDriver(authorizer=authorizer)
class Mutations(ObjectType):
create_driver = CreateDriver.Field()
update_driver = UpdateDriver.Field()
- project schema
import graphene
from apps.users.schema import Query as user_query
from apps.users.schema import Mutations as user_mutation
from graphql_auth.schema import UserQuery, MeQuery
from graphql_auth import mutations
class AuthMutation(graphene.ObjectType):
register = mutations.Register.Field()
class Query(user_query, UserQuery, MeQuery):
pass
class Mutations(user_mutation, AuthMutation):
pass
schema = graphene.Schema(
query=Query,
mutation=Mutations
)
Expected behavior
I expect the code to run without any problem but face to the following error in actual behavior
I also have another question. As I have explained for the various kind of user and registration of them, I need different arguments. But in schema we just add register = mutations.Register.Field()
, How can I reach to this purpose?
Actual behavior
Requirements
aniso8601==7.0.0
asgiref==3.2.10
Django==3.0.8
django-filter==2.3.0
django-graphql-auth==0.3.11
django-graphql-jwt==0.3.0
graphene==2.1.8
graphene-django==2.12.1
graphql-core==2.3.2
graphql-relay==2.0.1
Pillow==7.2.0
pkg-resources==0.0.0
promise==2.3
PyJWT==1.7.1
pytz==2020.1
Rx==1.6.1
singledispatch==3.4.0.3
six==1.15.0
sqlparse==0.3.1
Unidecode==1.1.1
Question 1: I expect the code to run without any problem but face to the following error in actual behavior
A: Make sure you have your
settings.py
properly configuredI ran into a similar "Connection refused" error, but the issue was that my settings were not configured properly.
Here's a slightly abbreviated copy of my
settings.py
from a scratch project I was using, just to be sure that you have it configured correctly:Source: django-graphql-auth quickstart.
N.B.: It's a little long, make sure to scroll all the way through
Question 2: As I have explained for the various kind of user and registration of them, I need different arguments. But in schema we just add register = mutations.Register.Field(), How can I reach to this purpose?
A: TLDR - this is explained in the dynamic fields section of the settings docs.
A: Walkthrough
Step 1: Make sure that your custom user model has the field set
Before we think about updating our settings, confirm that the custom field you need to set exists on the model. For example, if I wanted to have a
luck_number
field, I would add:Then you need to make sure you run migrations so that this exists in your database.
python manage.py makemigrations
python manage.py migrate
Step 2: Add
GRAPHQL_AUTH
tosettings.py
In your settings, make sure to set:
Step 3: Add your custom fields and double-check your schema
If you want to add fields to collect on registration, you need to add the
REGISTER_MUTATION_FIELDS
to yourGRAPHQL_AUTH
settings. So in the case of addingluck_number
to ourregister
mutation:edit 1: adding image
edit 2: adding clarification around my error on register mutation