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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:15:57