2. Django配置信息

第2章 Django配置信息

handlebars 复制代码
Django的配置文件settings.py用于配置整个网站的环境和功能, 
核心配置必须有项目路径, 密钥配置, 域名访问权限, App列表, 中间件, 资源文件, 模板配置, 数据库的连接方式.

* 项目运行时, 如果修改代码, 项目会自动检测发现改动后会重新运行, 除非报错否则无序手动重启项目.

2.1 基本配置信息

handlebars 复制代码
一个简单的项目必须具备的基本配置信息有: 项目路径, 密钥配置, 域名访问权限, App列表和中间件.
以MyDjango项目为例, settings.py的基本配置如下:
python 复制代码
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# 密钥配置
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '@p_m^!ha=$6m$9#m%gobzo&b0^g2obt4teod84xs6=f%$4a66x'
# SECURITY WARNING: don't run with debug turned on in production!

# 调试模式
DEBUG = True

# 域名访问权限
ALLOWED_HOSTS = []

# App列表
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
handlebars 复制代码
上述代码列出了项目路径BASE_DIR, 密钥配置SECRET_KEY, 调试模式DEBUG, 
域名访问权限ALLOWED_HOSTS和App列表INSTALLED_APPS, 各个配置说明如下:

* 1. 项目路径BASE_DIR: 
     主要通过os模块(从Python 3.4开始, 是pathlib模块)读取当前项目在计算机系统的具体路径,
     该代码在创建项目时自动生成, 一般情况下无须修改.

* 2. 密钥配置SECRET_KEY: 这是一个随机值, 在项目创建的时候自动生成, 一般情况下无须修改.
      主要用于重要数据的加密处理, 提高项目的安全性, 避免遭到攻击者恶意破坏.
      密钥主要用于用户密码, CSRF机制和会话Session等数据加密.
      ● 用户密码: Django内置一套Auth认证系统, 该系统具有用户认证和存储用户信息等功能,
        在创建用户的时候, 将用户密码通过密钥进行加密处理, 保证用户的安全性.
      ● CSRF机制: 该机制主要用于表单提交, 防止窃取网站的用户信息来制造恶意请求.
      ● 会话Session: Session的信息存放在Cookie中, 以一串随机的字符串表示, 
      用于标识当前访问网站的用户身份, 记录相关用户信息.

* 3. 调试模式DEBUG: 该值为布尔类型. 
      如果在开发调试阶段, 那么应设置为True,
      在开发调试过程中会自动检测代码是否发生更改, 根据检测结果执行是否刷新重启系统.
      如果项目部署上线, 那么应将其改为False, 否则会泄漏项目的相关信息.

* 4. 域名访问权限ALLOWED_HOSTS: 设置可访问的域名, 默认值为空列表.
     当DEBUG为True并且ALLOWED_HOSTS为空列表时, 项目只允许以localhost或127.0.0.1在浏览器上访问.
     当DEBUG为False时, ALLOWED_HOSTS为必填项, 否则程序无法启动, 如果想允许所有域名访问, 可设置ALLOW_HOSTS = ['*'].

* 5. App列表INSTALLED_APPS: 告诉Django有哪些App.
     在项目创建时已有admin, auth和sessions等配置信息, 这些都是Django内置的应用功能, 各个功能说明如下:
     ● admin: 内置的后台管理系统.
     ● auth: 内置的用户认证系统.
     ● contenttypes: 记录项目中所有model元数据(Django的ORM框架).
     ● sessions: Session会话功能, 用于标识当前访问网站的用户身份, 记录相关用户信息.
     ● messages: 消息提示功能.
     ● staticfiles: 查找静态资源路径.
     如果在项目中创建了App, 就必须在App列表INSTALLED_APPS添加App名称.
     将MyDjango项目已创建的App添加到App列表, 代码如下:
python 复制代码
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
]

2.2 资源文件配置

handlebars 复制代码
资源文件配置分为静态资源和媒体资源.
静态资源的配置方式由配置属性STATIC_URL, STATICFILES_DIRS和STATIC_ROOT进行设置;
媒体资源的配置方式由配置属性MEDIA_URL和MEDIA_ROOT决定.

2.2.1 资源路由--STATIC_URL

handlebars 复制代码
静态资源指的是网站中不会改变的文件.
在一般的应用程序中, 静态资源包括CSS文件, JavaScript文件以及图片等资源文件. 
此处简单介绍CSS和JavaScript文件.

