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时间戳与时间字符串互相转换实例代码
Nov 28 Python
Python实现大文件排序的方法
Jul 10 Python
python timestamp和datetime之间转换详解
Dec 11 Python
Python的UTC时间转换讲解
Feb 26 Python
关于Python 的简单栅格图像边界提取方法
Jul 05 Python
在Pycharm中调试Django项目程序的操作方法
Jul 17 Python
pycharm激活码快速激活及使用步骤
Mar 12 Python
基于Python把网站域名解析成ip地址
May 25 Python
python小白切忌乱用表达式
May 29 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
Jun 05 Python
Python如何实现自带HTTP文件传输服务
Jul 08 Python
python实现视频压缩功能
Dec 18 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实现的遍历文件夹下所有文件,编辑删除
2010/01/05 PHP
PHP利用APC模块实现大文件上传进度条的方法
2015/10/29 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
2017/11/10 PHP
extJs 常用到的增,删,改,查操作代码
2009/12/28 Javascript
JavaScript获取路径设计源码
2014/05/22 Javascript
js实现背景图片感应鼠标变化的方法
2015/02/28 Javascript
Jquery中$.post和$.ajax的用法小结
2015/04/28 Javascript
jQuery原型属性和原型方法详解
2015/07/07 Javascript
基于JavaScript创建动态Dom
2015/12/08 Javascript
zTree实现节点修改的实时刷新功能
2017/03/20 Javascript
ReactNative短信验证码倒计时控件的实现代码
2017/07/20 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
js canvas画布实现高斯模糊效果
2018/11/27 Javascript
如何进行微信公众号开发的本地调试的方法
2019/06/16 Javascript
微信小程序引入Vant组件库过程解析
2019/08/06 Javascript
详解Vue2的diff算法
2021/01/06 Vue.js
Python实现全角半角字符互转的方法
2016/11/28 Python
Python线程指南详细介绍
2017/01/05 Python
Python实现多进程共享数据的方法分析
2017/12/04 Python
Python中enumerate()函数编写更Pythonic的循环
2018/03/06 Python
python实现读Excel写入.txt的方法
2018/04/29 Python
Python中pandas dataframe删除一行或一列:drop函数详解
2018/07/03 Python
对pycharm代码整体左移和右移缩进快捷键的介绍
2018/07/16 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
全网首秀之Pycharm十大实用技巧(推荐)
2020/04/27 Python
Python应用实现双指数函数及拟合代码实例
2020/06/19 Python
英国时尚配饰、珠宝和服装网站:KJ Beckett
2020/01/23 全球购物
DBA的职责都有哪些
2012/05/16 面试题
实习生的自我评价
2014/01/08 职场文书
合作协议书模板2014
2014/09/26 职场文书
教师自我剖析材料范文
2014/09/30 职场文书
学校拾金不昧表扬信
2015/01/16 职场文书
小数乘法教学反思
2016/02/22 职场文书
导游词之秦皇岛燕塞湖
2020/01/03 职场文书
SQL SERVER存储过程用法详解
2022/02/24 SQL Server