我想在创建用户之前执行一些自定义操作。我想到了使用pre_save
信号。如果其中一个动作引发异常,则停止该事务,中止创建用户等。
这是要走的路吗?如果在这一步中出现故障(这是必需的行为),它会中止保存吗?我怀疑是这样但是找不到关于它的文档。
获得未来user.id的最佳做法是什么?根据我的理解,它在预存时尚不存在,但我需要它作为一些额外自定义操作的输入。
由于
答案 0 :(得分:3)
答案 1 :(得分:3)
以下是两部分答案:
是的,在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.id值为AUTO INCREMENT。因此,如果您需要了解新用户的价值,只需获取当前数据库中最高的User.id(即:创建的最后一个用户的ID)。这是一个简单的查询:
last_user = User.objects.latest('id')
然后,当然,last_user.id
会为您提供上次创建的用户的ID值,如果您添加一个,则您将拥有下一个用户ID。当然,如果您有一个繁忙的网站,您可能会遇到一些同时创建用户的问题。风险是这个值是由两次(或多次)用户创建尝试收到的,其中一个(或多个)最终错误。
当然,您始终可以将另一个字段设置为primary_key=True
,这将替换模型上的id
字段。然后你可以设计出任何你想象的索引机制!您可以使用唯一特征的哈希值。例如:User.username
具有唯一约束,您可以将其作为数字ID进行哈希或十六进制编码,以预先确定User.id
。或者您可以将id字段留在原位并通过为obj.id
赋值来在pre_save中手动设置它。它可能是你想要的任何东西。即使是哈希值!