CSS也称层叠样式表(Cascading Style Sheets), 
是一种用来表现HTML(标准通用标记语言的一个应用)或XML)标准通用标记语言的一个子集)等文件样式的计算机语言.
CSS不仅可以静态地修饰网页, 还可以配合各种脚本语言动态地对网页各元素进行格式化.

JavaScript是一种直译式脚本语言, 也是一种动态类型, 弱类型, 基于原型的语言, 内置支持类型.
它的解释器被称为JavaScript引擎, 为浏览器的一部分, 广泛用于客户端的脚本语言,
最早是在HTML(标准通用标记语言下的一个应用)网页上使用的, 用来给HTML网页增加动态功能.

一个项目在开发过程中肯定需要使用CSS和JavaScript文件,
这些静态文件的存放主要由配置文件settings.py设置, Django默认配置信息如下:
python 复制代码
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
handlebars 复制代码
上述配置是设置静态资源的路由地址, 其作用是通过浏览器访问Django的静态资源.
默认情况下, Django只能识别项目应用App的static文件夹里面的静态资源.
当项目启动时, Django会从项目应用App里面查找相关的资源文件, 查找功能主要由App列表INSTALLED_APPS的staticfiles实现.
在index中创建static文件夹并在文件夹中放置图片dog.jpg, 如图2-1所示.
handlebars 复制代码
图2-1 创建static文件夹
handlebars 复制代码
Django在调试模式(DEBUG=True)下只能识别项目应用App的static文件夹里面的静态资源, 
如果该文件夹改为其他名字, Django就无法识别, 若将static文件夹放在MyDjango的项目目录下, 
则Django也是无法识别的, 如图2-2所示.
handlebars 复制代码
图2-2 static的路径设置
handlebars 复制代码
为了进一步验证Django在调试模式(DEBUG=True)下只能识别项目应用App的static文件夹.
我们在index文件夹里创建Mystatic文件夹并放置图片cow.jpg, 
在MyDjango的根目录下创建static文件夹并放置图片duck.jpg.
最终, 整个MyDjango的静态资源文件夹有: static(在index文件夹),
Mystatic(在index文件夹)和static(在MyDjango的根目录), 如图2-3所示.
handlebars 复制代码
图2-3 静态资源文件夹
handlebars 复制代码
启动MyDjango并在浏览器上分别访问:
* 1: http://127.0.0.1:8000/static/dog.jpg ,
* 2: http://127.0.0.1:8000/static/duck.jpg ,
* 3. http://127.0.0.1:8000/static/cow.jpg ,
可以发现只有dog.jpg能正常访问, 而duck.jpg和cow.jpg无法访问, 如图2-4所示.
handlebars 复制代码
图2-4 访问静态资源
handlebars 复制代码
从上述例子说明, 若资源路由STATIC_URL的值为/static/, 则浏览器访问静态资源的网站必须为static, 
否则无法访问, 并且Django在调试模式(DEBUG=True)下只能识别App目录下的static文件夹.

2.2.2 资源集合--STATICFILES_DIRS

handlebars 复制代码
由于STATIC_URL的特殊性, 在开发中会造成诸多不便, 比如将静态文件夹存放在项目的根目录以及定义多个静态文件夹等.
以MyDjango为例, 若想在网页上正常访问图片duck.jpg和cow.jpg,
可以将根目录的static文件夹和index的Mystatic文件夹写入资源集合STATICFILES_DIRS.
在配置文件settings.py中设置STATICFILES_DIRS属性.

该属性以列表的形式表示, 设置方式如下:
python 复制代码
# 资源集合
STATICFILES_DIRS = [
    # 设置根目录的静态资源文件夹static
    BASE_DIR / 'static',
    # 设置App (index)的静态资源文件夹Mystatic
    BASE_DIR / 'index/Mystatic',
]
handlebars 复制代码
再次启动MyDjango并在浏览器上分别访问图片dog.jpg, duck.jpg和cow.jpg, 可以发现三者都能正常访问, 如图2-5所示.
handlebars 复制代码
图2-5 访问静态资源
handlebars 复制代码
浏览器访问图片的时候, 图片路径皆为http://127.0.0.1:8000/static/xxx.jpg, 
图片路径的static是指资源路径STATIC_URL的值, 若将STATIC_URL的值改为Allstatic,
则再次重启MyDjango项目并在浏览器上将图片资源路径的static改为Allstatic即可, 如图2-6所示.
python 复制代码
STATIC_URL = '/Allstatic/'
handlebars 复制代码
访问: 
* 1: http://127.0.0.1:8000/Allstatic/dog.jpg ,
* 2: http://127.0.0.1:8000/Allstatic/duck.jpg ,
* 3. http://127.0.0.1:8000/Allstatic/cow.jpg .
handlebars 复制代码
图2-6 修改图片路由地址

