Octaviotastico
Octaviotastico

Reputation: 134

Rename Django User fields

I'm creating an API, using Django. I need to create a LogIn for users. So I used the default Django User class and authentication to do that.
But there's a problem. The API for the LogIn (in the /users/login/ endpoint) is defined with the following format: {"user":value, "pass":value}.
And the User model given by Django has two important fields: "username" and "password".
As I said before, I want them to be "user" instead of "username", and "pass" instead of "password". Because that's how the JSON in the POSTs requests will be like in the front-end.
I know I can make a RenameField, but that will only change the column name in the database, it won't change how Django asks for the username and password in the body of the POST request.

I need to send (in a POST request in postman) a JSON to the /users/login/ endpoint, with the following format: {"user":value, "pass":value}.
But the Django User model doesn't know what are those fields, it doesn't need user, it needs username, and it doesn't need pass, it needs password, so I'm getting an error.
I need to change somehow the keys "user" and "pass" in the given JSON to be "username" and "password". Or, to change the field names in the User model. Otherwise, the response will be:

{
    "username": [
        "This field is required."
    ],
    "password": [
        "This field is required."
    ]
}

Because, as I said, Django is getting "user" and "pass", and it doesn't recognize those keys... It needs "username" and "password" fields.
i.e: I need to change somehow from:

{
    "user": value,
    "pass": value
}

to:

{
    "username": value,
    "password": value
}

Or viceversa.
I've tried not to create my own User model, and to use the model given by Django, I think it's not a good idea to create one...
I think I can add a new file called serializer.py and do something there but I'm not sure how, and I didn't found anything in the documentation.

If they're useful, these are my files.
urls.py:

from rest_framework.authtoken.views import obtain_auth_token
from django.contrib import admin
from catanAPI.catan import views
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/login/', obtain_auth_token)
]

settings.py

INSTALLED_APPS = [
    #...
    'django.contrib.auth',
    'rest_framework',
    'rest_framework.authtoken'
    #...
]

AUTH_USER_MODEL = 'auth.User'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ]
}

I know this question may be stupid or something, but I'm new in Django, and I'm trying to learn.

Upvotes: 1

Views: 2854

Answers (2)

ruddra
ruddra

Reputation: 51978

I think rather than changing the Model Fields, you should change in the view. You can override the ObtainAuthToken view, like this:

from django.utils.translation import gettext as _
# serializer
class CustomAuthTokenSerializer(serializers.Serializer):
    user = serializers.CharField(label=_("User"))

    def __init__(self, *args, **kwargs):
        super(CustomAuthTokenSerializer, self).__init__(*args, **kwargs)
        self.fields['pass'] = serializers.CharField(
            label=_("Pass"),
            style={'input_type': 'password'},
            trim_whitespace=False
        )
    def validate(self, attrs):
        username = attrs.get('user')
        password = attrs.get('pass')

        if username and password:
            user = authenticate(request=self.context.get('request'),
                                username=username, password=password)

            # The authenticate call simply returns None for is_active=False
            # users. (Assuming the default ModelBackend authentication
            # backend.)
            if not user:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg, code='authorization')
        else:
            msg = _('Must include "username" and "password".')
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

 # view
 from rest_framework.authtoken.views import ObtainAuthToken

 class CustomObtainAuthToken(ObtainAuthToken):
     serailizer_class = CustomAuthTokenSerializer

 # urls
 path('users/login/', CustomObtainAuthToken.as_view())

Upvotes: 3

pissall
pissall

Reputation: 7399

You can write your custom user:

application/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class User(AbstractUser):
    """
    Custom User Model 
    """

    user = models.CharField(max_length=255, unique=True)
    pass_w = models.CharField(max_length=50)
    email = models.CharField(max_length=255, unique=True)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["user"]

    def __str__(self):
        return self.email

project/settings.py

AUTH_USER_MODEL = 'application.User'

Upvotes: 0

Related Questions