外键和表关系

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

类定义为 class ForeignKey(to,on_delete,**options)。第一个参数to是应用的哪个模型(也就是应用的表),第二个参数on_delete在使用外键应用的模型数据被删除了,这个字段该如何处理。举例说明,如果有一个user和一个Article两个模型。一个user可以发表多篇文章,一个Article只能有一个Author,并且通过外键进行应用。

1. 使用外键引用同一个APP中的不同模型,示例代码如下:

# 注意:在定义一个模型的时候,模型的名字的首字母一定要大写,否者的话,模型名字下面会出现波浪线。
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模型。这样使用起来非常方便。

views.py文件中实现向数据库表中添加一条数据,示例代码如下:


from django.http import HttpResponse
from .models import User,Article def index(request):
# 向数据库表中添加一条数据,首先要先将被引用的表添加数据,并进行保存
user = User(username='孤烟逐云', password='hello')
user.save()
article = Article(title='Python', content='真好')
article.author = user
article.save()
return HttpResponse("Success ! ")
为什么使用了ForeignKey后,就能通过author属性访问到对应的user对象呢?

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

展示表User中的数据:

展示表article中的数据:

views.py文件实现从数据库表中查询数据,并且打印输出,示例代码如下:


from django.http import HttpResponse
from .models import User,Article def index(request):
article = Article.objects.all()
print(article)
return HttpResponse("Success ! ")
此时的打印结果为:

重写Article类的__str__(self)方法,将数据显示出来,示例代码如下:
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey('User',on_delete=models.CASCADE) def __str__(self):
return "<(Article id: %s, title: %s, content: %s, author: %s)>" % (self.id, self.title, self.content, self.author)
再次运行项目进行打印输出,数据具体信息:

2. 使用外键引用另外一个app的模型

那么应该在传递to参数的时候,使用app.model_name进行指定。以上例为例,如果User和Article不是在同一个APP中,那么在引用的时候的示例代码如下:
# Book模型在book,app中,
from django.db import models class Book(models.Model):
# 定义属性,出版社的地址
pub_add = models.CharField(max_length=100) # 在article模型中进行外键引用
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
# 使用外键引用同一个app下的模型
author = models.ForeignKey('User',on_delete=models.CASCADE)
# 使用外键引用不同app下的模型
pub = models.ForeignKey('book.Book',on_delete=models.CASCADE)
在使用命令python manage.py migrate将迁移脚本文件映射到数据库中的过程中,出现django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (`orm_relationship

_demo.#sql-158c_79, CONSTRAINT article_article_pub_id_e2e65cb7_fk_book_book_id FOREIGN KEY (pub_id) REFERENCES book

_book (id`))')

解决办法就是将settings.py文件中的DATABASE配置"default"变量中,添加:
# 取消对外键的检查
'OPTIONS':{
"init_command":"SET foreign_key_checks = 0;",
}
之后再次使用命令python manage.py migrate 就没有任何错误出现了。
来到navicat中查看映射生成的表:
book表中的字段信息

article表中的字段信息:

查看article_artilce表中外键的引用情况,由输出信息可以看出,引用了同一个app:article中的user表和不同app:book中的book表。

3.使用外键引用本身模型

'to'参数可以为'self',或者是这个模型的名字,在论坛开发中,一般的评论都可以进行二级评论,即可以针对另外一个评论进行评论,那么在定义模型的时候就需要使用外键来引用资深了,示例代码如下:
class Comment(models.Model):
content = models.TextField()
origion_comment = models.ForeignKey('self',on_delete=models.CASCADE)
查看article_comment这个表:

