我正在覆盖 django 的默认用户模型。我尝试将用户配置文件与 CustomUser 模型链接起来,并添加了一个接收器,当根据角色创建用户时,该接收器将自动创建配置文件模型的实例
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
from django.db.models.signals import post_save
# Create your models here.
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_("email"),primary_key=True,unique=True,blank=False,null=False)
phone_number = models.CharField(max_length=10,null=False,blank=False)
ROLE_CHOICES = (
('ADMIN', 'ADMIN'),
('STUDENT','STUDENT'),
('TEACHER', 'TEACHER'),
('PRINCIPAL', 'PRINCIPAL'),
)
role = models.CharField(choices=ROLE_CHOICES, blank=True,default='ADMIN',max_length=10)
REQUIRED_FIELDS = ['phone_number','first_name','last_name']
USERNAME_FIELD = "email"
objects = CustomUserManager()
def __str__(self):
return self.email
class StudentProfile(models.Model):
user = models.OneToOneField(CustomUser,on_delete=models.CASCADE)
id = models.AutoField(primary_key=True,unique=True)
merit = models.CharField(max_length=6,blank=True,null=True)
def __str__(self):
return self.user.email
class TeacherProfile(models.Model):
user = models.OneToOneField(CustomUser,on_delete=models.CASCADE)
id = models.AutoField(primary_key=True,unique=True)
salary = models.CharField(max_length=6,blank=True,null=True)
education = models.CharField(max_length=100,blank=True,null=True)
def __str__(self):
return self.user.email
class PrincipalProfile(models.Model):
user = models.OneToOneField(CustomUser,on_delete=models.CASCADE)
id = models.AutoField(primary_key=True,unique=True)
salary = models.CharField(max_length=6,blank=True,null=True)
education = models.CharField(max_length=100,blank=True,null=True)
years_of_experience = models.IntegerField(null=True, blank=True)
def __str__(self):
return self.user.email
@receiver(post_save, sender=CustomUser)
def create_user_profile(sender, instance, created, **kwargs):
if created:
if instance.role == 'PRINCIPAL':
PrincipalProfile.objects.create(user=instance)
elif instance.role == 'STUDENT':
StudentProfile.objects.create(user=instance)
elif instance.role == 'TEACHER':
TeacherProfile.objects.create(user=instance)
else:
pass
else:
print("Profile not created")
作为编码新手,我已经编写了我的第一段代码,并且正在寻求社区的专业知识来审查其合法性并就潜在的改进提出建议。非常感谢您的指导!
您不需要包含
id = models.AutoField(primary_key=True,unique=True)
。 Django 为你做:
默认情况下,Django 给每个模型一个自动递增的主键...
Django 字段的 null 和 blank 默认值为 False,因此您可以避免显式指定它。它不会影响代码的可理解性,因为它确实很常见。
您的配置文件模型具有相似的字段和功能,因此我将创建单独的类来继承,并将其 Meta 的属性 abstract 设置为 True。它阻止在数据库中创建相应的表。
class AbstractProfile(models.Model):
user = models.OneToOneField(CustomUser,on_delete=models.CASCADE)
def __str__(self):
return self.user.email
class Meta:
abstract = True
因此,您可以避免重复代码并确保配置文件的完整性。
我不知道你这样做是否是为了可读性,但通常信号存储在单独的称为handlers.py中。可以在与模型相同的文件中创建简单的管理器
我不知道你是否想要它,但目前你的用户可以同时拥有学生、教师等个人资料(至少在数据库级别)。