2.2.3 资源部署--STATIC_ROOT

handlebars 复制代码
静态资源配置还有STATIC_ROOT, 其作用是在服务器上部署项目, 实现服务器和项目之间的映射.
STATIC_ROOT主要收集整个项目的静态资源并存放在一个新的文件夹, 然后由该文件夹与服务器之间构建映射关系.
STATIC_ROOT配置如下:
python 复制代码
STATIC_ROOT = BASE_DIR / 'AllStatic'
handlebars 复制代码
当项目的配置属性DEBUG设为True的时候, Django会自动提供静态文件代理服务, 此时整个项目处于开发阶段, 因此无须使用STATIC_ROOT.
当配置属性DEBUG设为False的时候, 意味着项目进入生产环境, Django不再提供静态文件代理服务, 
此时需要在项目的配置文件中设置STATIC_ROOT.

设置STATIC_ROOT需要使用Django操作指令collectstatic来收集所有静态资源,
这些静态资源都会保存在STATIC_ROOT所设置的文件夹里.
关于STATIC_ROOT的使用会在后续的章节详细讲述.

2.2.4 媒体资源--MEDIA

handlebars 复制代码
一般情况下, STATIC_URL是设置静态文件的路由地址, 如CSS样式文件, JavaScript文件以及常用图片等.
对于一些经常变动的资源, 通常将其存放在媒体资源文件夹, 如用户头像, 歌曲文件等.

媒体资源和静态资源是可以同时存在的, 而且两者可以独立运行, 互不影响, 而媒体资源只有配置属性MEDIA_URL和MEDIA_ROOT.
以MyDjango为例, 在MyDjango的根目录下创建media文件夹并存放图片monkey.jpg, 如图2-7所示.
handlebars 复制代码
图2-7 创建media文件夹
handlebars 复制代码
然后在配置文件settings.py里设置配置属性MEDIA_URL和MEDIA_ROOT,
MEDIA_URL用于设置媒体资源的路由地址, MEDIA_ROOT用于获取media文件夹在计算机系统的完整路径信息, 如下所示:
python 复制代码
# 设置媒体路由地址信息
MEDIA_URL = '/media/'
# 获取media文件夹的完整路径信息
MEDIA_ROOT = BASE_DIR / 'media'
handlebars 复制代码
配置属性设置后, 还需要将media文件夹注册到Django里, 让Django知道如何找到媒体文件, 否则无法在浏览器上访问该文件夹的文件信息.
打开MyDjango文件夹的urls.py文件, 为媒体文件夹media添加相应的路由地址, 代码如下:
python 复制代码
from django.contrib import admin
from django.urls import path, re_path
# 导入项目应用index
from index.views import index
# 配置媒体文件夹media
from django.views.static import serve
from django.conf import settings


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index),
    # 配置媒体文件的路由地址
    re_path('media/(?P<path>.*)', serve,
            {'document_root': settings.MEDIA_ROOT}, name='media'),
]
handlebars 复制代码
最后再次启动MyDjango, 并在浏览器上访问:
* 1. http://127.0.0.1:8000/media/monkey.jpg ,
* 2. http://127.0.0.1:8000/allstatic/dog.jpg ,
发现两者皆可正常访问, 如图2-8所示.
handlebars 复制代码
图2-8 访问媒体文件

2.3 模板配置

handlebars 复制代码
在Web开发中, 模板是一种较为特殊的HTML文档. 
这个HTML文档嵌入了一些能够让Django识别的变量和指令, 
然后由Django的模板引擎解析这些变量和指令, 生成完整的HTML网页并返回给用户浏览.
模板是Django里面的MTV框架模式的T部分, 配置模板路径是告诉Django在解析模板时, 如何找到模板所在的位置.
创建项目时, Django已有初始的模板配置信息, 如下所示:
python 复制代码
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / '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',
            ],
        },
    },
]
handlebars 复制代码
模板配置是以列表格式呈现的, 每个元素具有不同的含义, 其含义说明如下:
● BACKEND: 定义模板引擎, 用于识别模板里面的变量和指令.
  内置的模板引擎有Django Templates和jinja2.Jinja2, 每个模板引擎都有自己的变量和指令语法.
