gpt4 book ai didi

django - Django删除异物?

转载 作者:行者123 更新时间:2023-12-03 13:31:06 26 4
gpt4 key购买 nike

如果我们设置个人资料,Django如何建议:

class Profile(models.Model):
user = models.ForeignKey(User, unique=True)

然后,当您从Django admin中删除 User对象时,它也会同时删除其个人资料,这是因为该个人资料具有用户外键,并且希望保护参照完整性。但是,即使指针朝其他方向移动,我也需要此功能。例如,在我的 Profile类上,我有:
shipper = models.ForeignKey(Shipper, unique=True, blank=True, null=True)
carrier = models.ForeignKey(Carrier, unique=True, blank=True, null=True)
affiliat = models.ForeignKey(Affiliate, unique=True, blank=True, null=True, verbose_name='Affiliate')

而且我想要这样,如果您删除 Profile,它将删除关联的托运人/承运人/附属对象(不要问我为什么Django使“附属”一些奇怪的关键字)。因为托运人,承运人和成员(member)是用户的类型,所以没有其余数据就没有它们存在(没有人能够一次登录)是没有意义的。

我之所以没有将键放在其他对象上是因为,每次我想要检查用户的类型时,Django都必须在内部联接所有这些表。

最佳答案

虽然使用上述bernardo所述的post_delete信号是一种不错的方法,但效果很好,但我尝试避免使用尽可能少的人为信号,因为我觉得这会不必要地在标准功能中添加行为,从而使代码不必要的麻烦可能在期待。

我更喜欢上面的重载方法,但是,Felix给出的示例确实有一个致命缺陷。覆盖的delete()函数如下所示:

def delete(self, using=None):
using = using or router.db_for_write(self.__class__, instance=self)
assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)

collector = Collector(using=using)
collector.collect([self])
collector.delete()

注意参数“using”,在大多数情况下,我们用空参数调用delete(),因此我们甚至可能知道它在那里。在上面的示例中,此参数被我们覆盖,而不是查看父类(super class)功能,如果有人在删除Profile时在其中传递“using”参数,则会导致意外行为。为了避免这种情况,我们将确保保留该参数及其默认的lika,以便:
class Profile(models.Model):
# ...

def delete(self, using=None):
if self.shipper:
self.shipper.delete()
if self.carrier:
self.carrier.delete()
if self.affiliat:
self.affiliat.delete()
super(Profile, self).delete(using)

但是,覆盖方法的一个陷阱是,在批量删除时,不会对每个db记录显式调用delete(),这意味着,如果您想一次删除多个Profile,并保持覆盖行为(调用。例如,在django查询集上的delete()),您将需要利用delete信号(如bernardo所述),或者需要遍历每条记录分别删除它们(既昂贵又丑陋)。

关于django - Django删除异物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2263233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com