Django模型与序列化器报错:Column 'dso_id' cannot be null 求助
解决Django REST Framework注册时
dso_id不能为空的错误 错误(1048, "Column 'dso_id' cannot be null")源于代码中多处逻辑疏漏,导致创建用户时dso字段未被正确赋值,以下是具体修复方案:
1. 修正User模型的dso字段定义
你的User模型中dso字段同时设置了blank=False(表示表单层面必填)和default=NULL,这本身存在矛盾。且ForeignKey默认null=False,数据库会强制该字段不为空。如果dso是业务必填项,应去掉default=NULL:
# Models.py class User(models.Model): # 移除default=NULL,保留blank=False确保必填 dso = models.ForeignKey(Dso, related_name='dso', blank=False, on_delete=models.CASCADE) # 其他字段保持不变...
2. 修复UserManager的create_user方法
create_user方法参数包含dso、name等字段,但内部未将这些参数赋值给user对象,导致保存时字段为空:
# Models.py class UserManager(BaseUserManager): def create_user(self, username, email, name, address, roleId, customerId, dso, password=None): if username is None: raise TypeError('User should have a username') if email is None: raise TypeError('Users should have an Email') # 将所有必填参数传入model构造器 user = self.model( username=username, email=self.normalize_email(email), name=name, address=address, roleId=roleId, customerId=customerId, dso=dso ) user.set_password(password) user.save() return user
注意:原参数列表中dso password=None缺少逗号,已补充。
3. 修正create_superuser方法
创建超级用户时,需向create_user传递所有必填参数,否则会触发同样的非空错误:
# Models.py def create_superuser(self, username, email, dso, password=None): if password is None: raise TypeError('User should have a password') # 按业务逻辑设置超级用户的默认参数 user = self.create_user( username, email, name='Admin', address='Admin Address', roleId=0, # 假设0为管理员角色ID customerId='admin', dso=dso, password=password ) user.is_superuser = True user.is_staff = True user.save() return user
4. 确保Serializer与View传递dso数据
你的RegisterSerializer已包含dso字段,前端请求时需传入对应Dso对象的ID(ModelSerializer默认接收ForeignKey的ID值)。示例请求JSON:
{ "email": "user@example.com", "username": "testuser", "password": "testpass123", "name": "Test User", "address": "Test Address", "customerId": "test123", "dso": 1, // 对应Dso对象的ID "roleId": 1 }
额外优化建议
- 你的User模型未继承
AbstractBaseUser和PermissionsMixin,这会导致set_password、is_superuser等Django内置认证功能异常。建议修改模型继承:
# Models.py from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin class User(AbstractBaseUser, PermissionsMixin): # 你的字段定义... USERNAME_FIELD = 'username' # 设置登录用的字段 REQUIRED_FIELDS = ['email', 'dso'] # createsuperuser命令必填字段
dateJoined字段可设置auto_now_add=True,自动记录用户创建时间:
dateJoined = models.DateTimeField(auto_now_add=True)
完成以上修复后,注册功能即可正常运行,不再出现dso_id cannot be null错误。
内容的提问来源于stack exchange,提问作者Melody
相关产品推荐
相关产品推荐

