在寻找一种方法来检查是否可以在 django 中删除模型实例之后,我发现了很多选项,但没有一个按预期工作。希望这个解决方案能有所帮助。
让我们首先创建一个可以被其他模型继承的抽象模型类
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
示例
假设我们有三个模型组织、部门和员工类型 一个组织中可以有很多部门 一个组织有一个特定的 StaffType
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")
所以假设添加一些信息后您想要删除组织模型实例 已经与部门绑定(bind)了
例如我们有 组织表=>(名称=工程,PK=1) 部门表=>(名称=开发人员,organization_fk=1,pk=1)
现在,当您在使用 pk 获取组织后尝试删除该组织时
a_org = Organization.objects.get(pk=1)
有了这个,您可以检查它是否可删除
deletable, related_obj = a_org.is_deletable()
if not deletable:
# do some stuff with the related_obj list
else:
# call the delete function
a_org.delete()
最佳答案
您的问题似乎是“如果我删除此模型对象,如何检测将删除哪些相关模型对象?”或“如果删除此行,如何检测哪些相关行将被删除?”
另一个选择是使用事务,执行删除,保存 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>只要你的数据库支持它。
关于python - Django 在删除模型之前检查模型是否有相关对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39727624/