Вся модель как только для чтения - PullRequest
14 голосов
/ 27 октября 2011

Есть ли способ сделать модель только для чтения в админке django? но я имею в виду всю модель. Итак, без добавления, без удаления, без изменения, просто посмотрите на объекты и поля, все только для чтения?

Ответы [ 6 ]

11 голосов
/ 01 ноября 2011

ModelAdmin предоставляет ловушку get_readonly_fields () - следующее не проверено, моя идея состоит в том, чтобы определить все поля так, как это делает ModelAdmin, не сталкиваясь с рекурсией самих полей только для чтения:

from django.contrib.admin.util import flatten_fieldsets

class ReadOnlyAdmin(ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if self.declared_fieldsets:
            fields = flatten_fieldsets(self.declared_fieldsets)
        else:
            form = self.get_formset(request, obj).form
            fields = form.base_fields.keys()
        return fields

затем создайте подкласс / mixin для этого администратора, где бы он ни был администратором только для чтения.

Для добавления / удаления и исчезновения их кнопок, вы, вероятно, также захотите добавить

    def has_add_permission(self, request):
        # Nobody is allowed to add
        return False
    def has_delete_permission(self, request, obj=None):
        # Nobody is allowed to delete
        return False

P.S .: В ModelAdmin, если has_change_permission (lookup или your override) возвращает False, вы не получите представление об изменении объекта - и ссылка на него даже не будет показана. Было бы здорово, если бы это было так, и по умолчанию get_readonly_fields () проверил разрешение на изменение и в этом случае установил все поля только для чтения, как описано выше. Таким образом, неизменяющие могут, по крайней мере, просматривать данные ... учитывая, что текущая структура администратора предполагает view = edit, как указывает jathanism, это, вероятно, потребовало бы введения разрешения "view" поверх add / change / delete ...

РЕДАКТИРОВАТЬ: в отношении установки всех полей только для чтения, также не проверено, но выглядит многообещающе:

readonly_fields = MyModel._meta.get_all_field_names()

РЕДАКТИРОВАТЬ: Вот еще один

if self.declared_fieldsets:
    return flatten_fieldsets(self.declared_fieldsets)
else:
    return list(set(
        [field.name for field in self.opts.local_fields] +
        [field.name for field in self.opts.local_many_to_many]
    ))
3 голосов
/ 24 февраля 2017

Так как «разрешения на просмотр» не попадут в Django 1.11 , к сожалению, вот решение, которое делает ваш ModelAdmin доступным только для чтения по , сохраняя изменения модели и добавляя историю модели записи в журнале без операции .

def false(*args, **kwargs):
    """A simple no-op function to make our changes below readable."""
    return False

class MyModelReadOnlyAdmin(admin.ModelAdmin):
    list_display = [
        # list your admin listview entries here (as usual) 
    ]
    readonly_fields = [
        # list your read-only fields here (as usual)
    ]

    actions = None
    has_add_permission = false
    has_delete_permission = false
    log_change = false
    message_user = false
    save_model = false

( ПРИМЕЧАНИЕ: Не путайте помощника false no-op со встроенным False. Если вы не симпатизируете вспомогательной функции вне класса, переместите ее в класс, назовите это no_op или что-то еще, или переопределите затронутые атрибуты обычными def с. Меньше СУХОГО, но если вам все равно ...)

Это будет:

  1. удалить выпадающий список действий (с «удалить») в виде списка
  2. запретить добавление новых записей модели
  3. запретить удаление существующих записей модели
  4. избегать создания записей журнала в истории модели
  5. избегать отображения сообщений об успешном изменении после сохранения
  6. избегать сохранения изменений changeform в базе данных

Не будет:

  • удалите или замените две кнопки «Сохранить и продолжить редактирование» и «СОХРАНИТЬ» (что было бы неплохо для улучшения взаимодействия с пользователем)

Обратите внимание, что get_all_field_names (как указано в принятом ответе) было удалено в Django 1.10 . Протестировано с Django 1.10.5.

2 голосов
/ 27 октября 2011

Вы можете настроить классы ModelAdmin с помощью атрибута readonly_fields.См. этот ответ для получения дополнительной информации.

1 голос
/ 16 октября 2018

Выбранный ответ не работает для Django 1.11, и я нашел гораздо более простой способ сделать это, поэтому я решил поделиться:

class MyModelAdmin(admin.ModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        return [f.name for f in obj._meta.fields]

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

    def has_add_permission(self, request):
        return False
0 голосов
/ 07 февраля 2016

Согласно моему тесту на Django 1.8 мы не можем использовать следующее, как отмечено в ответе № 3, но оно работает на Django 1.4 :

##     self.get_formset(request, obj)      ##
answer 3 needs fix. Generally, alternative codes for this issue about below section 
##          form = self.get_formset(request, obj).form    ##
##          fields = form.base_fields.keys()              ##

Может быть что-то вроде:

#~ (A) or
[f.name for f in self.model._meta.fields]

#~ (B) or
MyModel._meta.get_all_field_names()

#~ (C) 
list(set([field.name for field in self.opts.local_fields] +
                        [field.name for field in self.opts.local_many_to_many]         
  ))
0 голосов
/ 11 июня 2013

У меня был похожий сценарий, в котором:

  1. Пользователь должен иметь возможность создавать объекты модели
  2. Пользователь должен иметь возможность просматривать список объектов модели
  3. Пользователь НЕ ДОЛЖЕН иметь возможность редактировать объект после его создания

1.Переопределение представления изменения

Поскольку можно переопределить change_view() в ModelAdmin, мы можем использовать это для предотвращения редактирования экземпляров модели после их создания.Вот пример, который я использовал:

def change_view(self, request, object_id, form_url='', extra_context=None):
    messages.error(request, 'Sorry, but editing is NOT ALLOWED')
    return redirect(request.META['HTTP_REFERER'])

2.Условно изменить разрешения на редактирование

Я также понял, что документы интерпретируют результат ModelAdmin.has_change_permission() по-разному:

Должен возвращать True, если редактирование obj разрешено, False в противном случае.Если obj имеет значение None, должно возвращать значение True или False, чтобы указать, разрешено ли вообще редактирование объектов этого типа (например, False будет интерпретироваться как означающее, что текущему пользователю не разрешено редактировать любой объект этого типа).

То есть я могу проверить, является ли obj None, и в этом случае я возвращаю True, в противном случае я возвращаю False, и это фактически позволяет пользователям просматривать список изменений, ноневозможно изменить или просмотреть форму change_form после сохранения экземпляра модели.

def has_change_permission(self, request, obj = None, **kwargs):
    if obj is None:
        return True
    else:
        return False

Хотя я думаю, что это может также отменить любые разрешения MODEL_can_change, позволяющие нежелательным глазам просматривать список изменений?

...