数据库:MySql 5.7
下载:
https://dev.mysql.com/downloads/windows/installer/5.7.html
python安装Mysql的驱动
pip install mysqlclient
当然除此之外还有pymysql等第三方驱动可以使用,在这里用的是mysqlclient。
操作数据库
Django配置连接数据库:
在操作数据库之前,首先先要连接数据库。这里我们以配置MySQL为例。Django连接数据库,不需要单独的创建一个连接对象。只需要在settings.py文件中做好数据库相关的配置就可以了。示例:
DATABASES = {
'default':{
#数据库引擎
'ENGINE': 'django.db.backends.mysql',
#数据库名字
'NAME': 'name',
#连接数据库的用户名
'USER': 'username',
#用户密码
'PASSWORD': '********',
#mysql的主机地址
'HOST': 'ip_address',
#端口
'PORT': 'port'
}
}
在Django操作数据库:
操作方式有两种:
- 原生sql语句
- ORM模型
1.原生sql语句
在Django中使用原生的sql语句操作其实就是使用python ad api的接口来操作。如果使用的是mysqlclient驱动,那么就是用mysqlclient来操作的,只不过Django将数据库连接这一部分封装好了,我们只要在settings.py中配置好了数据库连接信息后直接使用Django封装好的接口就可以操作了。示例:
#使用django封装好的connection对象,会自动选取settings.py中数据库的配置信息
from django.db import connection
#获取游标对象
cursor = connection.cursor()
#拿到游标对象后执行sql语句
cursor.execute("select * from book")
#获取所有数据
rows = cursor.fetchall()
#遍历查询到的数据
for row in rows:
print(row)
附: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):获取多条查询到的数据
7.fetchall:获取所有查询到的数据
2.ORM模型
随着项目越来越大,采用写原生sql的方式在代码中会出现大量的SQL语句,那么问题就出现了:
- SQL语句重复利用率不高, 越复杂的SQL语句条件越多,代码越长,会出现很多相近的SQL语句。
- 很多SQL语句是在业务逻辑中拼出来的,如果有数据库需要更改,就要去修改这些逻辑,这会很容易漏掉对某些SQL语句的修改。
- 写SQL时容易忽略web安全问题,给未来造成隐患。SQL注入。
ORM,全称Object Relational Mapping,中文叫做对象关系映射,通过ORM我们可以通过类的方式去操作数据库,而不用再写原生的SQL语句。通过把表映射成类,把行作实例,把字段做属性,ORM在执行对象操作的时候最终还是会把对应的操作转换为数据库的原生语句。使用ORM有许多优点:
- 易用性:使用ORM做数据库的开发可以有效的减少重复SQL语句的概率,写出来的模型也更加直观、清晰。
- 性能损耗小:ORM转换成底层数据库操作指令确实会有一些开销。但从实际的情况来看,这种性能损耗很小,只要不是对性能有严苛的要求,综合考虑开发效率,代码的阅读性,带来的好处要远远大于性能损耗,而项目越大作用越明显。
- 设计灵活:可以轻松的写出复杂的查询。
- 可移植性:Django封装了底层的数据库实现,支持多个关系数据库引擎。可以非常轻松的切换数据库。
ORM模型的创建和映射:
1.创建ORM模型:
‘ORM’模型一般都是放在'app'的'models.py'文件中,每个'app'都可以拥有自己的模型,并且如果这个模型想要映射到数据库中,那么这个'app'必须要放在'settings.py'的'INSTALLED_APP'中进行安装,以下是写一个简单的数据'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)
以上便定义了一个模型。这个模型继承自'django.db.models.Model',如果这个模型想要映射到数据库中,就必须继承自这个类,这个模型以后映射到数据库中,表名是模型名称的小写形式,为'book'。在这个表中,有四个字段,一个为'name',这个字段是保存的是书的名称,是'varchar'类型,最长不能超过20个字符,并且不能为空。第二个字段是……
如果没有定义主键,那么将会自动生成一个自动增长的'int'类型的主键,并且这个主键的名字叫做'id'。
2.映射模型到数据库中:
将'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'来迁移脚本文件映射到数据库中。
ORM模型基本增删改查操作
1.添加数据:
只要使用ORM模型创建一个对象,然后再调用这个ORM模型的'save'方法就可以保存了。
示例:
book = Book(name='西游记',author='吴承恩',price=100)
book.save()
2.查找数据:
所有的查找工作都是使用模型上的'objects'属性来完成的,当然也可以试用自定义查询对象.
1.根据主键进行查找:使用主键进行查找,可以试用'objects.get'方法,然后传递'pk=xx'的方式进行查找。示例:
book = Book.objects.get(pk=2)
2.根据其他字段进行查找:可以使用'objects.filter'方法进行查找。示例:
book = Book.objects.filter(name='三国演义')
使用'filter'方法返回来的是一个'QuerySet'对象。这个对象类似于列表。我们可以使用这个对象的'first'方法来获取第一个值。
3.删除数据:
首先查找到对应的数据模型。然后再执行这个模型的'delete'方法即可。示例:
book = Book.objects.get(pk=1)
book.delete()
4.修改数据:
首先查找到对应的数据模型。然后修改这个模型上的属性的值。再执行'save'方法即可修改完成。示例:
book = Book.objects.get(pk=2)
book.price=200
book.save()
模型常用属性
常用字段:
在Django中,定义了一些Field来与数据库表中的字段类型来进行映射。
- AutoField:
映射到数据库中是int类型,可以由自动增长的特性。一般不需要使用这个类型,如果不指定主键,那么模型就会自动生成一个叫id的自动增长的主键。如果你想指定一个其它名字的并且具有自动增长的主键,使用AutoField也是可以的(primary_key=True)。
- BigAutoField:
64位的整型,类似于AutoField,只不过是产生的数据范围是从1-9223372036854775807
- BooleanField:
在模型层接收的是True/False。在数据库层面是tinyint类型。如果没有指定默认值,默认值是None。
- CharField:
在数据库层面是varchar类型。在python层面就是普通的字符串。这个类型在使用的时候必须要指定最大的长度,也即必须要传递max_length这个关键字参数进去。
- DateField:
日期类型。在python中是datetime.date类型,可以记录年月日。在映射到数据库中也是date类型,使用这个Field可以传递一下几个参数:
- aotu_now:在每次这个数据库保存的时候,都是用当前的时间。如果作为一个记录修改日期的字段,可以将这个属性设置为True。
- auto_now_add:在每次数据第一次被添加进去的时候,都是用当前的时间。比如作为一个记录第一次入库的字段,可以将这个属性设置为True。
- DateTimeField:
日期时间类型,类似于DateField。不仅仅可以存储日期,还可以存储时间。映射到数据库中是datetime类型。这个Field也可以使用auto_now和auto_now_add两个属性。
- TimeField:
时间类型。在数据库中是time类型。在Python中是datetime.time类型。
- EmailField:
类似于CharField。在数据库底层也是一个varchar类型。只不过这个Field可以存储字符串的时候检测这个字符串是否是一个有效的邮箱。最大长度是254个字符。
- FileField:
用来存储文件的。(待补充)
- ImageField:
用来存储图片文件。(待补充)
- FloatField:
浮点类型。映射到数据库中是float类型。
- IntegerField:
整型。-2147483647~2147483647
- BigIntegerField:
大整型。
- PositiveIntegerField:
正整型。0~2147483647
- SmallIntegerFlied:
小整型。-32768~32768
- TextField:
大量的文本类型。映射到数据库中是longtext类型。
- UUIDField:
只能存储uuid格式的字符串。uuid是一个32位的全球唯一的字符串,一般用来作为主键。
- URLField:
类似于CharField,只不过只能用来存储url格式的字符串。默认max_length是200。