Cả 2 đều cho phép thay auth.User mặc định, khác nhau ở mức độ phải tự viết.
AbstractUser giữ nguyên schema của User (username, first_name, last_name, email, is_staff, is_active...), bạn chỉ thêm field hoặc tinh chỉnh nhẹ — dùng khi vẫn muốn giữ username và admin có sẵn. AbstractBaseUser thì gần như trắng — chỉ có password + last_login. Bạn tự định nghĩa identity field (email, phone), tự viết Manager (create_user, create_superuser), tự thêm is_active/is_staff nếu cần — dùng khi muốn login bằng email, schema gọn, không cần username.
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
full_name = models.CharField(max_length=120)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager() # custom manager với create_user / create_superuser
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name']Xong nhớ set AUTH_USER_MODEL = 'accounts.User' trước lần migrate đầu tiên.
Và mọi ForeignKey(User, ...) trong code dự án phải đổi sang ForeignKey(settings.AUTH_USER_MODEL, ...) để app reusable không hard-code reference.
Both let you replace the default auth.User, but the amount of work differs:
AbstractUser= keeps theUserschema (username,first_name,last_name,email,is_staff,is_active...), you only add fields or tweak slightly. Use it when username + bundled admin still fit.AbstractBaseUser= onlypassword+last_login. You define the identity field (email,phone), write the Manager (create_user,create_superuser), addis_active/is_staffif needed. Use it when login is by email, schema is lean, no username.
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
full_name = models.CharField(max_length=120)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager() # custom manager with create_user / create_superuser
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name']Then set AUTH_USER_MODEL = 'accounts.User' before the first migrate.
Pitfall: Every ForeignKey(User, ...) in the project must be ForeignKey(settings.AUTH_USER_MODEL, ...) so reusable apps do not hard-code the reference.