Django: запретить удаление дочерней модели, если родительская модель не удалена - PullRequest
1 голос
/ 01 апреля 2019

У меня есть 2 модели (я упустил представление __str__ для простоты).

Customer:

# models.py

class Customer(models.Model):
    customer_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, 
                                     editable=False, db_index=True)
    customer_name = models.CharField(max_length=128)

и Device_group:

# models.py

class Device_group(models.Model):
    group_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, 
                                  editable=False, db_index=True)
    customer_uuid = models.ForeignKey(Customer, on_delete=models.CASCADE)
    device_group_name = models.CharField(max_length=20)
    color = models.CharField(max_length=8)
    is_default = models.BooleanField(default=False)

Каждый Customer может иметь только 1 Device_group, который используется по умолчанию.Я хочу иметь возможность запретить удаление группы по умолчанию, когда Customer все еще существует.Однако при удалении Customer все группы устройств, включая группу по умолчанию, должны быть удалены.

Чтобы предотвратить удаление группы по умолчанию, я использую сигнал pre_delete, например:

# signals.py

@receiver(pre_delete, sender=Device_group)
def protect_default_group(sender, instance, **kwargs):
    if instance.is_default:
        raise ProtectedError('The default group cannot be deleted.', instance)                        

Это поднимает ProtectedError и предотвращает удаление, когда пользователь пытается удалить группу по умолчанию из модели Device_group в Django Admin.

Чтобы убедиться, что все группы устройств, включая группу по умолчанию,удаленный при удалении Customer, я попытался использовать другой сигнал pre_delete, чтобы изменить поле is_default на False и удалить группу следующим образом:

# signals.py

@receiver(pre_delete, sender=Customer)
def unprotect_default_group(sender, instance, **kwargs):
    default_group = Device_group.objects.get(customer_uuid=instance, is_default=True)                                         
    default_group.is_default=False
    default_group.delete()

При попытке удалить Customer whoимеет значение по умолчанию Device_group, это приводит к ProtectedError.

Как мне убедиться, что при удалении Customer всегда всех групп устройствудаляются без броска ProtectedError.Но удаление Device_group запрещено, когда это группа по умолчанию?

Я использую Python 3.7.2 и Django 2.1.7

Спасибо

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Измените on_delete действие:

customer_uuid = models.ForeignKey(Customer, on_delete=models.DO_NOTHING)

Затем настройте свой сигнал.

@receiver(pre_delete, sender=Customer)
def unprotect_default_group(sender, instance, **kwargs):
    Device_group.objects.filter(customer_uuid=instance,
    is_default=False).delete()
0 голосов
/ 01 апреля 2019

После default_group.is_default=False необходимо сохранить его на default_group.save()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...