Django Admin- disable Editing and remove “Save” bu

2019-02-03 06:05发布

I have a Django Model which I wish to be only readonly. No adds and edits allowed.

I have marked all fields readonly and overridden has_add_permission in ModelAdmin as:

class SomeModelAdmin(admin.ModelAdmin):
     def has_add_permission(self, request):
        return False

Is there a similar has_edit_permission? Which can be disabled to remove "Save" and "Save and continue" buttons? And replace by a simple "Close and Return" button.

Django Documentation Only mentions only about read only fields not about overriding edit permissions.

7条回答
We Are One
2楼-- · 2019-02-03 06:34

Updated answer using Django 1.8 (Python 3 syntax).

There are three things to do:
1) extend the admin change form template, adding an if to conditionally suppress the submit buttons
2) override admin.ModelAdmin.change_view() and set a context var for the template if to read
3) prohibit unwanted POST requests (from DOM hacking, 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)

def change_view(self, request, object_id, form_url='', extra_context=None):
  obj = MyModel.objects.get(pk=object_id)
  editable = obj.get_status() == 'Active'

  if not editable and request.method == 'POST':
    return HttpResponseForbidden("Cannot change an inactive MyModel")

  more_context = {
    # set a context var telling our customized template to suppress the Save button group
    'my_editable': editable,
  }
  more_context.update(extra_context or {})
  return super().change_view(request, object_id, form_url, more_context)
查看更多
虎瘦雄心在
3楼-- · 2019-02-03 06:50

For 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)
查看更多
一夜七次
4楼-- · 2019-02-03 06:52

I had the same problem - the easiest way to do this, is to include some custom JS.

In you admin.py file include

class Media:
    js = ('/static/js/admin.js',)

Then in your admin.js file, include the following JS.

(function($) {
    $(document).ready(function($) {
         $(".submit-row").hide()
    });
})(django.jQuery);

The row is gone - it should work in all versions of Django too.

查看更多
女痞
5楼-- · 2019-02-03 06:53

I had same problem. I fixed it in 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

In MyModelAdmin class, add following function

@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)
查看更多
smile是对你的礼貌
6楼-- · 2019-02-03 06:56

Override the templates/admin/submit_line.html template and make the buttons whatever you want. You can do this for only the specific model by putting it in templates/admin/[app_label]/[model]/submit_line.html.

To conditionally show the default submit line or your custom submit line, override ModelAdmin.change_view, and add a boolean to extra_context:

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)
查看更多
孤傲高冷的网名
7楼-- · 2019-02-03 07:00

You could try this package Django Admin View Permission. This package adds a view permission for the specified models and handles the other stuff automatically.

查看更多
登录 后发表回答