django ORM 外键约束条件on_delete

目录

​编辑

一、CASCADE

二、PROTECT

三、SET_NULL

四、SET_DEFAULT

五、SET(值)

总结

1、需求:


-- 禁用外键约束
SET FOREIGN_KEY_CHECKS=0;
-- 清空表格
truncate table app1_book;
truncate table app1_publish;

INSERT INTO `app1_publish` VALUES (1, '张三', '昆明', '123@qq.com');
INSERT INTO `app1_publish` VALUES (2, '李四', '玉溪', '1234@qq.com');
INSERT INTO `app1_publish` VALUES (3, '王五', '大理', '1234@qq.com');

INSERT INTO `app1_book` VALUES (1, '标题1', 1.00, '2023-08-09', 1);
INSERT INTO `app1_book` VALUES (2, '标题2', 1.00, '2023-08-09', 1);
INSERT INTO `app1_book` VALUES (3, '标题3', 1.00, '2023-08-09', 1);
INSERT INTO `app1_book` VALUES (4, '标题三', 1.00, '2023-08-09', 2);
INSERT INTO `app1_book` VALUES (5, '标题四', 1.00, '2023-08-09', 2);


-- 启动外键约束
SET FOREIGN_KEY_CHECKS=1;

一、CASCADE

这就是默认的选项,级联删除,你无需显性指定它。

from django.db import models

# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()

def  delete(request):
    delete = Publish.objects.filter(pk=1).delete()
    print(delete)
    return JsonResponse({"msg":"删除成功","data":delete})

 注意:

使用CASCADE会将关联的其他内容页进行删除,如删除 Publish 中pk=1的会把Book中publish__id=1的也一起删除

二、PROTECT

保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。

from django.db import models

# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.PROTECT)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()

def  delete(request):
    try:
        delete = Publish.objects.filter(pk=1).delete()
        print(delete)
        return JsonResponse({"msg":"删除成功","data":delete})
    except Exception as e:
        print(e)
        return JsonResponse({"msg": "删除失败", "error": str(e)})

 

 删除无引用的外键数据


def  delete(request):
    try:
        delete = Publish.objects.filter(pk=1).delete()
        print(delete)
        return JsonResponse({"msg":"删除成功","data":delete})
    except Exception as e:
        print(e)
        exception_name = type(e).__name__
        print('exception_name:',exception_name)
        return JsonResponse({"msg": "删除失败", "error": str(e)})

三、SET_NULL

置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。

from django.db import models

# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.SET_NULL,null=True)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()

def  delete(request):
    try:
        delete = Publish.objects.filter(pk=1).delete()
        print(delete)
        return JsonResponse({"msg":"删除成功","data":delete})
    except Exception as e:
        print(e)
        exception_name = type(e).__name__
        print('exception_name:',exception_name)
        return JsonResponse({"msg": "删除失败", "error": str(e)})

四、SET_DEFAULT

置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。

from django.db import models

# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.SET_DEFAULT,default="",null=True)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()
def  delete(request):
    try:
        delete = Publish.objects.filter(pk=1).delete()
        print(delete)
        return JsonResponse({"msg":"删除成功","data":delete})
    except Exception as e:
        print(e)
        exception_name = type(e).__name__
        print('exception_name:',exception_name)
        return JsonResponse({"msg": "删除失败", "error": str(e)})

五、SET(值)

自定义一个值,该值当然只能是对应的实体了


# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish", on_delete=models.SET(2))


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    email = models.EmailField()
def  delete(request):
    try:
        delete = Publish.objects.filter(pk=1).delete()
        print(delete)
        return JsonResponse({"msg":"删除成功","data":delete})
    except Exception as e:
        print(e)
        exception_name = type(e).__name__
        print('exception_name:',exception_name)
        return JsonResponse({"msg": "删除失败", "error": str(e)})


总结

1、需求:

如果需要删除引用的外键后才能删除就使用:  on_delete=models.PROTECT

如果需删除全部使用: on_delete=models.CASCADE

允许删除字段: on_delete=models.SET_NULL 或者 on_delete=models.SET_DEFAULT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值