Django ForeignKey与数据库的FOREIGN KEY约束详解


Posted in Python onMay 20, 2020

数据库在高并发的场景下使用外键约束会有锁问题并且使用外键会增加运维成本,所以很多公司都规定生产环境的数据库禁止使用外键。

那么不使用外键约束的情况下使用 Django ORM 如何实现关联查询两个表呢?这曾是困扰我很久的一个问题,今天终于找到了答案,写出来分享一下。

Django 的 ForeignKey 和数据库的 FOREIGN KEY 并不一样。Django 的 ForeignKey 是一种逻辑上的两个表的关联关系,可以指定是否使用数据库的 FOREIGN KEY 约束。

在开头提到的场景下,我们可以这样创建两个表对应的 Model,以省和市的关联举例:

# demo/models.py
from django.db import models

class Province(models.Model):
  name = models.CharField(max_length=16)

  def __unicode__(self):
    return self.name

class City(models.Model):
  name = models.CharField(max_length=16)
  province = models.ForeignKey(Province, null=True, on_delete=models.SET_NULL,
                 related_name='cities', db_constraint=False)
  def __unicode__(self):
    return self.name

以上的 models.py 在执行 migrate 时生成的 SQL 如下(MySQL数据库):

CREATE TABLE `demo_city` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(16) NOT NULL);
CREATE TABLE `demo_province` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(16) NOT NULL);
ALTER TABLE `demo_city` ADD COLUMN `province_id` integer NULL;
CREATE INDEX `demo_city_province_id_50fffd49` ON `demo_city` (`province_id`);

如果 ForeignKey 不添加db_constraint=False 参数,会在数据库中使用外键约束,生成以下SQL:

ALTER TABLE `demo_city` ADD CONSTRAINT `demo_city_province_id_aff53934_fk_key_province_id` FOREIGN KEY (`province_id`) REFERENCES `demo_province` (`id`);

另外,ForeignKey 的 on_delete 参数默认为 on_delete=models.CASCADE,表示使用数据库的级联删除,使用 on_delete=models.SET_NULL 可以使删除 Province 时将关联的 City 表对应的 province_id 值设为 NULL

使用这种方式不会破坏 Django 的反向关联查询,以下查询仍然会返回正确的结果:

Province.objects.filter(cities__name='xxx')

实际执行的 SQL 为一个 Inner Join 查询:

SELECT `demo_province`.`id`, `demo_province`.`name` FROM `demo_province` INNER JOIN `demo_city` ON (`demo_province`.`id` = `demo_city`.`province_id`) WHERE `demo_city`.`name` = xxx;

补充知识:关于Django模型中中定义auto_now=True 数据库中的时间并没有自动更新

django的orm关于更新数据库的方法有update和save两种方法。

前提在模型中设置了auto_now=True时间戳属性,为了方便数据库自动更新时间,而

使用update更新的记录,数据库中并没有自动更新,达到我的需求。

auto_now=True自动更新,有一个条件,就是要通过django的model层。

如create或是save方法。

如果是filter之后update方法,则直接调用的是sql,不会通过model层,

所以不会自动更新此时间。所以使用save方法更新才能达到我的需求。

以上这篇Django ForeignKey与数据库的FOREIGN KEY约束详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现的百度站长自动URL提交小工具
Jun 27 Python
python格式化字符串实例总结
Sep 28 Python
Python的批量远程管理和部署工具Fabric用法实例
Jan 23 Python
判断网页编码的方法python版
Aug 12 Python
不同版本中Python matplotlib.pyplot.draw()界面绘制异常问题的解决
Sep 24 Python
python复制文件到指定目录的实例
Apr 27 Python
详解Python用户登录接口的方法
Apr 17 Python
简单了解Python3里的一些新特性
Jul 13 Python
在 Python 中接管键盘中断信号的实现方法
Feb 04 Python
基于PyQT实现区分左键双击和单击
May 19 Python
使用PyCharm安装pytest及requests的问题
Jul 31 Python
Python 制作自动化翻译工具
Apr 25 Python
让Django的BooleanField支持字符串形式的输入方式
May 20 #Python
django 解决model中类写不到数据库中,数据库无此字段的问题
May 20 #Python
基于Python脚本实现邮件报警功能
May 20 #Python
完美解决Django2.0中models下的ForeignKey()问题
May 19 #Python
Django 解决model 反向引用中的related_name问题
May 19 #Python
django queryset 去重 .distinct()说明
May 19 #Python
django正续或者倒序查库实例
May 19 #Python
You might like
php更改目录及子目录下所有的文件后缀扩展名的代码
2010/10/12 PHP
ThinkPHP使用Smarty第三方插件方法小结
2016/03/19 PHP
php常用字符串String函数实例总结【转换,替换,计算,截取,加密】
2016/12/07 PHP
jquery星级插件、支持页面中多次使用
2012/03/25 Javascript
jquery表单验证插件(jquery.validate.js)的3种使用方式
2015/03/28 Javascript
浅谈JS原生Ajax,GET和POST
2016/06/08 Javascript
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
2017/07/17 Javascript
Vue中添加滚动事件设置的方法详解
2020/09/14 Javascript
JavaScript中arguments的使用方法详解
2020/12/20 Javascript
Flask SQLAlchemy一对一,一对多的使用方法实践
2013/02/10 Python
Python中的异常处理学习笔记
2015/01/28 Python
matplotlib作图添加表格实例代码
2018/01/23 Python
使用Python更换外网IP的方法
2018/07/09 Python
Django组件cookie与session的具体使用
2019/06/05 Python
python 实现识别图片上的数字
2019/07/30 Python
Python3.7 读取 mp3 音频文件生成波形图效果
2019/11/05 Python
CSS3制作酷炫的三维相册效果
2016/07/01 HTML / CSS
深入浅析HTML5中的SVG
2015/11/27 HTML / CSS
Lee牛仔裤澳大利亚官网:美国著名牛仔裤品牌
2017/09/02 全球购物
Michael Kors香港官网:美国奢侈品品牌
2019/12/26 全球购物
俄罗斯三星品牌商店:GalaxyStore
2020/11/04 全球购物
师范应届生求职信
2013/11/15 职场文书
本科毕业生的求职信范文
2013/11/20 职场文书
环境科学毕业生自荐信
2013/11/21 职场文书
高中地理教学反思
2014/01/29 职场文书
无传销社区工作方案
2014/05/13 职场文书
食品工程专业求职信
2014/06/15 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
党员十八大心得体会
2014/09/12 职场文书
寒暑假实习证明书模板
2014/11/29 职场文书
社区三八妇女节活动总结
2015/02/06 职场文书
校友会致辞
2015/07/30 职场文书
计算机实训心得体会
2016/01/14 职场文书
关于html选择框创建占位符的问题
2021/06/09 HTML / CSS
Mybatis是这样防止sql注入的
2021/12/06 Java/Android
ECharts transform数据转换和dataZoom在项目中使用
2022/12/24 Javascript