Django 模型简介
在前面几章,我们介绍了Django建造网站的基本途径:URLcong和建立视图。正如我们所阐述的,视图负责处理一些主观逻辑,然后返回相应结果。
在当代web应用中,主观逻辑经常牵涉到与数据库的交互。数据库驱动网站在后台连接数据库服务器,从中取出一些数据,然后在Web页面用漂亮的格式展示这些数据。这个网站也可能会想访问者提供修改数据库数据的方法。
由于先天具备Python简单而强大的数据库查询执行方法,Django非常适合开发数据库驱动网站。
在视图中进行数据库查询
在视图中可以从数据中直接获取数据:用现有额任何Python类库执行一条SQL查询并对结果进行一些处理。
示例:
#view.py
from django.shortcuts import render_to_response
import MySQLdb
def book_list(request):
db = MySQLdb.connect(user='me', db='mydb', passwd='secret', host='localhost')
cursor = db.cursor()
cursor.execute('SELECT name FROM books ORDER BY name')
names = [row[0] for row in cursor.fetchall()]
db.close()
return render_to_response('book_list.html', {'names': names})
这个方法可用,但很快一些问题将出现在你面前:
- 我们将数据库连接参数硬行编码于代码之中。 理想情况下,这些参数应当保存在 Django 配置中。
- 我们不得不重复同样的代码: 创建数据库连接、创建数据库游标、执行某个语句、然后关闭数据库。 理想情况下,我们所需要应该只是指定所需的结果。
- 它把我们栓死在 MySQL 之上。 如果过段时间,我们要从 MySQL 换到 PostgreSQL,就不得不使用不同的数据库适配器(例如 psycopg 而不是 MySQLdb ),改变连接参数,根据 SQL 语句的类型可能还要修改SQL 。 理想情况下,应对所使用的数据库服务器进行抽象,这样一来只在一处修改即可变换数据库服务器。 (如果你正在建立一个开源的Django应用程序来尽可能让更多人使用的话,这个特性是非常适当的。)
为了解决上述问题,Django中直接提供了ORM框架,帮助开发者进行数据库开发。
ORM
ORM简介
- MVC框架中有一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
ORM是“对象-关系-映射”的简称,主要任务是:
- 根据对象的类型生成数据库表结构
- 将对象、列表的操作,转换为sql语句
- 将sql查询到的结果转换为对象、列表
为什么使用ORM
Django和其他大多数现代Web框架一样,依赖一个强大的DAO(data access object),视图将底层的关系数据库和Python的面向对象特质联系起来。
使用ORM有4个充分的理由:
封装有用的方法
Django模型对象是定义变量的首选方式,而变量通常对应的是数据库的列。
你可以请求一个 id 为 5 的Author对象并检查其 author.name
, 而不必去写SELECT name from authors WHERE id=5
这样的SQL语句, 这样要 Pythonic
的多。
而且,模型对象能给那个简陋的例子增加许多额外的价值,Django的ORM可以让你定义任何实例方法:
- 定义只读的变量或者属性集合,也称为 数据集合
data aggregation
或者计算属性calculated attribute
. - Django的ORM允许重写内置的数据库修改方法,例如保存和删除对象.
- 和编程语言集成(python)通常比较简单,可以让你的数据库对象和特定的接口或API更加一致
可移植性
ORM作为应用程序和数据库之间的代码层,通常具有很好的可移植性.
安全性
使用ORM之后很少有机会需要自己执行SQL查询,所以不必担心保护性很差的查询字符串导致的问题,如SQL注入攻击等
而且ORM还提供一个智能化的引用和转义输入变量的核心机制,让你不在花很多时间来处理这种细枝末节
表现力
跟直接编写SQL相比,ORM最大的好处就是从数据库中获取记录时使用的查询语法。高级一点的语法不仅更容易编写,而且这种带入到Python领域的查询机制更带来了一系列有用的技巧和方法。比如,直接循环一个数据结构,原本在SQL中是相当笨拙的,现在却简洁的多,还可以回避本来是无可避免的讨厌的字符串操作。
Django model
介绍
Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表。
简单示例
还是用我们建立的项目进行说明。
配置
在这之前我们已经用django-admin.py startproject myproject
创建了一个项目,并用python manage.py startapp myapp
创建了一个新的应用。myapp
也加入到了项目配置文件settings.py
里的INSTALLED_APPS
列表里。
这里假设配置文件里数据库相关配置已完成(数据库配置详见下一章)。
构建model
打开myapp/models.py
文件,构建我们自己的数据模型
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
这个例子定义了Person
,并给它赋予了first_name
和last_name
.其中first_name
和last_nam
e 是model
的字段。如你所见,每一个字段被定义为class类的一个属性,而每个属性对应着数据库的一列。
上面创建的Person
,model模型的过程用SQL语句翻译过来就是:
CREATE TABLE myapp_person(
"id" serial NOT NULL PRIMARY KEY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
这里只是个简单的示例,会在后文中对model进行详细的介绍
应用到数据库
上面的代码只是在我们的项目中定义了model,但它并没有在我们的数据库中生成myapp_person
这样一张表。那么,怎么应用到数据库中呢?
在命令行中运行:
python manage.py makemigrations myapp # 让 Django 知道我们在我们的模型有一些变更, 不加myapp默认生成全部模型变更文件
python manage.py migrate myapp # 创建表结构, 不加myapp默认创建项目全部表
总结
经过上面的基本步骤,我们简单的一个Person
ORM
就已经建立好了,后面通过Person
模型的增删查改就可以直接反映到数据库表中对myapp_person
表的增删查改