Административный интерфейс джанго позволяет настраивать права доступа к объектам различных приложений. Для любой модели любого приложения вы можете разрешить пользователю три действия: добавлять новые объекты, редактировать и удалять существующие объекты.
А что делать, если мы хотим разрешить пользователю редактировать только часть полей? И в то же время оставить возможность другим пользователям редактировать все поля.
Нам помогут прокси модели. В терминологии джанго прокси-модель — это объект, обладающий интерфейсом обычной модели, но не привязанный к базе данных, вернее он привязан к данным другой модели. Для чего это нужно?
В документации джанго используется следующий пример. Мы хотим, чтобы объекты модели
Вернёмся к нашей задаче. Прокси-модели полезны тем, что мы можем запретить пользователю работать с оригинальной моделью, разрешить ему доступ к прокси-модели и настроить форму редактирования так, чтобы были доступны только разрешённые поля.
Давайте, представим, что у нас есть следующая модель:
Мы хотим, чтобы редактор мог заходить в админку, видеть список статей, мог менять тэги, но не мог менять заголовок или тело статьи.
Давайте создадим для начала прокси-модель:
Теперь зарегистрируем эту модель в
Теперь, при заходите в админку пользователь сможет видеть список статей и сможет менять тэги у любой статьи, он также будет видеть заголовок и содержимое статьи, но не сможет их поменять.
Ещё один нюанс. Права доступа к объектам различных моделей реализованы в джанге через объекты модели Permission. Чтение — это один объект Permission, запись — другой, ещё один — удаление. Permission объекты для новых моделей создаются во время запуска команды
Вам придётся создать миграцию, которая будет посылать сигнал post_syncdb для вашей прокси-модели.
Подробности хака с миграцией я узнал в этом блоге.
А что делать, если мы хотим разрешить пользователю редактировать только часть полей? И в то же время оставить возможность другим пользователям редактировать все поля.
Нам помогут прокси модели. В терминологии джанго прокси-модель — это объект, обладающий интерфейсом обычной модели, но не привязанный к базе данных, вернее он привязан к данным другой модели. Для чего это нужно?
В документации джанго используется следующий пример. Мы хотим, чтобы объекты модели
auth.User
обладали дополнительным методом. Для этого мы создаём прокси-модель на базе модели auth.User
, описываем там этот метод и используем, где нужно, эту прокси-модель вместо оригинальной.Вернёмся к нашей задаче. Прокси-модели полезны тем, что мы можем запретить пользователю работать с оригинальной моделью, разрешить ему доступ к прокси-модели и настроить форму редактирования так, чтобы были доступны только разрешённые поля.
Давайте, представим, что у нас есть следующая модель:
class Article(models.Model):
title = models.CharField(...)
body = models.CharField(...)
tags = models.CharField(...)
Мы хотим, чтобы редактор мог заходить в админку, видеть список статей, мог менять тэги, но не мог менять заголовок или тело статьи.
Давайте создадим для начала прокси-модель:
class ArticleEditProxy(Article):
class Meta:
proxy = True
Теперь зарегистрируем эту модель в
admin.site
и назначим ей специальную форму, в которой доступны для редактирования только тэги
class ArticleEditProxyForm(forms.ModelForm):
class Meta:
model = ArticleEditProxy
fields = ['tags']
class ArticleEditProxyAdmin(admin.ModelAdmin):
list_display = ['title', 'tags']
form = ArticleEditProxyForm
readonly_fields = ['title', 'body']
admin.site.register(ArticleEditProxy, ArticleEditProxyAdmin)
Теперь, при заходите в админку пользователь сможет видеть список статей и сможет менять тэги у любой статьи, он также будет видеть заголовок и содержимое статьи, но не сможет их поменять.
Ещё один нюанс. Права доступа к объектам различных моделей реализованы в джанге через объекты модели Permission. Чтение — это один объект Permission, запись — другой, ещё один — удаление. Permission объекты для новых моделей создаются во время запуска команды
manage.py syncdb
. Если на момент создания прокси-модели ваше приложение контролировалось через south, то объекты Permission не будут созданы, south «не заметит» вашу прокси-модель, а операция syncdb не работает с приложениями, обслуживаемыми south.Вам придётся создать миграцию, которая будет посылать сигнал post_syncdb для вашей прокси-модели.
class Migration(SchemaMigration):
def forwards(self, orm):
db.send_create_signal('myapp', ['ArticleEditProxy'])
Подробности хака с миграцией я узнал в этом блоге.