Django自定义用户is_active默认设为False:前两种方法失效原因咨询
is_active=False方法失效的原因 1. 在管理器_create_user中直接设置user.is_active = False无效
Django Admin创建用户的流程并非完全受自定义管理器逻辑控制:当使用默认UserAdmin或其子类时,Admin会通过表单收集数据初始化用户实例,部分内部逻辑可能在保存前再次覆盖字段值。
更核心的原因是:若你的自定义用户模型继承自AbstractUser或AbstractBaseUser,is_active字段本身的默认值为True。如果Admin创建用户时,表单未传递is_active参数(默认UserCreationForm不包含该字段),实例初始化会先使用字段默认的True;即便你在_create_user中手动设为False,Admin的权限校验、字段同步等内部操作仍可能将其重置为True。
另外,若你自定义了Admin的save_model方法并显式设置is_active=True,也会直接覆盖管理器中的设置。
2. 使用extra_fields.setdefault('is_active', False)无效
dict.setdefault()的逻辑是仅当键不存在时才设置默认值。Admin创建用户时,若你的Admin配置(比如add_fieldsets)包含is_active字段,表单提交会主动传入is_active=True(默认勾选状态)到extra_fields;即便表单不包含该字段,继承自AbstractUser的模型会自动将字段默认的True注入实例,导致extra_fields中已存在is_active键,setdefault的默认值设置完全不会触发。
为什么重新定义is_active字段生效?
当你在CustomUser类中重新定义is_active字段并设置default=False时,直接覆盖了父类中该字段的默认配置:
- 若Admin表单未传递
is_active参数,实例会直接使用你定义的False作为默认值; - 若表单包含该字段,其初始勾选状态会被字段的
default值影响(默认变为未勾选),提交时会传递False(除非手动勾选)。
这种方式修改了字段的底层默认规则,优先级远高于管理器逻辑或Admin表单默认值,因此能确保生效。
内容的提问来源于stack exchange,提问作者Omid Shojaee

