Django视图中根据条件为用户设置is_staff权限的问题
解决Django注册表单根据自定义字段设置is_staff的问题
你触发的TypeError: 'UserRegistrationForm' object does not support item assignment错误,是因为你试图直接对表单对象做字典式的赋值操作(比如form['is_staff'] = True),但表单实例并不支持这种语法。正确的做法是操作表单生成的User模型实例,而不是表单本身。
下面提供两种可行的实现方案,你可以根据自己的代码结构选择:
方案1:在视图中处理逻辑
先通过表单的save(commit=False)方法获取未保存到数据库的User实例,修改其is_staff属性后再保存:
第一步:确认你的注册表单定义
确保表单正确继承UserCreationForm并添加了blogger字段:
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django import forms class UserRegistrationForm(UserCreationForm): blogger = forms.BooleanField(required=False, label="注册为博主(拥有后台管理权限)") class Meta: model = User fields = ['username', 'email', 'password1', 'password2', 'blogger']
第二步:修改视图逻辑
from django.shortcuts import render, redirect from .forms import UserRegistrationForm def register(request): if request.method == 'POST': form = UserRegistrationForm(request.POST) if form.is_valid(): # 获取未保存的用户实例(commit=False不写入数据库) user = form.save(commit=False) # 从表单验证后的cleaned_data中获取blogger字段值,设置is_staff user.is_staff = form.cleaned_data.get('blogger', False) # 保存用户到数据库 user.save() # 注册完成后跳转登录页 return redirect('login') else: form = UserRegistrationForm() return render(request, 'registration/register.html', {'form': form})
方案2:在表单类中重写save方法(推荐)
把业务逻辑封装在表单内部,让视图代码更简洁,也符合表单职责单一的原则:
修改表单类
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django import forms class UserRegistrationForm(UserCreationForm): blogger = forms.BooleanField(required=False, label="注册为博主(拥有后台管理权限)") class Meta: model = User fields = ['username', 'email', 'password1', 'password2', 'blogger'] def save(self, commit=True): # 调用父类方法获取未保存的用户实例 user = super().save(commit=False) # 根据blogger字段设置is_staff user.is_staff = self.cleaned_data.get('blogger', False) if commit: user.save() return user
视图代码可以保持简洁
from django.shortcuts import render, redirect from .forms import UserRegistrationForm def register(request): if request.method == 'POST': form = UserRegistrationForm(request.POST) if form.is_valid(): form.save() return redirect('login') else: form = UserRegistrationForm() return render(request, 'registration/register.html', {'form': form})
关键说明
- 使用
cleaned_data获取字段值:这是表单验证后的数据,比直接从request.POST取更安全,能避免未验证的原始数据导致的问题。 commit=False的作用:让表单生成User对象但不立即写入数据库,方便我们在保存前修改对象属性。
内容的提问来源于stack exchange,提问作者Abdul Rehman
相关产品推荐
相关产品推荐

