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)
এই কোড কিভাবে কাজ করে:
BaseUserManagerথেকে ইনারিট করা:CustomUserManagerDjango-এরBaseUserManagerথেকে ইনারিট করছে। এর মাধ্যমে আমরা আমাদের কাস্টম ইউজার মডেলের জন্য ইউজার এবং সুপার ইউজার তৈরি করার কাস্টম ফাংশন সংজ্ঞায়িত করছি।
create_userমেথড:- এই মেথডটি সাধারণ ইউজার তৈরি করতে ব্যবহৃত হয়। এটি প্রথমে চেক করে যে ইমেইল ঠিক আছে কিনা। যদি ইমেইল না থাকে, তাহলে একটি
ValueErrorএরর উত্থাপন করবে। - তারপর
normalize_emailমেথড দিয়ে ইমেইল ফরম্যাট নরমালাইজ করা হয়। উদাহরণস্বরূপ, বড় হাতের অক্ষরকে ছোট হাতের অক্ষরে পরিণত করা। - এরপর একটি ইউজার অবজেক্ট তৈরি হয় যেখানে ইমেইল, ইউজারনেম এবং অতিরিক্ত তথ্য দেওয়া হয়।
- অবশেষে, ইউজারের পাসওয়ার্ড সেট করে এবং ডাটাবেজে সেভ করা হয়।
- এই মেথডটি সাধারণ ইউজার তৈরি করতে ব্যবহৃত হয়। এটি প্রথমে চেক করে যে ইমেইল ঠিক আছে কিনা। যদি ইমেইল না থাকে, তাহলে একটি
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এই কোড কিভাবে কাজ করে:
AbstractUserথেকে ইনারিট করা:CustomUserমডেলটিAbstractUserথেকে ইনারিট করা হয়েছে। এটি Django এর বিল্ট-ইন ইউজার মডেলের বেশিরভাগ ফিচার অটোমেটিকভাবে প্রদান করে, যেমন ইউজার অ্যাট্রিবিউট এবং মেথডগুলো।
- ইমেইল এবং কন্টাক্ট নাম্বার যোগ করা:
- এখানে আমরা ইমেইলকে
unique=Trueদিয়ে সংজ্ঞায়িত করেছি। কারণ, আমাদের চাহিদা অনুযায়ী আমরা চাই যে প্রতিটি ইউজারের ইমেইল ইউনিক হবে। - এছাড়াও, আমরা
contact_numberনামে একটি ফিল্ড যোগ করেছি, যেখানে ইউজারদের মোবাইল নাম্বার সংরক্ষণ করা যাবে। এটাকেblank=True, null=Trueদিয়ে রাখা হয়েছে, যাতে এই ফিল্ডটি বাধ্যতামূলক না হয়।
- এখানে আমরা ইমেইলকে
- কাস্টম ম্যানেজার যুক্ত করা:
objects = CustomUserManager()দিয়ে আমরা মডেলেCustomUserManagerযুক্ত করেছি। ফলে, মডেলটি আমাদের কাস্টম ম্যানেজারের মেথডগুলো ব্যবহার করতে পারবে।
- ইমেইলকে ইউজারনেম হিসেবে ব্যবহার করা:
USERNAME_FIELDহিসেবে আমরাemailসেট করেছি। ফলে ইউজার লগইনের সময় ইমেইল ব্যবহার করবে।REQUIRED_FIELDSএusernameযুক্ত করা হয়েছে, কারণ এটিAbstractUserএর অংশ হিসেবে বাধ্যতামূলক একটি ফিল্ড। এছাড়া অন্যান্য ফিল্ডগুলোও এখানে যুক্ত করা যেতে পারে।
__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 মডেল তৈরি করার পরে, আমাদের মডেলকে ডাটাবেজে মাইগ্রেট করতে হবে।
- মাইগ্রেশন তৈরি করা:
- টার্মিনালে এই কমান্ডটি চালান:
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)PythonStep 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)
PythonStep 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'),
]PythonFor 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')),
]
PythonStep 7: Migrate Your Database
Run migrations to apply changes:
python manage.py makemigrations accounts
python manage.py migrate
PythonStep 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',
),
}
PythonAPI 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