这是覆盖默认用户模型的合法方式吗

问题描述 投票:0回答:1

我正在覆盖 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")

作为编码新手,我已经编写了我的第一段代码,并且正在寻求社区的专业知识来审查其合法性并就潜在的改进提出建议。非常感谢您的指导!

django django-models django-forms django-users django-custom-user
1个回答
0
投票

自动字段的使用

您不需要包含

id = models.AutoField(primary_key=True,unique=True)
。 Django 为你做

默认情况下,Django 给每个模型一个自动递增的主键...

空白和空

Django 字段的 nullblank 默认值为 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中。可以在与模型相同的文件中创建简单的管理器

我不知道你是否想要它,但目前你的用户可以同时拥有学生、教师等个人资料(至少在数据库级别)。

© www.soinside.com 2019 - 2024. All rights reserved.