AbstractUser
และ AbstractBaseUser
ให้ inheritModelBackend
เป็น defaultAuthenticationMiddleware
เพิ่ม request.user
attributeSessionMiddleware
จัดการ session ของผู้ใช้MIDDLEWARE
settingAbstractUser
หรือ AbstractBaseUser
USERNAME_FIELD
(field ที่ใช้ login)REQUIRED_FIELDS
(fields ที่ต้องกรอกตอน createsuperuser)
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
phone_number = models.CharField(max_length=15, blank=True)
birthdate = models.DateField(null=True, blank=True)
USERNAME_FIELD = 'email' # ใช้ email ในการ login
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
def __str__(self):
return self.email
AUTH_USER_MODEL
ใน settings.py
makemigrations
และ migrate
หลังจากสร้าง custom user model
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from myapp.models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'phone_number') # fields ที่ต้องการใน form
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email', 'phone_number')
from django.shortcuts import render, redirect
from myapp.forms import CustomUserCreationForm
def register_view(request):
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save() # สร้าง user ใหม่
return redirect('login') # Redirect ไปหน้า login
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form})
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
AUTH_USER_MODEL
ใน settings.py
แล้วmakemigrations
และ migrate
แล้ว{% csrf_token %}
ใน template form เสมอเพื่อป้องกัน CSRF attacks
from django import forms
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].widget.attrs.update({'class': 'form-control'})
self.fields['password'].widget.attrs.update({'class': 'form-control'})
* Inherit จาก AuthenticationForm
* สามารถปรับแต่ง widgets ของ fields ได้
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from .forms import LoginForm
def login_view(request):
if request.method == 'POST':
form = LoginForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('home') # Redirect ไปหน้า home
else:
return render(request, 'login.html', {'form': form, 'error': 'Invalid username or password'})
else:
form = LoginForm()
return render(request, 'login.html', {'form': form})
* ใช้ authenticate()
เพื่อตรวจสอบ username/password
* ใช้ login()
เพื่อสร้าง session ให้กับ user
* Redirect ไปยังหน้า home
หาก login สำเร็จ
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
{% if error %}
<p style="color:red">{{ error }}</p>
{% endif %}
</form>
from django.shortcuts import redirect
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect('home') # Redirect ไปหน้า home
* ใช้ logout()
เพื่อ clear session ของผู้ใช้
* Redirect ไปยังหน้า home
หลังจาก logout
from django.urls import path
from . import views
urlpatterns = [
path('logout/', views.logout_view, name='logout'),
]
* Map URL /logout/
ไปยัง view function logout_view
<a href="{% url 'logout' %}">Logout</a>
* สร้าง link ไปยังหน้า logout โดยใช้ {% url 'logout' %}
login_required
Decorator (FBV)
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required
def my_protected_view(request):
# code ที่ต้องการการ login
return render(request, 'protected.html')
* ใช้ @login_required
decorator เพื่อบังคับให้ผู้ใช้ต้อง login ก่อนเข้า view นี้
* หากผู้ใช้ยังไม่ได้ login จะถูก redirect ไปยังหน้า login (default: /accounts/login/
)
LoginRequiredMixin
(CBV)
from django.views.generic import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
class MyProtectedView(LoginRequiredMixin, View):
def get(self, request):
# code ที่ต้องการการ login
return render(request, 'protected.html')
* ใช้ LoginRequiredMixin
เพื่อบังคับให้ผู้ใช้ต้อง login ก่อนเข้า view นี้
* Inherit LoginRequiredMixin
ก่อน View
LOGIN_REDIRECT_URL = 'home' # หน้าที่จะ redirect ไปหลังจาก login สำเร็จ
LOGIN_URL = 'login' # ชื่อ url pattern ของหน้า login
* กำหนด LOGIN_REDIRECT_URL
เพื่อกำหนดหน้าที่จะ redirect ไปหลังจาก login สำเร็จ
* กำหนด LOGIN_URL
เพื่อกำหนด URL pattern ของหน้า login
from django.contrib.auth import authenticate
user = authenticate(username='myuser', password='mypassword')
if user is not None:
# Login สำเร็จ
pass
else:
# Login ไม่สำเร็จ
pass
* ใช้ authenticate()
function เพื่อตรวจสอบ password
* Django จะตรวจสอบ password โดยใช้ hashing algorithm เดียวกัน
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from myapp.models import Article # สมมติว่ามี Model ชื่อ Article
# สร้าง Role "Editor"
editor_group = Group.objects.create(name='Editor')
# กำหนด Permission "can_edit_article" ให้กับ Role "Editor"
content_type = ContentType.objects.get_for_model(Article)
can_edit_article = Permission.objects.create(
codename='can_edit_article',
name='Can Edit Article',
content_type=content_type,
)
editor_group.permissions.add(can_edit_article)
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required('myapp.can_edit_article') # ต้องมี permission ถึงจะเข้าได้
def edit_article(request, article_id):
# code สำหรับแก้ไข article
pass
{% if user.has_perm "myapp.can_edit_article" %}
<a href="{% url 'edit_article' article.id %}">Edit</a>
{% endif %}
accounts
)