● DIRS: 设置模板所在路径, 告诉Django在哪个地方查找模板的位置, 默认为空列表.
● APP_DIRS: 是否在App里查找模板文件.
● OPTIONS: 用于填充在RequestContext的上下文(模板里面的变量和指令), 一般情况下不做任何修改.
模板配置通常配置DIRS的属性值即可, 在项目的根目录和index下分别创建templates文件夹,
并在文件夹下分别创建文件index.html和app_index.html, 如图2-9所示.
handlebars 复制代码
图2-9 设置模板文件夹
handlebars 复制代码
一般情况下, 根目录的templates通常存放共用的模板文件, 能为各个App的模板文件调用, 这个模式符合代码重复使用原则.
根据图2-9的文件夹设置, 配置属性TEMPLATES的配置信息如下:
python 复制代码
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 注册根目录和 index 的 templates 文件夹
        'DIRS': [BASE_DIR / 'templates',
                 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',
            ],
        },
    },
]

2.4 数据库配置

handlebars 复制代码
本节讲述如何使用mysqlclient和pymysql模块实现Django与MySQL数据库通信连接, 并且简单介绍单个项目实现多个数据库连接方式.

2.4.1 mysqlclient连接MySQL

handlebars 复制代码
数据库配置是选择项目所使用的数据库的类型, 不同的数据库需要设置不同的数据库引擎, 
数据库引擎用于实现项目与数据库的连接, Django提供4种数据库引擎:
● 'django.db.backends.postgresql'
● 'django.db.backends.mysql'
● 'django.db.backends.sqlite3'
● 'django.db.backends.oracle'
handlebars 复制代码
项目创建时默认使用Sqlite3数据库, 这是一款轻型的数据库, 常用于嵌入式系统开发, 而且占用的资源非常少.
Sqlite3数据库配置信息如下:
python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
handlebars 复制代码
如果把上述的连接信息改为MySQL数据库, 首先安装MySQL连接模块, 由于mysqldb不支持Python 3,
因此Django 2.0以上版本不再使用mysqldb作为MySQL的连接模块, 而选择mysqlclient模块, 但两者之间在使用上并没有太大的差异.
在配置MySQL之前, 需要安装mysqlclient模块.
这里以pip安装方法为例, 打开命令提示符窗口并输入安装指令: pip install mysqlclient, 等待模板安装完成即可.
python 复制代码
# 使用这个:
pip install mysqlclient==1.4.6 -i https://pypi.tuna.tsinghua.edu.cn/simple mysqlclient 
handlebars 复制代码
如果使用pip在线安装mysqlclient的过程中出现错误, 就可以选择whl文件安装.
在浏览器访问www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient并下载与Python版本相匹配的mysqlclient文件.
我们将mysqlclient文件下载保存在D盘, 然后打开命令提示符窗口, 使用pip完成whl文件安装, 如下所示:
python 复制代码
pip install D:\mysqlclient-1.4.6cp37-cp37m-win_amd64.whl
handlebars 复制代码
完成mysqlclient模块的安装后, 在项目的配置文件settings.py中配置MySQL数据库连接信息, 代码如下:
python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'root',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
handlebars 复制代码
为了验证数据库连接信息是否正确, 我们使用数据库可视化工具Navicat Premium打开本地的MySQL数据库.
在本地的MySQL数据库创建数据库django_db, 如图2-10所示.
handlebars 复制代码
图2-10 数据库django_db
handlebars 复制代码
刚创建的数据库django_db是一个空白的数据库,
接着在PyCharm的Terminal界面下输入Django操作指令python manage.py migrate来创建Django内置功能的数据表.
因为Django自带内置功能, 如Admin后台系统, Auth用户系统和会话机制等功能, 这些功能都需要借助数据表实现,
所以该操作指令可以将内置的迁移文件生成数据表, 如图2-11所示.
handlebars 复制代码
图2-11 创建数据表
handlebars 复制代码
最后在数据库可视化工具Navicat Premium里查看数据库django_db是否生成相应的数据表, 如图2-12所示.
handlebars 复制代码
图2-12 查看数据表
handlebars 复制代码
使用mysqlclient连接MySQL数据库时, Django对mysqlclient版本有使用要求,
打开Django的源码查看mysqlclient的版本要求, 如图2-13所示.
handlebars 复制代码
图2-13 mysqlclient版本要求
handlebars 复制代码
一般情况下, 使用pip安装mysqlclient模块就能符合Django的使用要求.
如果在开发过程中发现Django提示mysqlclient过低, 那么可以对Django的源码进行修改, 将图2-13的if条件判断注释即可.

