Một custom user model thay thế User mặc định của Django để phù hợp nhu cầu ứng dụng của bạn — thêm field, thay đổi định danh đăng nhập (vd: email thay vì username), hoặc tùy biến hành vi. Lời khuyên then chốt, hay được nhắc lại: thiết lập một custom user model ngay từ đầu của một dự án, dù bạn chưa cần thay đổi, vì thay đổi nó về sau cực kỳ đau đớn.
Tại sao: User mặc định bị giới hạn và khó thay đổi về sau
User mặc định có các field cố định (username, email, first/last name) và dùng
USERNAME làm field đăng nhập. Các app thực thường cần:
✓ Đăng nhập dựa trên email (không username)
✓ Field bổ sung (phone, avatar, role, preferences) ngay trên user
✓ Hành vi xác thực tùy biến
Lý do then chốt để làm điều đó TRƯỚC
⚠️ Thay đổi user model SAU KHI migration đã tồn tại RẤT khó — User model được
tham chiếu bởi auth, admin, session, foreign key khắp database.
Hoán đổi nó về sau đòi hỏi các data migration phức tạp, rủi ro.
→ LUÔN định nghĩa một custom user model ngay từ ĐẦU dự án (trước migration đầu tiên),
dù là một cái rỗng, để bạn có thể mở rộng nó tự do về sau. Tài liệu của Django
khuyến nghị mạnh điều này cho MỌI dự án mới.
Đây là bài học thực tế then chốt: nó gần như không tốn gì để thiết lập một custom user model vào ngày đầu, nhưng lắp ngược một cái vào một dự án đã thành lập là một công việc lớn, dễ lỗi — nên bạn làm nó trước như một bảo hiểm.
Cách: mở rộng AbstractUser (cách dễ)
# models.py — thêm field, giữ hành vi auth của Django
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
avatar = models.ImageField(upload_to="avatars/", blank=True)
is_premium = models.BooleanField(default=False)
# settings.py — bảo Django dùng nó
AUTH_USER_MODEL = "myapp.User"
AbstractUser giữ tất cả các field mặc định và bộ máy auth của Django — bạn chỉ thêm field. Cách tiếp cận đơn giản nhất, phổ biến nhất.
Cách: AbstractBaseUser (kiểm soát đầy đủ, vd đăng nhập email)
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
USERNAME_FIELD = "email" # đăng nhập bằng EMAIL thay vì username
REQUIRED_FIELDS = []
objects = CustomUserManager() # một manager định nghĩa create_user/create_superuser
AbstractBaseUser cho kiểm soát đầy đủ trên user model (vd: loại bỏ username hoàn toàn cho đăng nhập chỉ-email) — nhiều công việc hơn, nhưng linh hoạt tối đa.
Tham chiếu user model đúng cách
from django.conf import settings
from django.contrib.auth import get_user_model
# trong model — tham chiếu qua settings.AUTH_USER_MODEL
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
# trong mã — lấy user model đang hoạt động một cách động
User = get_user_model() # KHÔNG phải import trực tiếp User mặc định
Luôn tham chiếu user model qua settings.AUTH_USER_MODEL (trong model) và get_user_model() (trong mã), không bao giờ bằng cách import trực tiếp User mặc định — để mã của bạn hoạt động với custom model.
Tại sao điều này quan trọng
Dùng một custom user model là kiến thức quan trọng với một bài học thực tế then chốt, thường được nhấn mạnh mà mọi lập trình viên Django nên ghi nhớ: thiết lập nó ngay từ đầu của mọi dự án.
Lý do điều này quan trọng đến vậy là sự bất đối xứng nghiêm trọng về độ khó — định nghĩa một custom user model vào ngày đầu (dù là một subclass AbstractUser rỗng) gần như không tốn gì và cung cấp sự linh hoạt vô giá, trong khi chuyển sang một custom user model sau khi dự án có migration và dữ liệu là cực kỳ đau đớn và rủi ro, vì User model được tham chiếu sâu khắp Django (xác thực, admin, session) và bởi foreign key xuyên toàn bộ database của bạn, đòi hỏi các data migration phức tạp, dễ lỗi để thay đổi.
Đây là lý do tài liệu của chính Django khuyến nghị mạnh một custom user model cho mọi dự án mới, bất kể nhu cầu trước mắt — nó là bảo hiểm chống lại một cơn ác mộng migration tương lai.
Ngoài lời khuyên timing then chốt này, hiểu cách tạo custom user model — AbstractUser để chỉ thêm field trong khi giữ hành vi auth của Django (trường hợp phổ biến, dễ), và AbstractBaseUser để kiểm soát đầy đủ như đăng nhập dựa trên email (loại bỏ username hoàn toàn) — có giá trị để đáp ứng các yêu cầu ứng dụng thực (field user bổ sung, định danh đăng nhập thay thế, auth tùy biến).
Quan trọng không kém là biết tham chiếu user model đúng cách (qua settings.AUTH_USER_MODEL và get_user_model(), không bao giờ import trực tiếp) để mã hoạt động với bất kỳ user model nào được cấu hình.
Vì gần như mọi ứng dụng thực đều có nhu cầu riêng về user vượt ra ngoài mặc định của Django (và ngay cả những cái không cũng hưởng lợi từ sự linh hoạt), và vì chi phí của việc không thiết lập điều này sớm rất cao, hiểu custom user model — đặc biệt là mệnh lệnh thiết lập một cái ngay từ đầu dự án — là kiến thức quan trọng, thiết yếu thực tế ngăn một sai lầm cấp dự án phổ biến và nghiêm trọng, khiến nó trở thành một mảnh trí khôn best-practice Django thường được trích dẫn.
