Так я изменил Django 1.0.2, чтобы добавить разрешения на «просмотр». Извините, различий нет.
[X] 1. Добавлено «просмотр» в список разрешений по умолчанию
#./contrib/auth/management/__init__.py
def _get_all_permissions(opts):
"Returns (codename, name) for all permissions in the given opts."
perms = []
for action in ('add', 'change', 'delete', 'view'):
perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
return perms + list(opts.permissions)
[X] 2. Проверка разрешения 'view' добавлена для всех моделей
run manage.py syncdb
Я подтвердил, что теперь для всех таблиц в таблице auth_permissions добавлено разрешение на просмотр
[X] 3. Добавьте «get_view_permission» в класс модели по умолчанию.
Добавлено get_view_permission к классу модели. Вы можете найти это в файле ./db/models/options.py Это используется классом администратора на следующем шаге.
def get_view_permission(self):
return 'view_%s' % self.object_name.lower()
[X] 4. Добавить "has_view_permission" в класс администратора по умолчанию
Просто чтобы быть последовательным, я собираюсь добавить "has_view_permission" в систему. Похоже, это должно быть где-то в contrib / admin / options.py . Убедитесь, что если у пользователя есть разрешение на изменение, то автоматически отображаются права на просмотр.
# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change or view
the given Django model instance.
If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.
"""
opts = self.opts
return self.has_change_permission(request, obj) or \
request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())
# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
"""
Returns a dict of all perms for this model. This dict has the keys
``add``, ``change``, and ``delete`` and ``view`` mapping to the True/False
for each of those actions.
"""
return {
'add': self.has_add_permission(request),
'change': self.has_change_permission(request),
'delete': self.has_delete_permission(request),
'view': self.has_view_permission(request),
}
# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
...
else:
self.message_user(request, msg)
# Figure out where to redirect. If the user has change permission,
# redirect to the change-list page for this object. Otherwise,
# redirect to the admin index.
#if self.has_change_permission(request, None):
if self.has_change_permission(request, None) or self.has_view_permission(request, None):
post_url = '../'
else:
post_url = '../../../'
return HttpResponseRedirect(post_url)
# modified the change_view function so it becomes the details
# for users with view permission
#if not self.has_change_permission(request, obj):
if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
raise PermissionDenied
# modified the changelist_view function so it shows the list of items
# if you have view permissions
def changelist_view(self, request, extra_context=None):
"The 'change list' admin view for this model."
from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
opts = self.model._meta
app_label = opts.app_label
#if not self.has_change_permission(request, None):
if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
raise PermissionDenied
[X] 5. Обновите шаблон по умолчанию для отображения списка моделей, если у пользователя есть разрешение на просмотр
Я изменил шаблон по умолчанию в contrib / admin / templates / admin / index.html. Это также может быть обработано путем копирования файла в локальный каталог шаблонов. Я внес изменения в оба, поэтому у меня есть копия, если позднее обновление перезаписывает мои изменения.
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
{% if model.perms.view %}
<th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
{% endif %}
[X] 6. Подтвердите, что пользователь может «просматривать», но не «менять» модель
Найденный contrib / admin / templatetags / admin_modify.py, по-видимому, управляет появлением кнопок сохранения / сохранения и продолжения или нет. Изменено поле «Сохранить» по умолчанию всегда True, чтобы проверить контекст и разрешения. Пользователь должен иметь возможность сохранить, если у него есть изменения или добавить разрешения.
'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])
[X] 7. Удалите кнопку «Сохранить и добавить еще», если пользователь просматривает элемент
Снова изменил contrib / admin / templatetags / admin_modify.py. Я не знаю, что означает «save_as», поэтому, возможно, я что-то сломал, но, похоже, это сработало.
#'show_save_and_add_another': context['has_add_permission'] and
# not is_popup and (not save_as or context['add']) ,
'show_save_and_add_another': not is_popup and
(( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
and
(not save_as or context['add']),
[X] 8. Измените разрешение на просмотр, чтобы сделать форму доступной только для чтения
Если у пользователя есть разрешение на «просмотр» и «изменение», ничего не делать. Изменить вид переопределений.
Если пользователь имеет разрешение на «просмотр» без «изменения», измените формы по умолчанию и добавьте атрибуты DISABLED или READONLY к элементам формы. Не все браузеры поддерживают это, но для моих целей я могу требовать, чтобы пользователи использовали правильный. Пример отключен / только для чтения
Обнаружено, что не все браузеры поддерживают "только чтение", поэтому некоторые элементы управления устанавливаются только для чтения, а другие - на отключенные. Это позволяет пользователям при необходимости копировать данные из текстовых элементов управления.
#/django/contrib/admin/templates/admin/change_form.html
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
<script type="text/javascript">
jQuery('input:text').attr('readonly', 'readonly');
jQuery('textarea').attr('readonly', 'readonly');
jQuery('input:checkbox').attr('disabled', true);
jQuery('select').attr('disabled', true);
jQuery('.add-another').hide();
</script>
{% endif %}