1. Home
  2. Attendance Management Sys...
  3. Backend
  4. কাস্টম ইউজার মডেল তৈরি করা

কাস্টম ইউজার মডেল তৈরি করা

python manage.py startapp authentication

প্রথমে আমাদের একটি নতুন অ্যাপ তৈরি করতে হবে যেটার নাম হবে authentication। এরপর, এই অ্যাপের models.py ফাইলে কাস্টম ইউজার মডেল এবং ইউজার ম্যানেজার তৈরি করব।

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

class Company(models.Model):
    """
    Model representing a company.
    """
    name = models.CharField(max_length=255, unique=True)  # Unique name for the company
    address = models.CharField(max_length=255, blank=True, null=True)  # Address of the company
    is_active = models.BooleanField(default=True)  # Indicates whether the company is active

    def __str__(self):
        return self.name

# CustomUserManager creates a custom user.
class CustomUserManager(BaseUserManager):
    """
    CustomUserManager inherits from Django's BaseUserManager.
    We create custom methods for user and superuser creation.
    """

    # Method for creating a standard user
    def create_user(self, email, username, password=None, **extra_fields):
        """
        Method for creating a standard user.
        """
        if not email:  # Raise an error if email is not provided
            raise ValueError('The Email field must be set')

        # Normalizing email
        email = self.normalize_email(email)

        # Create user object with email, username, and extra fields
        user = self.model(email=email, username=username, **extra_fields)

        # Set the user's password
        user.set_password(password)

        # Save the user object to the database
        user.save(using=self._db)
        return user

    # Method for creating a superuser
    def create_superuser(self, email, username, password=None, **extra_fields):
        """
        Method for creating a superuser.
        """

        # Set default fields for superuser
        extra_fields.setdefault('is_staff', True)  # Superuser must be staff
        extra_fields.setdefault('is_superuser', True)  # Superuser must be a superuser

        # Raise error if is_staff is False
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')

        # Raise error if is_superuser is False
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        # Create superuser using create_user method
        return self.create_user(email, username, password, **extra_fields)


# CustomUser model definition
class CustomUser(AbstractUser):
    """
    This model inherits from `AbstractUser`, allowing us to add custom fields as needed.
    """

    # Additional custom fields
    email = models.EmailField(unique=True)  # Email is defined as unique
    mobileNo = models.CharField(max_length=15, blank=True, null=True)  # Adding mobile number
    company = models.ForeignKey(Company, on_delete=models.SET_NULL, related_name='employees', null=True, blank=True) 
    # If a company is deleted, the user will still exist, but company will be set to null.

    # Adding custom manager
    objects = CustomUserManager()

    # Setting email as username field
    USERNAME_FIELD = 'email'  # Use email for login
    REQUIRED_FIELDS = ['username']  # Username field is required alongside email

    def __str__(self):
        """
        Return the user's email as a string.
        """
        return self.email
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')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)
from rest_framework import status
from django.contrib.auth import authenticate, login
from django.conf import settings
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import RegisterSerializer

# 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)


# Custom function to generate tokens for the user
def get_tokens_for_user(user):
    """
    Custom method to generate tokens (refresh and access) for a given user,
    and include extra fields in the token payload like email, username, and mobileNo.
    """
    refresh = RefreshToken.for_user(user)

    # Add custom fields to the access token
    refresh['email'] = user.email  # Add user's email to the token
    refresh['username'] = user.username  # Add user's username to the token

    return {
        'refresh': str(refresh),
        'access': str(refresh.access_token),
        # Optionally, include user data in the response
        'user': {
            'id': user.id,
            'email': user.email,
            'username': user.username,
        }
    }



