Вы можете сделать это автоматически как для работы в запросе, так и для команды.
Сначала измените on_delete на SET_NULL, это позволит добавить некоторые логи c, поэтому немедленно удалить связанную запись
# models.py
class Post(models.Model):
created_by = models.ForeignKey(User, on_delete=models.SET_NULL)
class AnotherModel(models.Model):
created_by = models.ForeignKey(User, on_delete=models.SET_NULL)
class YetAnotherModel(models.Model):
created_by = models.ForeignKey(User, on_delete=models.SET_NULL)
Чтобы сделать ее автоматически, у вас есть две опции, каждая из которых использует сигналы:
Опция 1: Более подробные c для удаления логинов пользователя c, Вы можете вскоре после удаления пользователя удалить все связанные права и передать его другому пользователю.
Это будет активировано один раз и может быть очень эффективным в большой базе данных.
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
@receiver(pre_delete, sender=User)
def default_created_by_to_user(sender, **kwargs):
instance = kwargs["instance"]
default_user = User.objects.get(username='default')
# * Here you will have to register all the related models to change the owner
# * Filter all the owned records from the user and perform the update on them with the new default user
Post.objects.filter(created_by=instance).update(created_by=default_user)
AnotherModel.objects.filter(created_by=instance).update(created_by=default_user)
YetAnotherModel.objects.filter(created_by=instance).update(created_by=default_user)
Вариант 2: Обновление с целевых моделей. Это более надежно, так как будет срабатывать, когда пользователь удаляется, а также когда для selected_by установлено значение None. Просто зарегистрируйте одну и ту же функцию приемника для всех моделей в поле created_by
.
Это будет срабатывать для каждой записи, она может быть медленной в большой базе данных, но вы также можете переместить ее в фоновое задание, используя сельдерей.
@receiver(post_save, sender=Post)
@receiver(post_save, sender=AnotherModel)
@receiver(post_save, sender=YetAnotherModel)
def default_created_by_to_user(sender, **kwarg):
instance = kwargs["instance"]
# created_by will be None when the user is deleted
if instance.created_by:
default_user = User.objects.get(username='default')
# * sender is the model class.
# * Updating with update() will avoid to trigger post_save again
sender.objects.filter(pk=instance.pk).update(created_by=default_user)