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的数据格式为列表类型,
每个中间件的设置顺序是固定的, 如果随意变更中间件, 就很容易导致程序异常.
相关推荐
ImomoTo35 分钟前
HarmonyOS学习(十三)——数据管理(二) 关系型数据库
数据库·学习·harmonyos·arkts·鸿蒙
机器视觉知识推荐、就业指导3 小时前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
毕设木哥3 小时前
25届计算机专业毕设选题推荐-基于python的二手电子设备交易平台【源码+文档+讲解】
开发语言·python·计算机·django·毕业设计·课程设计·毕设
jnrjian3 小时前
export rman 备份会占用buff/cache 导致内存压力
数据库·oracle
isNotNullX4 小时前
一文解读OLAP的工具和应用软件
大数据·数据库·etl
IT毕设梦工厂5 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
小诸葛的博客6 小时前
pg入门1——使用容器启动一个pg
数据库
大熊程序猿6 小时前
python 读取excel数据存储到mysql
数据库·python·mysql
落落落sss6 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle