Py学习  »  Django

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

Stevy Matt • 4 年前 • 787 次点击  

我有两个模型 __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)

每个 顾客 只能有一个 设备组 这是默认的。我希望能够防止默认组在 顾客 仍然存在。但是,当 顾客 如果删除,则应删除所有设备组,包括默认组。

为了防止删除默认组,我使用如下预删除信号:

# 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 当用户试图从 设备组 在Django管理的模型。

若要确保删除所有设备组(包括默认组),请在删除 顾客 ,我尝试使用另一个预删除信号来更改 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()

当试图删除 顾客 谁有违约 设备组 ,它将导致 保护错误 .

如何确保在删除 顾客 总是 全部的 删除设备组而不引发 保护错误 . 但是删除一个 设备组 当它是默认组时是否被阻止?

我使用的是Python3.7.2和Django 2.1.7

谢谢

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/50729
 
787 次点击  
文章 [ 2 ]  |  最新文章 4 年前
Jibin Mathews
Reply   •   1 楼
Jibin Mathews    5 年前

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

Stargazer
Reply   •   2 楼
Stargazer    5 年前

改变你的 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()