2013-01-22 50 views
1

我有2个模型 - 例如Book和Page。 页面具有预定的外键。Django Admin - 如何防止删除某些内联

每个页面都可以标记为“was_read”(布尔值),并且我想阻止删除已读取的页面(在管理员中)。

在管理 - 页面是书内嵌入(我不希望页面是管理中的独立模型)。

我的问题 - 我如何实现被读取的页面不会被删除的行为? 我使用Django 1.4和我尝试了几种选择:

  1. 覆盖“删除”扔ValidationError - 问题是,管理员没有“抓住”上删除ValidationError,你会得到一个错误页面,所以这不是一个好的选择。
  2. 覆盖在PageAdminInline方法 - has_delete_permission - 这里的问题 - 它的每种类型,所以要么我允许删除所有页面,要么我不允许。

是否有任何其他好的选择,而不覆盖的HTML代码?

感谢, 李

回答

5

该解决方案如下(不需要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 
1

我发现了一个很简单的解决办法以安静地避免不必要的删除某些内联。您可以重写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 
+0

通过这一解决方案,删除复选框仍然存在,它只是不工作。 –

0

您可以通过创建自己的自定义 表单集为联模型禁用删除复选框UI明智的,并设置can_deleteFalse那里。对于 例如:

from django.forms import models 
from django.contrib import admin 

class MyInline(models.BaseInlineFormSet): 
    def __init__(self, *args, **kwargs): 
     super(MyInline, self).__init__(*args, **kwargs) 
     self.can_delete = False 

class InlineOptions(admin.StackedInline): 
    model = InlineModel 
    formset = MyInline 

class MainOptions(admin.ModelAdmin): 
    model = MainModel 
    inlines = [InlineOptions]