Django Admin如何防止删除某些内联

2024-10-01 11:30:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个模型-例如,书和页。 Page有一个Book的外键。在

每个页面都可以标记为“was_read”(布尔值),我要防止删除已读的页面(在管理中)。在

在管理页面是一个内联的书(我不想页面是一个独立的模型在管理)。在

我的问题-我如何才能实现一个已读页面不会被删除的行为? 我使用的是Django 1.4,我尝试了几个选项:

  1. 重写“delete”抛出ValidationError-问题是管理员在删除时没有“捕获”ValidationError,而您会得到一个错误页面,因此这不是一个好的选择。在
  2. 在PageAdminInline中重写方法-具有“删除”权限-这里的问题是-它是按类型的,所以要么允许删除所有页面,要么不删除

在不重写html代码的情况下,还有其他好的选择吗?在

谢谢, 李


Tags: django标记模型read管理员选项错误page
3条回答

我找到了一个非常简单的解决方案,可以悄悄地避免不必要的删除某些内联线。您只需重写delete_forms属性方法。 这不仅适用于管理,也适用于常规内联。在

from django.forms.models import BaseInlineFormSet

class MyInlineFormSet(BaseInlineFormSet):

    @property
    def deleted_forms(self):
        deleted_forms = super(MyInlineFormSet, self).deleted_forms

        for i, form in enumerate(deleted_forms):
            # Use form.instance to access object instance if needed
            if some_criteria_to_prevent_deletion:
                deleted_forms.pop(i)

        return deleted_forms

另一种方法是禁用DELETE复选框。 此解决方案的优点是向用户提供视觉反馈,因为用户将看到一个灰显的复选框。在

from django.forms.models import BaseInlineFormSet

class MyInlineFormSet(BaseInlineFormSet):

    def add_fields(self, form, index):
        super().add_fields(form, index)
        if some_criteria_to_prevent_deletion:
            form.fields['DELETE'].disabled = True

这段代码利用了django1.9中添加的Field.disabled属性。正如文档中所说,“即使用户篡改了提交给服务器的字段值,它也会被忽略,取而代之的是表单初始数据中的值”,因此您不需要添加更多代码来防止删除。在

解决方案如下(不需要HTML代码):

在管理文件中,定义以下内容:

from django.forms.models import BaseInlineFormSet

class PageFormSet(BaseInlineFormSet):

    def clean(self):
        super(PageFormSet, self).clean()

        for form in self.forms:
            if not hasattr(form, 'cleaned_data'):
                continue                     

            data = form.cleaned_data
            curr_instance = form.instance
            was_read = curr_instance.was_read


            if (data.get('DELETE') and was_read):            
                raise ValidationError('Error')



class PageInline(admin.TabularInline):
    model = Page
    formset = PageFormSet

相关问题 更多 >