Django & Django Rest Framework. Custom accounts app

I need help in creating a custom accounts app instead of using django_allauth or the built-in django user model. I'm stuck on LoginView, LogoutView, SignupView, and linking the created model to django rest framework auth model (using the created model to authenticate your api with token). Here is what i have wrote:

models.py:

from django.db import models


class Account(models.Model):
    email = models.EmailField(unique=True, blank=True, null=True)
    phone = models.CharField(max_length=30, unique=True, blank=True, null=True)
    password = models.CharField(max_length=250)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

urls.py:

from django.urls import path
from accounts.views import (
    AccountsView, 
    AccountView,
    SignupView,
    LoginView,
    LogoutView
)


app_name = 'accounts'

urlpatterns = [
    path('', AccountsView.as_view()),
    path('<int:pk>', AccountView.as_view()),
    path('signup/', SignupView.as_view()),
    path('login/', LoginView.as_view()),
    path('logout/', LogoutView.as_view())
]

serializers.py:

from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from accounts.models import Account


class AccountSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    email = serializers.EmailField()
    phone = serializers.CharField(max_length=30)
    password = serializers.CharField(max_length=250, write_only=True, required=True)
    created_at = serializers.DateTimeField(read_only=True)
    updated_at = serializers.DateTimeField(read_only=True)

    def create(self, validated_data):
        password = make_password(validated_data.get('password'))
        account = Account.objects.create(
            email=validated_data.get('email'),
            phone=validated_data.get('phone'),
            password=password
        )
        return account

    def update(self, account, validated_data):
        password = make_password(validated_data.get('password')) if validated_data.get('password') is not None else account.password
        account.email = validated_data.get('email', account.email)
        account.phone = validated_data.get('phone', account.phone)
        account.password = password
        account.save()
        return account

views.py:

from django.http import Http404
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from accounts.models import Account
from accounts.serializers import AccountSerializer


class AccountsView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]  

    def get(self, request): 
        queryset = Account.objects.all()
        serializer = AccountSerializer(queryset, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = AccountSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class AccountView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]  

    def get(self, request, pk):
        try:
            account = Account.objects.get(pk=pk)
        except Account.DoesNotExist:
            raise Http404
        serializer = AccountSerializer(account)
        return Response(serializer.data, status=status.HTTP_200_OK)
    
    def put(self, request, pk):
        try:
            account = Account.objects.get(pk=pk)
        except Account.DoesNotExist:
            raise Http404
        serializer = AccountSerializer(account, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        try:
            account = Account.objects.get(pk=pk)
        except Account.DoesNotExist:
            raise Http404
        account.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class SignupView(APIView):
    def post(self, request):
        pass


class LoginView(APIView):
    def post(self, request):
        pass


class LogoutView(APIView):
    def post(self, request):
        pass
Back to Top