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守护进程(daemon)代码实例
Mar 06 Python
Python通过调用mysql存储过程实现更新数据功能示例
Apr 03 Python
使用python获取(宜宾市地震信息)地震信息
Jun 20 Python
pytorch 预训练层的使用方法
Aug 20 Python
Python 操作mysql数据库查询之fetchone(), fetchmany(), fetchall()用法示例
Oct 17 Python
flask框架自定义过滤器示例【markdown文件读取和展示功能】
Nov 08 Python
python将unicode和str互相转化的实现
May 11 Python
python 解决mysql where in 对列表(list,,array)问题
Jun 06 Python
Python字符串函数strip()原理及用法详解
Jul 23 Python
Python中zipfile压缩包模块的使用
May 14 Python
anaconda python3.8安装后降级
Jun 11 Python
教你用Python爬取英雄联盟皮肤原画
Jun 13 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
PHP读取PPT文件的方法
2015/12/10 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
Kindeditor编辑器添加图片上传水印功能(php代码)
2017/08/03 PHP
PHP+Apache环境中如何隐藏Apache版本
2017/11/24 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
2016/01/18 Javascript
AngularJS手动表单验证
2016/02/01 Javascript
JavaScript实现复制内容到粘贴板代码
2016/03/31 Javascript
在JSP中如何实现MD5加密的方法
2016/11/02 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
解决vue项目报错webpackJsonp is not defined问题
2018/03/14 Javascript
详解vue.js下引入百度地图jsApi的两种方法
2018/07/27 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
2018/10/26 Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
详解微信小程序网络请求接口封装实例
2019/05/02 Javascript
javascript导出csv文件(excel)的方法示例
2019/08/25 Javascript
解决layer弹出层中表单不起作用的问题
2019/09/09 Javascript
[02:19]2018年度DOTA2最佳核心位选手-完美盛典
2018/12/17 DOTA
安装Python的教程-Windows
2017/07/22 Python
python中多层嵌套列表的拆分方法
2018/07/02 Python
Python+Pyqt实现简单GUI电子时钟
2021/02/22 Python
python中return的返回和执行实例
2019/12/24 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
2020/05/11 Python
如何在Windows中安装多个python解释器
2020/06/16 Python
在pytorch中动态调整优化器的学习率方式
2020/06/24 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
python读取excel数据并且画图的实现示例
2021/02/08 Python
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
如果重写了对象的equals()方法,需要考虑什么
2014/11/02 面试题
校运动会广播稿(100篇)
2014/09/12 职场文书
毕业设计致谢语
2015/05/14 职场文书
学生病假条怎么写
2015/08/17 职场文书
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技