I tried to create custom user with AbstractBaseUser in django:
class UserManager(BaseUserManager):
"""
Custom user manager that allows you to create new users
"""
def create_user(self, username, password, **extra_fields):
"""
Creates and saves a new user with the given username and password
"""
if not username:
raise ValueError(_('Username is required'))
user = self.model(username=username, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, password, **extra_fields):
"""
Creates and saves a new superuser with the given username and password
"""
extra_fields.setdefault('is_active', True)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('is_staff=True'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('is_superuser=True'))
return self.create_user(username, password, **extra_fields)
class User(AbstractBaseUser, PermissionsMixin):
ROLE_CHOICES = (
('admin', 'Admin'),
('teacher', 'Teacher'),
('parent', 'Parent'),
('student', 'Student')
)
username = models.CharField(max_length=50, unique=True)
role = models.CharField(max_length=10, choices=ROLE_CHOICES)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.username
I want users to be able to have only one role, for example, they can only be students or teachers.
I know that I can use groups to give different permissions to each user, but my problem is that each type of user has different fields, for example, the fields that a teacher can have are different from a student, and I don’t know how to do this.
Of course, users can have common fields. For example, I created the following model for common fields:
class Profile(models.Model):
image = models.ImageField(upload_to='profile_pics/', blank=True, null=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profiles')
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
national_code = models.CharField(max_length=10, validators=[national_code_validator], unique=True, blank=True,
null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def get_full_name(self):
return f'{self.first_name} {self.last_name}'
def __str__(self):
return self.get_full_name()
But I don’t know what to do to have different fields in the Profile for different roles in addition to these common fields. please help.