Django中数据库的食用手册

1. 模型(Model)

1.1 基本介绍

一言以蔽之,Django中的模型(Model)对应于数据库中的一张表。
模型的基本知识:

  • 模型是一个Python类,继承自django.db.models.Model;
  • 模型的每个属性对应于数据库中的一个域(field);
  • Django提供了一系列操作数据库的API。

1.2 快速上手

以下代码定义了Person模型,有两个属性first_name和last_name。
在这里插入图片描述
以上代码对应的SQL语句为:
在这里插入图片描述
注意:id域是自动生成的,但是这个行为可以被自定义。

1.3 使用模型

以下以MySQL数据库为例。

1.3.1 创建app

在这里插入图片描述

1.3.2 注册app

在这里插入图片描述

1.3.3 配置MySQL数据库

在这里插入图片描述

1.3.4 在数据库中创建表

在这里插入图片描述

1.3.5 创建模型并应用

在这里插入图片描述
接下来,通过manage.py执行 makemigrations & migrate
在Pycharm中,可以通过“Tools -> Run manage.py task”来打开manage.py的命令行界面。

1.3.6 效果查看

在这里插入图片描述

2. 域(Field)

域,即数据库中表的字段。
以下先给出一个示例,之后再详细解释。
在这里插入图片描述

2.1 域的类型

域的类型决定以下三个方面:

  • 数据库中字段的类型;
  • Django表单中使用的HTML组件类型;
  • 基本的验证需求,用于Django的验证系统和表单系统。

完整的域类型列表,可以查阅完整的域类型列表

2.2 域的选项

每个域都可以指定参数,下面列出了所有类型的域都具有的公共参数:

  • null - 默认值为False,决定数据库的对应字段中能否存放NULL值。
  • blank - 默认值为False,与null的不同之处在于null是与数据库有关的,而blank是与Django验证有关的,如果blank=True,表单验证允许该项不键入值,如果blank=False,该项必须键入值。
  • choices - 二维元组/列表,如果指定了该参数则默认的表单控件变为select box,并且内容被限制为提供的选项。
  • default - 该域的默认值,既可以是值,也可以是函数。
  • help_text - 显示在表单上的帮助信息。
  • primary_key - 如果指定为True,则这个域被作为主键。如果不显式指定主键,Django会自动增加一个IntegerField作为主键。主键对应的域是不可改的,如果视图更改主键,将产生一条新的记录,而不会覆盖原记录。
  • unique - 如果指定为True,则这个域是unique的。

以下对choices参数作进一步说明:
在这里插入图片描述
打开Python命令行,执行如下命令:
在这里插入图片描述
然后查看数据库:
在这里插入图片描述
不难发现,虽然“x”和“java”都不是choices中的选项,但是也能正常加入,显然只有在表单中会受到choices的影响。

2.3 域的详细名称(Verbose names)

verbose name指定了一个人类可读的名称。
每一个域类型,其第一个参数都可以指定为verbose name,如果verbose name没有提供,Django会自动创建verbose name,规则是将域的属性名中的下划线转换为空格
:ForeignKey, ManyToManyField, OneToOneField这些域类型比较特殊,需要使用verbose_name关键字参数。
示例1:这个示例中,verbose name为“person’s first name”
在这里插入图片描述
示例2:这个示例中,verbose name为“first name”(下划线被转为空格)
在这里插入图片描述

2.4 关系

2.4.1 多对一关系(ForeignKey)

例如,每个人都有自己喜欢的一门编程语言,可写出以下模型:
在这里插入图片描述
接下来向表中增加几条记录:
在这里插入图片描述
查看数据库:
在这里插入图片描述
在这里插入图片描述
此时删除Hobby表中的记录:
在这里插入图片描述
发现两个表中都变得空空如也,体现了“级联删除”。

2.4.2 多对多关系(ManyToManyField)

例如,每个人都有喜欢的多门编程语言,可写出以下模型:
在这里插入图片描述
运行makemigrations & migrate之后,查看表的结构:

可以看出Django自动增加了一张表来实现多对多模型。
在这里插入图片描述
向表中增加几条记录:
在这里插入图片描述
给一个人添加他喜欢的编程语言:
在这里插入图片描述
此时查看一下三张表:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下是多对多模型的一些Python API演示:
在这里插入图片描述
:以上Python API都是执行完毕后立即在数据库中生效的!

多对多关系的特殊查询方式:
例如,查询所有 含有一个 姓名以“Paul”打头的成员 的小组。
在这里插入图片描述

2.4.2 一对一关系(OneToOneField)

OneToOneField,个人感觉用处不大,故省略。

3. 数据库的增删改查

3.1 增加记录

增加记录有两种方式:

  • 第一种需要两行代码
    在这里插入图片描述
    注:其实不需要写force_insert=True。
  • 第二种只需要一行代码
    在这里插入图片描述

3.2 修改记录

当取得记录对象后,可以用以下方式修改:
在这里插入图片描述
当调用save()方法时,会实施SQL中的UPDATE。

修改ForeignKey:
假设Blog模型是Entry模型的外键,可以用以下方法修改外键。
在这里插入图片描述