2.4.2 pymysql连接MySQL

handlebars 复制代码
除了使用mysqlclient模块连接MySQL之外, 还可以使用pymysql模块连接MySQL数据库.
pymysql模块的安装使用pip在线安装即可, 在命令提示符窗口下输入pip install pymysql指令并等待安装完成即可.
pymysql模块安装成功后, 项目配置文件settings.py的数据库配置信息无须修改,
只要在MyDjango文件夹的__init__.py中设置数据库连接模块即可, 代码如下:
python 复制代码
# MyDjango文件夹的__init__.py
import pymysql
pymysql.install_as_MySQLdb()
handlebars 复制代码
若要验证pymysql模块连接MySQL数据库的功能, 建议读者先将mysqlclient模块先行卸载, 
这样能排除干扰因素, 而验证方式与mysqlclient模块连接MySQL的验证方式一致.
记得在验证之前, 务必将数据库django_db的数据表删除, 具体的验证过程不再重复讲述.
handlebars 复制代码
值得注意的是, 如果读者使用的MySQL是8.0以上版本, 
在Django连接MySQL数据库时会提示django.db.utils.OperationalError的错误信息,
这是因为MySQL 8.0版本的密码加密方式发生了改变, 8.0版本的用户密码采用的是CHA2加密方式.
为了解决这个问题, 我们通过SQL语句将8.0版本的加密方式改回原来的加密方式,
这样可以解决Django连接MySQL数据库的错误问题.
在MySQL的可视化工具中运行以下SQL语句:
python 复制代码
# newpassword是已设置的用户密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpassword';
FLUSH PRIVILEGES;
handlebars 复制代码
Django除了支持PostgreSQL, SQLite3, MySQL和Oracle之外, 还支持SQL Server和MongoDB的连接.
由于不同的数据库有不同的连接方式, 因此此处不过多介绍, 本书主要以MySQL连接为例,
若需了解其他数据库的连接方式, 则可自行搜索相关资料.

2.4.3 多个数据库的连接方式

handlebars 复制代码
在一个项目里可能需要使用多个数据库才能满足开发需求, 特别对于数据量过大的系统,
单个数据库存储的数据越多就会使服务器负载越大, 因此会将数据划分成多个数据库服务器共同存储,
若Django想利用这些数据开发功能系统, 则需要对各个数据库服务器进行连接.
从Django单个数据库连接信息看到, 配置属性DATABASES的属性值是以字典的格式表示的, 字典里的每一对键值代表连接某一个数据库.
因此, 我们在配置属性DATABASES里设置多对键值对即可实现多个数据库连接, 实现代码如下:
python 复制代码
DATABASES = {
    # 第一个数据库
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    # 第二个数据库
    'MyDjango': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydjango_db',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    # 第三个数据库
    'MySqlite3': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'sqlite3',
    }
}
handlebars 复制代码
上述代码共连接了三个数据库,分别是django_db, mydjango_db和sqlite3.
django_db和mydjango_db均属于MySQL数据库系统, sqlite3属于Sqlite3数据库系统.
配置属性DATABASES设有3个键值对: default, MyDjango和MySqlite3, 每个键值对代表Django连接了某个数据库.

若项目中连接了多个数据库, 则数据库之间的使用需要遵从一定的规则和设置.
比如项目中定义了多个模型, 每个模型所对应的数据表可以选择在某个数据库中生成, 
如果模型没有指向某个数据库, 模型就会在key为default的数据库里生成.

2.4.4 使用配置文件动态连接数据库

handlebars 复制代码
在大多数情况下, 我们都是在settings.py中配置数据库的连接方式, 
但每次修改settings.py的配置属性都要重新启动Django, 否则修改内容就无法生效.

