如何在Django中为不同类型用户创建带专属字段的模型?
Django 医生/护士用户模型解决方案
你的代码核心思路没问题,但无法运行通常是因为遗漏了关键配置和数据一致性保障,下面是修正后的完整可行方案:
1. 必须配置自定义用户模型
在项目的settings.py中添加以下配置,告知Django使用你定义的User作为认证用户模型:
AUTH_USER_MODEL = '你的应用名.User' # 示例:若应用名为hospital,则写 AUTH_USER_MODEL = 'hospital.User'
注意:该配置必须在第一次执行迁移前设置;若已做过迁移,需清空数据库或重置迁移记录,否则会引发冲突。
2. 修正后的完整模型代码
保留原模型的基础结构,同时添加唯一性约束和信号机制,避免用户类型与对应档案不匹配的问题:
from django.db import models from django.contrib.auth.models import AbstractUser from django.db.models.signals import post_save from django.dispatch import receiver class User(AbstractUser): USER_TYPE_CHOICES = ( (1, '医生'), (2, '护士'), ) user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES, verbose_name='用户类型') class DoctorProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='doctor_profile') doctor_id = models.CharField(max_length=6, unique=True, verbose_name='医生编号') dept = models.CharField(max_length=255, verbose_name='所属科室') def __str__(self): return f"{self.user.username} - {self.dept}" class NurseProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='nurse_profile') nurse_id = models.CharField(max_length=6, unique=True, verbose_name='护士编号') def __str__(self): return f"{self.user.username} - 护士" # 信号:创建用户时自动生成对应类型的档案 @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: if instance.user_type == 1: DoctorProfile.objects.create(user=instance) elif instance.user_type == 2: NurseProfile.objects.create(user=instance) # 信号:更新用户时同步保存对应档案 @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): if instance.user_type == 1: instance.doctor_profile.save() elif instance.user_type == 2: instance.nurse_profile.save()
3. 关键优化说明
- 添加
related_name:可通过用户实例直接获取对应档案,例如user.doctor_profile或user.nurse_profile - 编号字段加
unique=True:避免重复的医生/护士编号 - 信号机制:确保用户创建时自动生成对应档案,避免数据不一致
- 优化
__str__方法:让模型在后台管理界面显示更清晰的标识
4. 使用示例
创建医生用户:
from django.contrib.auth import get_user_model User = get_user_model() doctor = User.objects.create_user(username='dr_zhang', password='123456', user_type=1) # 补充医生信息 doctor.doctor_profile.doctor_id = 'D00001' doctor.doctor_profile.dept = '内科' doctor.doctor_profile.save()
创建护士用户:
nurse = User.objects.create_user(username='nurse_li', password='123456', user_type=2) nurse.nurse_profile.nurse_id = 'N00001' nurse.nurse_profile.save()
5. 常见问题排查
- 迁移报错:检查是否已设置
AUTH_USER_MODEL,且无旧用户模型的迁移记录 - 信号不生效:确保信号代码在
models.py中,或在apps.py中完成信号注册 - 数据不一致:可通过数据库检查约束进一步限制,但ORM层面的信号已能覆盖绝大多数场景
内容的提问来源于stack exchange,提问作者Prakriti Saraf
相关产品推荐
相关产品推荐

