Django中ORM外键和表的关系详解


Posted in Python onMay 20, 2019

外键

在 MySQL 中,表有两种引擎,一种是 InnoDB ,另外一种是 myisam 。如果使用的是 InnoDB 引擎,是支持外键约束的。外键的存在使得 ORM 框架在处理表关系的时候异常的强大。因此这里我们首先来介绍下外键在 Django 中的使用。

类定义为 class ForeignKey(to,on_delete,**options) 。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有 CASCADE 、 SET_NULL 等。这里以一个实际案例来说明。比如有一个 User 和一个 Article 两个模型。一个 User 可以发表多篇文章,一个 Article 只能有一个 Author ,并且通过外键进行引用。那么相关的示例代码如下:

class User(models.Model):
  username = models.CharField(max_length=20)
  password = models.CharField(max_length=100)

class Article(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()

  author = models.ForeignKey("User",on_delete=models.CASCADE)

以上使用 ForeignKey 来定义模型之间的关系。即在 article 的实例中可以通过 author 属性来操作对应的 User 模型。这样使用起来非常的方便。示例代码如下:

article = Article(title='abc',content='123')
author = User(username='张三',password='111111')
article.author = author
article.save()

# 修改article.author上的值
article.author.username = '李四'
article.save()

为什么使用了 ForeignKey 后,就能通过 author 访问到对应的 user 对象呢。因此在底层, Django 为 Article 表添加了一个 属性名_id 的字段(比如author的字段名称是author_id),这个字段是一个外键,记录着对应的作者的主键。以后通过 article.author 访问的时候,实际上是先通过 author_id 找到对应的数据,然后再提取 User 表中的这条数据,形成一个模型。

如果想要引用另外一个 app 的模型,那么应该在传递 to 参数的时候,使用 app.model_name 进行指定。以上例为例,如果 User 和 Article 不是在同一个 app 中,那么在引用的时候的示例代码如下:

# User模型在user这个app中
class User(models.Model):
  username = models.CharField(max_length=20)
  password = models.CharField(max_length=100)

# Article模型在article这个app中
class Article(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()

  author = models.ForeignKey("user.User",on_delete=models.CASCADE)

如果模型的外键引用的是本身自己这个模型,那么 to 参数可以为 'self' ,或者是这个模型的名字。在论坛开发中,一般评论都可以进行二级评论,即可以针对另外一个评论进行评论,那么在定义模型的时候就需要使用外键来引用自身。示例代码如下:

class Comment(models.Model):
  content = models.TextField()
  origin_comment = models.ForeignKey('self',on_delete=models.CASCADE,null=True)
  # 或者
  # origin_comment = models.ForeignKey('Comment',on_delete=models.CASCADE,null=True)

外键删除操作:

如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过 on_delete 来指定。可以指定的类型如下:

  1. CASCADE :级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
  2. PROTECT :受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
  3. SET_NULL :设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
  4. SET_DEFAULT :设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
  5. SET() :如果外键的那条数据被删除了。那么将会获取 SET 函数中的值来作为这个外键的值。 SET 函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
  6. DO_NOTHING :不采取任何行为。一切全看数据库级别的约束。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
把大数据数字口语化(python与js)两种实现
Feb 21 Python
跟老齐学Python之Import 模块
Oct 13 Python
pandas中apply和transform方法的性能比较及区别介绍
Oct 30 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python:按行读入,排序然后输出的方法
Jul 20 Python
基于Python实现拆分和合并GIF动态图
Oct 22 Python
Python字符串格式化输出代码实例
Nov 22 Python
python [:3] 实现提取数组中的数
Nov 27 Python
如何定义TensorFlow输入节点
Jan 23 Python
python3跳出一个循环的实例操作
Aug 18 Python
详解Python爬虫爬取博客园问题列表所有的问题
Jan 18 Python
python基于opencv批量生成验证码的示例
Apr 28 Python
利用Django模版生成树状结构实例代码
May 19 #Python
使用Python3内置文档高效学习以及官方中文文档
May 19 #Python
python反编译学习之字节码详解
May 19 #Python
python从入门到精通 windows安装python图文教程
May 18 #Python
详解用Python实现自动化监控远程服务器
May 18 #Python
Python实现打砖块小游戏代码实例
May 18 #Python
如何在Python中实现goto语句的方法
May 18 #Python
You might like
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
IStream与TStream之间的相互转换
2008/08/01 PHP
PHP正则提取不包含指定网址的图片地址的例子
2014/04/21 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
PHP基于MySQLI函数封装的数据库连接工具类【定义与用法】
2017/08/11 PHP
Laravle eloquent 多对多模型关联实例详解
2017/11/22 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
JavaScript高级程序设计 错误处理与调试学习笔记
2011/09/10 Javascript
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
JS中数组Array的用法示例介绍
2014/02/20 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
JavaScript中对象property的读取和写入方法介绍
2014/12/30 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
2015/01/28 Javascript
Bootstrap实现提示框和弹出框效果
2017/01/11 Javascript
微信小程序城市定位的实现实例(获取当前所在国家城市信息)
2017/05/17 Javascript
JS随机密码生成算法
2019/09/23 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
python操作数据库之sqlite3打开数据库、删除、修改示例
2014/03/13 Python
在Python中用get()方法获取字典键值的教程
2015/05/21 Python
python类继承用法实例分析
2015/05/27 Python
Django框架中方法的访问和查找
2015/07/15 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
python实现简单登陆流程的方法
2018/04/22 Python
Python OpenCV处理图像之图像像素点操作
2018/07/10 Python
Python restful框架接口开发实现
2020/04/13 Python
Rockport乐步美国官网:风靡美国的白宫鞋
2016/11/24 全球购物
.NET remoting的两种通道是什么
2016/05/31 面试题
武汉某公司的C#笔试题面试题
2015/12/25 面试题
金鑫耀Java笔试题
2014/09/06 面试题
小区推广策划方案
2014/06/06 职场文书
综合素质自我评价怎么写
2014/09/14 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
学子宴致辞大全
2015/07/27 职场文书
工作建议书范文
2019/07/08 职场文书