Django post_delete:计算具有一个匹配属性和删除对象的所有对象

问题描述 投票:1回答:1

我有一个自定义函数,在删除模型订单的对象时调用,我使用post_delete。

模型“Orders”的实例始终具有ForeignKey“user”。当删除模型“订单”的对象时,我想检查模型“订单”的其他实例是否具有相同的“用户”。

def delete_reverse(sender, **kwargs):
try:
    if Orders.objects.filter(user__equal=kwargs['instance'].user).count() == 1:
        kwargs['instance'].user.delete()
    else:
        ...         
except:
    pass
post_delete.connect(delete_reverse, sender=Orders)

不幸的是,if条件不起作用,即使相应条目的计数应为1,它也不是真的。你看到我的count()函数有什么问题吗?

python django filter count signals
1个回答
1
投票

我认为这段代码存在一些问题:

  1. 你似乎使用了__equal字段查找,但这个查找不存在于standard field lookups [Django-doc]列表中,最接近的是__exact,但这里可能没有必要;
  2. 你使用“毯子例外”(!),这是一种严重的反模式:如果某些事情失败了,那么你将永远不会被告知这一点。就像Python的禅宗所说:永远不要默默地传递异常,除非明确地沉默。
  3. 删除后意味着删除已经发生,因此在那一刻,实例不再在数据库中,如documentation中所指定的: 请注意,该对象将不再存在于数据库中,因此请谨慎对待此实例。

因此,最后一项意味着您可能想要检查计数是否为零(因此不再存在与Order相关的user_id):

@receiver(post_save, sender=Orders)
def delete_reverse(sender, instance, **kwargs):
    if not Order.objects.filter(user_id=instance.user_id).exists():
        instance.user.delete()

但请注意,即使通过这样做,仍然存在数据库可以包含没有任何Users的Orders的场景:例如,当我们更改user_idOrder时,之前的用户可能不再拥有,但此函数将没有被触发。因此,定期检查数据库是否值得这样做。

此外,我不知道是否删除User是一个好主意。如果这是Django中的身份验证模型,则可能导致管理员用户被删除,例如,如果意外地将订单放在他们的名称上,并且该订单稍后被删除。此外,移除用户可能导致大量的删除(涉及该用户的所有类型的“实体”)。

注意:Django模型通常具有单数名称,因此我喜欢将Orders模型重命名为Order,就像我在答案中所做的那样。

© www.soinside.com 2019 - 2024. All rights reserved.