1. Home
  2. Docs
  3. Django Rest Framework
  4. Custom User Model Jwt

Custom User Model Jwt

Prerequisites

Step 1: Define the Custom User Model

In your app (let’s call it accounts), define your CustomUser model in models.py:

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

class CustomUserManager(BaseUserManager):
    def create_user(self, email, username, password=None, **extra_fields):
        if not email:
            raise ValueError('The Email field must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(email, username, password, **extra_fields)

class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
    mobileNo = models.CharField(max_length=15, blank=True, null=True)
    profile_pic = models.ImageField(upload_to='profile_pics/', null=True, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    objects = CustomUserManager()

Python

Step 2: Register the Custom User Model

In your project’s settings.py, register the custom user model:

AUTH_USER_MODEL = 'accounts.CustomUser'
Python

Step 3 : Admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin, GroupAdmin
from django.contrib.auth.models import Group, Permission
from django.contrib.auth import get_user_model

CustomUser = get_user_model()

class CustomUserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        ('Personal info', {'fields': ('email', 'mobileNo', 'profile_pic')}),
        ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
        ('Important dates', {'fields': ('last_login', 'date_joined')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'email', 'mobileNo', 'profile_pic', 'password1', 'password2', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}
        ),
    )
    list_display = ('username', 'email', 'mobileNo', 'is_staff')
    search_fields = ('username', 'email', 'mobileNo')
    filter_horizontal = ('groups', 'user_permissions',)

class CustomGroupAdmin(GroupAdmin):  # Inherits from GroupAdmin
    filter_horizontal = ('permissions',)

# Unregister the default Group admin
admin.site.unregister(Group)

# Register your CustomUserAdmin with the admin site
admin.site.register(CustomUser, CustomUserAdmin)

# Register your CustomGroupAdmin with the admin site
admin.site.register(Group, CustomGroupAdmin)
Python

Step 4: Create the Serializer for Registration

In serializers.py within the accounts app, create a serializer for user registration:

from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _

User = get_user_model()

class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('email', 'username', 'password', 'mobileNo', 'profile_pic')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)
Python

Step 5: Implement the Authentication Views

In views.py within the accounts app:

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from .serializers import RegisterSerializer
from rest_framework_simplejwt.tokens import RefreshToken

# Register View
class RegisterView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = RegisterSerializer(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)

# Logout View
class LogoutView(APIView):
    def post(self, request):
        try:
            refresh_token = request.data["refresh"]
            token = RefreshToken(refresh_token)
            token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception:
            return Response(status=status.HTTP_400_BAD_REQUEST)
Python

Step 6: Configure URL Patterns

In urls.py of the accounts app:

from django.urls import path
from .views import RegisterView, LogoutView
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

urlpatterns = [
    path('api/register/', RegisterView.as_view(), name='register'),
    path('api/logout/', LogoutView.as_view(), name='logout'),
    path('api/login/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
Python

For the login endpoint, you can directly use TokenObtainPairView and TokenRefreshView provided by djangorestframework-simplejwt in your project’s urls.py:

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('accounts.api.urls')),

]
Python

Step 7: Migrate Your Database

Run migrations to apply changes:

python manage.py makemigrations accounts
python manage.py migrate
Python

Step 8: Additional Configuration for JWT in settings.py

Ensure JWT authentication is configured in settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}
Python

API END POINT

# Authentication API Documentation

This API provides endpoints for managing user authentication, including registration, login, logout, and token refresh.

## Endpoints

1. **Register a new user:**
   - URL: `http://127.0.0.1:8000/account/api/register/`
   - Method: POST
   - Body: JSON with the data for the new user.
     ```json
     {
       "username": "newuser",
       "email": "newuser@example.com",
       "password": "newuserpassword",
       "mobileNo": "1234567890",
       "profile_pic": null
     }
     ```
   - Description: Registers a new user with the provided username, email, and password. Optionally, mobile number and profile picture can be included.

2. **Login and obtain JWT tokens:**
   - URL: `http://127.0.0.1:8000/account/api/login/`
   - Method: POST
   - Body: JSON with the login credentials.
     ```json
     {
       "email": "user@example.com",
       "password": "userpassword"
     }
     ```
   - Description: Authenticates the user with the provided email and password, returning access and refresh JWT tokens upon successful authentication.

3. **Logout and blacklist refresh token:**
   - URL: `http://127.0.0.1:8000/account/api/logout/`
   - Method: POST
   - Body: JSON containing the refresh token to blacklist.
     ```json
     {
       "refresh": "your_refresh_token_here"
     }
     ```
   - Description: Blacklists the provided refresh token, effectively logging the user out.

4. **Refresh access token:**
   - URL: `http://127.0.0.1:8000/account/api/token/refresh/`
   - Method: POST
   - Body: JSON containing the refresh token.
     ```json
     {
       "refresh": "your_refresh_token_here"
     }
     ```
   - Description: Provides a new access token given a valid refresh token.
Python

How can we help?