进阶Django(三):模型外键、多对多关系、自关联外键及Meta类

2023-05-16

目录

前言

模型中的映射关系

1 物理外键与逻辑外键

2 Django中的外键(一对一、一对多关系)

3 Django中的多对多关系

3.1 使用ManyToManyField自动建立多对多关系

3.2 另一种建立多对多表的方式

3.3 多对多关系的建立与查询

4 自关联外键

5 外键删除时

Model的Meta内部类

使用Model时遇到的一些问题

1 使用mysql报错 Did you install mysqlclient?

2 You are trying to add a non-nullable field 'xxx' to xxx


前言

本文为Django框架下Model模块的进阶教程,承接的是本专栏的文章《初识Django(七):模型》。本文主要介绍的是Model下外键(一对一、一对多)、多对多关系的使用和Meta类的使用,以及解决一些疑难问题。

模型中的映射关系

1 物理外键与逻辑外键

外键是表中一个特殊的字段,被用于与其他表建立关系。

外键分为物理外键与逻辑外键两种,物理外键在数据库中定义,其级联关系由数据库本身维护;而逻辑外键的关系由自定义的代码维护。由于物理外键会强制要求数据库在删除具有外键的记录时检查数据,在数据量大的情况下会造成数据库资源的浪费,加上mysql对外键的设计不合理,所以一般不建议使用物理外键。

2 Django中的外键(一对一、一对多关系)

Django中的ForeignKey为逻辑外键当你在Django中声明一个列为ForeignKey时,其实际上存入的是连接到的表的主键,并为此列建立一个索引。ForeignKey的使用如下例所示:

class ForeignModel(models.Model):

    data=models.CharField(max_length=100)

class ExampleModel(models.Model):

    id=models.CharField(default=CALLABLE_FUNC) #置为随机数函数

    username=models.CharField(max_length=30,blank=True)

    data=models.ForeignKey(ForeignModel)

如果要建立的两张表记录是一对一关系,记得在外键上添加unique=True属性,当记录的是一对多关系时,则需要在“多”的表中建立外键。

3 Django中的多对多关系

事实上,它原理上和一般的数据库多对多关系的实现并无二致。但在Django中,你可以直接使用ManyToManyField声明一个多对多字段,django会自动为你创建一张记录多对多关系的表。

3.1 使用ManyToManyField自动建立多对多关系

一个例子:

class Example1Model(models.Model): 

    data1=models.CharField(max_length=50)

class Example2Model(models.Model):

    data2=models.CharField(max_length=50)

    release=models.ManyToManyField(Example1Model) #多对多关系

运行migrate命令后,查看数据库,可以发现生成了一个app名_example2model_release表,即为记录多对多关系的表。

3.2 另一种建立多对多表的方式

使用Django ManyToMantField字段全自动建立第三张表总是差点味道,也不方便维护,那么,为何不直接将第三张表写成一个模型类呢?这种方式的扩展性更高,而且对强迫症非常友好^ ^。

手动书写联系表,然后在ManyToManyField字段中用through参数指定django使用此联系表做映射,如下所示:

class Example1Model(models.Model): 

    data1=models.CharField(max_length=50)

class Example2Model(models.Model):

    data2=models.CharField(max_length=50)

    release=models.ManyToManyField(Example1Model,through="Model1_Model2_Release") #多对多关系

class Model1_Model2_Release(models.Model):

    model1=models.ForeignKey(Example1Model,on_delete=DO_NOTHING)

    model2=models.ForeignKey(Example2Model,on_delete=DO_NOTHING)

3.3 多对多关系的建立与查询

请看以下代码:

e1=Example1Model.objects.create(data1="1234")

e2=Example2Model.objects.create(data2="5678")

#分别创建两个实例

e2.release.add(e1) 

#使用add直接添加对象建立映射关系

e2.release.all()

#正向查询 ,只需要引用ManyToManyField字段

#=> <QuerySet [<Example1Model: Example1Model object (1)>]>

e1.example2model_set.all()

#反查 ,example1model为被查询的类名全小写(即使是django官网那边也没写这个_set怎么来的,我只能自己写了一遍代码确认这玩意- -)

#=> <QuerySet [<Example2Model: Example2Model object (1)>]>

请注意反查引用的字段为[被查询的模型类全小写_set]

