项目配置是根据实际开发需求从而对整个 Web 框架编写相关配置信息。配置信息主要由项目的 settings.py
实现,主要配置有项目路径、密钥配置、域名访问权限、App 列表、配置静态资源、配置模板文件、数据库配置、中间件和缓存配置。
下述内容都是在名为
test01
的 Django 项目中演示,Django 项目的创建可参见上节。
基本配置信息
一个简单的项目必须具备的基本配置信息有: 项目路径、密钥配置、域名访问权限、App 列表和中间件。以 MyDjango 项目为例, settings.py
的基本配置如下:
import os
# 项目路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 密钥配置
SECRET_KEY = '1g(dn2(er(c$k1=6df%(0tb5_ir!1upwq_k6pek+zvlgnb7v&w'
# 调试模式
DEBUG = True
# 域名访问权限
ALLOWED_HOSTS = []
# App 列表
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
上述各个配置的说明如下:
BASE_DIR
:项目路径,主要通过 os 模块读取当前项目在系统的具体路径,该代码在创建项目时自动生成,一般情况下无需修改。SECRET_KEY
:密钥配置,是一个随机值,在项目创建的时候自动生成,一般情况下无需修改。主要用于重要数据的加密处理,提高系统的安全性,避免遭到攻击者的恶意破坏。密钥主要用于用户密码、CSRF 机制和会话 Session 等数据加密。
- 用户密码:Django 内置了一套用户管理系统,该系统具有用户认证和存储用户信息等功能,在创建用户的时候,将用户密码通过密钥进行加密处理,保证用户的安全性。
- CSRF 机制:该机制主要用于表单提交,防止窃取网站的用户信息来制造恶意请求。
- 会话 Session:Session 的信息存放在 Cookies,以一串随机的字符串表示,用于标识当前访问网站的用户身份,记录相关用户信息。
DEBUG
:调试模式,该值为布尔类型。如果在开发调试阶段应设置为True
,在开发调试过程中会自动检测代码是否发生更改,根据检测结果执行是否刷新重启系统。如果项目部署上线,应将其改为False
,否则会泄露系统的相关信息。ALLOWED_HOSTS
:域名访问权限,设置可访问的域名,默认值为空。当DEBUG
为True
并且ALLOWED_HOSTS
为空时,项目只允许以localhost
或127.0.0.1
在浏览器上访问。当DEBUG
为False
时,ALLOWED_HOSTS
为必填项,否则程序无法启动,如果想允许所有域名访问,可设置ALLOWED_HOSTS=['*']
。INSTALLED_APPS
:App 列表,告诉 Django 当前项目中有哪些 App。在项目创建时已有上述列出的admin
、auth
等信息,这些都是 Django 内置的应用功能。
admin
:内置的后台管理系统。auth
:内置的用户认证系统。contenttypes
:记录项目中所有 model 元数据(Django 的 ORM 框架)。sessions
:Session 会话功能,用于标识当前访问网站的用户身份,记录相关用户信息。messages
:消息提示功能。staticfiles
:查找静态资源路径。
如果在项目中创建了 App,必须在 App 列表的 INSTALLED_APPS
添加 App 名称。比如新建一个名为 index
的 App 并将其添加到 App 列表,操作如下。
首先在 Terminal 进入 Django 项目根目录,执行下面命令创建新的 App:
$ python3 manage.py startapp index
在 INSTALLED_APPS
中添加上新建的 App 名称:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
]
静态资源
一个 Web 项目在开发过程中肯定需要使用 CSS 和 Javascript 文件,这些静态文件的存放主要由 settings.py
设置,默认的配置信息如下:
STATIC_URL = '/static/'
上述配置将静态资源存放在文件夹 static
,而文件夹 static
只能放在 App
里面,当项目启动时,Django 会根据静态资源存放路径去查找相关的资源文件,查找功能主要由 App 列表 INSTALLED_APPS
的 staticfiles
实现。在 index
中添加文件夹 static
,并在文件夹放置图片,如下图所示:
启动项目,访问 http://127.0.0.1:8000/static/zze.jpg,会发现该图片可以被正常访问:
$ curl -I http://127.0.0.1:8000/static/zze.jpg
HTTP/1.1 200 OK
Date: Sat, 29 Aug 2020 08:58:32 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Content-Type: image/jpeg
Last-Modified: Sat, 29 Aug 2020 08:50:57 GMT
Content-Length: 20454
如果将 static
文件夹放置在 test01
文件夹下,再次访问则会返回 404
状态码:
$ curl -I http://127.0.0.1:8000/static/zze.jpg
HTTP/1.1 404 Not Found
Date: Sat, 29 Aug 2020 09:01:52 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Content-Type: text/html
如果想要在 test01
的根目录下存放静态资源,可以在配置文件 settings.py
中设置 STATICFILES_DIRS
属性。该属性以列表的形式展示,设置方式如下:
# 设置根目录的静态资源文件夹 public_static
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'public_static'),
# 设置 index App 的静态资源文件夹
os.path.join(BASE_DIR, 'index/static')]
此时上述设置的两个文件夹中就都可以存放静态资源了,下面在上述的两个文件夹中都放上图片如下:
启动项目程序后,可通过如下 URL 分别访问到 zze.jpg
和 index_zze.jpg
:
$ curl -I http://127.0.0.1:8000/static/zze.jpg
HTTP/1.1 200 OK
Date: Sat, 29 Aug 2020 09:11:24 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Content-Type: image/jpeg
Last-Modified: Sat, 29 Aug 2020 08:50:57 GMT
Content-Length: 20454
$ curl -I http://127.0.0.1:8000/static/index_zze.jpg
HTTP/1.1 200 OK
Date: Sat, 29 Aug 2020 09:11:28 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Content-Type: image/jpeg
Last-Modified: Sat, 29 Aug 2020 08:50:57 GMT
Content-Length: 20454
从上面的例子可以看到,配置属性 STATIC_URL
和 STATICFILES_DIRS
存在明显的区别:
STATIC_URL
是必须配置的属性而且属性值不能为空。如果没有配置STATICFILES_DIRS
,则STATIC_URL
只能识别 App 里的static
静态资源文件夹。STATICFILES_DIRS
是可选配置属性,属性值为列表或元组格式,每个列表(元组)元素代表一个静态资源文件夹,这些文件夹可自行命名。- 在浏览器上访问项目的静态资源时,无论项目的静态资源文件夹是如何命名的,访问静态资源的 URL 的上级目录必须为
STATIC_URL
属性值。
除此之外,静态资源配置还有 STATIC_ROOT
,其作用是方便在服务器上部署项目,实现服务器和项目之间的映射。STATIC_ROOT
主要收集整个项目的静态资源并存放到一个新的文件夹,然后由该文件夹与服务器之间构建映射关系。STATIC_ROOT
配置如下:
STATIC_ROOT = '/Users/zhangzhongen/Desktop'
STATIC_ROOT
用于项目生产部署,在项目开发过程中的作用不大。
模板路径
在 Web 开发中,模板是一种较为特殊的 HTML 文档。这个 HTML 文档嵌入了一些能够让 Python 识别的变量和指令,然后程序解析这些变量和指令,生成完整的 HTML 网页并返回给用户浏览。模板是 Django 里面的 MTV 框架模式的 T 部分,配置模板路径是告诉 Django 在解析模板时,如何找到模板所在的位置。创建项目时,Django 有初始的模板配置信息,如下:
TEMPLATES = [
{
# 也可以是 Jinjia2: django.template.backends.jinja2.Jinja2
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
模板配置是以列表格式呈现的,每个元素具有不同的含义,其含义说明如下。
BACKEND
:定义模板引擎,用于识别模板里面的变量和指令。内置的模板引擎有Django Templates
和jinja2.Jinja2
,每个模板引擎都有自己的变量和指令语法。DIRS
:设置模板所在路径,告诉 Django 在哪个地方查找模板的位置,默认为空列表。APP_DIRS
:是否在 App 里查找模板文件。OPTIONS
:用于填充在RequestContext
中上下文的调用函数,一般情况下不做任何修改。
模板配置通常配置 DIRS
的模板路径即可。在项目的根目录和 index
下分别创建 templates
文件夹,并在文件夹下分别创建文件 index.html
和 app_ index.html
,如下:
根目录的 templates
通常存放共用的模板文件,能够供各个 App 的调用,该模式符合代码重复使用的原则,如 HTML 的 <head>
部分。index
的 templates
是存放当前 App 所需要使用的模板文件。修改模板配置代码如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'index/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
关于模板的配置暂且说到这里,后面再详述模板的使用。
数据库配置
数据库配置是选择项目所使用的数据库的类型,不同的数据库需要设置不同的数据库引擎,数据库引擎用于实现项目与数据库的连接,Django 提供 4 种数据库引擎:
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.sqlite3
django.db.backends.oracle
项目创建时默认使用 Sqlite3 数据库,这是一款轻型的数据库,常用于嵌入式系统开发,而且占用的资源非常少。默认的 Sqlite3 数据库配置信息如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
如果把上述的连接信息改为 MySQL 数据库,首先需要安装 MySQL 连接模块,由于 mysqldb
不支持 Python 3,因此 Django 2.0 不再使用 mysqldb
作为 MySQL 的连接模块,而选择了 mysqlclient
模块,两者之间在使用上并没有太大的差异。
在配置 MySQL 之前,首先安装 mysqlclient
模块,这里以 pip
安装方法为例,打开 Terminal 窗口并输入安装指令 pip install mysqlclient
,等待模板安装完成。然后检测
mysqlclient
的版本信息,如果 mysqlclient
版本信息过低,就不符合 Django 的使用要求。
$ pip list | grep mysqlclient
mysqlclient 2.0.1
完成 mysqlclient 模块的安装后,我们就要准备测试用的 MySQL 实例了,我这里直接使用 Docker 启一个 MySQL 容器:
$ docker run --restart=always -p 3306:3306 --name mysql_new -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7.30
在项目的配置文件 settings.py
中配置 MySQL 数据库连接信息,代码如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_db',
'USER': 'root',
'PASSWORD': '123',
'HOST': '127.0.0.1',
'PORT': '3306'
}
}
上述连接方式用于连接 MySQL 里面一个名为 django_db
的数据库,这个数据库必须事先创建好,可执行如下 SQL 创建该数据库:
mysql> create database django_db default character set utf8;
上述配置只是连接了一个 django_db
数据库。在日常的开发中,有时候需要连接多个数据库,实现方法如下:
DATABASES = {
# 第一个数据库
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_db',
'USER': 'root',
'PASSWORD': '123',
'HOST': '127.0.0.1',
'PORT': '3306'
},
# 第二个数据库
'test01': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test01',
'USER': 'root',
'PASSWORD': '123',
'HOST': '127.0.0.1',
'PORT': '3306'
},
# 还可有第 n 个数据库 ...
}
从属性 DATABASES
的数据类型可以发现是一个 Python 的数据字典,也就是说如果需要连接多个数据库,只要在属性 DATABASES
中设置不同的键值对即可实现。
值得注意的是,这里我是以 MySQL 的 5.7 版本为例进行介绍的。如果你使用的是 5.7 以上的版本,在 Django 连接 MySQL 数据库时会提示 django.db.utils.OperationalError
的错误信息,这是因为 MySQL 8.0 版本的密码加密方式发生了改变,8.0 版本的用户密码采用的是 cha2 加密方法。
为了解决这个问题,我们通过 SQL 语句将 8.0 版本的加密方法改回原来的加密方式,这样可以解决 Django 连接 MySQL 数据库的错误问题。在 MySQL 中运行以下 SQL 语句:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123';
FLUSH PRIVILEGES;
中间件
中间件(Middleware)是处理 Django 的 request 和 response 对象的钩子。当用户在网站中进行单击某个按钮等操作时,这个动作是用户向网站发送请求(request);
而网页会根据用户的操作返回相关的网页内容,这个过程称为响应处理(response)。从请求到响应的过程中,当 Django 接收到用户请求时,Django 首先经过中间件处理请求信息,执行相关的处理,然后将处理结果返回给用户,中间件执行流程如下图所示:
从图中能清晰地看到,中间件的作用主要是处理用户请求信息。开发者也可以根据自己的开发需求自定义中间件,只要将自定义的中间件添加到配置属性 MIDDLEWARE
中即可激活。一般情况下,Django 默认的中间件配置均可满足大部分的开发需求。在项目的 MIDDLEWARE
中添加 LocaleMiddleware
中间件,使得 Django 内置的功能支持中文显示,代码如下:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# 使用中文
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
配置属性 MIDDLEWARE
的数据格式为列表类型,每个中间件的设置顺序是固定的,如果随意变更中间件很容易导致程序异常。每个中间件的说明如下:
SecurityMiddleware
: 内置的安全机制,保护用户与网站的通信安全。SessionMiddleware
:会话Session功能。LocaleMiddleware
:支持中文语言。CommonMiddleware
:处理请求信息,规范化请求内容。CsrfViewMiddleware
:开启CSRF防护功能。AuthenticationMiddleware
:开启内置的用户认证系统。MessageMiddleware
:开启内置的信息提示功能。XFrameOptionsMiddleware
:防止恶意程序点击劫持。
评论区