当项目运行上线之后, 为了保证在系统不中断的情况下切换到另一个数据库, 
可以将数据库的连接方式写到配置文件中, 这样无须修改settings.py的配置属性即可达成顺利切换数据的目的.

我们在MyDjango的目录下创建配置文件my.cnf, 然后在配置文件my.cnf写入MySQL数据库的连接信息, 代码如下所示:
sql 复制代码
# my.cnf
[client]
database=django_db
user=root
password=123456
host=127.0.0.1
port=3306
handlebars 复制代码
配置文件my.cnf中必须设置[client], [client]在配置信息中代表分组的意思, 它是将一个或多个配置信息划分到某一个分组里面.
在[client]里面, 每个配置信息分别代表MySQL的数据库名称, 用户名, 密码, IP地址和端口信息.
下一步在Django的配置文件settings.py中编写DATABASES的配置信息, 其代码如下:
python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {'read_default_file': str(BASE_DIR / 'my.cnf')}
    },
}
handlebars 复制代码
从DATABASES的配置信息看到, 我们只需在default->OPTIONS->read_default_file设置配置文件my.cnf的地址路径即可,
Django会自动读取配置文件my.cnf的数据库连接信息, 从而实现数据库连接.

为了验证能否使用配置文件my.cnf实现数据库连接, 在MyDjango2的urls.py中设置路由indexView,
路由的视图函数indexView()在项目应用index的view.py中定义, 代码如下:
python 复制代码
# MyDjango2的urls.py
from django.contrib import admin
from django.urls import path
# 导入项目应用index
from index.views import indexView
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', indexView, name='index')
]
handlebars 复制代码
在项目应用index的view.py中定义路由index的视图函数indexView(), 代码如下:
python 复制代码
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType


def indexView(request):
    c = ContentType.objects.values_list().all()
    print(c)
    return render(request, 'index.html')
handlebars 复制代码
视图函数indexView()读取并输出Django内置模型ContentType的数据, 并从模板文件夹templates的index.html作为当前请求的响应内容.
启动MyDjango之前, 需要使用Django内置指令创建数据表, 打开PyChram的Terminal窗口, 
确保窗口的当前路径是MyDjango目录, 然后输入python manage.py migrate指令, Django会自动创建内置数据表, 如图2-14所示.
handlebars 复制代码
# 提示: 直接执行会提示没有任何待应用的迁移文件,
# 因为这个库中已经执行过python manage.py migrate生成过表格, 且没有任何改动.
PS D:\MyDjango2> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  No migrations to apply.

# 需要先将所有表格删除后, 才能执行成功.
handlebars 复制代码
图2-14 创建数据表
handlebars 复制代码
数据表创建成功后, 我们启动MyDjango, 然后在浏览器访问: http://127.0.0.1:8000/ ,
在PyChram的Run窗口下看到当前的请求信息以及视图函数indexView()输出模型ContentType的数据信息, 如图2-15所示.
handlebars 复制代码
图2-15 输出信息
handlebars 复制代码
注意: Django使用配置文件my.cnf连接数据库, 必须确保项目的绝对路径不能出现中文,
否则Django无法连接数据库并提示OperationalError异常信息, 如图2-16所示.
handlebars 复制代码
* 1. 在d盘下新建文件夹'使用配件文件动态连接数据库'.
* 2. 复制一份Django项目到改文件下.
* 3. 打开项目并运行.
handlebars 复制代码
图2-16 异常信息

2.4.5 通过远程连接MySQL

handlebars 复制代码
在企业开发中, 数据库和Web系统很可能部署在不同的服务器, 当Web系统连接数据库的时候, 
如果数据库所在的服务器禁止了外网直连, 只允许通过SSH方式连接服务器, 再从已连接服务器的基础上连接数据库, 
遇到这一种情况, 如何在Django中实现数据库连接呢?

