正如第四章详细介绍的那个在视图中输出 HTML 的笨方法(通过在视图里对文本直接硬编码 HTML),在视图中也有笨方法可以从数据库中获取数据。很简单:用现有的任何 Python 类库执行一条 SQL 查询并对结果进行一些处理。
在本例的视图中,我们使用了 pymysql
类库(可以使用 pip install pymysql 安装上该模块)来连接
MySQL 数据库,取回一些记录,将它们提供给模板以显示一个网页:
from django.shortcuts import render_to_response import pymysql 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})
在上面的代码中你有两点需要注意:
try: import pymysql pymysql.install_as_MySQLdb() except: pass
在上面代码中,我们将数据库连接参数硬行编码于代码之中,将会出现一些令你撸码不愉快的问题。
psycopg
而不是
pymysql
),改变连接参数,根据 SQL 语句的类型可能还要修改
SQL。理想情况下,应对所使用的数据库服务器进行抽象,这样一来只在一处修改即可变换数据库服务器。(如果你正在建立一个开源的
Django 应用程序来尽可能让更多人使用的话,这个特性是非常适当的。)理想情况下,这些参数应当保存在配置中。正如你所期待的,Django 数据库层正是致力于解决这些问题,Django 把这些参数保存在 settings.py 文件配置中(下面会介绍),而在视图函数中,只需要关心业务逻辑。以下提前揭示了如何使用 Django 数据库 API 重写之前那个视图。
from django.shortcuts import render_to_response from mysite.books.models import Book def book_list(request): books = Book.objects.order_by('name') return render_to_response('book_list.html', {'books': books})
我们将在本章稍后的地方解释这段代码。目前而言,仅需对它有个大致的认识。
我们在前面章节提到过,Django 的设计鼓励松耦合及对应用程序中不同部分的严格分割。遵循这个理念的话,要想修改应用的某部分而不影响其它部分就比较容易了。 在视图函数中,我们已经讨论了通过模板系统把业务逻辑和表现逻辑分隔开的重要性。 在数据库层中,我们对数据访问逻辑也应用了同样的理念。
把数据存取逻辑、业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的 Model-View-Controller (MVC)模式。 在这个模式中, Model 代表数据存取层,View 代表的是系统中选择显示什么和怎么显示的部分,Controller 指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分。
为什么用缩写?
像 MVC 这样的明确定义模式的主要用于改善开发人员之间的沟通。 比起告诉同事,“让我们采用抽象的数据存取方式,然后单独划分一层来显示数据,并且在中间加上一个控制它的层”,一个通用的说法会让你收益,你只需要说:“我们在这里使用 MVC 模式吧。”。
Django 紧紧地遵循这种 MVC 模式,可以称得上是一种 MVC 框架。 以下是 Django 中 M、V 和 C 各自的含义:
M ,数据存取部分,由django数据库层处理,本章要讲述的内容。
V ,选择显示哪些数据要显示以及怎样显示的部分,由视图和模板处理。
C ,根据用户输入委派视图的部分,由 Django 框架根据 URLconf 设置,对给定 URL 调用适当的 Python 函数。
由于 C 由框架自行处理,而 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),Django 也被称为 MTV 框架。在 MTV 开发模式中:
M 代表模型(Model),即数据存取层。该层处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。
T 代表模板(Template),即表现层。该层处理与表现相关的决定:如何在页面或其他类型文档中进行显示。
V 代表视图(View),即业务逻辑层。该层包含存取模型及调取恰当模板的相关逻辑。你可以把它看作模型与模板之间的桥梁。
如果你熟悉其它的 MVC Web开发框架,比方说 Ruby on Rails,你可能会认为 Django 视图是控制器,而 Django 模板是视图。很不幸,这是对 MVC 不同诠释所引起的错误认识。在 Django 对 MVC 的诠释中,视图用来描述要展现给用户的数据;不是数据 如何展现 ,而且展 哪些 数据。相比之下,Ruby on Rails 及一些同类框架提倡控制器负责决定向用户展现哪些数据,而视图则仅决定 如何 展现数据,而不是展现 哪些 数据。
两种诠释中没有哪个更加正确一些。重要的是要理解底层概念。
为了遵循软件工程设计规则之后,让我们来开始 Django 数据库层的探索。首先,我们需要做些初始配置;我们需要告诉 Django 使用什么数据库以及如何连接数据库。
我们在本机上已经完成了数据库服务器的安装和激活,并且已经在其中创建了数据库(例如,用 CREATE DATABASE 语句)。如果你使用 SQLite,不需要这步安装,因为 SQLite 使用文件系统上的独立文件来存储数据,我们使用比较流行的企业级数据库服务器 Mysql。
像前面提到的 TEMPLATE_DIRS 一样,数据库配置也是在 Django 的配置文件里,缺省是 settings.py。打开这个文件并查找数据库配置,如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
在实际项目中,我们需要在 DATABASES 这个字典中详细配置我们要连接的数据库,我的一个配置例子如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'feng_blog', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '', 'PORT': '', } }
其中 'ENGINE': 'django.db.backends.mysql'
的意思是我们使用的数据库管理系统是 mysql。
其中 'NAME': 'feng_blog'
的意思是我们连接的数据库的名字是 feng_blog。
其中 'USER': 'root'
的意思是我们连接 mysql 使用的数据库账户名是 root(项目开发中我们不建议使用 root 账户)。
其中 'PASSWORD': '123456'
的意思是我们使用连接数据库账户 root 的密码是 123456。
其中 'HOST': ''
为空代表是数据库管理系统在本机上(127.0.0.1),如果在其它机器上,则需要填写其它机器的 IP 地址。
其中 'PORT': ''
为空代表连接的数据库管理系统的端口是 3306(mysql 数据库管理系统默认的端口)。