55.ORM外键:引用同app下的不同模型,引用不同app下的模型,引用模型自身使用详解的更多相关文章

  1. Django(四) ORM 外键操作及初识Ajax

    一.内容回顾 1.Django请求的生命周期: ​ 路由系统 -> 视图函数(获取模板+数据 -> 渲染) -> 字符串返回给用户 2.路由系统: /index/ #-> 函数 ...

  2. Django - orm外键操作

    1.orm外键操作 创建外键: 备注:ForeignKey两个参数,1个为关联的表名,1个为关联的字段名: 在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避 ...

  3. VMware下OSSIM 4.1.0的下载、安装和初步使用(图文详解)

    不多说,直接上干货! 为什么,我写了一篇OSSIM 5.2.0的,还要再来写OSSIM 4.1.0呢,是因为,OSSIM 5.2.0所需内存较大,8G甚至16G,但是,肯定性能和里面集成组件越高级.也 ...

  4. Django中ORM外键和表的关系(Django编程-4)

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

  5. python django中的orm外键级联删除

    今天添加了一个路由表,路由表做外键,然后添加了几个组,路由表为组的外键,当我使用删除功能对路由表进行删除时,竞然将我的组也相当的删除了:尽管这是测试,但放到生产环境中还是会发生意外的:这个问题要解决: ...

  6. Django学习手册 - ORM 外键

    Django 外键创建 关键语法: models.ForeignKey("UserGroup",to_field="gid",default=1,on_dele ...

  7. Python sqlalchemy orm 外键关联

    创建外键关联 并通过relationship 互相调用 如图: 实现代码: import sqlalchemy # 调用链接数据库 from sqlalchemy import create_engi ...

  8. django ORM 外键详解

    Django中的外键: 首先,为了方便理解,我们把使用ForeignKey的字段所在的表定义为从表,把ForeignKey中to参数连接的表称为主表. 外键使用的先决条件: 在mysql数据表中,数据 ...

  9. django orm 外键id返回对应的名称

    原文:https://blog.csdn.net/gghhm/article/details/99652143 当我们在写django的orm模块时,有时候会在用外键关联时,保存的是对应表中的id字段 ...

随机推荐

  1. 【STM32H7教程】第47章 STM32H7的FMC总线基础知识和HAL库API

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第47章       STM32H7的FMC总线基础知识和HA ...

  2. cmake 指定编译特定可执行文件

    最近进行编译项目,但是项目中有很多可执行文件:每次编译起来比较费时,下面一组代码可以指定特定的编译目标进行编译,而不用编译所有目标: #!/bin/bash # 通过传递第一个参数,表示要编译的目标: ...

  3. gitlab被屏蔽问题

    There was an error with the reCAPTCHA. Please solve the reCAPTCHA again. 解决办法 俗话说:哪里有碍事的墙,哪里就使劲推好了 h ...

  4. Visual Studio 2019新建Web项目

    选择创建新项目 选择ASP.NET Web 应用程序,下一步 填好相关信息,位置是保存项目的位置,点击创建 创建你需要的项目项,我们这里选择空项目,点击创建 添加文件 右击项目名 -> 添加 - ...

  5. JavaScript 浅复制和深复制

    浅复制只会复制第一层的元素,嵌套的元素还是原来的引用. const obj = { a: 1, b: 2 } const copyObj = Object.assign({}, obj) const ...

  6. 洛谷新手题 P1028 数的计算题解

    题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数nn): 先输入一个自然数nn(n \le 1000n≤1000),然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个 ...

  7. 【一起刷LeetCode】整数反转

    前言&絮叨 别人都忙着参加年会晒奖品,我却忙着写代码.每逢年底都要安排几个紧急项目,我什么时候能摆脱这种宿命. 在忙也不能忘记刷LeetCode,毛毛向前冲!!! 题目描述 给出一个 32 位 ...

  8. VMware与Centos系统安装之重置root密码

    VMware与Centos系统安装之重置root密码   今日任务 1.Linux发行版的选择 2.vmware创建一个虚拟机(centos) 3.安装配置centos7 4.xshell配置连接虚拟 ...

  9. netty 的事件驱动

    netty 是事件驱动的,这里面有两个含义,一是 netty 接收到 socket 数据后,会产生事件,事件在 pipeline 上传播,二是事件由特定的线程池处理. NioEventLoop 轮询网 ...

  10. 【新人赛】阿里云恶意程序检测 -- 实践记录 11.24 - word2vec模型 + xgboost

    使用word2vec训练词向量 使用word2vec无监督学习训练词向量,输入的是训练数据和测试数据,输出的是每个词的词向量,总共三百个词左右. 求和:然后再将每行数据中的每个词的词向量加和,得到每行 ...