Django:除非删除父模型,否则阻止删除子模型

问题描述 投票:1回答:2

我有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)                        

当用户尝试从Django Admin中的ProtectedError模型中删除默认组时,这会引发Device_group并阻止删除。

为了确保在删除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()

当试图删除一个有默认CustomerDevice_group时,它会产生ProtectedError

如何确保在删除Customer后,所有设备组都会被删除而不会抛出ProtectedError。但是当它是默认组时,会阻止删除Device_group吗?

我使用的是Python 3.7.2和Django 2.1.7

谢谢

python django
2个回答
1
投票

更改你的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
投票

default_group.is_default=False之后你需要通过default_group.save()保存它

© www.soinside.com 2019 - 2024. All rights reserved.