Django中实现多对多字段(ManyToManyField)间赋值的问题处理
问题背景
我想要将StudentMeeting模型的current_courses多对多字段的值设置为Student模型的course多对多字段的值,从而在每次会议记录中留存学生参会当时的选课快照。
现有实现代码
from django.db import models from django.utils import timezone from django.contrib.auth.models import User from django.urls import reverse from django.db.models.signals import post_save from django.dispatch import receiver # 无关模型已省略... class Student(models.Model): """代表学生的模型""" first_name = models.CharField(max_length=50, help_text="学生名") last_name = models.CharField(max_length=50, help_text="学生姓") course = models.ManyToManyField(Course, help_text="选择学生就读的课程", blank=True, default='') def __str__(self): """模型对象的字符串表示""" return self.last_name + ", " + self.first_name def get_absolute_url(self): """返回访问该学生详情页的url""" return reverse("checkin-student-detail", args=[str(self.id)]) class StudentMeeting(models.Model): """代表签到预约的模型""" instructor = models.ForeignKey(User, on_delete=models.PROTECT, null=True, blank=True, default='') student = models.ForeignKey(Student, help_text="学生姓名", on_delete=models.CASCADE, null=True) appointment_date = models.DateField("日期", default=timezone.now) attended_meeting = models.BooleanField() missing_work_amount = models.IntegerField(default=0) narrative = models.TextField(blank=True, default='') current_courses = models.ManyToManyField(Course, blank=True, default='') def __str__(self): """模型对象的字符串表示""" return str(self.appointment_date) + ": " + self.student.last_name + ", " + self.student.first_name @receiver(post_save, sender=StudentMeeting) def set_current_courses(sender, instance, created, **kwargs): if created: instance.current_courses.set(instance.student.course.all())
遇到的问题
最后一行代码抛出了错误,无法确定是语法错误还是实现思路存在问题。
问题解决方案
该问题为操作疏漏导致:修改模型后未执行migrate相关的迁移操作,也没有重启服务器,重新执行迁移并重启项目后功能可正常运行。
同类问题排查参考
- 涉及模型字段增删/修改时,必须依次执行
python manage.py makemigrations和python manage.py migrate命令,将字段变更同步到数据库 - 多对多字段的
set()方法仅接收可迭代的模型实例对象,上述代码中instance.student.course.all()返回的QuerySet符合参数要求,逻辑本身没有问题 - 如果使用
post_save信号操作多对多字段时遇到关联对象未保存的问题,可以考虑将信号逻辑用transaction.on_commit包裹,确保主表数据落库后再操作关联字段
内容的提问来源于stack exchange,提问作者Autonomous Dev
相关产品推荐
相关产品推荐