4 自关联外键

有时候会发生这样的情况:表中的一条记录与同一张表中的另一条记录相关联,这种情况就叫做自关联。

自关联的三种关系写法与上文相同,只是将引用的类名改成self即可。

5 外键删除时

对于外键而言,由于其引用的是另一条数据库记录,故而不得不考虑一个问题:当它所引用的记录被删除时,它本身所处的记录又该如何?由于一对一、一对多、多对多关系中都需要用到外键,所以这也是上面这些关系中需要共同考虑的内容。

我们在声明外键时,必须设置一个on_delete参数,通过这个参数决定Django在外键依赖的记录删除时会如何处理这个外键对应的数据。

这个参数有以下几个取值:

  • CASCADE:级联删除,当被引用记录删除时,本记录也删除
  • DO_NOTHING:什么也不做
  • SET_NULL:设为空
  • SET_DEFAULT:设为默认值
  • PROTECT:保护模式,当删除引用记录时,会报错
  • SET():设置一个对象,其中填写一个callable对象(比如说一个方法,返回一个默认模型对象)

Model的Meta内部类

如果说模型中字段的参数是对这个字段的设置,那Meta类就是对整个模型的设置。我们可以通过在模型类中建立Meta类并声明特定名称的字段来调整模型。

下方列出一些常用的Meta字段及其意义:

class ExampleModel(models.Model):

    id=models.CharField(default=CALLABLE_FUNC) #置为随机数函数

    username=models.CharField(max_length=30,blank=True)

    class Meta():

        db_table="声明在数据库中对应的表名,不声明django会自动命名为app名_类名"

        app_label="这个字段仅在你的模型类不在默认的models.py文件内,用于指定此模型所属的app,内容为所属app的名字"

        get_latest_by="这个字段指示django的get_latest()按照哪个字段查询。应为一个模型字段名,此字段为DateField或者DateTimeField"

        managed="Boolean。当其为真,django按照Model类修改数据库表,当其为假,django不会进行这些操作。"

        ordering="这个字段指示django返回的数据按照哪个字段排序。为一个DateField或DateTimeField。"

        verbose_name="此模型的别名。这个字段也可用于模型中的字段(有点拗口,这个选项也可以在模型中的列名中单独设置,这里设置的是表的别名,那里设置的是列的别名)。"

使用Model时遇到的一些问题

1 使用mysql报错 Did you install mysqlclient?

发生在manage.py的makemigrations命令中。这问题呢,是一个连环坑。

最开始的报错图如下所示:

意思是我们没有安装mysqlclient,第一反应肯定是打开命令行pip安装一下包,但pip安装又会报错,说打不开文件“mysql.h”。pip安装不成,只能自己去下whl文件安装了。

下载地址如下所示:

https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient

下载后以安装whl文件的方式安装完毕再次运行,问题解决。

2 You are trying to add a non-nullable field 'xxx' to xxx

