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 18 Python
Python自定义scrapy中间模块避免重复采集的方法
Apr 07 Python
python基础while循环及if判断的实例讲解
Aug 25 Python
pandas按若干个列的组合条件筛选数据的方法
Apr 11 Python
Python检测网络延迟的代码
May 15 Python
详解python实现交叉验证法与留出法
Jul 11 Python
python tkinter窗口最大化的实现
Jul 15 Python
pandas按行按列遍历Dataframe的几种方式
Oct 23 Python
用Python生成HTML表格的方法示例
Mar 06 Python
树莓派升级python的具体步骤
Jul 05 Python
python 多线程死锁问题的解决方案
Aug 25 Python
Django如何创作一个简单的最小程序
May 12 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
什么是MVC,好东西啊
2007/05/03 PHP
一些需要禁用的PHP危险函数(disable_functions)
2012/02/23 PHP
解析dedeCMS验证码的实现代码
2013/06/07 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP验证信用卡卡号是否正确函数
2015/05/27 PHP
PHP技术开发微信公众平台
2015/07/22 PHP
Javascript学习笔记4 Eval函数
2010/01/11 Javascript
div层的移动及性能优化
2010/11/16 Javascript
jqueyr判断checkbox组的选中(示例代码)
2013/11/08 Javascript
jQuery判断复选框是否勾选的原理及示例
2014/05/21 Javascript
无限树Jquery插件zTree的常用功能特性总结
2014/09/11 Javascript
js实现商城星星评分的效果
2015/12/29 Javascript
JS中的进制转换以及作用
2016/06/26 Javascript
JavaScript 实现 Tab 点击切换实例代码
2017/03/25 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
2017/11/21 Javascript
Javascript 编码约定(编码规范)
2018/03/11 Javascript
基于jQuery的时间戳与日期间的转化
2019/06/21 jQuery
[09:47]2018DOTA2亚洲邀请赛4.5SOLO赛 No[o]ne vs Sumail
2018/04/06 DOTA
Python获取网页上图片下载地址的方法
2015/03/11 Python
Python中处理字符串的相关的len()方法的使用简介
2015/05/19 Python
Python字符串逆序的实现方法【一题多解】
2019/02/18 Python
Python实现简单查找最长子串功能示例
2019/02/26 Python
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
2019/04/03 Python
python图片验证码识别最新模块muggle_ocr的示例代码
2020/07/03 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
利用CSS3实现开门效果实例源码
2016/08/22 HTML / CSS
全球地下的服装和态度:Slam Jam
2018/02/04 全球购物
公司薪酬管理制度
2014/01/31 职场文书
培训专员岗位职责
2014/02/26 职场文书
读群众路线心得体会
2014/03/07 职场文书
2014领导干部四风问题查摆思想汇报
2014/09/13 职场文书
缓刑期间思想汇报范文
2014/10/10 职场文书
考试作弊检讨
2015/01/27 职场文书
2016秋季运动会开幕词
2016/03/04 职场文书
Mysql中调试存储过程最简单的方法
2021/06/30 MySQL
spring注解 @PropertySource配置数据源全流程
2022/03/25 Java/Android