Django医生预约系统:注册时is_user/is_doctor无法设为True求助
问题根源与修复
你的代码存在两个核心问题导致is_user和is_doctor无法被正确设置:
- 模型类中的无效赋值:
User_reg和dr_reg里的User.is_user = True、user.is_doctor = True是类定义阶段的无效赋值,不会作用到实际创建的用户实例上。 - 视图中未设置用户类型字段:创建
User实例后,你没有手动将is_user或is_doctor设为True,因此它们保持默认的False值。
以下是具体修正步骤:
1. 修正models.py
from django.db import models from django.contrib.auth.models import AbstractUser # 继承AbstractUser,无需重复定义first_name/last_name(AbstractUser已自带) class User(AbstractUser): is_user = models.BooleanField(default=False, verbose_name='是否为患者') is_doctor = models.BooleanField(default=False, verbose_name='是否为医生') # 患者扩展信息模型,删除冗余的用户名/密码字段 class UserReg(models.Model): user = models.OneToOneField('User', on_delete=models.CASCADE, primary_key=True) email = models.EmailField(max_length=100, blank=False) address = models.TextField(max_length=500, blank=False) gender = models.CharField(max_length=7, blank=False) phone = models.CharField(max_length=12, unique=True, blank=False) def __str__(self): return self.user.first_name # 医生扩展信息模型,修正类名规范,删除冗余字段 class DrReg(models.Model): user = models.OneToOneField('User', on_delete=models.CASCADE, primary_key=True) image = models.ImageField(upload_to='doctor_avatars/', verbose_name='医生头像') specialisation = models.CharField(max_length=100, blank=False, verbose_name='专业') qualificaton = models.CharField(max_length=100, blank=False, verbose_name='资质') phone = models.CharField(max_length=12, blank=False, unique=True) gender = models.CharField(max_length=7, blank=False) address = models.TextField(max_length=500, blank=False) state = models.CharField(max_length=50, blank=False) city = models.CharField(max_length=50, blank=False) zip = models.CharField(max_length=50, blank=False) email = models.EmailField(max_length=50, blank=False) def __str__(self): return self.user.first_name
- 移除
User模型中重复的first_name/last_name字段 - 删除
UserReg和DrReg中冗余的用户名、密码字段(这些信息已存储在关联的User实例中) - 给
ImageField添加upload_to参数,指定图片上传路径
2. 修正views.py
from django.shortcuts import render from django.contrib import messages from .models import User, UserReg, DrReg def register(request): if request.method == "POST": fname = request.POST.get('fname') lname = request.POST.get('lname') email = request.POST.get('email') address = request.POST.get('add') gender = request.POST.get('sex') phone = request.POST.get('phone') username = request.POST.get('uname') userpassword = request.POST.get('upass') # 创建用户并设置患者标识 myuser = User.objects.create_user(username, email, userpassword) myuser.first_name = fname myuser.last_name = lname myuser.is_user = True # 关键:设置is_user为True myuser.save() UserReg.objects.create( user=myuser, email=email, address=address, gender=gender, phone=phone ) messages.success(request, '注册成功') return render(request,'user/login.html') else: return render(request, 'user/register.html') def dr_register(request): if request.method == "POST": fname = request.POST.get('dfname') lname = request.POST.get('dlname') # 图片需从request.FILES获取,且前端表单需添加enctype="multipart/form-data" image = request.FILES.get('img') qualification = request.POST.get('qualification') specialist = request.POST.get('specialisation') phone = request.POST.get('dphone') gender = request.POST.get('dsex') address = request.POST.get('dadd') state = request.POST.get('state') city = request.POST.get('city') zip = request.POST.get('zip') email = request.POST.get('demail') dr_username = request.POST.get('duname') dr_password = request.POST.get('dpass') # 创建用户并设置医生标识 mydoctor = User.objects.create_user(dr_username, email, dr_password) mydoctor.first_name = fname mydoctor.last_name = lname mydoctor.is_doctor = True # 关键:设置is_doctor为True mydoctor.save() DrReg.objects.create( user=mydoctor, image=image, qualificaton=qualification, specialisation=specialist, phone=phone, gender=gender, address=address, state=state, city=city, zip=zip, email=email ) messages.success(request, '注册成功') return render(request, 'doctor/login.html') else: return render(request, 'doctor/register.html')
- 创建
User实例后,手动设置is_user/is_doctor为True并保存 - 医生注册的图片字段改为从
request.FILES获取(需确保前端表单添加enctype="multipart/form-data"属性) - 移除冗余的用户名、密码参数传递
后续开发优化建议
- 使用Django表单类:用
forms.ModelForm替代手动处理POST数据,自动完成字段验证和数据清洗,减少重复代码,例如创建UserRegForm和DrRegForm关联对应模型。 - 优化用户类型设计:用枚举字段替代两个布尔字段,避免出现同时为患者和医生的异常情况:
class User(AbstractUser): USER_TYPE_CHOICES = ( ('PATIENT', '患者'), ('DOCTOR', '医生'), ) user_type = models.CharField(max_length=10, choices=USER_TYPE_CHOICES, default='PATIENT') - 使用信号自动创建扩展信息:通过Django的
post_save信号,在创建User实例时自动生成对应的UserReg或DrReg,解耦业务逻辑。 - 密码安全:绝对不要在扩展模型中存储明文密码,
User.objects.create_user已自动对密码进行哈希处理。 - 权限控制:自定义装饰器或使用Django权限系统,限制患者和医生的访问路径,例如仅医生可访问预约管理页面。
- 邮箱验证:注册后发送验证邮件,要求用户激活账号,避免无效注册。
- 图片上传配置:在
settings.py中配置MEDIA_ROOT和MEDIA_URL,确保图片正确上传和访问:
并在项目MEDIA_ROOT = BASE_DIR / 'media' MEDIA_URL = '/media/'urls.py中添加媒体文件路由。 - 错误处理:捕获
IntegrityError等异常,处理用户名/手机号重复的情况,返回友好的错误提示。 - 代码规范:遵循PEP8规范,变量名用小驼峰,模型类名用大驼峰,添加必要注释。
内容的提问来源于stack exchange,提问作者Ashraf Patel
相关产品推荐
相关产品推荐

