django-graphql-jwt with django-phone-field Object of type PhoneNumber is not JSON serializable

311 Views Asked by At

I'm currently using the django-phone-field library in a project where I use graphene-django as well.

Here's my custom User model, where I'm using the PhoneField.

class User(AbstractBaseUser, PermissionsMixin):
    """
    Custom User model to add the required phone number
    """
    first_name = models.CharField(
        max_length=100
    )
    last_name = models.CharField(
        max_length=100
    )
    email = models.EmailField(
        verbose_name='Email address',
        max_length=255,
        unique=True,
        # Because it's unique, blank is not an option because there could be 2 with the same value ('')
        blank=False,
        null=True
    )
    phone = CustomPhoneField(
        # Please note this formatting only works for US phone numbers right now
        # https://github.com/VeryApt/django-phone-field#usage
        # If international numbers are needed at some point, take a look at:
        # https://github.com/stefanfoulis/django-phonenumber-field
        E164_only=True,
        unique=True
    )
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = ['first_name', 'last_name',]

I'm using django-graphql-jwt to handle authentication.

Here's my tokenAuth query:

mutation TokenAuth ($phone: String!, $password: String!) {
    tokenAuth(phone: $phone, password: $password) {
        token
        payload
        refreshExpiresIn
    }
}

The server is retrieving me an error when trying to execute that query:

{
    "errors": [
        {
            "message": "Object of type PhoneNumber is not JSON serializable",
            "locations": [
                {
                    "line": 2,
                    "column": 5
                }
            ],
            "path": [
                "tokenAuth"
            ]
        }
    ],
    "data": {
        "tokenAuth": null
    }
}

I temporarily made a monkey patch by overriding the to_python method of the PhoneField, like this:

class CustomPhoneField(PhoneField):
    """
    I had to override this to_python method because the phone field is now being used as the username field.
    In GraphQL JWT I was getting the following exception:
    Object of type PhoneNumber is not JSON serializable

    I don't really understand the implications of overriding this method.
    """
    def to_python(self, value):
        # Called during deserialization and from clean() methods in forms
        if not value:
            return None
        elif isinstance(value, PhoneNumber):
            return str(value)
        return str(value)

I'm wondering what is the right solution for this problem and also looking to understand how it really works so I can move forward with a more elegant solution.

1

There are 1 best solutions below

0
On

Looking at your problem I think you are trying to take string instead of Json field.This can be overcome if phone number is a JSON-field that you can try with JsonString datatype.