class LoginView(APIView):
    """
    Custom login view to authenticate the user and return JWT tokens securely.
    """
    permission_classes = [AllowAny]

    def post(self, request):
        email = request.data.get('email')
        password = request.data.get('password')

        if not email or not password:
            return Response({"error": "Email and password are required."}, status=status.HTTP_400_BAD_REQUEST)

        user = authenticate(request, email=email, password=password)

        if user is not None:
            # Log the user in
            login(request, user)

            # Generate JWT tokens
            tokens = get_tokens_for_user(user)

            # Set refresh token in a secure HTTP-only cookie
            response = Response({
                'user': tokens['user'],  # Include user details in response
                'access': tokens['access'],  # Send access token in the response
            }, status=status.HTTP_200_OK)

            # Set the refresh token in an HttpOnly cookie
            response.set_cookie(
                key='refresh_token',
                value=tokens['refresh'],
                httponly=True,  # Prevent JavaScript access
                secure=True,  # Only send over HTTPS
                samesite='Strict',  # Prevent CSRF
                max_age=settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'].total_seconds()  # Set token expiry
            )

            return response

        return Response({"error": "Invalid credentials."}, status=status.HTTP_401_UNAUTHORIZED)
    
# 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)


from django.urls import path
from .views import RegisterView, LoginView, LogoutView

urlpatterns = [
    path('auth/register/', RegisterView.as_view(), name='register'),
    path('auth/login/', LoginView.as_view(), name='login'),  # Custom login route
    path('auth/logout/', LogoutView.as_view(), name='logout'),  # Logout route
]
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
from .models import Company 
CustomUser = get_user_model()

class CustomUserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        ('Personal info', {'fields': ('email', 'mobileNo','company' )}),
        ('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', 'company' 'password1', 'password2', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}
        ),
    )
    list_display = ('username', 'email', 'mobileNo', 'is_staff','company')
    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)


# Admin class for Company model
class CompanyAdmin(admin.ModelAdmin):
    list_display = ('name', 'address')  # Fields to display in the list view
    search_fields = ('name',)  # Searchable fields in the admin interface

# Register the Company model with the admin site
admin.site.register(Company, CompanyAdmin)

Django ডিফল্টভাবে AbstractUser এবং BaseUserManager ব্যবহার করে ইউজার মডেল পরিচালনা করে। তবে যদি আমাদের প্রজেক্টে কাস্টম ইউজার মডেলের প্রয়োজন হয়, তাহলে আমরা ডিফল্ট ইউজার মডেল পরিবর্তন করে আমাদের নিজস্ব মডেল তৈরি করতে পারি। নিচে আমরা CustomUserManager এবং CustomUser মডেল তৈরি করব যা Django-এর ডিফল্ট মডেল ম্যানেজারের উপর ভিত্তি করে তৈরি করা হয়েছে।

Step 1: CustomUserManager তৈরি করা

প্রথমেই আমরা CustomUserManager ক্লাস তৈরি করবো যা আমাদের কাস্টম ইউজার মডেল পরিচালনা করবে।

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

# CustomUserManager তৈরি করা যেটা আমাদের কাস্টম ইউজার তৈরি করতে সহায়তা করবে
class CustomUserManager(BaseUserManager):
    """
    CustomUserManager Django এর BaseUserManager ক্লাস থেকে ইনারিট (inherit) করছে।
    আমরা এখানে ইউজার এবং সুপার ইউজার তৈরির জন্য কাস্টম মেথড তৈরি করব।
    """

    # সাধারণ ইউজার তৈরি করার মেথড
    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)  # is_staff সুপার ইউজার এর ক্ষেত্রে True হবে
        extra_fields.setdefault('is_superuser', True)  # is_superuser সুপার ইউজার এর ক্ষেত্রে True হবে

        # যদি is_staff ফিল্ড False হয়, তাহলে এরর দিবে
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')

        # যদি is_superuser ফিল্ড False হয়, তাহলে এরর দিবে
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        # create_user মেথড ব্যবহার করে সুপার ইউজার তৈরি করা হচ্ছে
        return self.create_user(email, username, password, **extra_fields)

