Django在删除模型之前检查模型是否具有相关对象

时间:2016-09-27 14:40:33

标签: python django django-models

在寻找一种方法来检查是否可以在django中删除模型实例之后,我遇到了很多样本​​,但是没有按预期工作。希望这个解决方案可以提供帮助。

首先创建一个可以由其他模型继承的抽象模型类

o

实施例

因此,假设我们有三个模型组织和部门以及StaffType 这么多部门都可以在一个组织中 组织有一个特定的StaffType

class ModelIsDeletable(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True, unique=True)
    description = models.CharField(max_length=200, blank=True, null=True)
    date_modified = models.DateTimeField(auto_now_add=True)

    def is_deletable(self):
        # get all the related object
        for rel in self._meta.get_fields():
            try:
                # check if there is a relationship with at least one related object
                related = rel.related_model.objects.filter(**{rel.field.name: self})
                if related.exists():
                    # if there is return a Tuple of flag = False the related_model object
                    return False, related
            except AttributeError:  # an attribute error for field occurs when checking for AutoField
                pass  # just pass as we dont need to check for AutoField
        return True, None

     class Meta:
        abstract = True

所以,在添加一些您要删除组织模型实例的信息后,请说 已经与部门联系在一起

例如我们有 组织表=> (name = Engineering,pk = 1) 部门表=> (name = Developer,organization_fk = 1,pk = 1)

现在,当您尝试使用pk

获取组织后删除组织
class StaffType(ModelIsDeletable):
    pensionable = models.BooleanField(default=False)

class Organization(ModelIsDeletable):
    staff_type = models.ForeignKey(to=StaffType)


class Department(ModelIsDeletable):
    organization = models.ForeignKey(to=Organization, to_field="id")

有了这个,您可以检查它是否可删除

a_org = Organization.objects.get(pk=1)

1 个答案:

答案 0 :(得分:0)

您的问题似乎是“如果我删除此模型对象,如何检测将删除哪些相关模型对象?”或“如果我删除此行,如何检测将删除哪些相关行?”

另一个选择是使用事务,执行删除操作,保存django提供的信息,但是在提交更改之前回滚。这可以在Postgres和MySQL等数据库中使用,但我对其他人一无所知。

在此示例中,我想知道如果删除名为“ pdemo”的组织将删除什么,并且我看到它具有408个相关的Property对象。

https://gist.github.com/cgthayer/25aa97bb4b74efb75e3467fb7bbdaacb

>>> from django.db import transaction
>>> transaction.set_autocommit(autocommit=False)
>>> o = Organization_v2.objects.get(name='pdemo')
>>> del_info = o.delete()
>>> del_info
(1404, {'data.Property': 408, [..more stuff..], 'data.Organization_v2': 1})
>>> Property.objects.filter(scope__organization_id=o).count()
0
>>> transaction.rollback()
>>> o = Organization_v2.objects.get(name='pdemo')
>>> Property.objects.filter(scope__organization_id=o).count()
408

这可以转换为通用函数。

研究此问题时,我发现许多旧解决方案都使用django.contrib.admin中的功能来确定这一点,但这是一个未记录的api,它似乎有时会发生变化,因此使用事务似乎更容易< em> iff 您的数据库支持它。