这个其实也不算报错,但是需要使用者注意。即使你确定这个字段在后续生成记录时始终不为空,也最好为其设置一个默认值,否则在为表增加字段时django也会强制你添加一个值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进阶Django(三):模型外键、多对多关系、自关联外键及Meta类 的相关文章

  • 简化代码和Kotlin的特性-Kotlin在Android中的使用(二)

    文章目录 一 使用Kotlin来简化findViewById代码二 Kotlin特性1 不需要 xff1b 结尾2 xff1a 的使用3 没有 new 关键字4 变量 xff0c 常量定义 xff0c 类型推断5 空指针安全6 函数定义7
  • Thunderbird 里面 QQ 企业邮箱 POP3/SMTP 设置

    端口自动检测 接收邮件服务器 xff1a pop exmail qq com 发送邮件服务器 xff1a smtp exmail qq com
  • 图像细节增强(直方图均衡化,对数变换,Gamma变换(校正))

    图像细节增强 xff08 直方图均衡化 xff0c 对数变换 xff0c Gamma变换 xff08 校正 xff09 xff09 文章目录 一 直方图均衡化1 定义2 原理3 方法步骤 二 对数变换1 原理 三 Gamma校正1 原理 前
  • ubuntu20.04搭建arm交叉编译环境

    1 下载arm交叉编译程序 源码下载地址 xff1a Downloads GNU A Downloads Arm Developer 要根据目标系统选择编译器版本 xff0c 我的主板 xff1a aarch64bit体系结构 xff08
  • 【python】《多媒体技术与应用》实验报告「数字视频处理」

    多媒体技术与应用 实验报告 实验名称 数字视频处理 实验时间 2022 4 25 姓名 班级 计非201 学号 成绩 实验目的1 理解并掌握数字视频的相关概念 xff1b 2 掌握并利用 Python 读取和观察视频数据 xff1b 3 掌
  • Python GUI开发之Tkinter:详解安装和使用方法

    Python GUI开发之Tkinter 详解安装和使用方法 Tkinter是Python中最常用的GUI图形库之一 它是Python自带的标准库 所以不需要额外安装 在Python的标准库中 Tkinter模块被用来创建桌面GUI应用程序
  • windows下ssh免密登录ubuntu

    一 先查看要登录的服务器是否安装ssh server服务 dpkg l grep ssh 若没有则需要安装 apt span class token operator span get install openssh span class
  • CentOS 7下安装MPICH3.2过程详解

    最近由于专业需要 xff0c 需要在CentOS 7平台下安装并行计算包MPICH 由于我才接触Linux xff0c 鸟哥的基础入门书也才看了四分之一不到 xff0c 所以安装也一步一步按照官方给的文档安装 官方安装方法 首先附上官网给出
  • 洛谷 P3366 【模板】最小生成树

    洛谷 P3366 模板 最小生成树 题目 给出一个无向图 xff0c 求出最小生成树 xff0c 如果该图不连通 xff0c 则输出orz 题目链接 模板 最小生成树 洛谷 输入 第一行包含两个整数N M xff0c 表示该图共有N个结点和
  • 2019 计蒜之道 复赛 D “星云系统”

    2019 计蒜之道 复赛 D 星云系统 题目 现在给定你一个字符串s以及一个整数k xff0c 请求出s的字典序最小的长度为k的子序列 题目链接https nanti jisuanke com t 39614 输入格式 第一行一个由小写英文
  • Linux mysql 配置

    一 数据库处室化密码 刚刚装好的数据库需要重置密码 alter user user identified by 39 12345678 39 如果是测试环境 或者自己玩的环境 设置密码过于简单 可以通过一下命令修改关于密码的校验 set g
  • 二进制安装Kubernetes(k8s) v1.26.0 IPv4/IPv6双栈

    二进制安装Kubernetes xff08 k8s xff09 v1 26 0 IPv4 IPv6双栈 https github com cby chen Kubernetes 开源不易 xff0c 帮忙点个star xff0c 谢谢了 介
  • ThinkPad E430 蓝牙驱动 BCM43142A0

    最近我意外发现公司的 ThinkPad E430 笔记本竟然是带有蓝牙的 D 查看蓝牙设备标识 ID 利用 lsusb 命令找到蓝牙模块信息 Bus 001 Device 004 ID 105b e065 Foxconn Internati
  • cephadm 安装部署 ceph 集群

    介绍 手册 xff1a https access redhat com documentation zh cn red hat ceph storage 5 html architecture guide index http docs c
  • PVE Cloud-INIT 模板配置

    PVE Cloud INIT 模板配置 Cloud init是什么 Cloud init是开源的云初始化程序 xff0c 能够对新创建弹性云服务器中指定的自定义信息 xff08 主机名 密钥和用户数据等 xff09 进行初始化配置 通过Cl
  • openstack 环境部署

    22 1 了解云计算 人类基于千年的物种衍变基础 xff0c 在这个世纪终于有了爆发式的科技成果 xff0c 尤其这二十年内互联网的发展 xff0c 更像是一种催化剂 xff0c 让原本已经热闹的地球更加的沸腾 xff0c 互联网经济泡沫破
  • C语言,计算圆的面积程序

    C语言 xff0c 计算圆的面积程序 span class token comment 计算圆的面积程序 日期 xff1a 2020 8 29 姓名 xff1a 张倩峰 span span class token macro propert
  • 博图软件搜索不到网卡

  • 台达伺服手动调试

  • 博途V15.1激活工具出错。

    博图V15 1激活 xff0c 软件出错 出现以下报错信息 解决方法 xff1a 下载新版本激活工具 再次激活

随机推荐