Django用户更新表单role字段报错That choice is not one of the available choices
Django用户更新表单role字段可选值校验错误解决方案
- 第一步:先加调试代码定位问题
在UserUpdateForm的__init__方法中加入以下调试代码,确认过滤后的可选值和提交的值是否匹配:
def __init__(self, request, *args, **kwargs): super().__init__(*args, **kwargs) self.request = request # 新增调试代码 print("登录用户绑定的customer:", request.user.customer) if request.user.customer: role_qs = TbRole.objects.filter(customer=request.user.customer) print("过滤后的role可选ID:", list(role_qs.values_list('id', flat=True))) if 'role' in self.data: print("前端提交的role值:", self.data.get('role')) # 原有逻辑不变 if request.user.customer: self.fields['department'].queryset = TbDepartment.objects.filter( customer=request.user.customer) self.fields['role'].queryset = TbRole.objects.filter( customer=request.user.customer) # 后面的required配置不变
运行后查看控制台输出,确认提交的role值是否在过滤后的可选ID列表里。
- 第二步:修复动态过滤逻辑的边界问题
你当前的过滤逻辑仅使用当前登录用户的customer做过滤,存在两个边界问题:
- 若当前登录用户是平台管理员,未绑定customer,就不会触发role的过滤逻辑,字段默认会使用
TbRole.objects.all()作为可选值,若提交的role不在全量列表里就会报错 - 若你编辑的目标用户所属的customer和当前登录用户的customer不一致,目标用户原有role不属于当前登录用户的customer下的角色,也会触发校验错误
修复方案:优先取登录用户的customer,若为空则取目标编辑用户的customer作为过滤条件:
def __init__(self, request, *args, **kwargs): super().__init__(*args, **kwargs) self.request = request # 确定过滤用的customer filter_customer = request.user.customer # 如果登录用户没有绑定customer,且是编辑场景,取编辑用户的customer if not filter_customer and self.instance.pk: # 若TbUser没有直接关联customer,可通过self.instance.department.customer获取 filter_customer = self.instance.customer if filter_customer: self.fields['department'].queryset = TbDepartment.objects.filter(customer=filter_customer) self.fields['role'].queryset = TbRole.objects.filter(customer=filter_customer) # 原有required配置不变
- 第三步:校验字段类型匹配
检查TbRole的主键类型,如果是CharField,确认前端提交的role值格式是否和主键一致,避免出现整型字符串和字符型主键匹配失败的问题。 - 第四步:确认参数传递正常
检查视图的get_form_kwargs方法在POST请求时是否正常传递request参数,你当前的写法是没问题的,UpdateView无论是GET还是POST请求都会走这个方法注入request,不需要额外调整。
内容的提问来源于stack exchange,提问作者kakakakakakakk
相关产品推荐
相关产品推荐

