[英]Django pre_save signal - would an exception fail the transaction?
我想在创建用户之前执行一些自定义操作。 我想pre_save
使用pre_save
信号。 如果这些操作之一会引发异常,请停止事务,中止创建用户等。
这是要走的路吗? 如果在此步骤中出现某些问题(这是必需的行为),它会中止保存吗?我怀疑是这样,但找不到有关它的文档。
获取未来 user.id 的最佳实践是什么。 根据我的理解,它在预保存中尚不存在,但我需要它作为一些额外自定义操作的输入。
谢谢
这是两部分的答案:
是的,在 pre_save() 信号中引发异常将中止对 save() 方法的调用。 例如,我在 pre_save() 中这样做了:
if SOME_TEST: raise exceptions.ParseError(detail="I reject your data. Here is why.")
注意:这是使用 DRF 异常,但我假设您知道如何引发您喜欢的任何异常。
您可以使用 post_save() 信号在 save() 方法之后获取 id。 但如果这对你不起作用,那么下面是我对在 pre_save() 中做你想做的一些策略的原始解释:
在 pre_save 中,您可以访问 User.objects.all() (当然,如果您导入 User 模型)。 如果您使用标准 User 模型,则 User.id 值为 AUTO INCREMENT。 因此,如果您需要知道新用户的值是多少,只需获取当前数据库中最高的 User.id(即:最后创建的用户的 ID)。 这是一个简单的查询来做到这一点:
last_user = User.objects.latest('id')
然后当然, last_user.id
将为您提供最后一个创建的用户的 id 值,如果您添加一个,您将拥有下一个用户 id。 当然,如果您有一个繁忙的站点,您可能会在同时创建用户时遇到一些问题。 风险在于,此值由两次(或更多)用户创建尝试接收,其中一次(或多次)以错误告终。
当然,您始终可以将另一个字段设置为primary_key=True
,这将替换模型上的id
字段。 然后你可以设计任何你能想到的索引机制! 您可以使用唯一特征的哈希值。 例如: User.username
有一个 Unique 约束,您可以将其散列或十六进制编码为数字 ID 以预先确定User.id
。 或者您可以保留 id 字段并通过为 obj.id 分配一个值在obj.id
手动设置它。 它可以是你想要的任何东西。 甚至是哈希值!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.