繁体   English   中英

Django pre_save 信号 - 异常会导致事务失败吗?

[英]Django pre_save signal - would an exception fail the transaction?

我想在创建用户之前执行一些自定义操作。 我想pre_save使用pre_save信号。 如果这些操作之一会引发异常,请停止事务,中止创建用户等。

  1. 这是要走的路吗? 如果在此步骤中出现某些问题(这是必需的行为),它会中止保存吗?我怀疑是这样,但找不到有关它的文档。

  2. 获取未来 user.id 的最佳实践是什么。 根据我的理解,它在预保存中尚不存在,但我需要它作为一些额外自定义操作的输入。

谢谢

文档

在您调用save()之前,无法确定 ID 的值是什么,因为该值是由您的数据库决定的,而不是由 Django 决定的。

所以如果你的预存处理需要user.id ,恐怕这是不可能的。

这是两部分的答案:

  1. 是的,在 pre_save() 信号中引发异常将中止对 save() 方法的调用。 例如,我在 pre_save() 中这样做了:

     if SOME_TEST: raise exceptions.ParseError(detail="I reject your data. Here is why.")

    注意:这是使用 DRF 异常,但我假设您知道如何引发您喜欢的任何异常。

  2. 您可以使用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM