Django - 在管理员保存时更新另一个模型

1 投票
2 回答
2561 浏览
提问于 2025-04-18 00:00

我正在用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。

撰写回答