Django中ORM外键和表的关系详解
作者:KadyCui 发布时间:2022-04-27 10:25:59
外键
在 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 来指定。可以指定的类型如下:
CASCADE :级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
PROTECT :受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
SET_NULL :设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
SET_DEFAULT :设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
SET() :如果外键的那条数据被删除了。那么将会获取 SET 函数中的值来作为这个外键的值。 SET 函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
DO_NOTHING :不采取任何行为。一切全看数据库级别的约束。
来源:http://www.cnblogs.com/kadycui/p/10886580.html


猜你喜欢
- 本文实例讲述了python的keyword模块用法。分享给大家供大家参考。具体如下:Help on module keyword:NAME
- 食用前准备python 3.10.10 #二维码的库ddddocr 需要库import timeimport ddddocr源码# impo
- 安装了python3之后,会有pip31. 使用pip install XXX新安装的库会放在这个目录下面python2.7/site-pa
- 方法一:现在用 notepad++,在 UTF-8 格式下编写以下语句:#coding=utf-8 print"打印中文字符&qu
- 前言摘要昨天和同事merge代码又遇到了很多冲突,发现之前有些方法写的参数不规范,没有传入Context,不方便进行链路追踪。他在revie
- has_key()方法可以检查字典中是否含有指定的键,如果有则返回True,否则就返回False。语法格式:dictionary_name.
- 教你如何清除SQL日志 1.打开查询分析器,输入命令DUMP TRANSACTION 数据库名 WITH NO_LOG2. 再打开企业管理器
- 一、 升级前准备工作1、 确认数据库版本使用dba登陆查询当前数据库的版本SQL> select * from v$version;
- 最近项目中的资产的任务状态频频出现问题,查看日志文件,看代码逻辑,也没发现什么具体的错误,总是过段时间就会出现一个表的字段没有更新的问题,很
- 免责声明:本教程所有资源均来源于网络;仅用于学习交流,请勿用于任何商业行为;如需要,请使用正版授权;侵权联删。此篇教程通过无限重置试用期持续
- 一个网站的导航就相当于是一条路的路标,不同的是,网站的不同栏目页的入口远远比马路要来得复杂,所以一个清晰的导航设计对于一个网站的意义远远大于
- 本文实例讲述了JS数组合并push与concat区别。分享给大家供大家参考,具体如下:共同点两个方法都可以在一个数组内增添新的元素,参数都是
- asp 在线备份 恢复 sql server 数据库,对于远程没有提供sql server远程连接或打包下载的朋友是个临时解决方法,对于大数
- 在php编写中有时会用户页面跳转,在这里收集了几种不错的跳转方法,可以用到。用HTTP头信息实现也就是用PHP的HEADER函数。PHP里的
- 场景应用老大我让爬取内部网站获取数据,插入到新建的表中,并每天进行爬取更新数据(后面做了定时任务)。然后根据该表统计每日的新增数量/更新数量
- 前言本文主要使用 cpu 版本的 tensorflow 2.4 版本完成文本的 word embedding 训练,并且以此为基础完成影评文
- 前言今天在开发时发现一个奇怪的问题,我手动改完数据库竟然不生效,反复确认环境无误后猜测是缓存的问题,因为是新接手的项目,代码还不熟悉,仔细一
- 前言:Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是Unicode,由str类型表示,二进制数据则由by
- 字符串字符串用''或者""括起来,如果字符串内部有‘或者",需要使用\进行转义>>
- 开发新版本 Vue 项目推荐你使用 Vite 脚手架构建开发环境,然而 Vite 脚手架更倾向于构建纯 Web 页面,而不是桌面应用,因此开