Как сделать экземпляр модели доступным только для чтения после однократного сохранения? - PullRequest
3 голосов
/ 21 января 2009

Одна из функциональных возможностей проекта Django, который я пишу, - отправка бюллетеня. У меня есть модель Newsletter и функция send_newsletter, которую я зарегистрировал для прослушивания сигнала Newsletter post_save. Когда объект новостной рассылки сохраняется через интерфейс администратора, send_newsletter проверяет, является ли created Истиной, и если да, он действительно отправляет почту.

Однако, по понятным причинам нет смысла редактировать уже отправленный бюллетень. Есть ли способ сделать объект Newsletter доступным только для чтения после его сохранения?

Edit:

Я знаю, что могу переопределить метод save объекта, чтобы вызвать ошибку или ничего не делать, если объект существовал. Однако я не вижу смысла в этом. Что касается первого, я не знаю, где поймать эту ошибку и как сообщить пользователю, что объект не был сохранен. Что касается последнего, то предоставление ложной обратной связи с пользователем (интерфейс администратора говорит, что сохранение выполнено успешно) не похоже на хорошую вещь.

Что я действительно хочу, так это позволить пользователю использовать интерфейс администратора, чтобы написать информационный бюллетень и отправить его, а затем просмотреть уже отправленные информационные бюллетени. Я хотел бы, чтобы интерфейс администратора отображал данные для отправленных информационных бюллетеней в не редактируемом поле ввода без кнопки «Сохранить». Как вариант, я бы хотел, чтобы кнопка «Сохранить» была неактивной.

Ответы [ 4 ]

7 голосов
/ 21 января 2009

Вы можете проверить, является ли это создание или обновление в методе save модели:

def save(self, *args, **kwargs):
    if self.pk:
        raise StandardError('Can\'t modify bla bla bla.')
    super(Payment, self).save(*args, **kwargs)

Код выше вызовет исключение, если вы попытаетесь сохранить существующий объект. Объекты, ранее не сохраненные, не имеют своих первичных ключей.

1 голос
/ 10 февраля 2009

Рекомендуемое чтение: Дзен Админа в главе 17 Книги Джанго .

Резюме: администратор не предназначен для того, что вы пытаетесь сделать: (

Однако, версия 1.0 книги охватывает только Django 0.96, и с тех пор произошли хорошие события.

В Django 1.0 администраторский сайт более настраиваемый. Поскольку я не настраивал администратора самостоятельно, мне придется угадывать на основе документов, но я бы сказал, что переопределение формы модели - ваша лучшая ставка.

0 голосов
/ 15 января 2014

Что вы можете легко сделать, это сделать все поля доступными только для чтения:

class MyModelAdmin(ModelAdmin):
    form = ...
    def get_readonly_fields(self, request, obj=None):
        if obj:
            return MyModelAdmin.form.Meta.fields
        else: # This is an addition
            return []

Что касается исчезновения Сохранить, было бы гораздо проще, если бы

  1. has_change_permission возвращение False не отключит даже отображение формы
  2. фрагмент кода, отвечающий за отрисовку элементов управления формы администратора (admin_modify.submit_row templatetag), не будет использовать show_save=True безоговорочно.

В любом случае, один из способов сделать этого парня не подлежащим визуализации:

  1. Создать альтернативную версию has_change_permission с правильной логикой:

    class NoSaveModelAdminMixin(object):
        def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
            response = super(NoSaveModelAdmin, self).render_change_form(request, context, add, change,form_url, obj)
            response.context_data["has_change_permission"] = self.has_real_change_permission(request, obj)
        def has_real_change_permission(self, request, obj):
            return obj==None
        def change_view(self, request, object_id, extra_context=None):
            obj = self.get_object(request, unquote(object_id))
            if not self.has_real_change_permission(request, obj) and request.method == 'POST':
                raise PermissionDenied 
            return super(NoSaveModelAdmin, self).change_view(request, object_id, extra_context=extra_context)
    
  2. Переопределить тег шаблона submit_row, подобный следующему:

    @admin_modify.register.inclusion_tag('admin/submit_line.html', takes_context=True)
    def submit_row(context):
        ...
            'show_save': context['has_change_permission']
        ...
    
    admin_modify.submit_row = submit_row
    
0 голосов
/ 19 марта 2010

используйте readonlyadmin в вашем amdin.py. Перечислите все поля, которые вы хотите сделать доступными только для чтения. После создания объекта вы не можете редактировать их, затем

используйте ссылку

http://www.djangosnippets.org/snippets/937/

Скопируйте файл, а затем импортируйте в ваш admin.py и используйте его

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...