Django - 在管理员保存时更新另一个模型
我正在用django创建一个视频库网站。
这个视频库有三个模型:视频(Video)、视频主题(VideoTopic)和课程(Course)。
每个视频都有一个时间字段(TimedeltaField),用来表示视频的时长。在管理员界面保存每个视频时,我想计算一个课程下所有视频的时长总和,然后把这个总和保存到课程模型的一个时间字段里。
我使用了django-timedeltafield,这个工具可以很好地处理时长的汇总。不过,我还没有找到一个解决方案,来在我每次在管理员界面保存视频后更新课程模型。有没有什么建议呢?
我的模型如下:
class Video(models.Model):
title = models.CharField(max_length=200)
topic = models.ForeignKey('VideoTopic')
duration = timedelta.fields.TimedeltaField(default="3 minutes, 30 seconds", help_text="(x minutes, x seconds)")
class VideoTopic(models.Model):
name = models.CharField(max_length=200, blank=True)
course = models.ForeignKey('course.Course')
class Course(models.Model):
name = models.CharField(max_length=200)
duration = timedelta.fields.TimedeltaField()
2 个回答
1
另一种方法是重写管理员的保存方法,以便更新课程模型。你可以查看这个链接了解更多信息:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-methods。
3
我建议你使用Django信号。这样可以确保你的模型在任何地方更新时都能保持同步(无论是在应用程序中、管理后台等地方)。
在视频(Video)模型上注册保存后信号。在这个信号中,你会收到视频实例。然后,你只需要查询与之相关的VideoTopic和Course记录,并在这里进行计算。如果你不想让它失败,建议把这些操作放在一个事务中。如果你不需要信息总是保持最新,这也是一个可以进行一些后台处理的机会,这样保存操作会更轻便。
为什么要用信号呢?
- 可以将不同的功能分开处理
- 确保你的逻辑总是能执行
- 如果模型有依赖关系,信号可以帮助你将这些依赖关系解耦,这样可以减少加载顺序或循环依赖的问题。
另外,你也可以直接重写视频模型的保存方法,在那里做同样的事情。在这两种情况下,如果你不想自己写查询,可以直接使用外键的相关属性来操作ORM。