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

Django自定义用户模型报错:'NoneType' object is not callable 求助

解决Django自定义用户模型中self.model为None的TypeError问题

看起来你遇到的问题核心是直接实例化了CustomUserManager,而没有通过模型绑定的管理器来调用方法。让我一步步帮你分析和修复:

问题根源

在你的views.py里,你手动创建了CustomUserManager的实例:

user_creator = CustomUserManager()
user_creator.create_user(...)

但Django的Manager类是通过模型的objects = CustomUserManager()语句自动绑定到模型的。直接实例化的管理器没有关联到任何模型,所以self.model会是None,当你在create_user里调用self.model(...)时自然会抛出'NoneType' object is not callable的错误。

修复步骤

1. 修正视图中的用户创建逻辑

永远不要手动实例化管理器,直接使用CustomUser模型的objects属性——这是Django设计管理器的正确方式:

from django.shortcuts import render, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import authenticate, login
from .models import CustomUser  # 导入模型而非管理器

def index(request):
    if request.method == 'POST':
        # 判断是注册还是登录请求(通过是否存在password1字段区分)
        if 'password1' in request.POST:
            # 处理注册
            try:
                email = request.POST['email']
                username = request.POST['username']
                displayname = request.POST['displayname']
                password1 = request.POST['password1']
                password2 = request.POST['password2']

                # 调用模型绑定的管理器创建用户
                user = CustomUser.objects.create_user(
                    email=email,
                    user_name=username,
                    display_name=displayname,
                    password=password1,
                    password2=password2
                )
                messages.success(request, "注册成功!")
            except ValueError as e:
                messages.error(request, str(e))
        else:
            # 处理登录(使用Django自带的认证方法)
            email = request.POST['email']
            password = request.POST['password']
            # 注意:因为USERNAME_FIELD是email,所以authenticate的username参数传email
            user = authenticate(request, username=email, password=password)
            if user:
                login(request, user)
                messages.success(request, "登录成功!")
            else:
                messages.error(request, "邮箱或密码错误")
        return HttpResponseRedirect(request.path)
    return render(request, 'index.html')

2. 修复create_superuser方法的参数问题

你的create_superuser方法调用create_user时,缺少了user_name和display_name这两个必填参数,这会导致创建超级用户时失败。同时需要把这两个字段加入模型的REQUIRED_FIELDS,这样createsuperuser命令会提示输入它们:

修改managers.py的create_superuser:

def create_superuser(self, email, user_name, display_name, password, **extra_fields):
    """创建并保存带邮箱、用户名、昵称的超级用户"""
    extra_fields.setdefault('is_staff', True)
    extra_fields.setdefault('is_superuser', True)
    extra_fields.setdefault('is_active', True)

    if extra_fields.get('is_staff') is not True:
        raise ValueError(_('超级用户必须设置is_staff=True'))
    if extra_fields.get('is_superuser') is not True:
        raise ValueError(_('超级用户必须设置is_superuser=True'))
    
    # 调用create_user时传入所有必填参数,password2直接传password(超级用户不需要重复验证)
    return self.create_user(email, user_name, display_name, password, password, **extra_fields)

修改models.py的CustomUser:

REQUIRED_FIELDS = ['user_name', 'display_name']  # 添加必填字段

3. 推荐使用表单类处理请求(更安全规范)

你已经定义了CustomUserCreationForm,但没有充分利用它。表单类会自动处理字段验证、错误信息等,比手动读取POST数据更可靠:

更新forms.py的表单:

from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm):
        model = CustomUser
        fields = ('email', 'user_name', 'display_name')  # 加入自定义字段

class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = CustomUser
        fields = ('email', 'user_name', 'display_name')

用表单重构视图:

from django.shortcuts import render, HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import authenticate, login
from .forms import CustomUserCreationForm
from .models import CustomUser

def index(request):
    register_form = CustomUserCreationForm()
    if request.method == 'POST':
        if 'password1' in request.POST:
            # 注册逻辑:使用表单验证
            register_form = CustomUserCreationForm(request.POST)
            if register_form.is_valid():
                user = register_form.save()
                messages.success(request, "注册成功!")
                return HttpResponseRedirect(request.path)
        else:
            # 登录逻辑
            email = request.POST['email']
            password = request.POST['password']
            user = authenticate(request, username=email, password=password)
            if user:
                login(request, user)
                messages.success(request, "登录成功!")
            else:
                messages.error(request, "邮箱或密码错误")
        return HttpResponseRedirect(request.path)
    return render(request, 'index.html', {'register_form': register_form})

最后检查

做完这些修改后,记得:

  • 运行python manage.py makemigrations和python manage.py migrate确保模型变更生效
  • 测试注册和登录功能,确认错误不再出现

内容的提问来源于stack exchange,提问作者黒성배

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:12:57