Django数据模型中on_delete使用详解


Posted in Python onNovember 30, 2020

on_delete属性针对外键ForeignKey

一、django3.0官方文档介绍:

Many-to-one relationships多对一关系

To define a many-to-one relationship, use django.db.models.ForeignKey. You use it just like any other Field type: by including it as a class attribute of your model.

ForeignKey requires a positional argument: the class to which the model is related.

For example, if a Car model has a Manufacturer ? that is, a Manufacturer makes multiple cars but each Car only has one Manufacturer ? use the following definitions:

from django.db import models

class Manufacturer(models.Model):
  # ...
  pass

class Car(models.Model):
  manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
  # ...

 You can also create recursive relationships (an object with a many-to-one relationship to itself) and relationships to models not yet defined; see the model field reference for details.

It's suggested, but not required, that the name of a ForeignKey field (manufacturer in the example above) be the name of the model, lowercase. You can, of course, call the field whatever you want.

常见的使用方式(设置为null)

class ApiList(models.Model):
 desc = models.CharField(max_length=255, verbose_name="接口描述")
 keyword = models.CharField(max_length=100, verbose_name="请求关键字")
 response = models.TextField(verbose_name="响应结果")
 api = models.ForeignKey(Api, blank=True, null=True, on_delete=models.SET_NULL, verbose_name="所属接口")
 status = models.IntegerField(default=1, verbose_name="状态")
 create_at = models.CharField(max_length=20, verbose_name="创建时间")
 update_at = models.CharField(max_length=20, verbose_name="更新时间")

一对多(ForeignKey)

class ForeignKey(ForeignObject):
  def __init__(self, to, on_delete, related_name=None, related_query_name=None,
         limit_choices_to=None, parent_link=False, to_field=None,
         db_constraint=True, **kwargs):
    super().__init__(to, on_delete, from_fields=['self'], to_fields=[to_field], **kwargs)

一对一(OneToOneField)

class OneToOneField(ForeignKey):
  def __init__(self, to, on_delete, to_field=None, **kwargs):
    kwargs['unique'] = True
    super().__init__(to, on_delete, to_field=to_field, **kwargs)

从上面外键(ForeignKey)和一对一(OneToOneField)的参数中可以看出,都有on_delete参数,而 django 升级到2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常:

TypeError: __init__() missing 1 required positional argument: 'on_delete'

因此,整理一下on_delete参数的各个值的含义:

on_delete=None,        # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE,   # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT,   # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL,  # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET,     # 删除关联数据,
 a. 与之关联的值设置为指定值,设置:models.SET(值)
 b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

多对多(ManyToManyField)

class ManyToManyField(RelatedField):
  def __init__(self, to, related_name=None, related_query_name=None,
         limit_choices_to=None, symmetrical=None, through=None,
         through_fields=None, db_constraint=True, db_table=None,
         swappable=True, **kwargs):
    super().__init__(**kwargs)

因为多对多(ManyToManyField)没有 on_delete 参数,所以略过不提. 

二、on_delete外键删除方式

  1. CASCADE:级联删除。当Manufacturer对象删除时,它对应的Car对象也会删除。
  2. PROTECT:保护模式,采用该选项,删除时会抛出ProtectedError错误。
  3. SET_NULL:置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。当Manufacturer对象删除时,它对应的Car对象的manufacturer字段会置空,前提是null=True
  4. SET_DEFAULT:置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
  5. SET():自定义一个值,该值当然只能是对应的实体了

django3.0关于models官方文档地址:
1.https://docs.djangoproject.com/en/3.0/topics/db/models/
2.https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey

到此这篇关于Django数据模型中on_delete使用详解的文章就介绍到这了,更多相关Django on_delete使用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python判断两个对象相等的原理
Dec 12 Python
详解python OpenCV学习笔记之直方图均衡化
Feb 08 Python
Python实现接受任意个数参数的函数方法
Apr 21 Python
python list是否包含另一个list所有元素的实例
May 04 Python
Python 查看list中是否含有某元素的方法
Jun 27 Python
python requests爬取高德地图数据的实例
Nov 10 Python
Python2 Selenium元素定位的实现(8种)
Feb 25 Python
Python控制Firefox方法总结
Jun 03 Python
python实现手势识别的示例(入门)
Apr 15 Python
python实现扫雷小游戏
Apr 24 Python
基于python检查矩阵计算结果
May 21 Python
教你怎么用Python生成九宫格照片
May 20 Python
Django数据统计功能count()的使用
Nov 30 #Python
Python常用断言函数实例汇总
Nov 30 #Python
在pycharm中使用pipenv创建虚拟环境和安装django的详细教程
Nov 30 #Python
Django 用户认证Auth组件的使用
Nov 30 #Python
python tqdm库的使用
Nov 30 #Python
Python+unittest+DDT实现数据驱动测试
Nov 30 #Python
Python logging自定义字段输出及打印颜色
Nov 30 #Python
You might like
从零开始的异世界生活:第二季延期后,B站上架了第二部剧场版
2020/05/06 日漫
function.inc.php超越php
2006/12/09 PHP
PHP n个不重复的随机数生成代码
2009/06/23 PHP
php学习笔记 数组的常用函数
2011/06/13 PHP
PHP常用的缓存技术汇总
2014/05/05 PHP
laravel容器延迟加载以及auth扩展详解
2015/03/02 PHP
PHP输出一个等腰三角形的方法
2015/05/12 PHP
php简单实现批量上传图片的方法
2016/05/09 PHP
php多文件打包下载的实例代码
2017/07/12 PHP
预加载css或javascript的js代码
2010/04/23 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
2014/09/23 Javascript
JavaScript的内存释放问题详解
2015/01/21 Javascript
jQuery实现带分组数据的Table表头排序实例分析
2015/11/24 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
js严格模式总结(分享)
2016/08/22 Javascript
浅谈在vue中使用mint-ui swipe遇到的问题
2018/09/27 Javascript
js中对象和面向对象与Json介绍
2019/01/21 Javascript
jQuery事件多次绑定与解绑问题实例分析
2019/02/19 jQuery
微信小程序实现获取小程序码和二维码java接口开发
2019/03/29 Javascript
js实现3D旋转相册
2020/08/02 Javascript
举例讲解Python中的算数运算符的用法
2015/05/13 Python
python机器学习实战之树回归详解
2017/12/20 Python
python3学生名片管理v2.0版
2018/11/29 Python
在TensorFlow中屏蔽warning的方式
2020/02/04 Python
css3个性化字体_动力节点Java学院整理
2017/07/12 HTML / CSS
女子锻炼服装和瑜伽服装:Splits59
2019/03/04 全球购物
Street One瑞士:德国现代时装公司
2019/10/09 全球购物
意大利奢侈品牌在线精品店:Jole.it
2020/11/23 全球购物
网吧消防安全制度
2014/01/28 职场文书
党员批评与自我批评思想汇报(集锦)
2014/09/14 职场文书
委托证明模板
2014/09/16 职场文书
自我检讨书范文
2015/01/28 职场文书
2015年上半年信访工作总结
2015/03/30 职场文书
质检员工作总结2015
2015/04/25 职场文书
运输公司工作总结
2015/08/11 职场文书
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle