Понимание администратора django readonly_fields - PullRequest
3 голосов
/ 23 января 2012

Я создал некоторый код, чтобы различать две группы пользователей в админке Django, в результате чего все поля показывались только для чтения или только некоторые из них, которые установлены непосредственно в классе ModelAdmin.

Сначала вот код:

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at','created_by',)

def get_form(self, request, obj=None, **kwargs):
    if obj:     # we are in edit mode
        if request.user.is_superuser:
            self.readonly_fields = ()
        else:
            for group in request.user.groups.all():
                if str(group) == 'readonlyuser':
                    allfields = tuple(obj._meta.get_all_field_names())
                    self.readonly_fields = allfields

    return super(PersonAdmin, self).get_form(request, obj, **kwargs)

Я делю между группами и соответственно устанавливаю поля.Все работает нормально, если пользователи из двух групп не вошли в систему одновременно! После того, как пользователь «только для чтения» вошел в систему, администратор также получит все поля только для чтения.

Мои проверки также предоставили решение: если я добавлю дополнительный оператор if для администратора в пределах для блока все работает как положено.

if str(group) == 'adminuser':
    self.readonly_fields = PersonAdmin.readonly_fields

Почему это происходит и что там происходит?

У меня нет специальных настроек кэша, и это происходит на сервере dev кактакже как и на Apache с WSGI.

Насколько я понимаю, request.user.groups.all () должен возвращать все группы, к которым в данный момент принадлежит пользователь, к которому принадлежит .Откуда Django получает все поля (только для чтения), если другой пользователь с другим IP-адресом и сессией соответствует этому блоку if?

Ответы [ 2 ]

12 голосов
/ 23 января 2012

ModelAdmin создается только один раз для всех запросов, которые он получает. Поэтому, когда вы определяете такие поля только для чтения, вы постоянно устанавливаете их на доске.

Пока вы используете Django 1.2+, есть метод get_readonly_fields, который вы можете использовать вместо этого именно для этой цели:

class MyModelAdmin(admin.ModelAdmin):
    ...

    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return super(MyModelAdmin, self).get_readonly_fields(request, obj)
        else:
            return ('created_at', 'created_by')

Удалите атрибут readonly_fields из вашего ModelAdmin или задайте для него поля, которые должны быть доступны только для каждого . Затем в блоке else укажите все поля, которые должны быть доступны только для чтения не суперпользователям.

1 голос
/ 23 января 2012

Поскольку поля в Django Admin устанавливаются (т. Е. Кэшируются) после первого запуска при перезапуске веб-сервера.Возможно, вы могли бы обойти это, повторно объявив кортеж readonly_fields.Примерно так (не проверено):

def get_form(self, request, obj=None, **kwargs):  
    self.readonly_fields = ('created_at','created_by',)
    # ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...