Чтобы сделать это правильно, нужно выполнить два шага:
- Скрыть ссылку редактирования, чтобы никто не оступился на странице сведений (изменить вид) по ошибке.
- Измените представление изменения, чтобы перенаправить обратно в представление списка.
Вторая часть важна: если вы этого не сделаете, люди все равно смогут получить доступ к представлению изменений, введя URL-адрес напрямую (что, по-видимому, вам не нужно). Это тесно связано с тем, что OWASP называет «Небезопасная прямая ссылка на объект» .
В рамках этого ответа я создам класс ReadOnlyMixin
, который можно использовать для обеспечения всех отображаемых функций.
Скрытие ссылки редактирования
Django 1.7 делает это действительно легко: вы просто устанавливаете list_display_links
на None
.
class ReadOnlyMixin(): # Add inheritance from "object" if using Python 2
list_display_links = None
Django 1.6 (и, вероятно, ранее) не делает это настолько простым. Довольно много ответов на этот вопрос предложили переопределить __init__
, чтобы установить list_display_links
после того, как объект был построен, но это усложняет повторное использование (мы можем переопределить конструктор только один раз).
Я думаю, что лучший вариант - переопределить метод get_list_display_links
Джанго следующим образом:
def get_list_display_links(self, request, list_display):
"""
Return a sequence containing the fields to be displayed as links
on the changelist. The list_display parameter is the list of fields
returned by get_list_display().
We override Django's default implementation to specify no links unless
these are explicitly set.
"""
if self.list_display_links or not list_display:
return self.list_display_links
else:
return (None,)
Это делает наш миксин простым в использовании: он скрывает ссылку редактирования по умолчанию, но позволяет нам добавить его обратно, если это требуется для определенного вида администратора.
Перенаправление на просмотр списка
Мы можем изменить поведение страницы сведений (изменить представление), переопределив метод change_view
. Вот расширение техники, предложенной Крисом Праттом, которая автоматически находит нужную страницу:
enable_change_view = False
def change_view(self, request, object_id, form_url='', extra_context=None):
"""
The 'change' admin view for this model.
We override this to redirect back to the changelist unless the view is
specifically enabled by the "enable_change_view" property.
"""
if self.enable_change_view:
return super(ReportMixin, self).change_view(
request,
object_id,
form_url,
extra_context
)
else:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
opts = self.model._meta
url = reverse('admin:{app}_{model}_changelist'.format(
app=opts.app_label,
model=opts.model_name,
))
return HttpResponseRedirect(url)
Опять же, это можно настраивать - переключая enable_change_view
на True
, вы можете снова включить страницу сведений.
Снятие кнопки «Добавить ITEM »
Наконец, вы можете переопределить следующие методы, чтобы люди не могли добавлять или удалять новые элементы.
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
Эти изменения будут:
- отключить кнопку «Добавить элемент »
- запретить людям добавлять элементы напрямую, добавив
/add
к URL-адресу
- предотвратить массовое удаление
Наконец, вы можете удалить действие «Удалить выбранные items », изменив параметр actions
.
Собираем все вместе
Вот готовый миксин:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
class ReadOnlyMixin(): # Add inheritance from "object" if using Python 2
actions = None
enable_change_view = False
def get_list_display_links(self, request, list_display):
"""
Return a sequence containing the fields to be displayed as links
on the changelist. The list_display parameter is the list of fields
returned by get_list_display().
We override Django's default implementation to specify no links unless
these are explicitly set.
"""
if self.list_display_links or not list_display:
return self.list_display_links
else:
return (None,)
def change_view(self, request, object_id, form_url='', extra_context=None):
"""
The 'change' admin view for this model.
We override this to redirect back to the changelist unless the view is
specifically enabled by the "enable_change_view" property.
"""
if self.enable_change_view:
return super(ReportMixin, self).change_view(
request,
object_id,
form_url,
extra_context
)
else:
opts = self.model._meta
url = reverse('admin:{app}_{model}_changelist'.format(
app=opts.app_label,
model=opts.model_name,
))
return HttpResponseRedirect(url)
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False