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,提问作者黒성배
相关产品推荐
相关产品推荐