为了清楚理解SSH连接数据库的实现过程, 我们使用数据库可视化工具Navicat Premium演示如何通过SSH连接数据库.
首先打开Navicat Premium连接MySQL的界面, 然后单击'SSH'选项, 在SSH连接界面输入服务器的连接信息, 如图2-17所示.
handlebars 复制代码
图2-17 SSH连接信息
handlebars 复制代码
然后切换到'常规'界面, 输入服务器里面MySQL的连接信息, 如图2-18所示.
最后单击'确定'按钮即可完成整个连接过程.
handlebars 复制代码
图2-18 MySQL连接信息
handlebars 复制代码
既然数据库只允许SSH方式连接, 我们只能通过这种方式实现数据库连接,
首先使用pip指令下载sshtunnel模块, 该模块能通过SSH方式连接到目标服务器, 生成服务器的SSH连接对象
然后在Django的配置文件settings.py的DATABASES中设置数据库连接, 实现过程如下:
python 复制代码
# 数据库服务器的ip地址或主机名
ssh_host = "XXX.XXX.XXX.XXX"
# 数据库服务器的SSH连接端口号, 一般都是22, 必须是数字
ssh_port = 22
# 数据库服务器的用户名
ssh_user = "root"
# 数据库服务器的用户密码
ssh_password = "123456"

# 数据库服务器的mysql的主机名或ip地址
mysql_host = "localhost"
# 数据库服务器的mysql的端口, 默认为3306, 必须是数字
mysql_port = 3306
# 数据库服务器的mysql的用户名
mysql_user = "root"
# 数据库服务器的mysql的密码
mysql_password = "123456"
# 数据库服务器的mysql的数据库名
mysql_db = "mydjango"

from sshtunnel import open_tunnel
def get_ssh():
    server = open_tunnel(
        (ssh_host, ssh_port),
        ssh_username=ssh_user,
        ssh_password=ssh_password,
        # 绑定服务器的MySQL数据库
        remote_bind_address=(mysql_host, mysql_port))
    # ssh通道服务启动
    server.start()
    return str(server.local_bind_port)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': mysql_db,
        'USER': mysql_user,
        'PASSWORD': mysql_password,
        'HOST': mysql_host,
        'PORT': get_ssh(),
    }
handlebars 复制代码
上述代码中, 我们分别设定了两组不同的IP地址, 用户名和密码等信息, 每组配置信息说明如下:
(1) 带有ssh_开头的配置信息是实现SSH连接目标服务器, 主要在sshtunnel模块中使用.
(2) 带有mysql_开头的配置信息是在目标服务器基础上连接MySQL数据库, 在配置属性DATABASES和sshtunnel模块中均被使用.

从整个配置过程可以看出, Django使用SSH连接服务器的MySQL过程如下:
(1) 分别定义服务器的SSH连接信息和数据库的连接信息.
(2) 定义服务器的SSH连接函数get_ssh(), 使用sshtunnel模块的open_tunnel函数实现, 并设置相应的函数参数,
    其中参数remote_bind_address是绑定服务器的MySQL数据库.
(3)在配置属性DATABASES的PORT调用get_ssh(), Django自动根据DATABASES的PORT连接到服务器的MySQL数据库.

2.5 中间件

handlebars 复制代码
中间件(Middleware)是一个用来处理Django的请求(Request)和响应(Response)的框架级别的钩子,
它是一个轻量, 低级别的插件系统, 用于在全局范围内改变Django的输入和输出.

当用户在网站中进行某个操作时, 这个过程是用户向网站发送HTTP请求(Request);
而网站会根据用户的操作返回相关的网页内容, 这个过程称为响应处理(Response).
从请求到响应的过程中, 当Django接收到用户请求时, 首先经过中间件处理请求信息, 执行相关的处理, 然后将处理结果返回给用户.
中间件的执行流程如图2-19所示.
handlebars 复制代码
图2-19 中间件的执行流程
handlebars 复制代码
从图2-19中能清晰地看到, 中间件的作用是处理用户请求信息和返回响应内容.
开发者可以根据自己的开发需求自定义中间件, 只要将自定义的中间件添加到配置属性MIDDLEWARE中即可激活.
一般情况下, Django默认的中间件配置均可满足大部分的开发需求.
我们在项目的MIDDLEWARE中添加LocaleMiddleware中间件, 使得Django内置的功能支持中文显示, 代码如下:
python 复制代码
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    # 添加中间件LocaleMiddleware
    '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',
]
handlebars 复制代码
配置属性MIDDLEWARE的数据格式为列表类型, 每个中间件的设置顺序是固定的, 如果随意变更中间件, 就很容易导致程序异常.
每个中间件的说明如下:
● SecurityMiddleware: 内置的安全机制, 保护用户与网站的通信安全.
● SessionMiddleware: 会话Session功能.
● LocaleMiddleware: 国际化和本地化功能.
● CommonMiddleware: 处理请求信息, 规范化请求内容.
● CsrfViewMiddleware: 开启CSRF防护功能.
● AuthenticationMiddleware: 开启内置的用户认证系统.
● MessageMiddleware: 开启内置的信息提示功能.
● XFrameOptionsMiddleware: 防止恶意程序单击劫持.