修改ManyToManyField:
例如,给entry增加作者。
在这里插入图片描述
在这里插入图片描述

3.3 检索记录

为了从数据库中取出记录(在Python中为对象),需要通过Model类的Manager来构造一个QuerySet。
QuerySet中含有一系列数据库中的记录(对象),数量可以为0、1、或更多。
考虑SQL语言,QuerySet对应于SELECT语句,而filter对应于WHERE。
每一个Model类至少有一个Manager,它默认被称为objects。

3.3.1 取出所有记录

用以下方法可以取出一个表中的所有记录,作为QuerySet对象返回。
在这里插入图片描述

3.3.2 过滤器的使用

如果只需要选取一部分特定的记录,可以使用过滤器filter()和exclude()。
filter()返回与指定查询条件匹配的记录。
exclude()返回与指定查询条件不匹配的记录。
所有的查询方法可参阅这篇文档:Django中五花八门的数据库查询

过滤器也可以级联使用:
在这里插入图片描述
:QuerySet是惰性求值的,只有当它被求值时,才会访问数据库进行查询。例如以下4行代码,实际上只有在执行第4行print时才会访问数据库。
在这里插入图片描述

3.3.3 检索一行记录

使用filter()总是会返回QuerySet,如果只需要取出一行记录,可以使用get()方法。
使用get()方法可以直接取得一个对象:
在这里插入图片描述
如果没有检索到记录,会抛出异常,异常是模型类的类属性,比如Entry.DoesNotExist。
如果检索到多条记录,也会抛出异常,异常是模型类的类属性,比如Entry.MultipleObjectsReturned。

3.3.4 QuerySet索引与切片

对QuerySet使用切片,相当于SQL中的LIMIT和OFFSET字句。
例如:
在这里插入图片描述
:QuerySet不支持使用负的索引。

对QuerySet使用下标,就可以提取一个记录对象。
例如:
在这里插入图片描述

3.3.5 在过滤器中使用别的字段的值(F表达式)

在以上的过滤器示例中,我们都是将一个域与一个常数比较,那么如果想将一个域与该模型中另一个域相比较可以不可以呢?答案是肯定的!方法是使用F表达式

例如,查询 一个域的值大于另一个域的值 的所有记录:
在这里插入图片描述
F()也可以和加减乘除搭配使用,也可以使用多个F():
在这里插入图片描述
对于date和datetime域,可以对F()对象加上或减去一个timedelta对象。
例如,选出 修改日期在发表日期3天后 的记录:
在这里插入图片描述

3.3.6 pk - 主键

在查询中,“pk”表示主键的意思,例如下面3句语句是等价的:
在这里插入图片描述

3.3.7 LIKE字句中的自动转义

当需要进行与SQL中LIKE字句有关的查询时,Django会自动转义两个特殊字符:百分号%和下划线_。
例如,
在这里插入图片描述
对应于SQL语句:
在这里插入图片描述

3.3.8 Cache

每一个QuerySet对象都有一个Cache,目的是减少对数据库的访问。
Cache的详细介绍可参阅:Caching and QuerySets

3.3.9 与、或、非关系(Q对象)

使用Q对象可以实现与、或、非关系,Q对象之间可以使用 & 、| 、~ 操作符连接,将会产生一个新的Q对象。
例如,
在这里插入图片描述
对应于SQL的WHERE字句:
在这里插入图片描述
在filter()、exclude()、get()中可以使用Q对象,如果传递了多个Q对象作为参数,是“与”的关系,例如,
在这里插入图片描述
对应于SQL语句:
在这里插入图片描述
Q对象可以关键字参数(双下划线查询)混合使用,但是Q对象一定要放在最前,例如,
在这里插入图片描述

3.3.10 记录之间的比较

假如有两个记录对象需要比较,使用“==”号比较,比较的是主键的值是否相等。

3.4 删除记录

3.4.1 删除单行记录

取出记录对象,然后调用delete()方法,将会返回 所有删除记录的数量 和 每个表删除记录的数量构成的字典。
在这里插入图片描述

3.4.2 删除多行记录

每一个QuerySet都有一个delete()方法,因此结合filter()等函数可以删除特定的记录。
在这里插入图片描述
对于ForeignKey,在定义ForeignKey域时指定的on_delete参数决定了如何删除。假如on_delete=CASCADE,当调用delete()时,
在这里插入图片描述

3.4.3 删库跑路

如果想要删除表中所有记录,可以使用以下方法。
在这里插入图片描述

3.4 拷贝记录

Django中不提供内建的方法拷贝记录,但是有一种简单的方法可以实现。
在这里插入图片描述
原因是,当修改记录对象的主键时,不会覆盖原有记录,而是会插入一条新的记录。
将pk设置为None,则自动生成一个主键值。

3.5 修改多条记录

QuerySet有一个update()方法,可以批量修改记录。例如,
在这里插入图片描述
在这里插入图片描述
update()可以与F表达式配合使用,例如将所有记录的值+1,
在这里插入图片描述

3.6 原生SQL语句

如果以上Django提供的API不能满足需求,就需要执行原生SQL语句了,具体细节可以参阅:使用原生SQL语句

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值