Django新用户自动加入所有组且无法移除问题求助
Django自定义用户创建异常:自动加入所有组且无法移除
问题场景
我正在开发第一个Django项目,创建用户时遇到异常:新用户会被自动加入所有组,且在管理面板中也无法将其从组中移除。
相关代码
views.py
class registerCrispyForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(registerCrispyForm, self).__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.form_method = 'POST' self.helper.add_input(Submit('submit', 'Submit')) class Meta: model = models.UserExt fields = ('username', 'password') def register(request): template_name = 'gestionePrenotazioni/login.html' formR = registerCrispyForm(request.POST) context = {'formRegister':formR} if request.method == 'POST': if formR.is_valid(): user = formR.save() user.set_password(request.POST['password']) user.save() return redirect("home") return render(request, template_name, context)
models.py
class UserExt(AbstractUser): Image = models.ImageField(upload_to='media/users') abbonamento = models.DateField(null=True, blank=True) class Meta: verbose_name_plural = 'Utenti'
已尝试的无效操作
- 调用
user.groups.clear()无法清除用户所属组 - 手动尝试将用户加入单个组,无任何效果
问题排查与解决方法
1. 修正视图初始化逻辑
当前视图中无论请求方法是GET还是POST,都直接用request.POST初始化表单,这会导致GET请求时表单绑定空数据,同时form.save()直接保存对象的逻辑可能引发意外关联。调整视图代码:
def register(request): template_name = 'gestionePrenotazioni/login.html' if request.method == 'POST': formR = registerCrispyForm(request.POST) if formR.is_valid(): # 创建用户但暂不保存到数据库 user = formR.save(commit=False) # 使用表单清洗后的密码设置(更安全) user.set_password(formR.cleaned_data['password']) # 强制清除所有组关联 user.groups.clear() user.save() return redirect("home") else: # GET请求初始化空表单 formR = registerCrispyForm() context = {'formRegister':formR} return render(request, template_name, context)
2. 显式排除表单中的组字段
虽然表单fields只声明了username和password,但AbstractUser自带的groups字段可能被隐式包含,显式排除它避免意外赋值:
class registerCrispyForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(registerCrispyForm, self).__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.form_method = 'POST' self.helper.add_input(Submit('submit', 'Submit')) class Meta: model = models.UserExt fields = ('username', 'password') exclude = ('groups', 'user_permissions') # 排除组和权限字段
3. 检查Admin配置
如果管理面板无法修改用户组,检查admin.py中是否有强制关联组的逻辑:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import UserExt class UserExtAdmin(UserAdmin): # 确保save_model方法没有强制添加组的代码 def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) admin.site.register(UserExt, UserExtAdmin)
4. 排查信号(Signals)
项目中如果存在post_save信号,可能在用户创建后自动关联所有组。检查是否有类似代码,如有则删除或修改:
# 示例:错误的信号逻辑,需删除或调整 # from django.db.models.signals import post_save # from django.dispatch import receiver # from .models import UserExt # from django.contrib.auth.models import Group # @receiver(post_save, sender=UserExt) # def add_user_to_all_groups(sender, instance, created, **kwargs): # if created: # groups = Group.objects.all() # instance.groups.add(*groups)
内容的提问来源于stack exchange,提问作者Pini02
相关产品推荐
相关产品推荐

