Django管理-禁用编辑并删除;“保存”;特定型号的按钮
我有一个Django模型,我希望它是只读的。不允许添加和编辑 我已将所有字段标记为只读,并在ModelAdmin中覆盖了“添加”权限,如下所示:Django管理-禁用编辑并删除;“保存”;特定型号的按钮,django,django-admin,Django,Django Admin,我有一个Django模型,我希望它是只读的。不允许添加和编辑 我已将所有字段标记为只读,并在ModelAdmin中覆盖了“添加”权限,如下所示: class SomeModelAdmin(admin.ModelAdmin): def has_add_permission(self, request): return False 是否有类似的具有编辑权限?可以禁用哪个按钮来删除“保存”和“保存并继续”按钮?并替换为一个简单的“关闭并返回”按钮 仅提及只读字段,不涉及覆盖
class SomeModelAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
是否有类似的具有编辑权限
?可以禁用哪个按钮来删除“保存”和“保存并继续”按钮?并替换为一个简单的“关闭并返回”按钮
仅提及只读字段,不涉及覆盖编辑权限。覆盖
模板/admin/submit\u line.html
模板,并根据需要制作按钮。通过将特定模型放入templates/admin/[app\u label]/[model]/submit\u line.html
,您可以仅对特定模型执行此操作
要有条件地显示默认提交行或自定义提交行,请覆盖ModelAdmin.change\u view
,并向extra\u上下文添加布尔值:
class MyModelAdmin(admin.ModelAdmin):
...
def change_view(self, request, object_id, extra_context=None):
if not request.user.is_superuser:
extra_context = extra_context or {}
extra_context['readonly'] = True
return super(MyModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
我也遇到了同样的问题——最简单的方法是包含一些自定义JS
在您的admin.py文件中包括
class Media:
js = ('/static/js/admin.js',)
然后在admin.js文件中,包含以下js
(function($) {
$(document).ready(function($) {
$(".submit-row").hide()
});
})(django.jQuery);
行消失了-它也应该在Django的所有版本中工作。使用Django 1.8(Python 3语法)更新了答案
有三件事要做:
1) 扩展管理员更改表单模板,添加if
以有条件地抑制提交按钮
2) 覆盖admin.ModelAdmin.change_view()
并将模板的上下文变量设置为if
读取
3) 禁止不必要的POST
请求(来自DOM黑客、curl/Postman)
MyProject/my_app/templates/admin/my_app/change_form.html
{% extends "admin/change_form.html" %}
{% load admin_modify %}
{% block submit_buttons_top %}{% if my_editable %}{% submit_row %}{% endif %}{% endblock %}
{% block submit_buttons_bottom %}{% if my_editable %}{% submit_row %}{% endif %}{% endblock %}
MyProject/my_app/admin.py(MyModelAdmin)
我也有同样的问题。我在admin.py中修复了它
from django.contrib.admin.templatetags.admin_modify import register, submit_row as original_submit_row
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def submit_row(context):
''' submit buttons context change '''
ctx = original_submit_row(context)
ctx.update({
'show_save_and_add_another': context.get('show_save_and_add_another',
ctx['show_save_and_add_another']),
'show_save_and_continue': context.get('show_save_and_continue',
ctx['show_save_and_continue']),
'show_save': context.get('show_save',
ctx['show_save']),
'show_delete_link': context.get('show_delete_link', ctx['show_delete_link'])
})
return ctx
在MyModelAdmin类中,添加以下函数
@classmethod
def has_add_permission(cls, request):
''' remove add and save and add another button '''
return False
def change_view(self, request, object_id, extra_context=None):
''' customize add/edit form '''
extra_context = extra_context or {}
extra_context['show_save_and_continue'] = False
extra_context['show_save'] = False
return super(MyModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
对于Django 1.11:
def has_add_permission(self, request, obj=None):
return False
def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['show_save_and_continue'] = False
extra_context['show_save'] = False
return super(YourModelAdmin, self).changeform_view(request, object_id, extra_context=extra_context)
你可以试试这个包裹。这个包为指定的模型添加了一个查看权限
,并自动处理其他内容 基于卓越的解决方案,以下是我的解决方案:
主要区别在于UX'y:
- 使用and(with),而不是
HttpResponseForbidden
来防止保存
- 有条件地定义以防止显示不可保存的输入
此外:
- 应用程序范围,因为
只读
是一种非常有用的非侵入性增强功能
- 定义(OP可能不需要)
- 测试
request.method!='获取“
以阻止补丁
和朋友(不完全确定是否需要,待定)
我的应用程序/admin.py
admin/change\u form.html
(在Django 1.9上测试:注意:自那时以来,一些导入已经移动,例如反向
)最简单的方法是禁用ModelAdmin类中的相应权限。例如,我有一个Cart模型,我希望管理员只查看(列表和详细信息),我所做的只是将以下函数添加到CartAdmin类中,以禁用删除、更改和添加
class CartAdmin(admin.ModelAdmin):
list_display = ['listing']
def has_add_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
这三种方法具有添加权限、更改权限和删除权限,它们是在管理中禁用添加按钮、添加表单、编辑表单和删除按钮的方法
以下是在禁用上述权限的管理员中查看记录详细信息时的示例输出
如上图所示,您只有“关闭”按钮,而详细信息不会以表格形式显示。这已经有一段时间了。名称为具有添加权限
,具有更改权限
和具有删除权限
。有关参考信息,请参阅。这里还有一个例子:
@admin.register(Object)
class Admin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
这是另一个副本,请参阅是否覆盖了模板/admin/[app\u label]/[model]/submit\u line.html
仍应与Django 1.4一起使用?根据法律规定,每个应用/模型只能覆盖某些模板。也许不能。但是,无论是add_视图
还是change_视图
视图都会将app_标签
添加到上下文中,因此您可以使用它来测试特定的应用程序。根据模型进行更改需要覆盖ModelAdmin
上的这两个视图,并将module\u name
添加到上下文中。@ChrisPrattextra\u context['readonly']=True
不适用于Django 1.4。不知何故,该变量从未进入submit\u line.html
太糟糕了,Django 1.4不再允许每个应用程序/模型覆盖submit\u line.html
。(想知道他们为什么要摆脱它吗?)无论如何,在submit\u line.html
中,是否显示单个按钮取决于不同的上下文布尔值,例如show\u save
,show\u delete\u link
等。如何设置这些按钮以隐藏/显示按钮,而不实际覆盖模板?我尝试了extra_context
,但这不起作用——这似乎只是针对额外的上下文,而不是更改现有的上下文变量。有什么想法吗?你只能在每个应用的基础上覆盖某些模板。submit_line.html不是其中之一。这绝对是关于这个问题的最佳答案。为什么选票这么少?另外,如果您的模板位于自定义路径上,请在MyModelAdmin
类中使用template
属性。默认情况下,Django将检查多个位置以查看更改表单模板admin/myapp/model/change\u form.html
和admin/myapp/change\u form.html
。如何为所有应用禁用它?(接下来,我可以禁用单个应用)@akashrajkn您可以将ModelAdmin
子类化为ReadOnlyModelAdmin
,并将其用于您定义的所有应用。将该子类上的模板
定义为readonly\u change\u form.html
可能是最干净的方法。此外,建议定义get\u readonly\u字段
,以便字段显示为文本,而不是表单字段;看,谢谢!与@mat_gessel的答案结合使用(我创建了一个模板,read_o
{% extends "admin/change_form.html" %}
{% load admin_modify %}
{# remove the save buttons if read_only is truthy #}
{% block submit_buttons_top %}{% if not read_only %}{% submit_row %}{% endif %}{% endblock %}
{% block submit_buttons_bottom %}{% if not read_only %}{% submit_row %}{% endif %}{% endblock %}
class CartAdmin(admin.ModelAdmin):
list_display = ['listing']
def has_add_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
@admin.register(Object)
class Admin(admin.ModelAdmin):
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False