2011-10-27 71 views
13

有沒有辦法在django admin中製作模型只讀?但我的意思是整個模型。 因此,不添加,不刪除,不改變,只看到對象和字段,一切都只讀?整個模型爲只讀

+1

這似乎是一個正在進行的工作:https:// github。COM/Django的/ Django的/拉/ 5297 – Bosco

回答

11

的ModelAdmin提供了鉤get_readonly_fields() - 以下是未經測試,我的想法是,以確定各個領域的ModelAdmin做的方式,而不會遇到與只讀遞歸域就是:

from django.contrib.admin.util import flatten_fieldsets 

class ReadOnlyAdmin(ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     if self.declared_fieldsets: 
      fields = flatten_fieldsets(self.declared_fieldsets) 
     else: 
      form = self.get_formset(request, obj).form 
      fields = form.base_fields.keys() 
     return fields 

然後子類/ mixin這個管理員無論它應該是一個只讀的管理員。

對於添加/刪除,並讓自己的按鈕消失了,你可能還需要添加

def has_add_permission(self, request): 
     # Nobody is allowed to add 
     return False 
    def has_delete_permission(self, request, obj=None): 
     # Nobody is allowed to delete 
     return False 

PS:在的ModelAdmin,如果has_change_permission(查找或您的覆蓋)返回False,你不」不會進入對象的變化視圖 - 甚至不會顯示鏈接。如果它真的很酷,並且默認情況下get_readonly_fields()檢查了更改權限並將所有字段設置爲readonly,如上所述。這樣,非轉換者至少可以瀏覽數據...鑑於當前的管理結構假設view = edit,正如jathanism指出的那樣,這可能需要在add/change/delete之上引入「view」權限...

編輯:關於設置所有字段只讀,還未經測試,但看起來很有希望:

readonly_fields = MyModel._meta.get_all_field_names() 

編輯:這是另外一個

if self.declared_fieldsets: 
    return flatten_fieldsets(self.declared_fieldsets) 
else: 
    return list(set(
     [field.name for field in self.opts.local_fields] + 
     [field.name for field in self.opts.local_many_to_many] 
    )) 
+1

P.S:我現在已經創建了一個功能請求,這種效果https://code.djangoproject.com/ticket/17295 –

+1

注:get_formset方法只用於InlineModelAdmin –

+0

嗨定義,由於此編譯選項。可能是禮貌,雖然也提供的鏈接,你得到了個答案,因爲我看他們是不是都是你的。另一個好處是,讀者也可以看到其他人對每個建議提出的意見。 – steps

2

您可以使用readonly_fields屬性自定義您的ModelAdmin類。有關更多信息,請參閱this answer

+0

但有一種方法,使整個** **模式爲READ_ONLY,而不必添加到列表readonly_fields其所有屬性? – juliomalegria

+1

有,但不容易。你可以在Django中創建自定義權限,但是當涉及到管理站點時,這是不重要的。 Django認爲,如果允許人們在管理界面中查看內容,他們也可以編輯它。您可以從[這個問題]如果你感覺大膽(http://stackoverflow.com/questions/4334049/make-a-django-model-read-only)嘗試的建議。國際海事組織只是更容易明確地設置所有領域只讀,並繼續前進。 – jathanism

0

我也有類似的情形,其中:

  1. 用戶應該能夠創建模型對象
  2. 用戶應該能夠查看模型的上市對象
  3. 用戶SHOULD'NT能夠編輯對象一旦它被創建

1 。覆蓋更改視圖

因爲可以覆蓋ModelAdmin中的change_view(),所以我們可以利用它來防止在創建模型實例後編輯模型實例。這是我用過的一個例子:

def change_view(self, request, object_id, form_url='', extra_context=None): 
    messages.error(request, 'Sorry, but editing is NOT ALLOWED') 
    return redirect(request.META['HTTP_REFERER']) 

2。有條件地更改編輯權限

我也意識到,文檔以不同的方式詮釋ModelAdmin.has_change_permission()結果:

Should return True if editing obj is permitted, False otherwise. If obj is None, should return True or False to indicate whether editing of objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to edit any object of this type).

含義我可以檢查obj是否爲None,在這種情況下,我回到True,否則我回到False ,這實際上允許用戶查看更改列表,但不能在模型實例保存後編輯或查看change_form。

def has_change_permission(self, request, obj = None, **kwargs): 
    if obj is None: 
     return True 
    else: 
     return False 

雖然我想這也可能會覆蓋任何MODEL_can_change權限允許不希望的眼睛觀看的變化列表?

-1

根據我的Django的1.8作爲答案#3注意,但它適用於Django 1.4我們不能使用下面的測試:

##  self.get_formset(request, obj)  ## 
answer 3 needs fix. Generally, alternative codes for this issue about below section 
##   form = self.get_formset(request, obj).form ## 
##   fields = form.base_fields.keys()    ## 

可以是這樣的:

#~ (A) or 
[f.name for f in self.model._meta.fields] 

#~ (B) or 
MyModel._meta.get_all_field_names() 

#~ (C) 
list(set([field.name for field in self.opts.local_fields] + 
         [field.name for field in self.opts.local_many_to_many]   
)) 
3

爲「視圖權限「will not make it into Django 1.11,不幸的是,這裏有一個解決方案,使您的ModelAdmin 只讀同時保存模型更改和添加模型歷史日誌條目a no-op

def false(*args, **kwargs): 
    """A simple no-op function to make our changes below readable.""" 
    return False 

class MyModelReadOnlyAdmin(admin.ModelAdmin): 
    list_display = [ 
     # list your admin listview entries here (as usual) 
    ] 
    readonly_fields = [ 
     # list your read-only fields here (as usual) 
    ] 

    actions = None 
    has_add_permission = false 
    has_delete_permission = false 
    log_change = false 
    message_user = false 
    save_model = false 

注:不要搞錯與False內置的false無操作幫手如果你不與類的外部輔助函數同情將其移動到類,稱之爲no_op或別的東西,或覆蓋由通常的def S中受影響的屬性少幹,但如果你不小心...)

這將:

  1. 刪除操作下拉框(與「刪除」)在列表視圖
  2. 不允許添加新的模式條目
  3. 不允許刪除現有的模型保存後條目
  4. ,避免創建的模型歷史
  5. 避免顯示「已成功更改」的消息日誌條目
  6. 避免保存changeform更改數據庫

它不會:

  • 取出或更換兩個按鈕「保存並繼續編輯」和get_all_field_names(如在接受答覆中提到)是removed in Django 1.10「保存」(這將是不錯的改善用戶體驗)

注意。 經過Django 1.10.5測試。