Это завернуть решение от реализации в моем приложении.Некоторые коды формы LWN's answer.
Есть 4 ситуации, что ваши данные удаляются:
- SQL запрос
- Вызывающие
delete()
на экземпляре модели: project.delete()
- Вызывающие
delete()
на QuerySet innstance: Project.objects.all().delete()
- Удалено иностранным полем на другом языке. Модель
Хотя в первом случае вы ничего не можете сделать, остальные три могут контролироваться мелкозернистым. Советуем, что в большинстве случаев вы никогда не должны удалять сами данные, поскольку эти данные отражают историю и использование нашего приложения. Настройка на active
Вместо этого выбрано булевское поле.
Для предотвращения delete()
на модели, например, подкласса delete()
в вашей модели декларации:
def delete(self):
self.active = False
self.save(update_fields=('active',))
Хотя delete()
на экземпляре QuerySet нуждается в небольшой настройки с менеджером пользовательских объектов, как в LWN's answer.
обернуть это в повторное использование:
class ActiveQuerySet(models.QuerySet):
def delete(self):
self.save(update_fields=('active',))
class ActiveManager(models.Manager):
def active(self):
return self.model.objects.filter(active=True)
def get_queryset(self):
return ActiveQuerySet(self.model, using=self._db)
class ActiveModel(models.Model):
""" Use `active` state of model instead of delete it
"""
active = models.BooleanField(default=True, editable=False)
class Meta:
abstract = True
def delete(self):
self.active = False
self.save()
objects = ActiveManager()
Использование, только su bclass ActiveModel
класс:
class Project(ActiveModel):
...
Тем не менее наш объект все еще может быть удален, если какой-либо один из его ForeignKey полей удаляются:
class Employee(models.Model):
name = models.CharField(name, unique=True)
class Project(models.Model):
name = models.CharField(name, unique=True)
manager = purchaser = models.ForeignKey(
Employee, related_name='project_as_manager')
>>> manager.delete() # this would cause `project` deleted as well
Это можно предотвратить путем добавления on_delete argument поля Модель:
class Project(models.Model):
name = models.CharField(name, unique=True)
manager = purchaser = models.ForeignKey(
Employee, related_name='project_as_manager',
on_delete=models.PROTECT)
По умолчанию on_delete
- CASCADE
, что приведет к удалению вашего экземпляра с помощью PROTECT
вместо этого поднимет ProtectedError
(подкласс IntegrityError
). Другая цель заключается в том, что ForeignKey данных следует хранить в качестве ссылки.
Это невозможно, только используя код Python; сама база данных также должна быть изменена. –
Спасибо за ваш комментарий. Сначала я ищу часть Python/Django и посмотрю, как далеко это заставляет меня в моем приложении. – dyve