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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:24:26