对Django外键关系的描述


Posted in Python onJuly 26, 2019

注:本文需要你有一定的数据库知识,本文的数据库语法使用mysql书写

Django中,跟外键有关的关系有三种,下面来一一介绍。

OneToManyField

这种最好理解,说白了就是最普通的外键,看看下面两个模型:

class GoodsType(models.Model):
  name = models.CharField(max_length=50)

class GoodsMessage(models.Model):
  Title = models.CharField(max_length='100') # 商品标题
  Category = models.ManyToManyField(GoodsType) # 商品标签

分析一下:

这里Django会在数据库中创两张表:

create table GoodsType(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

create table GoodsMessage(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Title` varchar(50) NOT NULL,
  `Category_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`Category_id`) REFERENCES `SchoolBuy_goodstype` (`id`)
)

这样的结果就是一个商品会对应一个类别,即类别是商品的外键。

OneToOneField

这种关系和OneToMany类似,是一种有约束的外键,看看下面两个模型:

class GoodsType(models.Model):
  name = models.CharField(max_length=50)

class GoodsMessage(models.Model):
  Title = models.CharField(max_length='100') # 商品标题
  Category = models.OneToManyField(GoodsType) # 商品标签 (变为一对一关系)

他们会使得数据库创建什么表呢?

create table GoodsType(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

create table GoodsMessage(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Title` varchar(50) NOT NULL,
  `Category_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`Category_id`) REFERENCES `SchoolBuy_goodstype` (`id`),
  UNIQUE KEY `SchoolBuy_goodsmessage_Category_id_4dd415fc1e19cf24_uniq` (`Category_id`) # 新增
)

那么这里已经很明显了,在这两个模型里,每个商品有一个商品类型,并且每个商品类型只属于一个商品(用了UNIQUE约束),即如果我A商品的类型是电脑,那么其他商品的类型都不能定义为电脑了。

所以商品与类型的对应关系肯定不能是OneToOne,而应该是OneToMany。

那么OneToOne用在哪里呢?这里说一个地方,在扩展Django的User模型时,因为系统自带的字段不够,所以一种最基本的扩展方法是定义一个User_profile表,用来作为用户的扩展,那么一条用户记录只会有一个扩展表记录,并且这个这个记录也只属于该用户。

ManyToMany

多对多关系,这里我们假设一种情景:

我现在有一个商品表,这个商品有一些图片(不定数量),那么可以使用多对多关系:

class GoodsPicture(models.Model):
  Pic = models.ImageField(upload_to='pic/')

class GoodsMessage(models.Model):
  Title = models.CharField(max_length='100') # 商品标题
  Pic = models.ManyToManyField(GoodsPicture)

这里数据库不同啦,建立了三张表,具体如下:

create table GoodsPicture(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Pic` varchar(255) NOT NULL, # Django对于图片的保存采用的是二进制图片文件存硬盘,数据库只保存图片路径
  PRIMARY KEY (`id`)
)

create table GoodsMessage(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Title` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
  # 注意了,这里没有外键约束了
)

create table GoodsMessage_CoodsPicture(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `goodsmessage_id` int(11) NOT NULL,
  `goodpicture_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `goodsmessage_id` (`goodsmessage_id`,`goodspicture_id`),
  FOREIGN KEY (`goodsmessage_id`) REFERENCES `GoodsMessage` (`id`),
  FOREIGN KEY (`goodstype_id`) REFERENCES `GoodsPicture` (`id`)
)

前两个表就不讲了,主要说一下第三个表GoodsMessage_CoodsPicture,

Django用这个表来记录一条数据,内容为:某个商品对应某张图片。其中有一个UNIQUE约束,说明不能有重复的记录。

这样,每次查询GoodsMessage_CoodsPicture表,就能获得某件商品对应的图片。

这里讲了他们在数据库中的实现,那么Django如何来查询这些数据呢,有一篇好的博文推荐给大家:

以上这篇对Django外键关系的描述就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用MONGODB入门实例
May 11 Python
django实现分页的方法
May 26 Python
python&MongoDB爬取图书馆借阅记录
Feb 05 Python
打包发布Python模块的方法详解
Sep 18 Python
django加载本地html的方法
May 27 Python
python删除字符串中指定字符的方法
Aug 13 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
Oct 22 Python
python根据txt文本批量创建文件夹
Dec 08 Python
python psutil监控进程实例
Dec 17 Python
keras 获取某层的输入/输出 tensor 尺寸操作
Jun 10 Python
python的链表基础知识点
Sep 13 Python
python热力图实现简单方法
Jan 29 Python
python绘图模块matplotlib示例详解
Jul 26 #Python
详解Python中正则匹配TAB及空格的小技巧
Jul 26 #Python
基于Django ORM、一对一、一对多、多对多的全面讲解
Jul 26 #Python
Django Rest framework频率原理与限制
Jul 26 #Python
Django 使用easy_thumbnails压缩上传的图片方法
Jul 26 #Python
解决django服务器重启端口被占用的问题
Jul 26 #Python
深入解析神经网络从原理到实现
Jul 26 #Python
You might like
php中的比较运算符详解
2013/10/28 PHP
php中file_get_contents与curl性能比较分析
2014/11/08 PHP
php字符比较函数similar_text、strnatcmp与strcasecmp用法分析
2014/11/18 PHP
PHP new static 和 new self详解
2017/02/19 PHP
网页的标准,IMG不支持onload标签怎么办
2006/06/29 Javascript
用CSS+JS实现的进度条效果效果
2007/06/05 Javascript
js中精确计算加法和减法示例
2014/03/28 Javascript
JavaScript function 的 length 属性使用介绍
2014/09/15 Javascript
javascript中parseInt()函数的定义和用法分析
2014/12/20 Javascript
基于JS实现密码框(password)中显示文字提示功能代码
2016/05/27 Javascript
javascript正则表达式之分组概念与用法实例
2016/06/16 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
Angular组件化管理实现方法分析
2017/03/17 Javascript
详解AngularJS ng-class样式切换
2017/06/27 Javascript
webpack 1.x升级过程中的踩坑总结大全
2017/08/09 Javascript
新手快速入门JavaScript装饰者模式与AOP
2019/06/24 Javascript
vue 实现动态路由的方法
2020/07/06 Javascript
[03:38]2014DOTA2西雅图国际邀请赛 VG战队巡礼
2014/07/07 DOTA
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
使用Python写个小监控
2016/01/27 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
python 整数越界问题详解
2019/06/27 Python
Python Selenium 设置元素等待的三种方式
2020/03/18 Python
python属于解释型语言么
2020/06/15 Python
Python3基于plotly模块保存图片表格
2020/08/03 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
2021/02/18 Python
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
英国在线照明超市:Castlegate Lights
2019/10/30 全球购物
Linux内核产生并发的原因
2016/11/08 面试题
毕业生幼师求职自荐信
2013/10/01 职场文书
网站开发实习生的自我评价
2013/12/11 职场文书
《草原的早晨》教学反思
2014/04/08 职场文书
担保书范本
2015/01/20 职场文书
如何理解Vue简单状态管理之store模式
2021/05/15 Vue.js
pytorch中[..., 0]的用法说明
2021/05/20 Python