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发送邮件接收邮件示例分享
Jan 21 Python
python自动格式化json文件的方法
Mar 11 Python
python压缩文件夹内所有文件为zip文件的方法
Jun 20 Python
python3.5 + PyQt5 +Eric6 实现的一个计算器代码
Mar 11 Python
[原创]pip和pygal的安装实例教程
Dec 07 Python
python写入已存在的excel数据实例
May 03 Python
Python实现多态、协议和鸭子类型的代码详解
May 05 Python
Pytorch中实现只导入部分模型参数的方式
Jan 02 Python
解决更改AUTH_USER_MODEL后出现的问题
May 14 Python
django 解决model中类写不到数据库中,数据库无此字段的问题
May 20 Python
keras model.fit 解决validation_spilt=num 的问题
Jun 19 Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 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
在服务端进行目录建立、删除,文件上传、删除的过程的php代码
2008/09/10 PHP
PHP入门经历和学习过程分享
2014/04/11 PHP
php检查字符串中是否包含7位GSM字符的方法
2015/03/17 PHP
PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 如何解决
2016/04/17 PHP
php关闭warning问题的解决方法
2016/05/17 PHP
得到文本框选中的文字,动态插入文字的js代码
2007/03/07 Javascript
jquery tab标签页的制作
2010/05/10 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
2010/11/14 Javascript
JS实现下拉框的动态添加(附效果)
2013/04/03 Javascript
解析Jquery取得iframe中元素的几种方法
2013/07/04 Javascript
javascript数字时钟示例分享
2014/04/23 Javascript
js获取元素相对窗口位置的实现代码
2014/09/28 Javascript
jQuery中大家不太了解的几个方法
2015/03/04 Javascript
Javascript闭包实例详解
2015/11/29 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
2016/06/26 Javascript
jQuery动态生成Bootstrap表格
2016/11/01 Javascript
js脚本编写简单刷票投票系统
2017/06/27 Javascript
jQuery插件DataTables分页开发心得体会
2017/08/22 jQuery
Angular4学习笔记之根模块与Ng模块
2017/09/09 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
2018/11/10 Javascript
vue+element UI实现树形表格带复选框的示例代码
2019/04/16 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
2019/09/28 Javascript
python实现淘宝秒杀脚本
2020/06/23 Python
python异步实现定时任务和周期任务的方法
2019/06/29 Python
Python中typing模块与类型注解的使用方法
2019/08/05 Python
Django框架 查询Extra功能实现解析
2019/09/04 Python
Django 限制访问频率的思路详解
2019/12/24 Python
Python实现疫情通定时自动填写功能(附代码)
2020/05/27 Python
建材投资建议书
2014/05/16 职场文书
教师求职信范文
2014/05/24 职场文书
欢迎领导标语
2014/06/27 职场文书
2014年中秋节活动总结
2014/08/29 职场文书
2014年心理健康教育工作总结
2014/12/06 职场文书
2015小学教师德育工作总结
2015/05/12 职场文书
详解CocosCreator项目结构机制
2021/04/14 Javascript
Python django中如何使用restful框架
2021/06/23 Python