2012-02-29 3 views
5

Есть ли способ, надеюсь, без нарушения администрирования, чтобы отключить редактирование существующих экземпляров модели на уровне ORM?Django - отключить редактирование модели

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

Предпочтительно вариант «Сохранить как» должен работать.

ответ

8

Переписать функцию сохранения для вашей модели, как так:

 
class MyModel(models.Model): 

    def save(self, *args, **kwargs): 

     if self.pk is None: 
      super(MyModel, self).save(*args, **kwargs) 

Эта функция только вызвать суперкласс сохранить функцию (которая на самом деле сохранение изменений), если нет рк, например, экземпляр модели является новым.

+3

Что мне не нравится в этом подходе, так это то, что после нажатия кнопки «Сохранить» есть сообщение «... было успешно изменено». Ничего не изменилось. Есть ли способ изменить это сообщение на «Изменение отключено»? Или еще лучше отключить нажатие этой строки? – WebOrCode

+3

Есть ли способ предотвратить 'MyModel.objects.filter (pk = my_model.pk) .update (name =" bob ")' –

4

Вы можете переопределить сохраните модель класса,() (ничего не делать, если self.pk) и удалять (всегда ничего не делать)

Но на самом деле, уровень базы данных является самым безопасным местом для этого. Например, в PostgreSQL можно написать два простых правила:

CREATE RULE noupd_myapp_mymodel AS ON UPDATE TO myapp_mymodel 
    DO NOTHING; 
CREATE RULE nodel_myapp_mymodel AS ON DELETE TO myapp_mymodel 
    DO NOTHING; 

В любом случае, администратор бы ничего об этом не знает, так что все еще выглядит редактируемые. См. Мой ответ на Whole model as read-only, чтобы попытаться создать модель для чтения только для администратора. Для ваших целей сохраните разрешение добавления как есть, и только объявляйте все поля только для чтения, когда не добавляете.

EDIT: одна из причин, почему переопределение метода delete() в классе модели небезопасно, заключается в том, что «массовое удаление» (Queryset.delete(), например, действие флажков admin) не будет вызывать удаление отдельных экземпляров (), он перейдет прямо к SQL: https://docs.djangoproject.com/en/dev/topics/db/queries/#deleting-objects

+0

Спасибо за этот ответ. Я пытаюсь выяснить, как передать эти правила на models.py. Наиболее важной частью документации, которую я нашел, является [Выполнение пользовательского SQL непосредственно] (https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly). Не могли бы вы привести простой пример, иллюстрирующий этот подход? – raratiru

+1

Вышеупомянутые статуты SQL выполняются только один раз, как вам угодно. Как только правило будет в Postgres, оно будет соблюдаться. Поэтому вы можете использовать psql для этого. Если вы используете юг для миграции модели, я бы рекомендовал настраиваемую миграцию, чтобы db.execute() правила. См. Например, ответ http://stackoverflow.com/a/5466251/640759 –

Смежные вопросы