Как установить другой экземпляр в качестве внешнего ключа при удалении в django?

Итак, если у меня есть модель "компания" и модель "человек", и у модели "компания" есть владелец (экземпляр модели "человек"), и совладелец (тоже экземпляр модели "человек"), я хочу сделать так, чтобы при удалении владельца совладелец становился владельцем, а совладелец становился пустым, возможно ли это в Django?

Да, это возможно. Вы можете, например, переопределить метод delete:

class Company(models.Model):
    owner = models.ForeignKey(
        Person,
        null=True,
        on_delete=models.SET_NULL,
        related_name='owned_companies'
    )

    co_owner = models.ForeignKey(
        Person,
        null=True,
        on_delete=models.SET_NULL,
        related_name='co_owned_companies'
    ) 


class Person(models.Model):
    # fields and stuff...

    def delete(self, *args, **kwargs):
        for company in self.owned_companies.all():
            company.owner = company.co_owner
            company.co_owner = None
            company.save()
        super(Person, self).delete(*args, **kwargs)

Написано из головы, возможно on_delete должно быть models.DO_NOTHING на Company.owner, не уверен. Но в целом это должно работать.

Это не работает с массовыми функциями. Если вы хотите использовать массовые функции djangos, вам необходимо зарегистрировать сигнал предварительного удаления в качестве альтернативного метода.

Вы можете переопределить метод delete в модели Person, чтобы он изменил владельца компании на совладельца. Как только это изменение будет сделано, он удалит Person.

class Company(model.Models):
    owner = models.ForeignKey(Person, null=True, on_delete=DO_NOTHING)
    co_owner = models.ForeignKey(Person, null=True, on_delete=SET_NULL)

class Person(models.Model):
    #Person model stuff here

    def delete(self):
        companies = Company.objects.filter(owner=self)
        
        for company in companies:
            company.owner = company.co_owner
            company.owner = None
            company.save()
            super(Person, self).delete()
Вернуться на верх