第六章 数据库
- 第六章 数据库
-
- 一、mysql 数据库
- 二、数据库操作
- 三、ORM模型
-
- 1. ORM介绍
- 2. 创建ORM
- 3. 映射模型到数据库中(含文件)
- 4. 模型的增减改查操作—views.py(含文件)
- 5. 模型常用属性—models.py
-
- (1)常用字段:
-
- 1)AutoField:指定名字且自动增长的主键
- 2)BigAutoField:
- 3)BooleanField:
- 4)CharField:
- 5)DateField:
- 6)DateTimeField:
- 7)TimeField:
- 8)EmailField:
- 9)FileField:
- 10)ImageField:
- 11)FloatField:
- 12)IntegerField:
- 13)BigIntegerField:
- 14)PositiveIntegerField:
- 15)SmallIntegerField:
- 16)PositiveSmallIntegerField:
- 17)TextField:
- 18)UUIDField:
- 19)URLField:
- (2)Field的常用参数:
- (3)Meta 配置:使用自己指定的表名
- 6. 外键和表关系(含文件)
- 7. 模型操作
- 8. 查询操作(含文件)
-
- (1)exact:精确查询 =
- (2)iexact:模糊查询 like
- (3)QuerySet.query/get
- (4)contains:大小写敏感
- (5)icontains:大小写不敏感
- (6)contains与icontains
- (7)in:提取值是否在容器中
- (8)gt:大于
- (9)gte:大于等于
- (10)lt:小于
- (11)lte:小于等于
- (12)startswith:以某个值开始(大小写敏感)
- (13)istartswith:以某个值开始(大小写不敏感)
- (14)endswith:以某个值结束(大小写敏感)
- (15)iendswith:以某个值结束(大小写不敏感)
- (16)range:在给定的区间中
- (17)date:指定 date 的范围
- (18)year:根据年份进行查找
- (19)month: 根据月份进行查找
- (20)day: 根据日期进行查找
- (21)week_day:根据星期几进行查找
- (22)time:根据时间进行查找
- (23)isnull:根据值是否为空进行查找
- (24)regex和iregex:正则表达式
- 9. 聚合函数(含文件)
- 10. QuerySet API(含文件)
第六章 数据库
.
一、mysql 数据库
pymysql、nacicat
.
二、数据库操作
1. Django配置连接数据库(含文件)
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\1db_operation_demo
.
2. python DB API cursor 常用接口
(1)description
如果 cursor
执行了查询的sql 代码
。那么读取 cursor.description 属性
的时候,将返回一个列表,这个列表中装的是元组,元组中装的分别是 (name,type_code,display_size,internal_size,precision,scale,null_ok)
,其中name
代表的是查找出来的数据的字段名称,其他参数暂时用处不大。
(2)rowcount
代表的是在执行了 sql 语句
后受影响的行数。
(3)close
关闭游标。关闭游标以后就再也不能使用了,否则会抛出异常。
(4)execute(sql[,parameters])
执行某个 sql 语句。如果在执行 sql 语句的时候还需要传递参数,那么可以传给 parameters
参数。示例代码如下:
cursor.execute("select * from article where id=%s",(1,))
(5)fetchone
在执行了查询操作以后,获取第一条数据。
(6)fetchmany(size)
在执行查询操作以后,获取多条数据。具体是多少条要看传的 size
参数。如果不传size
参数,那么默认是获取第一条数据。
(7)fetchall
获取所有满足 sql 语句的数据。
.
3. book_manager 案例(含文件)
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\2book_manager
.
三、ORM模型
1. ORM介绍
全称:
Object Relational Mapping
,中文叫做对象关系映射,通过 ORM 我们可以通过类的方式去操作数据库,而不用再写原生的SQL语句。
ORM 优点:
1.易用性:使用 ORM 做数据库的开发可以有效的减少重复SQL语句的概率,写出来的模型也更加直观、清晰。
2.性能损耗小: ORM 转换成底层数据库操作指令确实会有一些开销。但从实际的情况来看,这种性能损耗很少(不足5%),只要不是对性能有严苛的要求,综合考虑开发效率、代码的阅读性,带来的好处要远远大于性能损耗,而且项目越大作用越明显。
3.设计灵活:可以轻松的写出复杂的查询。SQL注入(疑问)
4.可移植性:Django
封装了底层的数据库实现,支持多个关系数据库引擎,包括流行的 MySQL
、 PostgreSQL
和SQLite
。可以非常轻松的切换数据库。
2. 创建ORM
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=20,null=False)
author = models.CharField(max_length=20,null=False)
pub_time = models.DateTimeField(default=datetime.now)
price = models.FloatField(default=0)
3. 映射模型到数据库中(含文件)
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\3orm_intro_demo
将 ORM 模型映射到数据库中,总结起来就是以下几步:
1.在 settings.py
中,配置好 DATABASES
,做好数据库相关的配置。
2.在 app
中的models.py
中定义好模型,这个模型必须继承自django.db.models
。
3.将这个 app
添加到 settings.py
的INSTALLED_APP
中。
4.在命令行终端,进入到项目所在的路径,然后执行命令 python manage.py makemigrations
来生成迁移脚本文件。
5.同样在命令行中,执行命令 python manage.py migrate
来将迁移脚本文件映射到数据库中。
.
4. 模型的增减改查操作—views.py(含文件)
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\4base_orm_demo
(1)添加数据:save
只要使用ORM模型创建一个对象。然后再调用这个ORM模型的save
方法就可以保存了
示例代码如下:
book = Book(name='三国演义', author='罗贯中', price='200')
book = Book(name='西游记', author='吴承恩', price='100')
book.save()
(2)查找数据:get
所有的查找工作都是使用模型上的objects
属性来完成的。
当然也可以自定义查找对象。这部分功能会在后面讲到。
- 根据主键进行查找:使用主键进行查找。
可以使用objects.get
方法。然后传递pk=xx
的方式进行查找。
示例代码如下:
book = Book.objects.get(pk=2)
- 根据其他字段进行查找:可以使用
objects.filter
方法进行查找。
示例代码如下:
books = Book.objects.filter(name='三国演义')
books = Book.objects.filter(name='三国演义').first()
使用filter
方法返回来的是一个QuerySet
对象。这个对象类似于列表。
我们可以使用这个对象的first
方法来获取第一个值。
(3)删除数据:get、delete
首先查找到对应的数据模型。然后再执行这个模型的delete
方法即可删除。
示例代码如下:
book = Book.objects.get(pk=1)
book.delete()
(4)修改数据:get、save
首先查找到对应的数据模型。然后修改这个模型上的属性的值。
再执行save
方法即可修改完成。
示例代码如下:
book = Book.objects.get(pk=2)
book.price = 200
book.save()
.
5. 模型常用属性—models.py
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\5orm_field_demo
(1)常用字段:
在Django
中,定义了一些Field
来与数据库表中的字段类型来进行映射。以下将介绍那些常用的字段类型。
1)AutoField:指定名字且自动增长的主键
映射到数据库中是 int 类型,可以有自动增长的特性。一般不需要使用这个类型,如果不指定主键,那么模型会自动的生成一个叫做 id 的自动增长的主键。如果你想指定一个其他名字的并且具有自动增长的主键,使用 AutoField 也是可以的。
2)BigAutoField:
64位的整形,类似于 AutoField
,只不过是产生的数据的范围是从 1-9223372036854775807 。
3)BooleanField:
在模型层面接收的是 True/False
。在数据库层面是 tinyint
类型。如果没有指定默认值,默认值是None
。
4)CharField:
在数据库层面是 varchar
类型。在 Python 层面就是普通的字符串。这个类型在使用的时候必须要指定最大的长度,也即必须要传递max_length
这个关键字参数进去。
5)DateField:
日期类型。在 Python 中是 datetime.date
类型,可以记录年月日。在映射到数据库中也是 date
类型。使用这个 Field
可以传递以下几个参数:
auto_now
:在每次这个数据保存的时候,都使用当前的时间。比如作为一个记录修改日期的字段,可以将这个属性设置为 True 。auto_now_add
:在每次数据第一次被添加进去的时候,都使用当前的时间。比如作为一个记录第一次入库的字段,可以将这个属性设置为 True 。
6)DateTimeField:
日期时间类型,类似于 DateField
。不仅仅可以存储日期,还可以存储时间。映射到数据库中是 datetime
类型。这个 Field 也可以使用 auto_now
和 auto_now_add
两个属性。
7)TimeField:
时间类型。在数据库中是time
类型。在 Python 中是 datetime.time
类型。
8)EmailField:
类似于CharField
。在数据库底层也是一个 varchar
类型。最大长度是254个字符。
9)FileField:
用来存储文件的。这个请参考后面的文件上传章节部分。
10)ImageField:
用来存储图片文件的。这个请参考后面的图片上传章节部分。
11)FloatField:
浮点类型。映射到数据库中是 float 类型。
12)IntegerField:
整形。值的区间是 -2147483648——2147483647 。
13)BigIntegerField:
大整形。值的区间是 -9223372036854775808——9223372036854775807 。
14)PositiveIntegerField:
正整形。值的区间是 0——2147483647 。
15)SmallIntegerField:
小整形。值的区间是 -32768——32767 。
16)PositiveSmallIntegerField:
正小整形。值的区间是 0——32767 。
17)TextField:
大量的文本类型。映射到数据库中是longtext类型。
18)UUIDField:
只能存储 uuid 格式的字符串。 uuid 是一个32位的全球唯一的字符串,一般用来作为主键。
19)URLField:
类似于CharField
,只不过只能用来存储 url 格式的字符串。并且默认的 max_length
是200。
(2)Field的常用参数:
1)null:是否为空
如果设置为 True , Django 将会在映射表的时候指定是否为空。默认是为 False 。在使用字符串相关的 Field (CharField/TextField)的时候,官方推荐尽量不要使用这个参数,也就是保持默认值 False 。因为 Django 在处理字符串相关的 Field 的时候,即使这
个 Field 的 null=False ,如果你没有给这个 Field 传递任何值,那么 Django 也会使用一个空的字符串 “” 来作为默认值存储进去。
因此如果再使用 null=True , Django 会产生两种空值的情形(NULL或者空字符串)。如果想要在表单验证的时候允许这个字符串为空,那么建议使用 blank=True 。如果你的 Field 是 BooleanField ,那么对应的可空的字段则为 NullBooleanField 。
2)blank:验证是否为空
标识这个字段在表单验证的时候是否可以为空。默认是 False 。
这个和 null 是有区别的, null 是一个纯数据库级别的。而 blank 是表单验证级别的。
3)db_column:字段在数据库中的名字
这个字段在数据库中的名字。如果没有设置这个参数,那么将会使用模型中属性的名字。
4)default:默认值,值/函数
默认值。可以为一个值,或者是一个函数,但是不支持lambda
表达式。并且不支持列表/字典/集合等可变的数据结构。
5)primary_key:主键
是否为主键。默认是 False 。
6)unique:值是否唯一
在表中这个字段的值是否唯一。一般是设置手机号码/邮箱等。
更多 Field 参数请参考官方文档:https://docs.djangoproject.com/zh-hans/2.0/ref/models/fields/
(3)Meta 配置:使用自己指定的表名
对于一些模型级别的配置。我们可以在模型中定义一个类,叫做 Meta 。
然后在这个类中添加一些类属性来控制模型的作用。比如我们想要在数据库映射的时候使用自己指定的表名,而不是使用模型的名称。
那么我们可以在 Meta 类中添加一个 db_table
的属性。
示例代码如下:
class Book(models.Model):
name = models.CharField(max_length=20,null=False)
desc = models.CharField(max_length=100,name='description',db_column="description1")
class Meta:
db_table = 'book_model'
以下将对 Meta 类中的一些常用配置进行解释。
1)db_table:映射到数据库中的表名
这个模型映射到数据库中的表名。如果没有指定这个参数,那么在映射的时候将会使用模型名来作为默认的表名。
2)ordering:提取数据的排序方式
设置在提取数据的排序方式。后面章节会讲到如何查找数据。比如我想在查找数据的时候根据添加的时间排序,那么示例代码如下:
class Book(models.Model):
name = models.CharField(max_length=20,null=False)
desc = models.CharField(max_length=100,name='description',db_column="description1") pub_date = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'book_model' ordering = ['pub_date']
更多的配置后面会慢慢介绍到。 官方文
档:https://docs.djangoproject.com/en/2.0/ref/models/options/
.
6. 外键和表关系(含文件)
文件地址:
E:\Python3.8.0\python_item\python_diango\chapter04\6orm_relationship_demo
(1)外键
在MySQL
中,表有两种引擎,一种是InnoDB
,另外一种是 myisam
。如果使用的是 InnoDB
引擎,是支持外键约束的。外键的存在使得 ORM
框架在处理表关系的时候异常的强大。因此这里我们首先来介绍下外键在 Django
中的使用。
1)两个模型之间的引用
类定义为 class ForeignKey(to,on_delete,**options)
。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有 CASCADE
、SET_NULL
等。
这里以一个实际案例来说明。
比如有一个 User
和一个 Article
两个模型。一个User
可以发表多篇文章,一个Article
只能有一个Author
,并且通过外键进行引用。
示例代码如下:
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey("User",on_delete=models.CASCADE)
以上使用ForeignKey
来定义模型之间的关系。即在article
的实例中可以通过 author
属性来操作对应的 User
模型。这样使用起来非常的方便。
示例代码如下:
author = User(username='张三',password='111111')
author.save()
article = Article(title='abc',content='123')
article.author = author
article.save()
# 修改article.author上的值
article.author.username = '李四'
article.save()
为什么使用了ForeignKey
后,就能通过 author
访问到