Django ManyToMany添加实例报错:字段值为None问题排查
问题原因
这个报错和时序无关,根源是Student模型的主键设计和对象创建顺序错误:
- 你将
Student的user字段设为了主键primary_key=True,这意味着Student实例的主键就是关联的CustomUser对象的主键,你在创建Student时没有给user字段赋值就直接调用save(),导致保存后的Student实例主键为None。往多对多关联插入中间表数据时,中间表需要存储Student的主键值,主键为空就会触发the value for field "student" is None报错。 - 额外还有一个逻辑错误:你当前代码中创建的默认
User对象没有和Student的user字段关联,且如果你的项目中CustomUser是继承自AbstractUser的自定义用户模型,你创建User的写法也不匹配关联字段要求。
修复方案
调整对象创建顺序,先创建关联的CustomUser对象,再将其赋值给Student的user字段后再保存Student,修改对应分支代码如下:
# 校验学生是否已存在 if not Student.objects.filter(student_number=sn).exists(): first = all_names.pop(0) last = "" for name in all_names: last = last + name + " " last = last[:-1] # 拼接学生属性 email_add = sn + "@bc.ca" nick = first + last[0] full = first + " " + last # 先创建/获取对应的CustomUser对象 if CustomUser.objects.filter(username=sn).exists(): user = CustomUser.objects.get(username=sn) else: user = CustomUser.objects.create_user(username=sn, email=email_add) user.last_name = last user.first_name = first user.save() # 创建Student时传入user作为主键 new_student = Student( user=user, student_last=last, student_first=first, student_number=sn, nickname=nick, fullname=full, email=email_add ) new_student.save() classblock.students.add(new_student)
补充说明
你在Django Shell中测试能成功,是因为你取出的Student实例是已经正确关联了CustomUser、拥有合法主键的对象,自然可以正常添加多对多关联。
内容的提问来源于stack exchange,提问作者Doug Smith
相关产品推荐
相关产品推荐

