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

 更新时间:2020年05月20日 09:32:11   作者:唯美落叶  
这篇文章主要介绍了Django ForeignKey与数据库的FOREIGN KEY约束详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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

那么不使用外键约束的情况下使用 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实现单向链表详解

    这篇文章主要介绍了python实现单向链表详解,分享了相关代码示例,每一步操作前都有简单分析,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • python利用pd.cut()和pd.qcut()对数据进行分箱操作

    python利用pd.cut()和pd.qcut()对数据进行分箱操作

    本文主要介绍了python利用pd.cut()和pd.qcut()对数据进行分箱操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Python机器学习之KNN近邻算法

    Python机器学习之KNN近邻算法

    KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法,文中非常详细的介绍了该算法,对正在学习python的小伙伴们有很好的帮助,需要的朋友可以参考下
    2021-05-05
  • python requests库的使用

    python requests库的使用

    这篇文章主要介绍了python requests库的使用,帮助大家更好的利用python进行爬虫,感兴趣的朋友可以了解下
    2021-01-01
  • 使用Python向C语言的链接库传递数组、结构体、指针类型的数据

    使用Python向C语言的链接库传递数组、结构体、指针类型的数据

    今天小编就为大家分享一篇关于使用Python向C语言的链接库传递数组、结构体、指针类型的数据,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Python实战之梦幻钢琴小游戏的实现

    Python实战之梦幻钢琴小游戏的实现

    这篇文章主要为大家详细介绍了如何利用Python语言编写一款界面化的(Tkinter)电子钢琴小程序,文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-02-02
  • Python数据分析与处理(二)——处理中国地区信息

    Python数据分析与处理(二)——处理中国地区信息

    这篇文章主要介绍了Python数据分析与处理-处理中国地区信息,上文介绍了北京高考分数线统计分析,这篇文章依然围绕Python数据分析与处理的相关资料来介绍处理中国地区信息,需要的朋友可以参考一下
    2021-12-12
  • 对Python中TKinter模块中的Label组件实例详解

    对Python中TKinter模块中的Label组件实例详解

    今天小编就为大家分享一篇对Python中TKinter模块中的Label组件实例详解,具有很好的价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • Python matplotlib绘图设置图例案例

    Python matplotlib绘图设置图例案例

    这篇文章主要给大家分享Python matplotlib绘图设置图例案例,过程会学到edgecolor 图例边框线颜色 facecolor 图例背景色 shadow 是否添加阴影 title 图例标题 fontsize 设置字体大小,小编觉得挺有意思的,感兴趣的小伙伴也可以参考一下
    2021-12-12
  • Python中的np.vstack()和np.hstack()详解

    Python中的np.vstack()和np.hstack()详解

    这篇文章主要介绍了np.vstack()和np.hstack(),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04

最新评论