2013-01-22 78 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]