Django Admin-отключить редактирование и удалить кнопки "Сохранить" для определенной модели

у меня есть модель Django, которую я хочу только читать. Не допускается добавление и редактирование.

я отметил все поля только для чтения и переопределил has_add_permission в ModelAdmin как:

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

есть ли аналогичные has_edit_permission? Что можно отключить, чтобы удалить кнопки" Сохранить "и" сохранить и продолжить"? И замените простой кнопкой" закрыть и вернуть".

Документация Django только упоминает только о полях только для чтения, а не о переопределении редактировать разрешения.

7 ответов


переопределить templates/admin/submit_line.html шаблон и сделать кнопки, что вы хотите. Вы можете сделать это только для конкретной модели, поместив ее в templates/admin/[app_label]/[model]/submit_line.html.

чтобы условно показать строку отправки по умолчанию или пользовательскую строку отправки, переопределите ModelAdmin.change_view и добавить boolean к 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)

у меня была такая же проблема. Я установил его в 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.8 (синтаксис Python 3).

есть три вещи делать:
1) расширьте шаблон формы изменения администратора, добавив if условно подавить кнопок
2) переопределить admin.ModelAdmin.change_view() и установите контекст var для шаблона if читать
3) запретить неугодные POST запросы (от взлома DOM, скручиваемость/почтальон)


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)

Для 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)

у меня была та же проблема - самый простой способ сделать это-включить некоторые пользовательские JS.

в вас admin.py файл включает

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

затем в вашем администраторе.JS файл, включают в себя следующие JS.

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

строка исчезла - она должна работать во всех версиях Django тоже.


вы можете попробовать этот пакет Разрешение Администратора Django View. Этот пакет добавляет view permission для указанных моделей и обрабатывает другие вещи автоматически.


основанный на превосходном ответ от @mat_gessel, вот мое решение:

основные отличия UX'y:

также:

  • переопределить форму change_form.HTML-код App-wide, потому что read_only такое полезное, неинвазивное повышение
  • определение has_delete_permission (может не потребоваться OP)
  • тест request.method != 'GET' предупреждения PATCH и друзья (не совсем уверен, что это требуется, tbh)

my_app/admin.py

from django.core.urlresolvers import reverse
from django.shortcuts import redirect

from django.contrib import admin
from django.contrib import messages


class MyModelAdmin(admin.ModelAdmin):
    # let's assume two fields...
    fields = (field1, field2)

    def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        if object_id:
            extra_context = extra_context or {}
            extra_context['read_only'] = True

            if request.method != 'GET':
                messages.error(request, "Cannot edit a MyModel object")
                return redirect(
                    reverse('admin:myapp_mymodel_change', args=[object_id])
                )

        return super(MyModelAdmin, self).changeform_view(request, object_id, extra_context=extra_context)

    def has_delete_permission(self, request, obj=None):
        return False

    def get_readonly_fields(self, request, obj=None):
        if obj:
            # display all fields as text, rather than inputs
            return (field1, field2)
        else:
            return []

admin/change_form.HTML-код

{% 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 %}

(протестировано на Django 1.9: heads up: некоторые импорт переместился с тех пор, например reverse)