Django:在更新模型之前,我想“看看”模型它以前的属性
当对 Django 模型(.save()
)执行更新/创建时,我希望能够“介入”并将某些特定属性与之前设置的内容进行比较(如果它们以前根本就存在)。
我正在考虑预保存信号,并查找执行.objects.get(instance.id)
的原始模型,但这感觉很浪费。另外,验证是否已在 pre_save()
中进行?
When an update/create is performed on a Django model (.save()
) I would like to be able to "step in" and compare some particular attributes to what they were set to previously (if they previously existed at all).
I'm thinking Pre-Save Signals, with a look-up to the original model doing a .objects.get(instance.id)
, but that feels wasteful. Also, has the validation already happened in pre_save()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
关于 模型验证< /a>:
然后,关于预保存信号,请注意,您将获取正在保存的实例作为参数发送消息。由于模型的前一个版本仅存在于数据库中,我不知道您还能在哪里获得属性的先前值...
您没有说出为什么要这样做,所以很难说,但是我现在正在考虑的其他解决方案:
如果您提供更多详细信息,可能会更容易...
编辑:
没错...如果您发出自定义的“foo_has_updated”,您将无法确定修改是否已保存。
在这种情况下,我想您可以在初始化实例时缓存您感兴趣的变量,并捕获保存后或保存前信号。
缓存你的变量可以这样完成:
或者类似的事情......然后,在你的信号处理程序中:
你得到了你需要的(我认为)!
about model validation :
Then, about the
pre-save signal
, note that you get the instance that is being saved sent as a parameter with the message. As the former version of your model exists only in the database, I don't see where else you could get the previous value of the attributes ...You don't tell why you want to do this so it's hard to say, but other solutions I'm thinking of right now :
If you give more details, it might be easier...
EDIT :
That's right ... If you emit a custom 'foo_has_updated', you will not be sure that the modification is saved.
In this case, I guess you could cache the variables that interest you while initializing the instance, and catch the post-save OR pre-save signal.
Caching your variables could be done like this :
Or something like this ... Then, in your signal handler :
And you got what you needed (I think)!!!
这是我的想法:尝试使用属性。
假设您有此类:
相反,重命名您的字段(如果是第一次,则不需要迁移
你正在这样做)并且:
我们向你的 Foo 实例添加了两个属性:'_initial_name' 和
'_name_changed' 和属性:'name'。这些不是模型字段,将
永远不会保存到数据库中。另外,你不必搞乱“_name”
只要“name”属性处理所有事情,字段就可以不再存在。
现在,您的“pre_save”或“post_save”信号处理程序可以检查已保存的内容
改变:
Here's my idea: play around with properties.
Say you have this class:
Instead, rename your field (you won't need a migration if it's the first time
you're doing this) and:
We added two attributes to your Foo instances: '_initial_name' and
'_name_changed' and a property: 'name'. These are not model fields and will
never be saved to the database. Also, you won't have to mess with the '_name'
field any longer as long as the 'name' property takes care of everything.
Now, your 'pre_save' or 'post_save' signal handler can make checks on what has
changed:
您可以在保存之前询问数据库中当前存储的值。我这样做是为了仅记录更改的值,但每次保存时都会导致另一个数据库查询。
You can ask for the currently stored values in the database before you save. I have done this to log only changed values, but it causes another database query each time you save.
虽然我非常赞成 Sébastien Piquemal 的回答 我最终最终使用了
pre_save
和post_save
信号。我没有重写 __init__(),而是在pre_save
中执行非常类似的操作,然后检查/比较post_save
中的值并发出自定义信号如果满足某些条件,则从那里开始。我想我仍然会接受他的回答,因为我花了很多时间。我看不出我们在哪里做的有什么不同,除了我在信号中做我的工作而他在初始化期间做。
While I very much approve of Sébastien Piquemal's answer I ultimately ended up using both the
pre_save
andpost_save
signals. Instead of overriding__init__()
, I do something very similar inpre_save
, and then check/compare the values inpost_save
and emit a custom signal from there if certain conditions are met.I think I'll still accept his answer, for the time spent on it. I don't see where we're doing much different, except I'm doing my work in a signal and he's doing it during initialization.
您可以使用 pre_save 信号并将数据库记录(旧版本)与实例记录(已更新,但未保存在数据库版本中)进行比较。
以这样的模型为例:
在 pre_save 函数中,您可以比较实例版本
与数据库版本。
You can use the pre_save signal and compare the db record (the old version) with the instance record (the updated, but not saved in the db version).
Take a model like this one as example:
In a pre_save function you can compare the instance version
with the db version.