如何在Django Admin 1.5中有条件地否决删除尝试



文档明确指出ModelAdmin.delete_model()必须删除该对象,并且它不用于否决目的。问题是,他们没有给出任何提示,你将如何实施否决应该你需要。

这里有一些背景,因为也许有一种更好的方式来实现我正在努力实现的目标。我正在Django 1.5应用程序中捕获iptables规则,并希望使用Admin页面来处理所有维护。我手头有两个与这个问题相关的模型:Chain和Target。以下是这些模型的关键:

class Chain(models.Model):
"""A netfilter chain."""
name = models.CharField(max_length=30, unique=True, primary_key=True)
built_in = models.BooleanField(
default=False,
help_text=u'This option should be selected if this chain is one of '
u'those provided by netfilter.  Leaving this option '
u'unselected indicates that the chain is user-defined.'
)
table = models.ForeignKey(Table, verbose_name='netfilter table')
class Target(models.Model):
"""A netfilter target."""
name = models.CharField(
max_length=30, unique=True, primary_key=True,
help_text=u'This may be either an iptables built-in target or a '
u'user-defined chain.  Built-in targets must be one of '
u'those supported by iptables.'
)
built_in = models.BooleanField(
default=False, verbose_name='built-in',
help_text=u'This option should be selected if this target is one of '
u'those provided by netfilter.  Leaving this option '
u'unselected indicates that the target is user-defined.',
)

因此,Chain表将具有"FORWARD"、"INPUT"one_answers"OUTPUT"的记录,这些记录都内置并链接到"filter"表。当然,管理员也可以在这里输入其他用户定义的链,但会用built_in == False设置这些链。

不过,目标队的情况变得很奇怪。它们可以引用Chain(嘿,ForeignKey在这里会很好!)或我不想公开为Chain的内置Target(例如,"ACCEPT"或"DROP")(嘿,ForegnKey在这里不会那么热门!.)。

现在是进退两难的局面。Admin UI在将目标链接到用户定义的链时有点笨拙,因为它没有定义为FK,所以我选择了常规字符输入字段,clean_name()可以处理验证以确保目标的链存在。我一直纠结于如何防止删除目标引用的链。

您应该能够通过在Chain管理员中重写has_delete_permission(request, obj)来实现这一点。您可以检查obj,看看是否有Targets在引用它。请参阅文档。

不过,这不会阻止通过更改列表视图中的删除所选操作进行删除。您可以通过用自己的操作覆盖内置的delete_selected操作来解决这个问题,如果不应该删除任何项目,该操作将拒绝执行删除操作。请参阅管理操作文档。

最新更新