2012-12-11 47 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

相关问题