You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django医生预约系统:注册时is_user/is_doctor无法设为True求助

问题根源与修复

你的代码存在两个核心问题导致is_user和is_doctor无法被正确设置:

  1. 模型类中的无效赋值:User_reg和dr_reg里的User.is_user = True、user.is_doctor = True是类定义阶段的无效赋值,不会作用到实际创建的用户实例上。
  2. 视图中未设置用户类型字段:创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 20:45:46