Django(15)外键和表关系
外键删除操作
如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过on_delete
来指定。可以指定的类型如下:
- CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
- PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
- SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,
前提是要指定这个字段可以为空
。 - SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
- SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
- DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。
注意:以上这些选项只是Django级别
的,数据级别依旧是RESTRICT
!
表关系
表之间的关系都是通过外键来进行关联的。而表之间的关系,无非就是三种关系:一对一、一对多、多对多等。以下将讨论一下三种关系的应用场景及其实现方式。
一对多
应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系
实现方式:一对多,都是通过ForeignKey
来实现的。
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)
那么以后在给Article
对象指定category
,就可以使用以下代码来完成:
article = Article(title='abc',content='123')
author = User(username='jkc',password='123456')
# 要先保存到数据库中
author.save()
article.author = author
article.save()
并且以后如果想要获取某个种类下所有的文章,可以通过article_set
来实现。示例代码如下:
user = User.objects.first()
# 获取第一个用户写的所有文章
articles = user.article_set.all()
for article in articles:
print(article)
一对一
- 在Django中一对一是通过
models.OnetToOneField
来实现的。这个OneToOneField
其实本质上就是一个外键,只不过这个外键有一个唯一约束(unique key)
,来实现一对一。 - 以后如果想要反向引用,那么是通过引用的模型的名字转换为小写的形式进行访问。比如以下模型:
class FrontUser(models.Model):
username = models.CharField(max_length=200)
class UserExtension(models.Model):
school = models.CharField(max_length=100)
user = models.OneToOneField("FrontUser",on_delete=models.CASCADE)
# 通过userextension来访问UserExtension对象
user = FrontUser.objects.first()
print(user.userextension)
UserExtension
的对象,可以通过user来访问到对应的user对象。并且FrontUser
对象可以使用userextension
来访问对应的UserExtension
对象。 如果不想使用Django默认的引用属性名字。那么可以在OneToOneField
中添加一个related_name
参数。示例代码如下:
class FrontUser(models.Model):
username = models.CharField(max_length=200)
class UserExtension(models.Model):
school = models.CharField(max_length=100)
user = models.OneToOneField("FrontUser",on_delete=models.CASCADE,related_name='extension')
# 通过extension来访问到UserExtension对象
user = FrontUser.objects.first()
print(user.extension)
那么以后就FrontUser
的对象就可以通过extension
属性来访问到对应的UserExtension
对象。
多对多
- 应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。
- 实现方式:Django为这种多对多的实现提供了专门的Field。叫做
ManyToManyField
。还是拿文章和标签为例进行讲解。示例代码如下:
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
tags = models.ManyToManyField("Tag",related_name="articles")
class Tag(models.Model):
name = models.CharField(max_length=50)
在数据库层面,实际上Django是为这种多对多的关系建立了一个中间表。这个中间表分别定义了两个外键,引用到article
和tag
两张表的主键。
在我们使用多对多反向引用添加的时候,只能使用add
这种添加方式,比如向文章中添加标签,示例代码如下:
article = Article.objects.first()
tag = Tag(name="好看")
tag.save()
article.tag_set.add(tag) # 向文章中添加标签tag
Django(15)外键和表关系的更多相关文章
- django中有外键关系两张表的相互查找方法
两张通过外键联系的表,如何在一张表上根据另一张表上的属性查找满足条件的对象集? 1 平常查找表中数据的条件是python中已有的数据类型,通过名字可以直接查找.如果条件是表中外键列所对应表的某一列, ...
- 主外键多表查询demo
https://www.cnblogs.com/DragonFire/p/6949767.html mySQL练习-主外键多表查询 MySQL练习-主外键多表查询 练习: 1.建立表关系: 请创建如下 ...
- mysql外键与表查询
目录 自增特性 外键 外键关系 外键创建 外键的约束效果 级联更新级联删除 多对多关系 一对一关系 表查询关键字 select与from where筛选 group by分组 练习 关系练习 查询练习 ...
- oracle查询某张表的外键,并用 truncate 命令有外键的表中的数据
注:本文来源于<oracle查询某张表的外键(最终解决办法)> 一:几个查询表外键的脚本 select b.table_name, b.column_name from user_cons ...
- Django - orm外键操作
1.orm外键操作 创建外键: 备注:ForeignKey两个参数,1个为关联的表名,1个为关联的字段名: 在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避 ...
- 删除带外键的表【foreign key constraint fails】报错
title: 删除带外键的表[foreign key constraint fails]报错 date: 2018-08-02 21:59:06 tags: 数据库 --- 遥想当时正在学hibern ...
- 【Hibernate】无外键多表查询
无外键多表查询时编写hql,直接使用逗号分隔表,where作为联合查询条件进行查询.查询出来的结果可为两种,List<List<Object>>或者List<Map< ...
- Django中ORM外键和表的关系(Django编程-4)
外键 在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam.如果使用的是InnoDB引擎,是支持外键约束的.外键的存在使得ORM框架在处理表关系的时候异常的强大.因此这里我们首先来 ...
- Python Django orm操作数据库笔记之外键和表关系
外键 在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam.如果使用的是InnoDB引擎,是支持外键约束的. 外键的使用 使用外键前需要先确保相应外键已存储在数据库中(flask中 ...
随机推荐
- java注解基础入门
前言 这篇博客主要是对java注解相关的知识进行入门级的讲解,包括**,核心内容主要体现在对java注解的理解以及如何使用.希望通过写这篇博客的过程中让自己对java注解有更深入的理解,在工作中可以巧 ...
- c语言链表从本地文件中读取和写入数据
1 typedef struct Data{ 2 40 char *name; 3 41 char *IDCARD; 4 42 char *job_id; 5 43 char *length; 6 4 ...
- 【linux】驱动-1-环境准备
目录 前言 1. 开发环境搭建 1.1 环境准备 1.1.1 安装工具 1.1.2 编译内核 1.1.2.1 获取内核源码 1.1.2.2 编译内核 1.2 内核驱动模块编译和加载 1.2.1 hel ...
- Tex中的引号(JAVA语言)
package 第三章; import java.util.Scanner; public class Tex中的引号 { public static void main(String[] args) ...
- Github 镜像资源
1.GitHub 镜像访问 这里提供两个最常用的镜像地址(别登录账号): https://github.com.cnpmjs.org https://hub.fastgit.org 也就是说上面的镜像 ...
- 三次给你讲清楚Redis之Redis是个啥
摘要:Redis是一款基于键值对的NoSQL数据库,它的值支持多种数据结构:字符串(strings).哈希(hashes).列表(lists).集合(sets).有序集合(sorted sets)等. ...
- Windows Server 2016不小心卸载了.NET Framwork4.6后服务器管理器等功能都不能用的解决方案
之前卸载IIS的时候手贱把.NET FrameWork 4.6给卸载了,下面有一个比较简单的恢复方法. 可以尝试一下通过cmd命令DISM启用.NET 4.6:1. 首先运行如下命令查看当前的功能安装 ...
- OAuth2.0理解和用法
现在网络的资料到处都是,很容易搜索到自己想要的答案.但答案通常只能解决自己一部分的问题.如果自己想要有一套自己的解决方案,还得重新撸一遍靠谱. 我需要学下OAuth2.0吗? 没看之前以为OAuth2 ...
- 墙裂推荐:这可能是CAP理论的最好现实解释
这篇文章蓝本:http://ksat.me/a-plain-english-introduction-to-cap-theorem 经过小码甲意译.原创配图, 干到让你怀孕. 你可能经常听到CAP定理 ...
- 自定义函数和调用函数 return返回值
1.Q: 为什么要有函数,函数是什么? A: 函数能提高应用的模块性,和代码的重复利用率 2. 函数分为两个阶段: 1.定义阶段 2.调用阶段 3.关于函数调用: 01.函数的内存地址加上()就是调用 ...