Я думаю, что вы имеете в виду тот факт, что вам обычно приходится явно указывать Monitor.objects.all().delete()
. Вы можете получить такое поведение, реализовав свой менеджер и набор запросов отдельно вместо создания менеджера из набора запросов с помощью as_manager
, например:
class NoBinLogQuerySet(models.QuerySet):
def delete(self, *args, **kwargs):
with connection.cursor() as cur:
cur.execute('SET @@session.sql_log_bin = 0')
ret = super().delete(*args, **kwargs)
cur.execute('SET @@session.sql_log_bin = 1')
return ret
class NoBinLogManager(models.Manager):
def get_queryset(self):
return NoBinLogQuerySet(self.model, using=self._db)
class Monitor(models.Model):
...
objects = models.Manager()
nobinlog = NoBinLogManager()
Это не защитит вас от неправильных аргументов .filter()
и случайного удаления ваших данных.
Если у вас есть фиксированный набор условий, таких как «записи старше 30 дней», я бы написал вспомогательный метод вместо создания дополнительного менеджера. В этом методе вы можете жестко запрограммировать условие. В качестве дополнительной меры безопасности вы можете добавить параметр dry_run
, который будет возвращать записи, которые будут удалены. Примерно так:
def delete_old_records(dry_run=True):
kwargs = {'updated_at__lt': now() - timedelta(days=30)}
if dry_run:
ret = Monitor.objects.filter(**kwargs)
else:
with connection.cursor() as cur:
cur.execute('SET @@session.sql_log_bin = 0')
ret = Monitor.objects.delete(**kwargs)
cur.execute('SET @@session.sql_log_bin = 1')
return ret
В зависимости от того, как вы выполняете этот метод, рассмотрите возможность создания настраиваемой команды управления.