Django创建超级用户报错:cid_id字段不可为空,求解决方案
解决Django自定义用户创建超级用户时外键非空报错问题
方案1:给cid字段设置默认值
修改users/models.py中的cid字段,添加default参数指向一个已存在的Category实例(需确保该实例已在数据库中存在,可通过手动添加或数据迁移提前创建)。
修改后的模型代码:
from django.db import models from blog.models import Category from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): # 替换为你数据库中实际存在的Category的id,比如第一个分类的id=1 cid = models.ForeignKey(Category, on_delete=models.CASCADE, default=1) profile_pic = models.ImageField(default='default_person.jpg', upload_to='profile_pics')
执行数据库迁移:
python manage.py makemigrations python manage.py migrate
此后使用createsuperuser命令时,系统会自动填充默认分类,不会触发非空约束报错;普通用户注册时仍可通过表单强制要求选择分类。
方案2:自定义超级用户创建表单
通过重写用户创建表单,让创建超级用户时能手动选择或自动填充Category。
步骤1:创建自定义表单(users/forms.py)
from django.contrib.auth.forms import UserCreationForm from .models import CustomUser from blog.models import Category class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ('username', 'email', 'cid', 'password1', 'password2') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 自动填充第一个分类作为默认值 self.fields['cid'].initial = Category.objects.first()
步骤2:在admin中注册自定义表单(users/admin.py)
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser from .forms import CustomUserCreationForm class CustomUserAdmin(UserAdmin): add_form = CustomUserCreationForm fieldsets = ( *UserAdmin.fieldsets, ( '额外信息', { 'fields': ('cid', 'profile_pic',) } ) ) admin.site.register(CustomUser, CustomUserAdmin)
设置完成后,在后台创建超级用户时会显示分类选择字段,也会自动填充默认值,避免报错。
方案3:允许cid为空,但在注册表单中强制必填
修改模型让cid允许为空,同时在普通用户注册表单中强制要求填写分类。
修改后的模型代码:
class CustomUser(AbstractUser): cid = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True) profile_pic = models.ImageField(default='default_person.jpg', upload_to='profile_pics')
创建普通用户注册表单(users/forms.py):
from django import forms from .models import CustomUser class UserRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput) password2 = forms.CharField(widget=forms.PasswordInput, label='确认密码') class Meta: model = CustomUser fields = ('username', 'email', 'cid') def clean_password2(self): cd = self.cleaned_data if cd['password'] != cd['password2']: raise forms.ValidationError('密码不匹配') return cd['password2'] def clean_cid(self): cid = self.cleaned_data.get('cid') if not cid: raise forms.ValidationError('必须选择分类') return cid
这种方式下,创建超级用户时可留空cid,但需注意后续业务逻辑中处理cid为空的场景,避免出现异常。
内容的提问来源于stack exchange,提问作者Sudipta Bhatta
相关产品推荐
相关产品推荐

