对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检测QQ在线状态的方法
May 09 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
Python fileinput模块使用实例
May 28 Python
python比较两个列表大小的方法
Jul 11 Python
Python3实现Web网页图片下载
Jan 28 Python
Python使用Pickle库实现读写序列操作示例
Jun 15 Python
Python3内置模块pprint让打印比print更美观详解
Jun 02 Python
利用Python实现手机短信监控通知的方法
Jul 22 Python
python matplotlib库绘制散点图例题解析
Aug 10 Python
Python 多线程,threading模块,创建子线程的两种方式示例
Sep 29 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
Oct 16 Python
用Python将库打包发布到pypi
Apr 13 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面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
2009/09/30 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
jquery实现顶部向右伸缩的导航区域代码
2015/09/02 Javascript
JS处理json日期格式化问题
2015/10/01 Javascript
浅谈JS继承_借用构造函数 & 组合式继承
2016/08/16 Javascript
jQuery 移动端拖拽(模块化开发,触摸事件,webpack)
2016/10/28 Javascript
微信小程序上传多图到服务器并获取返回的路径
2019/05/05 Javascript
elementUI table表格动态合并的示例代码
2019/05/15 Javascript
微信小程序实现语音识别转文字功能及遇到的坑
2019/08/02 Javascript
vue data对象重新赋值无效(未更改)的解决方式
2020/07/24 Javascript
原生js实现九宫格拖拽换位
2021/01/26 Javascript
Python 除法小技巧
2008/09/06 Python
Python之eval()函数危险性浅析
2014/07/03 Python
使用Python中的greenlet包实现并发编程的入门教程
2015/04/16 Python
Python基于回溯法子集树模板解决旅行商问题(TSP)实例
2017/09/05 Python
python爬取指定微信公众号文章
2018/12/20 Python
python selenium 弹出框处理的实现
2019/02/26 Python
Python实现的银行系统模拟程序完整案例
2019/04/12 Python
Pycharm远程调试原理及具体配置详解
2019/08/08 Python
Python3 Tensorlfow:增加或者减小矩阵维度的实现
2020/05/22 Python
Python类绑定方法及非绑定方法实例解析
2020/10/09 Python
CSS3字体效果的设置方法小结
2016/06/13 HTML / CSS
英国文胸专家:AmpleBosom.com
2018/02/06 全球购物
Bulk Powders意大利:运动补充在线商店
2019/02/09 全球购物
俄罗斯在线水暖商店:Perfecto.ru
2019/10/25 全球购物
英国第一独立滑雪板商店:The Snowboard Asylum
2020/01/16 全球购物
《社戏》教学反思
2014/04/15 职场文书
大学生活动总结怎么写
2014/04/29 职场文书
办理房产证委托书
2014/09/18 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
计算机专业自荐信范文
2015/03/26 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
关于vue中如何监听数组变化
2021/04/28 Vue.js
聊聊mysql都有哪几种分区方式
2022/04/13 MySQL