2.6 本章小结

handlebars 复制代码
项目配置是根据实际开发需求对整个Web框架编写相关配置信息.
配置信息主要由项目的settings.py实现, 主要配置有项目路径, 密钥配置, 
域名访问权限, App列表, 配置静态资源, 配置模板文件, 数据库配置, 中间件和缓存配置.

当DEBUG为True并且ALLOWED_HOSTS为空时, 项目只允许以localhost或127.0.0.1在浏览器上访问.
当DEBUG为False时, ALLOWED_HOSTS为必填项, 否则程序无法启动, 如果想允许所有域名访问, 那么可设置ALLOW_HOSTS = ['*'].

App列表INSTALLED_APPS的各个功能说明如下:
● admin: 内置的后台管理系统.
● auth: 内置的用户认证系统.
● contenttypes: 记录项目中所有model元数据(Django的ORM框架).
● sessions: Session会话功能, 用于标识当前访问网站的用户身份, 记录相关用户信息.
● messages: 消息提示功能.
● staticfiles: 查找静态资源路径.

资源文件配置分为静态资源和媒体资源. 
静态资源指的是网站中不会改变的文件. 在一般的应用程序中, 静态资源包括CSS文件, JavaScript文件以及图片等资源文件;
媒体资源是指经常变动的资源, 通常将其存放在媒体资源文件夹, 如用户头像, 歌曲文件等.

静态资源的配置属性包括: STATIC_URL, STATICFILES_DIRS和STATIC_ROOT, 三者说明如下:
● STATIC_URL: 设置静态资源的路由地址.
● STATICFILES_DIRS: 将项目里自定义的静态资源文件夹绑定到Django里.
● STATIC_ROOT: 收集整个项目的静态资源并存放在一个新的文件夹, 然后由该文件夹与服务器之间构建映射关系.

媒体资源的配置属性包括: MEDIA_URL和MEDIA_ROOT, 说明如下:
● MEDIA_URL: 设置媒体资源的路由地址.
● MEDIA_ROOT: 获取项目里自定义的媒体资源文件的文件路径.

模板信息是以列表格式呈现的, 每个元素具有不同的含义, 其含义说明如下:
● BACKEND: 定义模板引擎, 用于识别模板里面的变量和指令.
  内置的模板引擎有DjangoTemplates和jinja2.Jinja2, 每个模板引擎都有自己的变量和指令语法.
● DIRS: 设置模板所在的路径, 告诉Django在哪个地方查找模板的位置, 默认为空列表.
● APP_DIRS: 是否在App里查找模板文件.
● OPTIONS: 用于填充在RequestContext的上下文(模板里面的变量和指令), 一般情况下不做任何修改.

Django可以选择不同的模块连接MySQL, 但配置信息有固定的写法, 如下所示:
python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'root',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
handlebars 复制代码
中间件由属性MIDDLEWARE完成配置, 属性MIDDLEWARE的数据格式为列表类型,
每个中间件的设置顺序是固定的, 如果随意变更中间件, 就很容易导致程序异常.
相关推荐
背太阳的牧羊人21 分钟前
Neo4j 的向量搜索(Neo4jVector)和常见的向量数据库(比如 Milvus、Qdrant)之间的区别与联系
数据库·neo4j·milvus
liulun37 分钟前
在浏览器中使用SQLite(官方sqlite3.wasm)
数据库·sqlite·wasm
IT项目管理2 小时前
达梦数据库DMHS介绍及安装部署
linux·数据库
你都会上树?2 小时前
MySQL MVCC 详解
数据库·mysql
大春儿的试验田2 小时前
高并发收藏功能设计:Redis异步同步与定时补偿机制详解
java·数据库·redis·学习·缓存
Ein hübscher Kerl.2 小时前
虚拟机上安装 MariaDB 及依赖包
数据库·mariadb
醇醛酸醚酮酯3 小时前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
GreatSQL社区4 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql
掘根4 小时前
【MySQL进阶】错误日志,二进制日志,mysql系统库
数据库·mysql
weixin_438335404 小时前
基础知识:mysql-connector-j依赖
数据库·mysql