Найти - Пользователи
Полная версия: Как запретить удаление данных для некоторых моделей?
Начало » Django » Как запретить удаление данных для некоторых моделей?
1 2
vvp91
Есть определенный класс моделей, для которых хотелось бы запретить удаление записей.
Вместо удаления снимать признак активности - булевое поле is_active, определенное для такого класса моделей.
Для такого класса определил менеджера, который возвращает только активные объекты.

Можно переопределить метод Model.delete, но при этом остается еще метод пакетного удаления QuerySet.delete, который не понятно как переопределять.

Как бы получше переопределить удаление объектов? Или возможны другие варианты, явно запрещающие удалять объекты. Возможно через использование permission.
Кто и что посоветует?
Ferroman
Да можно переопределить метод модели. По поводу QuerySet в таком случае оф. документация гоыорит
If you've provided a custom delete() method on a model class and want to ensure that it is called, you will need to “manually” delete instances of that model (e.g., by iterating over a QuerySet and calling delete() on each object individually) rather than using the bulk delete() method of a QuerySet
Т.е. придётся забыть про стандартный метод querySet'а и удалять записи итератором “вручную”.
Александр Кошелев
Ferroman
Т.е. придётся забыть про стандартный метод querySet'а и удалять записи итератором “вручную”.
Не вижу проблем чтобы переопределить delete и у QuerySet.
vvp91
Ferroman
Т.е. придётся забыть про стандартный метод querySet'а и удалять записи итератором “вручную”.
Да, я именно поэтому и задумался.
Daevaorn
Не вижу проблем чтобы переопределить delete и у QuerySet.
В принципе да, возможен вариант, когда дефолтный менеджер модели будет возвращать “мой” переопределенный QuerySet.
Но поскольку всех потрохов джанги я не знаю, то опасаюсь, что возможно какое-либо прямое использование оригинальных QuerySet для модели в джанге, минуя мой дефолтный менеджер.

Про саму модель все понятно.
Собственно и вопрос стоит такой - насколько корректно будет унаследовать от QuerySet и переопределить наследнику метод delete, и возвращать такой QuerySet во всех менеджерах моих специфических моделей?
Ferroman
Я бы QuerySet не трогал. Всё-таки “Special cases aren't special enough to break the rules”.
Переопределять части внешнего инструмента - не то же, что и свою модель.
vvp91
Ferroman
Я бы QuerySet не трогал. Всё-таки “Special cases aren't special enough to break the rules”.
Переопределять части внешнего инструмента - не тоже, что и свою модель.
Вот и опасаюсь.
Хотя ход мысли такой:
# Наследуюсь от QuerySet
class DescriptorQuerySet(query.QuerySet):
def delete(self):
self.update(is_active=False) # вот и все переопределение

class DescriptorManager(models.Manager):
def get_query_set(self):
return DescriptorQuerySet(self.model) # возвращаем переопределенный QuerySet

class Descriptor(models.Model):
is_active = models.BooleanField()
objects = DescriptorManager() # задаем менеджера модели
По идее здесь уже все должно начать работать как хочется.
НО!
Тут возникают опасения по работе админки - там и actions активно используют queryset`ы и формы и т.д.
Я понимаю, в доках написано, что админка использует исключительно дефолтный менеджер модели.
Но немного стремно.
Может кто копался в этих потрохах?
Ferroman
А поддерживать как?
vvp91
Ferroman
А поддерживать как?
В каком смысле?

class Descriptor - это абстрактная модель, от которой происходит наследование прикладных моделей. Таким образом прикладные модели имеют унаследованное поведение, заменяющее удаление объектов на снятие признака активности.

Если джанга в типовых механизмах действительно работает, как описано в документации, то для наследников Descriptor всегда будет использоваться “правильный” менеджер с правильным queryset`ом.
Ferroman
В смысле обновлять джангу, да и поддерживать код.
Но, хозяин - барин.
vvp91
Ferroman
В смысле обновлять джангу, да и поддерживать код.
Гхм!
Я вообще-то говорил про модели, менеджеры и кверисеты в моем приложении. В потроха джанги я влазить не собираюсь, манкипатчинга тоже не делаю.
Есть мой базовый модуль core, в котором определена абстрактная модель, рядом с ней лежит менеджер и кверисет, унаследованные от базовых менеджера и кверисета.
Про наследование от django.db.models.Manager хорошо написано в документации.
Никто не запрещает унаследоваться от django.db.models.query.QuerySet.
Просто я пытался выяснить, какие могут быть подводные камни. Похоже никто здесь с этим не сталкивался.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB