Django 信号与重写保存方法

发布于 2024-10-06 22:22:59 字数 388 浏览 3 评论 0原文

我很难理解这个问题。现在我有一些看起来像这样的模型:

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

评论有几个“分数”,overall_score 是分数的平均值。保存评论或分数后,我需要重新计算总体分数平均值。现在我正在使用重写的保存方法。使用 Django 的信号调度程序有什么好处吗?

I'm having trouble wrapping my head around this. Right now I have some models that looks kind of like this:

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

A Review is has several "scores", the overall_score is the average of the scores. When a review or a score is saved, I need to recalculate the overall_score average. Right now I'm using a overridden save method. Would there be any benefits to using Django's signal dispatcher?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小猫一只 2024-10-13 22:23:00

当您需要进行不完全特定于相关模型的更改,或者可以应用于具有共同点的模型,或者可以配置为跨模型使用时,保存/删除信号通常是有利的。

重写的 save 方法中的一项常见任务是从模型中的某些文本字段自动生成 slugs。这是一个示例,如果您需要为多个模型实现它,则可以使用 pre_save 信号,其中信号处理程序可以获取 slug 字段的名称和生成 slug 的字段。一旦您有了类似的东西,您放置的任何增强功能也将适用于所有模型 - 例如,查找您要为相关模型类型添加的段,以确保唯一性。

可重用应用程序通常受益于信号的使用 - 如果它们提供的功能可以应用于任何模型,它们通常(除非不可避免)不希望用户必须直接修改其模型才能从中受益。

例如,对于 django-mptt,我使用了 pre_save 信号用于管理一组字段,这些字段描述即将创建或更新的模型的树结构,而 pre_delete 信号用于删除要删除的对象及其整个子对象的树结构详细信息之前的对象树,并且它们被删除。由于使用信号,用户不必在模型上添加或修改 savedelete 方法来为他们完成此管理,他们只需要让django-mptt 知道他们希望它管理哪些模型。

Save/delete signals are generally favourable in situations where you need to make changes which aren't completely specific to the model in question, or could be applied to models which have something in common, or could be configured for use across models.

One common task in overridden save methods is automated generation of slugs from some text field in a model. That's an example of something which, if you needed to implement it for a number of models, would benefit from using a pre_save signal, where the signal handler could take the name of the slug field and the name of the field to generate the slug from. Once you have something like that in place, any enhanced functionality you put in place will also apply to all models - e.g. looking up the slug you're about to add for the type of model in question, to ensure uniqueness.

Reusable applications often benefit from the use of signals - if the functionality they provide can be applied to any model, they generally (unless it's unavoidable) won't want users to have to directly modify their models in order to benefit from it.

With django-mptt, for example, I used the pre_save signal to manage a set of fields which describe a tree structure for the model which is about to be created or updated and the pre_delete signal to remove tree structure details for the object being deleted and its entire sub-tree of objects before it and they are deleted. Due to the use of signals, users don't have to add or modify save or delete methods on their models to have this management done for them, they just have to let django-mptt know which models they want it to manage.

感性不性感 2024-10-13 22:23:00

您问:

使用 Django 的信号调度程序有什么好处吗?

我在 django 文档中找到了这一点:

批量操作不会调用重写的模型方法

请注意,对象的delete()方法不一定会被调用
使用 QuerySet 或作为结果批量删除对象时
级联删除。为了确保执行自定义删除逻辑,您
可以使用 pre_delete 和/或 post_delete 信号。

不幸的是,创建或更新时没有解决方法
批量对象,因为 save()、pre_save 和 post_save 都不是
已调用。

来自:覆盖预定义的模型方法

You asked:

Would there be any benefits to using Django's signal dispatcher?

I found this in the django docs:

Overridden model methods are not called on bulk operations

Note that the delete() method for an object is not necessarily called
when deleting objects in bulk using a QuerySet or as a result of a
cascading delete. To ensure customized delete logic gets executed, you
can use pre_delete and/or post_delete signals.

Unfortunately, there isn’t a workaround when creating or updating
objects in bulk, since none of save(), pre_save, and post_save are
called.

From: Overriding predefined model methods

七分※倦醒 2024-10-13 22:23:00

Django 文档中关于批量删除的小补充(QuerySet 对象上的.delete() 方法):

请记住,只要有可能,这将纯粹在
SQL,因此各个对象实例的delete()方法将
过程中不一定会被调用。如果您提供了
模型类上的自定义 delete() 方法并希望确保它是
调用时,您将需要“手动”删除该模型的实例
(例如,通过迭代 QuerySet 并在每个查询集上调用 delete()
单独的对象)而不是使用批量删除()方法
查询集。

https://docs.djangoproject.com/en/1.11/ topic/db/queries/#deleting-objects

和批量更新(QuerySet 对象上的 .update() 方法):

最后,认识到 update() 在 SQL 级别进行更新,并且,
因此,不会在模型上调用任何 save() 方法,也不会
发出 pre_save 或 post_save 信号(这是
调用 Model.save())。如果你想更新一组记录
具有自定义 save() 方法的模型,循环它们并调用 save()

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update

Small addition from Django docs about bulk delete (.delete() method on QuerySet objects):

Keep in mind that this will, whenever possible, be executed purely in
SQL, and so the delete() methods of individual object instances will
not necessarily be called during the process. If you’ve provided a
custom delete() method on a model class and want to ensure that it is
called, you will need to “manually” delete instances of that model
(e.g., by iterating over a QuerySet and calling delete() on each
object individually) rather than using the bulk delete() method of a
QuerySet.

https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects

And bulk update (.update() method on QuerySet objects):

Finally, realize that update() does an update at the SQL level and,
thus, does not call any save() methods on your models, nor does it
emit the pre_save or post_save signals (which are a consequence of
calling Model.save()). If you want to update a bunch of records for a
model that has a custom save() method, loop over them and call save()

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update

风透绣罗衣 2024-10-13 22:23:00

如果您使用信号,则每次保存相关评分模型时都可以更新审核评分。但如果不需要这样的功能,我认为没有任何理由将其放入信号中,这是与模型相关的东西。

If you'll use signals you'd be able to update Review score each time related score model gets saved. But if don't need such functionality i don't see any reason to put this into signal, that's pretty model-related stuff.

尛丟丟 2024-10-13 22:23:00

这是一种非规范化。看看这个漂亮的解决方案。就地组合字段定义。

It is a kind sort of denormalisation. Look at this pretty solution. In-place composition field definition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文