ORM
Django
框架中内置了ORM
支持,不必像Spring MVC
、Struct2
等框架需要使用独立的ORM框架。
配置数据库连接
django框架中已经内置了对主流数据库的支持,将需要使用的数据库写入项目配置文件settings.py
的DATABASES
字典中。
默认情况下,django使用的是sqlite
数据库。
在创建项目的同时已经在项目目录下创建了数据库文件db.sqlite3
并生成了对应的默认数据库配置,默认配置如下所示:
# file: [项目名称]/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
使用其它数据库需要修改DATABASES
字典中的内容,不同数据库的配置字段不尽相同。
以MySQL
为例,配置应当写成:
# file: [项目名称]/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '连接的数据库名称',
'USER': '数据库账户名称',
'PASSWORD': '数据库账户对应密码',
'host': '主机地址',
'port': 3306 # mysql数据库默认端口为3306
}
}
对于MySQL
数据库而言,仅仅正确配置DATABASES
列表中的参数并不能立即完成数据库连接,还需要安装mysql数据库驱动,否则在启动项目时会出现下列错误输出:
ImportError: No module named 'MySQLdb'
缺少MySQLdb
模块不能连接到MySQL
数据库。
使用Python2
可以安装mysql-python
包。
mysql-python
包没有移植到Python3
,对于Python3
,文档中建议安装mysqlclient
包作为MySQL
数据库驱动。
使用pip
包管理器安装mysql数据库驱动:
$ pip install mysql-python //for Python2
$ pip install mysqlclient //for Python3
项目管理脚本manager.py
中提供了一系列指令用于数据库操作:
flush
清理来自数据库的数据dumpdata
以指定的格式输出数据库中的内容dbshell
登陆到配置中指定数据库的命令行界面上(如果该数据库支持)inspectdb
扫描配置的数据库,将数据库中的表导出为django模型代码migrate
执行迁移操作,真正将makemigrations指令提交的改动实施到数据库中makemigrations
提交模型改动,创建一个迁移操作,但不会同步到数据库中
对一个新创建的django项目,配置完数据库之后应该使用管理脚本manager.py
的migrate
指令来进行数据迁移。
首次执行migrate
指令会在配置的数据库中创建一系列django项目需要的表,没有这些表则django的一些功能(Session
、站点管理等)将无法正常运行。
定义模型
在Django
中,模型定义一般写在App目录下的models.py
文件中:
- 模型应继承自
django.db.models.Model
类,一个模型类一般对应数据库中的一张表。 - 字段为
django.db.models.Field
的子类,为模型类的类成员,对应数据库表中的字段(列)。
根据数据表的字段为模型类中的字段选择正确的字段类型,以MySQL
为例,常见字段与django类型的对应关系为:
MySQL | Django |
---|---|
INT | IntegerField |
CHAR | CharField |
FLOAT、DOUBLE | FloatField |
DECIMAL | DecimalField |
DATE | DateField |
DATETIME | DateTimeField |
TIME | TimeField |
BLOB | BinaryField |
TEXT | TextField |
假设有以下结构的MySQL表:
CREATE TABLE `TestTable` (
`Index` int(4) NOT NULL DEFAULT '0',
`Name` varchar(48) NOT NULL DEFAULT '',
PRIMARY KEY (`Index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
在django框架中,该表对应的模型类可以写成:
# file: [应用名称]/models.py
from django.db import models
class TestTable(models.Model):
index = models.IntegerField(primary_key = True, db_column = "Index") # primary_key用于标识主键
name = models.CharField(max_length = 48, db_column = 'Name') # max_length用于设定最大字串长度
class Meta:
db_table = "TestTable"
managed = False # managed成员设为False则该模型不由django管理(django不会为其自动生成数据库表)
默认情况下,模型类中的类名、成员名与数据库表中的表名、字段名的关系为数据库表名/字段名 = App名 + 下划线 + 模型类名/成员名
。
很多时候,django默认生成的表名/字段名并不符合项目的命名规范,如TestTable
表默认生成的表名为[AppName]_TestTable
,此时可以手动指定模型类和类成员的对应表/字段:
- 对于表名,通过自定义
Meta
类,指定Meta
类成员db_table
来设定模型类关联的数据库表名。 - 对于字段名,通过在创建字段时指定
db_column
参数内容来指定类成员关联的数据库字段名。
数据库操作
每一个模型都至少有一个管理器,通过管理器来访问、操作数据。
默认管理器名称为objects
,需要通过模型类访问,并且不能通过模型类实例访问。
查询
对于模型中的数据,可以通过模型中的管理器来获取查询集,从查询集中获取数据库中的数据。
查询的基本语法如下:
py
模型类名.objects.all() # 获取包含所有对象的查询集
模型类名.objects.filter(**kwargs) # 获取一个满足参数的查询集
模型类名.objects.exclude(**kwargs) # 获取一个不满足参数的查询集
模型类名.objects.order_by(*field_names) # 获取以指定字段为参数排序的结果集
模型类名.objects.get(**kwargs) # 获取一个单一的查询对象(单行记录)
查询集的类型为
QuerySet
,支持索引访问,并可以对其执行切片操作。django中的模型查询操作(
filter()、exclude()
等)具有以下特性:
- 查询函数返回的结果依然是查询集,因此可以连续调用查询函数,进行链式过滤。
- 每次调用查询函数得到的查询集都是独立的,与之前的查询集无关。
- 查询集是惰性执行的,只有在需要求值时,查询才会被真正的执行。
对于查询集,可以进行遍历操作,以前面的
TestTable
表为例,打印出表中的所有数据:
py
for object in TestTable.objects.all():
print("Index: " + object.index + " Name: " + object.name)
插入
向数据库中插入数据,主要有两种方式:
- 使用管理器/查询集中的
create()
成员方法。- 构建带有新数据的模型类实例,之后调用
save()
成员方法。以前面的
TestTable
表为例,添加记录:“`py
# 使用create()方法
# 添加一行字段index为100,字段name为”TestInsert1”的记录
TestTable.objects.create(index = 100, name = ‘TestInsert1’)# 使用save()方法
# 添加一行字段index为200,字段name为”TestInsert2”的记录
insertItem = TestTable(index = 200, name = ‘TestInsert2’)
insertItem.save()
“`
修改
修改已有的字段需要以下步骤:
- 通过管理器的
get()
成员方法获取一行记录。- 再访问成员字段修改为需要的内容。
- 执行
save()
方法保存修改。以前面的
TestTable
表为例,修改已有记录:
py
# 修改index为100的记录,将其name字段修改为"TestAlter"
alterItem = TestTable.objects.get(index = 0)
alterItem.name = 'TestAlter'
alterItem.save()