এই কোড কিভাবে কাজ করে:

  1. BaseUserManager থেকে ইনারিট করা:
    • CustomUserManager Django-এর BaseUserManager থেকে ইনারিট করছে। এর মাধ্যমে আমরা আমাদের কাস্টম ইউজার মডেলের জন্য ইউজার এবং সুপার ইউজার তৈরি করার কাস্টম ফাংশন সংজ্ঞায়িত করছি।
  2. create_user মেথড:
    • এই মেথডটি সাধারণ ইউজার তৈরি করতে ব্যবহৃত হয়। এটি প্রথমে চেক করে যে ইমেইল ঠিক আছে কিনা। যদি ইমেইল না থাকে, তাহলে একটি ValueError এরর উত্থাপন করবে।
    • তারপর normalize_email মেথড দিয়ে ইমেইল ফরম্যাট নরমালাইজ করা হয়। উদাহরণস্বরূপ, বড় হাতের অক্ষরকে ছোট হাতের অক্ষরে পরিণত করা।
    • এরপর একটি ইউজার অবজেক্ট তৈরি হয় যেখানে ইমেইল, ইউজারনেম এবং অতিরিক্ত তথ্য দেওয়া হয়।
    • অবশেষে, ইউজারের পাসওয়ার্ড সেট করে এবং ডাটাবেজে সেভ করা হয়।
  3. create_superuser মেথড:
    • সুপার ইউজার তৈরির সময় অতিরিক্ত কিছু চেক করা হয়। যেমন:
      • is_staff এবং is_superuser ফিল্ডগুলো True কিনা তা চেক করা হয়। যদি না হয়, তাহলে এরর উত্থাপন করা হয়।
    • এর পরে, এটি create_user মেথড ব্যবহার করে ইউজার তৈরি করে, এবং সুপার ইউজার তৈরির জন্য প্রয়োজনীয় ফিল্ডগুলো সেট করে দেয়।

কাস্টমাইজেশন:

  • আপনি চাইলে create_user এবং create_superuser মেথডে আরো ফিল্ড যোগ করতে পারেন। যেমন: first_name, last_name, বা যেকোনো অতিরিক্ত ফিল্ড যেগুলো আপনার কাস্টম ইউজার মডেলে থাকবে।
  • উদাহরণস্বরূপ, যদি আপনি চান যে ইউজারের মোবাইল নাম্বারও বাধ্যতামূলক ফিল্ড হিসেবে থাকুক, তাহলে আপনি create_user মেথডে এটি চেক করতে পারেন:
if not mobile_no:
    raise ValueError('The Mobile No field must be set')

CustomUser মডেল তৈরি এবং CustomUserManager যুক্ত করা

CustomUserManager তৈরি করার পর, আমরা CustomUser মডেল তৈরি করবো, যেখানে আমরা AbstractUser থেকে ইনারিট করবো এবং Django এর ডিফল্ট ইউজার মডেলকে কাস্টমাইজ করবো। এছাড়া, আমরা CustomUserManager-কে এই মডেলে যুক্ত করবো যাতে কাস্টম মেথডগুলো মডেলে কাজ করে।

CustomUser মডেল:


# CustomUser মডেল তৈরি করা হচ্ছে
class CustomUser(AbstractUser):
    """
    এই মডেলটি `AbstractUser` থেকে ইনারিট করছে, যা Django এর ডিফল্ট ইউজার মডেল।
    এখানে আমরা অতিরিক্ত কিছু ফিল্ড যোগ করতে পারি এবং প্রয়োজন অনুযায়ী পরিবর্তন করতে পারি।
    """

    # অতিরিক্ত কাস্টম ফিল্ড যোগ করা
    email = models.EmailField(unique=True)  # ইমেইলকে ইউনিক হিসেবে সংজ্ঞায়িত করা
    mobileNo = models.CharField(max_length=15, blank=True, null=True)  # মোবাইল নাম্বার যোগ করা

    # আমরা কাস্টম ম্যানেজার যুক্ত করব
    objects = CustomUserManager()

    # ইউজারের ইমেইলকে ইউজারনেম হিসেবে সংজ্ঞায়িত করা হচ্ছে
    USERNAME_FIELD = 'email'  # লগইনের জন্য ইমেইলকে ইউজারনেম হিসেবে ব্যবহার করা
    REQUIRED_FIELDS = ['username']  # ইমেইলের পাশাপাশি ইউজারনেম ফিল্ড বাধ্যতামূলক

    def __str__(self):
        """
        ইউজারের রিটার্ন স্ট্রিং আমরা ইমেইল হিসেবে রিটার্ন করবো
        """
        return self.email

