2

Suppose I have a self-made User Model which holds username and password field. Now I want to login with my self-made username and password in Django. How can I do that? Besides I need to build a Login Api using this username and password. How to do that?

3
  • 1
    Make a view with a form asking for a username/password. Try getting the object (User Model) which has this username/password, if object exists connect, if not says wrong username/password. It should works, however I do not recommand doing this for security reasons, you should use the default User Model from django and make a Profile class (which could contain other attributes) for example with a Foreign Key to a User Object. Commented Aug 8, 2022 at 8:10
  • Thanks for your answer. Actually, I have got an assignment for learning purpose. Can you tell me how I can create login Api with this? Commented Aug 8, 2022 at 8:23
  • Go through custom backend auth documentation docs.djangoproject.com/en/4.0/topics/auth/customizing . It shows how the default backend authentication can be overridden. For a login API you can check the DRF documentation, there is plenty of info django-rest-framework.org/api-guide/authentication Commented Aug 8, 2022 at 8:29

1 Answer 1

1

I can implement the simple login system like the following.

TokenAuthentication can be used in the DRF by adding some configs in settings.py file.

# REST framework
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication'
    ]
}

Now create the users app by executing the following command.

python manage.py startapp users

And I can create the custom user model in the models.py. Let's say that the app name is "users" and the model name is "Account". You need to set the AUTH_USER_MODEL in settings.py.

# Application definition
INSTALLED_APPS = [
    ...
    'rest_framework',
    'corsheaders',
    'users',
    'rest_framework.authtoken'
]

# specify user model
AUTH_USER_MODEL = 'users.Account'

In models.py of the users app, I can define the user model by deriving from the AbstractBaseUser.

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, UserManager
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token


class Account(AbstractBaseUser):
    """
    A model for users

    It simply has the three fields `username`, `password`, `last_login`.
    In addition, it has several shifts.
    """
    username = models.CharField(max_length=50, unique=True)

    USERNAME_FIELD = 'username'
    objects = UserManager()


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

In serializers.py, you can set the password field as write-only.

from attr import fields
from rest_framework import serializers    
from .models import Account
    
class AccountSerializer(serializers.ModelSerializer):   
    class Meta:
        fields = '__all__'
        model = Account
        extra_kwargs = {
            'password': {'write_only': True}
        }

Finally, in urls.py of the users app, login can be implemented using rest_framework.authtoken

from django.urls import path
from rest_framework.authtoken import views
from .views import AccountView

urlpatterns = [
    path('login', views.obtain_auth_token, name="login"),
    path('register', AccountView.as_view(), name="register")
]

Of course, you can also implement the user register in views.py.

from django.shortcuts import render
from rest_framework.generics import CreateAPIView

from users.serializers import AccountSerializer
from .models import Account
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status

class AccountView(CreateAPIView):
    queryset = Account.objects.all()
    serializer_class = AccountSerializer
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            input_data = serializer.validated_data
            username = input_data.get('username')
            password = input_data.get('password')

            # create user and set password
            user = Account.objects.create(username=username)
            user.set_password(password)
            user.save()
            return Response(AccountSerializer(user).data, status=status.HTTP_201_CREATED)

        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.