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 相关文章推荐
Flask框架的学习指南之用户登录管理
Nov 20 Python
ansible作为python模块库使用的方法实例
Jan 17 Python
Anaconda多环境多版本python配置操作方法
Sep 12 Python
python3 pillow生成简单验证码图片的示例
Sep 19 Python
pip matplotlib报错equired packages can not be built解决
Jan 06 Python
Python集中化管理平台Ansible介绍与YAML简介
Jun 12 Python
selenium+Chrome滑动验证码破解二(某某网站)
Dec 17 Python
python实现名片管理器的示例代码
Dec 17 Python
使用python+poco+夜神模拟器进行自动化测试实例
Apr 23 Python
Manjaro、pip、conda更换国内源的方法
Nov 17 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
Jan 06 Python
详解python第三方库的安装、PyInstaller库、random库
Mar 03 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验证手机号码(支持归属地查询及编码为UTF8)
2013/02/01 PHP
php5.3 注意事项说明
2013/07/01 PHP
CodeIgniter钩子用法实例详解
2016/01/20 PHP
PHP抽象类基本用法示例
2018/12/28 PHP
yii2.0框架实现上传excel文件后导入到数据库的方法示例
2020/04/13 PHP
php7连接MySQL实现简易查询程序的方法
2020/10/13 PHP
jQuery动态地获取系统时间实现代码
2013/05/24 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
JS,Jquery获取select,dropdownlist,checkbox下拉列表框的值(示例代码)
2014/01/11 Javascript
jQuery中DOM操作实例分析
2015/01/23 Javascript
js比较日期大小的方法
2015/05/12 Javascript
利用Jquery队列实现根据输入数量显示的动画
2016/09/01 Javascript
详解Bootstrap各式各样的按钮(推荐)
2016/12/13 Javascript
JavaScript正则表达式exec/g实现多次循环用法示例
2017/01/17 Javascript
js实现旋转木马效果
2017/03/17 Javascript
Vue异步组件使用详解
2017/04/08 Javascript
关于javascript获取内联样式与嵌入式样式的实例
2017/06/01 Javascript
nodejs async异步常用函数总结(推荐)
2017/11/17 NodeJs
在Windows8上的搭建Python和Django环境
2014/07/03 Python
对PyTorch torch.stack的实例讲解
2018/07/30 Python
django foreignkey外键使用的例子 相当于left join
2019/08/06 Python
Django Path转换器自定义及正则代码实例
2020/05/29 Python
Python项目实战之使用Django框架实现支付宝付款功能
2021/02/23 Python
利用html5 file api读取本地文件示例(如图片、PDF等)
2018/03/07 HTML / CSS
Sneaker Studio波兰:购买运动鞋
2018/04/28 全球购物
2014年大班元旦活动方案
2014/02/26 职场文书
外贸采购员岗位职责
2014/03/08 职场文书
环保倡议书50字
2014/05/15 职场文书
建筑专业毕业生自荐信
2014/05/25 职场文书
公司领导九九重阳节发言稿2014
2014/09/25 职场文书
给老婆的保证书怎么写
2015/05/08 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
MySQL中出现乱码问题的终极解决宝典
2021/05/26 MySQL
利用Python判断你的密码难度等级
2021/06/02 Python
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
2021/08/07 HTML / CSS
python代码实现扫码关注公众号登录的实战
2021/11/01 Python