এই কোড কিভাবে কাজ করে:

  1. AbstractUser থেকে ইনারিট করা:
    • CustomUser মডেলটি AbstractUser থেকে ইনারিট করা হয়েছে। এটি Django এর বিল্ট-ইন ইউজার মডেলের বেশিরভাগ ফিচার অটোমেটিকভাবে প্রদান করে, যেমন ইউজার অ্যাট্রিবিউট এবং মেথডগুলো।
  2. ইমেইল এবং কন্টাক্ট নাম্বার যোগ করা:
    • এখানে আমরা ইমেইলকে unique=True দিয়ে সংজ্ঞায়িত করেছি। কারণ, আমাদের চাহিদা অনুযায়ী আমরা চাই যে প্রতিটি ইউজারের ইমেইল ইউনিক হবে।
    • এছাড়াও, আমরা contact_number নামে একটি ফিল্ড যোগ করেছি, যেখানে ইউজারদের মোবাইল নাম্বার সংরক্ষণ করা যাবে। এটাকে blank=True, null=True দিয়ে রাখা হয়েছে, যাতে এই ফিল্ডটি বাধ্যতামূলক না হয়।
  3. কাস্টম ম্যানেজার যুক্ত করা:
    • objects = CustomUserManager() দিয়ে আমরা মডেলে CustomUserManager যুক্ত করেছি। ফলে, মডেলটি আমাদের কাস্টম ম্যানেজারের মেথডগুলো ব্যবহার করতে পারবে।
  4. ইমেইলকে ইউজারনেম হিসেবে ব্যবহার করা:
    • USERNAME_FIELD হিসেবে আমরা email সেট করেছি। ফলে ইউজার লগইনের সময় ইমেইল ব্যবহার করবে।
    • REQUIRED_FIELDSusername যুক্ত করা হয়েছে, কারণ এটি AbstractUser এর অংশ হিসেবে বাধ্যতামূলক একটি ফিল্ড। এছাড়া অন্যান্য ফিল্ডগুলোও এখানে যুক্ত করা যেতে পারে।
  5. __str__ মেথড:
    • এই মেথডটি রিটার্ন করে কীভাবে ইউজার অবজেক্টকে রিডেবল হিসেবে প্রিন্ট করা হবে। এখানে আমরা ইউজারের ইমেইল রিটার্ন করছি, যাতে যখনই প্রিন্ট হবে বা রেপ্রেজেন্টেশন করা হবে তখন ইমেইল দেখাবে।

পরবর্তী ধাপ: settings.py এ কাস্টম ইউজার মডেল সেট করা

এবার আমাদের settings.py তে গিয়ে কাস্টম ইউজার মডেল সেট করতে হবে, যাতে Django আমাদের নতুন কাস্টম ইউজার মডেল চিনতে পারে।

# settings.py ফাইলে

AUTH_USER_MODEL = 'your_app_name.CustomUser'  # আপনার অ্যাপের নাম দিয়ে 'your_app_name' রিপ্লেস করুন 

AUTH_USER_MODEL ফিল্ডে আমরা আমাদের নতুন তৈরি করা CustomUser মডেল সেট করলাম। এতে Django ভবিষ্যতে সব ইউজার সংক্রান্ত কাজের জন্য এই কাস্টম মডেলটি ব্যবহার করবে।

Step 3: মাইগ্রেশন ফাইল তৈরি এবং ডাটাবেজ আপডেট করা

CustomUser মডেল তৈরি করার পরে, আমাদের মডেলকে ডাটাবেজে মাইগ্রেট করতে হবে।

  1. মাইগ্রেশন তৈরি করা:
    • টার্মিনালে এই কমান্ডটি চালান:
python manage.py makemigrations

মাইগ্রেশন অ্যাপ্লাই করা:

  • টার্মিনালে এই কমান্ডটি চালান:
python manage.py migrate

এর মাধ্যমে আপনার কাস্টম ইউজার মডেল ডাটাবেজে যুক্ত হবে।

সংক্ষেপে:

  • প্রথমে CustomUserManager তৈরি করে ইউজার এবং সুপার ইউজার তৈরির কাস্টম মেথড তৈরি করা হয়।
  • এরপর CustomUser মডেল তৈরি করে আমরা ডিফল্ট মডেলের ফিচারগুলো ব্যবহার করি এবং অতিরিক্ত ফিল্ড ও কাস্টম লজিক যোগ করি।
  • অবশেষে, আমরা settings.py তে কাস্টম ইউজার মডেল যুক্ত করি এবং ডাটাবেজ মাইগ্রেট করি।

