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中index()和seek()的用法(详解)
Apr 27 Python
python3实现跳一跳点击跳跃
Jan 08 Python
python装饰器深入学习
Apr 06 Python
python验证码识别教程之利用投影法、连通域法分割图片
Jun 04 Python
Python之两种模式的生产者消费者模型详解
Oct 26 Python
Python对接支付宝支付自实现功能
Oct 10 Python
numpy 返回函数的上三角矩阵实例
Nov 25 Python
基于Python获取照片的GPS位置信息
Jan 20 Python
Python bytes string相互转换过程解析
Mar 05 Python
在jupyter notebook 添加 conda 环境的操作详解
Apr 10 Python
windows上彻底删除jupyter notebook的实现
Apr 13 Python
keras之权重初始化方式
May 21 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大批量数据操作时临时调整内存与执行时间的方法
2011/04/20 PHP
php获取指定范围内最接近数的方法
2015/06/02 PHP
php实现处理输入转义字符的代码
2015/11/08 PHP
php 判断过去离现在几年的函数(实例代码)
2016/11/15 PHP
Thinkphp事务操作实例(推荐)
2017/04/01 PHP
PHP中命名空间的使用例子
2019/03/22 PHP
PHP MVC框架中类的自动加载机制实例分析
2019/09/18 PHP
PHP常量DIRECTORY_SEPARATOR原理及用法解析
2020/11/10 PHP
一个tab标签切换效果代码
2009/03/27 Javascript
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
使用jQuery卸载全部事件的思路详解
2017/04/03 jQuery
JavaScript转换数据库DateTime字段类型方法
2017/06/27 Javascript
jQuery实现的弹幕效果完整实例
2017/09/06 jQuery
微信小程序实现全国机场索引列表
2018/01/31 Javascript
JavaScript动态加载重复绑定问题
2018/04/01 Javascript
微信小程序如何实现精确的日期时间选择器
2020/01/21 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
2020/05/15 Javascript
微信小程序实现时间戳格式转换
2020/07/20 Javascript
在python中的socket模块使用代理实例
2014/05/29 Python
Python连接phoenix的方法示例
2017/09/29 Python
解决python "No module named pip" 的问题
2018/10/13 Python
Python利用itchat库向好友或者公众号发消息的实例
2019/02/21 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
django xadmin action兼容自定义model权限教程
2020/03/30 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
python3爬虫GIL修改多线程实例讲解
2020/11/24 Python
css3高级选择器使用方法
2013/12/02 HTML / CSS
css3实现蒙版弹幕功能
2019/06/18 HTML / CSS
自我评价如何写好?
2014/01/05 职场文书
三八节主持词
2014/03/17 职场文书
教师产假请假条范文
2014/04/10 职场文书
爱护公物标语
2014/06/24 职场文书
寒暑假实习证明书模板
2014/11/29 职场文书
MySQL 存储过程的优缺点分析
2021/05/20 MySQL
Python机器学习应用之基于线性判别模型的分类篇详解
2022/01/18 Python