2012-12-11 48 views
18

我試圖使所有字段只讀而不明確列出它們。Django管理員 - 使所有字段只讀

喜歡的東西:

class CustomAdmin(admin.ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     if request.user.is_superuser: 
      return self.readonly_fields 

     return self.fields 

問題是CustomAdmin.fields沒有設置在這一點上。

任何想法?

+0

請看看這個鏈接的http://計算器。 com/questions/4343535/django-admin-make-a-field-read-only-when-modifying-obj-but-required-when-adding – Prateek

+0

沒有答案可以回答我的問題 - 「...沒有列出它們明確地「 – yprez

+1

希望這一個幫助http://stackoverflow.com/questions/7920371/whole-model-as-read-only – Prateek

回答

28

小心,self.model._meta.fields不一定是CustomAdmin具有的相同字段!

「所有管理領域」 看起來更像是這樣的:

from django.contrib import admin 
from django.contrib.admin.utils import flatten_fieldsets 

class CustomAdmin(admin.ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     if request.user.is_superuser: 
      return self.readonly_fields 

     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] 
      )) 
+0

非常感謝。剛剛必須刪除many_to_many,因爲它看起來很奇怪(它們無論如何都被註冊爲內聯並且擁有自己的權限) 獲得'model._meta'後感覺更安全 – yprez

+1

不用擔心,小心如果您有m2m這不是內聯,儘管它應該讓自己知道:-) –

+0

謝謝。這是我找到的最合理的答案。 –

5

你可以通過模型元字段重複:

def get_readonly_fields(self, request, obj=None): 
    if obj: 
     self.readonly_fields = [field.name for field in obj.__class__._meta.fields] 
    return self.readonly_fields 
+2

當用戶嘗試創建新對象時,您在此處有例外:obj .__ class __._ meta.fields – inoks

+1

@Likeit的確已更新。 –

+0

好吧,我刪除了我的答案,你真的是第一個:) – inoks

14

好了,現在有這樣的:

class CustomAdmin(admin.ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     # ... 

     return [f.name for f in self.model._meta.fields] 

還在尋找一個不太難看的方式。

+1

請解釋downvote。 – yprez

+0

其實我在別處找到了這個。然後在upvoting你的答案和調整它的一點我使用和測試在我的代碼張貼我自己的版本。 – yprez

+0

if子句不會爲您的問題添加任何內容 –

-1

隨着get_fieldsets你從形式

def get_readonly_fields(self, request, obj=None): 
    readonly = [] 
    for fs in self.get_fieldsets(request, obj): 
     if len(fs) > 1: 
      readonly += fs[1].get('fields', []) 
    return readonly 
+0

'get_readonly_fields()'內部調用'get_fieldsets()'達到遞歸限制:( –

5

各個領域對於內聯(Tab或堆棧)

def get_readonly_fields(self, request, obj=None): 
    fields = [] 
    for field in self.model._meta.get_all_field_names(): 
     if field != 'id': 
      fields.append(field) 
    return fields 

def has_add_permission(self, request): 
    return False 
+0

return [field for field在self.model._meta.get_all_field_names()if field!='id'] ###謝謝YPREZ –

1

這對Django工作1.10

def get_readonly_fields(self, request, obj=None): 
    if request.user.is_superuser: 
     return self.readonly_fields 

    return list(set(
     [field.name for field in self.opts.local_fields] + 
     [field.name for field in self.opts.local_many_to_many] 
    )) 
0

我的要求很相似。我需要只有一個字段顯示爲只讀。這工作得很好:

class ChoiceInline(admin.TabularInline): 
    model = Choice 
    extra = 1 
    fields = ['choice_text', 'votes'] 
    readonly_fields = ['votes'] 

class QuestionAdmin(admin.ModelAdmin): 
    #fields = ['pub_date', 'question_text'] 
    fieldsets = [ 
     (None, {'fields': ['question_text']}), 
     ('Date Information', {'fields': ['pub_date']}), 
    ] 
    search_fields = ['question_text'] 


    inlines = [ChoiceInline] 

參考:C:\ Python27 \ LIB \站點包\ Django的\的contrib \ ADMIN \ options.py

相關問題