2011-10-27 46 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测试。