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

Django项目创建预订时出现"Cannot assign "<User: mhar>": "Booking.teacher" must be a "User" instance"错误求助

Django项目创建预订时出现"Cannot assign "<User: mhar>": "Booking.teacher" must be a "User" instance"错误求助

嘿,我来帮你捋捋这个问题!这个错误看起来有点反常识——<User: mhar>明明就是User实例啊,怎么会说不是呢?咱们一步步拆解问题:

最可能的核心原因:自定义User模型未配置全局识别

Django默认使用自带的auth.User模型,如果你自定义了User类但没在配置里声明,就会导致模型关联时出现「类型不匹配」的问题。先检查你的settings.py,有没有加这一行:

AUTH_USER_MODEL = '你的应用名.User'  # 比如你的app叫booking,就写'booking.User'

这一步是新手用自定义User模型最容易漏的,必须补上,否则Django会把默认User和你的自定义User当成两个完全不同的类,自然就会出现「无法赋值」的错误。

再来修正代码里的几个逻辑问题

1. 视图里的角色判断逻辑混乱

你在视图里用groups判断用户是否是老师,但你的User模型明明有专门的role字段,既多余又容易出错。而且你还把booking.teacher设为None,但你的Booking模型里teacher字段是必填的(没有blank=True/null=True),这也会触发错误。修改后的视图逻辑:

def booking_calendar(request):
    rooms = Room.objects.all()
    bookings = Booking.objects.all()

    if request.method == 'POST':
        form = BookingForm(request.POST)
        if form.is_valid():
            # 先验证用户身份:必须是已登录的老师
            if not request.user.is_authenticated or request.user.role != 'teacher':
                messages.error(request, '你没有权限以老师身份创建预订。')
                return redirect('booking_calendar')
            
            booking = form.save(commit=False)
            booking.teacher = request.user  # 已经验证过是老师,直接赋值即可
            booking.save()
            messages.success(request, '预订创建成功!')
            return redirect('booking_calendar')
        else:
            messages.error(request, '预订表单有误,请检查日期、时间等信息是否正确。')
    else:
        form = BookingForm()

    return render(request, 'booking_calendar.html', {'bookings': bookings, 'form': form, 'rooms': rooms})

2. 表单里的老师过滤逻辑不匹配

你在表单里用groups__name='teacher'过滤老师,但你的User模型是靠role字段区分角色的,这和模型里limit_choices_to={'role': 'teacher'}的设置不一致。修改表单的__init__方法:

class BookingForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 和模型的过滤条件保持一致,用role字段筛选老师
        self.fields['teacher'].queryset = User.objects.filter(role='teacher')

    # 其他代码保持不变...

额外优化:如果需要管理员代老师创建预订

如果你想让管理员能选择任意老师创建预订,而普通老师只能创建自己的预订,可以调整视图逻辑:

def booking_calendar(request):
    rooms = Room.objects.all()
    bookings = Booking.objects.all()

    if request.method == 'POST':
        form = BookingForm(request.POST)
        if form.is_valid():
            booking = form.save(commit=False)
            # 非管理员用户必须是老师,且只能选择自己作为预订人
            if not request.user.is_superuser:
                if request.user.role != 'teacher':
                    messages.error(request, '你没有权限创建预订。')
                    return redirect('booking_calendar')
                if booking.teacher != request.user:
                    messages.error(request, '你只能创建自己的预订。')
                    return redirect('booking_calendar')
            booking.save()
            messages.success(request, '预订创建成功!')
            return redirect('booking_calendar')
        else:
            messages.error(request, '预订表单有误,请检查后重试。')
    else:
        form = BookingForm()

    return render(request, 'booking_calendar.html', {'bookings': bookings, 'form': form, 'rooms': rooms})

先把AUTH_USER_MODEL配置好,再调整上面的代码,应该就能解决这个奇怪的错误啦!

备注:内容来源于stack exchange,提问作者BSIT-3E_GOLOSINDA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:44:30