对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制作获取网站目录的图形化程序
May 04 Python
在MAC上搭建python数据分析开发环境
Jan 26 Python
使用python3.5仿微软记事本notepad
Jun 15 Python
Python 3.x 判断 dict 是否包含某键值的实例讲解
Jul 06 Python
记录Python脚本的运行日志的方法
Jun 05 Python
Python 进程操作之进程间通过队列共享数据,队列Queue简单示例
Oct 11 Python
Python的缺点和劣势分析
Nov 19 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
python多线程实现代码(模拟银行服务操作流程)
Jan 13 Python
Python 的 __str__ 和 __repr__ 方法对比
Sep 02 Python
python中复数的共轭复数知识点总结
Dec 06 Python
利用Python判断你的密码难度等级
Jun 02 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中使用正则表达式提取中文实现笔记
2015/01/20 PHP
php里array_work用法实例分析
2015/07/13 PHP
JavaScript prototype属性使用说明
2010/05/13 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
JS.getTextContent(element,preformatted)使用介绍
2013/09/21 Javascript
jquery动态调整div大小使其宽度始终为浏览器宽度
2014/06/06 Javascript
JavaScript中最简洁的编码html字符串的方法
2014/10/11 Javascript
node.js+Ajax实现获取HTTP服务器返回数据
2014/11/26 Javascript
Vue.js动态添加、删除选题的实例代码
2016/09/30 Javascript
JS实现淡入淡出图片效果的方法分析
2016/12/20 Javascript
原生JS实现图片翻书效果
2017/02/16 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
nginx+vue.js实现前后端分离的示例代码
2018/02/12 Javascript
AngularJS使用Filter自定义过滤器控制ng-repeat去除重复功能示例
2018/04/21 Javascript
微信小程序列表时间戳转换实现过程解析
2019/10/12 Javascript
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
Python的ORM框架SQLAlchemy入门教程
2014/04/28 Python
python操作redis的方法
2015/07/07 Python
Python 数据结构之队列的实现
2017/01/22 Python
在java中如何定义一个抽象属性示例详解
2017/08/18 Python
python 中字典嵌套列表的方法
2018/07/03 Python
pyhanlp安装介绍和简单应用
2019/02/22 Python
Django框架组成结构、基本概念与文件功能分析
2019/07/30 Python
Django和Flask框架优缺点对比
2019/10/24 Python
python多进程重复加载的解决方式
2019/12/13 Python
python+selenium+Chrome options参数的使用
2020/03/18 Python
python中count函数知识点浅析
2020/12/17 Python
CSS3 渐变(Gradients)之CSS3 径向渐变
2016/07/08 HTML / CSS
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
家庭财产分割协议范文
2014/11/24 职场文书
2014年民警工作总结
2014/11/25 职场文书
武侯祠导游词
2015/02/04 职场文书
2015暑期社会实践个人总结
2015/07/13 职场文书
详解Python小数据池和代码块缓存机制
2021/04/07 Python
Nginx四层负载均衡的配置指南
2021/06/11 Servers