Django ORM

ORM

Django框架中内置了ORM支持,不必像Spring MVCStruct2等框架需要使用独立的ORM框架。

配置数据库连接

django框架中已经内置了对主流数据库的支持,将需要使用的数据库写入项目配置文件settings.pyDATABASES字典中。

默认情况下,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.pymigrate指令来进行数据迁移。
首次执行migrate指令会在配置的数据库中创建一系列django项目需要的表,没有这些表则django的一些功能(Session、站点管理等)将无法正常运行。

定义模型

Django中,模型定义一般写在App目录下的models.py文件中:

  • 模型应继承自django.db.models.Model类,一个模型类一般对应数据库中的一张表。
  • 字段django.db.models.Field的子类,为模型类的类成员,对应数据库表中的字段(列)。

根据数据表的字段为模型类中的字段选择正确的字段类型,以MySQL为例,常见字段与django类型的对应关系为:

MySQLDjango
INTIntegerField
CHARCharField
FLOAT、DOUBLEFloatField
DECIMALDecimalField
DATEDateField
DATETIMEDateTimeField
TIMETimeField
BLOBBinaryField
TEXTTextField

假设有以下结构的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()
“`

修改

修改已有的字段需要以下步骤:

  1. 通过管理器的get()成员方法获取一行记录。
  2. 再访问成员字段修改为需要的内容。
  3. 执行save()方法保存修改。

以前面的TestTable表为例,修改已有记录:

py
# 修改index为100的记录,将其name字段修改为"TestAlter"
alterItem = TestTable.objects.get(index = 0)
alterItem.name = 'TestAlter'
alterItem.save()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值