এভাবে আমরা Django প্রজেক্টে কাস্টম ইউজার মডেল ব্যবহার করতে পারি।

Customizing Django Admin with CustomUserAdmin

এই টিউটোরিয়ালে, আমরা দেখবো কিভাবে Django এর ডিফল্ট ইউজার এবং গ্রুপ মডেলগুলো কাস্টমাইজ করে অ্যাডমিন প্যানেলে ব্যবহার করা যায়। আমরা প্রথমে CustomUserAdmin তৈরি করবো এবং তারপরে Django এর ডিফল্ট Group মডেলের জন্য CustomGroupAdmin তৈরি করবো।

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() এর মাধ্যমে
CustomUser = get_user_model()

# CustomUserAdmin তৈরি করা হচ্ছে
class CustomUserAdmin(BaseUserAdmin):
    # fieldsets মেথড দিয়ে বিভিন্ন সেকশনে ফিল্ডগুলো ভাগ করা
    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 এর মাধ্যমে নির্ধারণ
    add_fieldsets = (
        (None, {
            'classes': ('wide',),  # ক্লাসের মাধ্যমে স্টাইল কাস্টমাইজ করা
            'fields': ('username', 'email', 'mobileNo', 'profile_pic', 'password1', 'password2', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}
        ),
    )
    
    # list_display: অ্যাডমিন প্যানেলে ইউজারের কোন ফিল্ডগুলো দেখানো হবে তার তালিকা
    list_display = ('username', 'email', 'mobileNo', 'is_staff')
    
    # search_fields: কোন কোন ফিল্ডে সার্চ করা যাবে, সেটা নির্ধারণ করা
    search_fields = ('username', 'email', 'mobileNo')
    
    # filter_horizontal: গ্রুপ এবং ইউজার পারমিশন ফিল্ডের জন্য ফিল্টার হরিজন্টাল ভাবে করা
    filter_horizontal = ('groups', 'user_permissions',)

# CustomGroupAdmin তৈরি করা
class CustomGroupAdmin(GroupAdmin):  # GroupAdmin থেকে ইনারিট করা হয়েছে
    filter_horizontal = ('permissions',)  # গ্রুপের পারমিশনের জন্য ফিল্টার

# ডিফল্ট Group মডেলকে আনরেজিস্টার করা হচ্ছে
admin.site.unregister(Group)

# CustomUserAdmin কে অ্যাডমিন প্যানেলে রেজিস্টার করা হচ্ছে
admin.site.register(CustomUser, CustomUserAdmin)

# CustomGroupAdmin কে অ্যাডমিন প্যানেলে রেজিস্টার করা হচ্ছে
admin.site.register(Group, CustomGroupAdmin)

কোডের প্রতিটি অংশের বিস্তারিত ব্যাখ্যা:

১. CustomUserAdmin তৈরি করা

class CustomUserAdmin(BaseUserAdmin):
    ...
  • BaseUserAdmin থেকে ইনারিট করা হয়েছে, কারণ আমরা চাই Django এর ডিফল্ট ইউজার অ্যাডমিন ফাংশনালিটি বজায় রাখতে এবং কিছু অতিরিক্ত ফিল্ড যোগ করতে।
  • আমরা CustomUserAdmin ক্লাসের মাধ্যমে অ্যাডমিন প্যানেলে কাস্টম ফিল্ড, সেকশন এবং অন্যান্য অপশনগুলো দেখানোর জন্য কাস্টম লজিক অ্যাপ্লাই করতে পারি।

২. fieldsets: ফিল্ডগুলোকে সেকশনে ভাগ করা

fieldsets = (
    (None, {'fields': ('username', 'password')}),
    ('Personal info', {'fields': ('email', 'mobileNo')}),
    ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
    ('Important dates', {'fields': ('last_login', 'date_joined')}),
)
  • fieldsets ফিল্ডের মাধ্যমে আমরা বিভিন্ন ফিল্ডকে ভিন্ন ভিন্ন সেকশনে ভাগ করে অ্যাডমিন প্যানেলে দেখাতে পারি।
  • উদাহরণস্বরূপ, Personal info সেকশনে ইউজারের ব্যক্তিগত তথ্য যেমন ইমেইল, মোবাইল নাম্বার, এবং প্রোফাইল পিকচার দেখানো হবে।
  • Permissions সেকশনে ইউজারের অনুমতিসমূহ (যেমন is_active, is_staff, groups, ইত্যাদি) দেখানো হয়।

৩. add_fieldsets: নতুন ইউজার তৈরির সময় ফিল্ডের বিন্যাস

add_fieldsets = (
    (None, {
        'classes': ('wide',),
        'fields': ('username', 'email', 'mobileNo', 'password1', 'password2', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}
    ),
)
  • add_fieldsets নতুন ইউজার তৈরির সময় যে ফিল্ডগুলো প্রদর্শিত হবে, তা নির্ধারণ করে। এখানে username, email, mobileNo সহ আরও কিছু ফিল্ড থাকবে।
  • classes: এর মাধ্যমে আমরা ফর্মে wide ক্লাস যোগ করেছি, যা ফর্মটিকে চওড়া করবে।

৪. list_display: ইউজারের কোন ফিল্ডগুলো লিস্ট আকারে দেখাবে

list_display = ('username', 'email', 'mobileNo', 'is_staff')
  • list_display এর মাধ্যমে আমরা অ্যাডমিন প্যানেলে ইউজার লিস্টে কোন কোন ফিল্ড দেখানো হবে তা নির্ধারণ করতে পারি। এখানে আমরা username, email, এবং mobileNo দেখাচ্ছি।

৫. search_fields: কোন ফিল্ডে সার্চ করা যাবে

search_fields = ('username', 'email', 'mobileNo')
  • search_fields এর মাধ্যমে ইউজারের যেসব ফিল্ডে সার্চ করা যাবে তা নির্ধারণ করা হয়। এখানে ইউজারনেম, ইমেইল এবং মোবাইল নাম্বার ফিল্ডে সার্চ করা যাবে।

৬. filter_horizontal: গ্রুপ এবং পারমিশন ফিল্ডের জন্য ফিল্টার

filter_horizontal = ('groups', 'user_permissions',)

filter_horizontal এর মাধ্যমে আমরা groups এবং user_permissions ফিল্ডগুলোর জন্য হরিজন্টাল ফিল্টার ব্যবহার করতে পারি। এটা লম্বা তালিকার পরিবর্তে গ্রাফিকালি সহজে ফিল্টার করতে সাহায্য করে।

CustomGroupAdmin তৈরি

class CustomGroupAdmin(GroupAdmin):  # GroupAdmin থেকে ইনারিট করা হয়েছে
    filter_horizontal = ('permissions',)  # গ্রুপের পারমিশনের জন্য ফিল্টার
  • GroupAdmin থেকে ইনারিট করে আমরা CustomGroupAdmin তৈরি করেছি, যা permissions ফিল্ডে হরিজন্টাল ফিল্টার দেয়। এটি আমাদের গ্রুপের পারমিশনগুলো সহজভাবে ফিল্টার করতে সাহায্য করে।

ডিফল্ট Group মডেল আনরেজিস্টার করা এবং নতুন অ্যাডমিন রেজিস্টার করা

# ডিফল্ট Group মডেলকে আনরেজিস্টার করা হচ্ছে
admin.site.unregister(Group)

# CustomUserAdmin এবং CustomGroupAdmin রেজিস্টার করা হচ্ছে
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.register(Group, CustomGroupAdmin)

আমরা Django এর ডিফল্ট Group মডেলকে unregister করেছি, যাতে আমাদের কাস্টম CustomGroupAdmin এর মাধ্যমে গ্রুপ ম্যানেজমেন্ট অ্যাডমিন প্যানেলে দেখানো যায়।এরপর আমরা CustomUserAdmin এবং CustomGroupAdmin কে admin.site.register এর মাধ্যমে অ্যাডমিন প্যানেলে যুক্ত করেছি।

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')
        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?