如何解决仅在调用更新时发布保存信号
你好,我有两个模型和一个 post_save 信号,但我的信号只有在对象更新时才有效,当我创建一个新对象时它不起作用
我的代码:
class Attendance(models.Model):
classroom = models.ForeignKey('Class',on_delete=models.CASCADE)
student = models.ForeignKey(User,on_delete=models.CASCADE)
is_present = models.BooleanField(default=False)
present_time = models.DateTimeField(null=True,blank=True)
def __str__(self):
return self.student.username
class Class(models.Model):
course = models.ForeignKey(Course,on_delete=models.CASCADE)
students = models.ManyToManyField(User)
quantity = models.PositiveSmallIntegerField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
class Meta:
unique_together = ['quantity','course']
def __str__(self):
return f'{self.quantity} / {self.course}'
@receiver(post_save,sender=Class)
def create_attendance(sender,instance,**kwargs):
for student in instance.students.all():
try:
Attendance.objects.get(classroom=instance,student=student)
except Attendance.DoesNotExist:
Attendance.objects.create(classroom=instance,student=student)
解决方法
在您创建实例时,instance.students
尚未填充(尚未)因此空,这意味着for student in instance.students.all()
将枚举空集合,因此根本不枚举。
这是因为它首先需要创建一个带有主键的记录,然后将其用于junction表,这也是为什么使用信号经常不是一个好主意。
使用 m2m_changed
signal [Django-doc] 可能会更好,因此实现如下:
@receiver(m2m_changed,sender=Class.students.through)
def create_attendance(sender,instance,action,pk_set=None,**kwargs):
if action == 'post_add':
for pk in pk_set:
Attendance.objects.get_or_create(classroom=instance,student_id=pk)
然而建模看起来有点奇怪。为什么不让Attendance
成为你的through model [Django-doc]ManyToManyField
?这样 Django 将创建 Attendance
记录,然后您可以相应地更新。
post_save 信号中有一个 created 参数,当实例被创建时为 True,当实例没有被创建(更新)时为 False。
@receiver(post_save,sender=Class)
def create_attendance(sender,created,**kwargs):
if not created:
for student in instance.students.all():
try:
Attendance.objects.get(classroom=instance,student=student)
except Attendance.DoesNotExist:
Attendance.objects.create(classroom=instance,student=student)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。