2. Django配置信息

2024-04-06_231835

第2章 Django配置信息

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

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

2.1 基本配置信息

一个简单的项目必须具备的基本配置信息有: 项目路径, 密钥配置, 域名访问权限, App列表和中间件.
以MyDjango项目为例, settings.py的基本配置如下:
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',
]
上述代码列出了项目路径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列表, 代码如下:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
]

2.2 资源文件配置

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

2.2.1 资源路由–STATIC_URL

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

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

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

一个项目在开发过程中肯定需要使用CSS和JavaScript文件,
这些静态文件的存放主要由配置文件settings.py设置, Django默认配置信息如下:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
上述配置是设置静态资源的路由地址, 其作用是通过浏览器访问Django的静态资源.
默认情况下, Django只能识别项目应用App的static文件夹里面的静态资源.
当项目启动时, Django会从项目应用App里面查找相关的资源文件, 查找功能主要由App列表INSTALLED_APPS的staticfiles实现.
在index中创建static文件夹并在文件夹中放置图片dog.jpg, 如图2-1所示.

2024-04-05_205043

2024-04-05_210059

2024-04-05_205312

2-1 创建static文件夹
Django在调试模式(DEBUG=True)下只能识别项目应用App的static文件夹里面的静态资源, 
如果该文件夹改为其他名字, Django就无法识别, 若将static文件夹放在MyDjango的项目目录下, 
则Django也是无法识别的, 如图2-2所示.

2024-04-05_205726

2024-04-05_210241

2024-04-05_210410

2-2 static的路径设置
为了进一步验证Django在调试模式(DEBUG=True)下只能识别项目应用App的static文件夹.
我们在index文件夹里创建Mystatic文件夹并放置图片cow.jpg, 
在MyDjango的根目录下创建static文件夹并放置图片duck.jpg.
最终, 整个MyDjango的静态资源文件夹有: static(在index文件夹),
Mystatic(在index文件夹)和static(在MyDjango的根目录), 如图2-3所示.

2024-04-05_210847

2-3 静态资源文件夹
启动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所示.

2024-04-05_211521

2-4 访问静态资源
从上述例子说明, 若资源路由STATIC_URL的值为/static/, 则浏览器访问静态资源的网站必须为static, 
否则无法访问, 并且Django在调试模式(DEBUG=True)下只能识别App目录下的static文件夹.

2.2.2 资源集合–STATICFILES_DIRS

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

该属性以列表的形式表示, 设置方式如下:
# 资源集合
STATICFILES_DIRS = [
    # 设置根目录的静态资源文件夹static
    BASE_DIR / 'static',
    # 设置App (index)的静态资源文件夹Mystatic
    BASE_DIR / 'index/Mystatic',
]

2024-04-05_213032

再次启动MyDjango并在浏览器上分别访问图片dog.jpg, duck.jpg和cow.jpg, 可以发现三者都能正常访问, 如图2-5所示.

2024-04-05_212704

2-5 访问静态资源
浏览器访问图片的时候, 图片路径皆为http://127.0.0.1:8000/static/xxx.jpg, 
图片路径的static是指资源路径STATIC_URL的值, 若将STATIC_URL的值改为Allstatic,
则再次重启MyDjango项目并在浏览器上将图片资源路径的static改为Allstatic即可, 如图2-6所示.
STATIC_URL = '/Allstatic/'
访问: 
* 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 .

2024-04-05_220246

2024-04-05_220527

2-6 修改图片路由地址

2.2.3 资源部署–STATIC_ROOT

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

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

2.2.4 媒体资源–MEDIA

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

媒体资源和静态资源是可以同时存在的, 而且两者可以独立运行, 互不影响, 而媒体资源只有配置属性MEDIA_URL和MEDIA_ROOT.
以MyDjango为例, 在MyDjango的根目录下创建media文件夹并存放图片monkey.jpg, 如图2-7所示.

2024-04-05_222057

2-7 创建media文件夹
然后在配置文件settings.py里设置配置属性MEDIA_URL和MEDIA_ROOT,
MEDIA_URL用于设置媒体资源的路由地址, MEDIA_ROOT用于获取media文件夹在计算机系统的完整路径信息, 如下所示:
# 设置媒体路由地址信息
MEDIA_URL = '/media/'
# 获取media文件夹的完整路径信息
MEDIA_ROOT = BASE_DIR / 'media'
配置属性设置后, 还需要将media文件夹注册到Django里, 让Django知道如何找到媒体文件, 否则无法在浏览器上访问该文件夹的文件信息.
打开MyDjango文件夹的urls.py文件, 为媒体文件夹media添加相应的路由地址, 代码如下:

2024-04-05_222939

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'),
]

2024-04-05_224837

最后再次启动MyDjango, 并在浏览器上访问:
* 1. http://127.0.0.1:8000/media/monkey.jpg ,
* 2. http://127.0.0.1:8000/allstatic/dog.jpg ,
发现两者皆可正常访问, 如图2-8所示.

2024-04-05_231024

2-8 访问媒体文件

2.3 模板配置

在Web开发中, 模板是一种较为特殊的HTML文档. 
这个HTML文档嵌入了一些能够让Django识别的变量和指令, 
然后由Django的模板引擎解析这些变量和指令, 生成完整的HTML网页并返回给用户浏览.
模板是Django里面的MTV框架模式的T部分, 配置模板路径是告诉Django在解析模板时, 如何找到模板所在的位置.
创建项目时, Django已有初始的模板配置信息, 如下所示:
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',
            ],
        },
    },
]

2024-04-05_231901

模板配置是以列表格式呈现的, 每个元素具有不同的含义, 其含义说明如下:
 BACKEND: 定义模板引擎, 用于识别模板里面的变量和指令.
  内置的模板引擎有Django Templates和jinja2.Jinja2, 每个模板引擎都有自己的变量和指令语法.
 DIRS: 设置模板所在路径, 告诉Django在哪个地方查找模板的位置, 默认为空列表.
 APP_DIRS: 是否在App里查找模板文件.
 OPTIONS: 用于填充在RequestContext的上下文(模板里面的变量和指令), 一般情况下不做任何修改.
模板配置通常配置DIRS的属性值即可, 在项目的根目录和index下分别创建templates文件夹,
并在文件夹下分别创建文件index.html和app_index.html, 如图2-9所示.

2024-04-05_232520

2-9 设置模板文件夹
一般情况下, 根目录的templates通常存放共用的模板文件, 能为各个App的模板文件调用, 这个模式符合代码重复使用原则.
根据图2-9的文件夹设置, 配置属性TEMPLATES的配置信息如下:
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',
            ],
        },
    },
]

2024-04-05_233140

2.4 数据库配置

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

2.4.1 mysqlclient连接MySQL

数据库配置是选择项目所使用的数据库的类型, 不同的数据库需要设置不同的数据库引擎, 
数据库引擎用于实现项目与数据库的连接, 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': BASE_DIR / 'db.sqlite3',
    }
}

image-20240405234251893

如果把上述的连接信息改为MySQL数据库, 首先安装MySQL连接模块, 由于mysqldb不支持Python 3,
因此Django 2.0以上版本不再使用mysqldb作为MySQL的连接模块, 而选择mysqlclient模块, 但两者之间在使用上并没有太大的差异.
在配置MySQL之前, 需要安装mysqlclient模块.
这里以pip安装方法为例, 打开命令提示符窗口并输入安装指令: pip install mysqlclient, 等待模板安装完成即可.
# 使用这个:
pip install mysqlclient==1.4.6 -i https://pypi.tuna.tsinghua.edu.cn/simple mysqlclient 

image-20240405235526741

如果使用pip在线安装mysqlclient的过程中出现错误, 就可以选择whl文件安装.
在浏览器访问www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient并下载与Python版本相匹配的mysqlclient文件.
我们将mysqlclient文件下载保存在D盘, 然后打开命令提示符窗口, 使用pip完成whl文件安装, 如下所示:
pip install D:\mysqlclient-1.4.6cp37-cp37m-win_amd64.whl
完成mysqlclient模块的安装后, 在项目的配置文件settings.py中配置MySQL数据库连接信息, 代码如下:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'root',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}

image-20240406000339008

为了验证数据库连接信息是否正确, 我们使用数据库可视化工具Navicat Premium打开本地的MySQL数据库.
在本地的MySQL数据库创建数据库django_db, 如图2-10所示.

image-20240406002300647

2-10 数据库django_db
刚创建的数据库django_db是一个空白的数据库,
接着在PyCharm的Terminal界面下输入Django操作指令python manage.py migrate来创建Django内置功能的数据表.
因为Django自带内置功能, 如Admin后台系统, Auth用户系统和会话机制等功能, 这些功能都需要借助数据表实现,
所以该操作指令可以将内置的迁移文件生成数据表, 如图2-11所示.

image-20240406204538321

2-11 创建数据表
最后在数据库可视化工具Navicat Premium里查看数据库django_db是否生成相应的数据表, 如图2-12所示.

image-20240406204119272

image-20240406192716176

2-12 查看数据表
使用mysqlclient连接MySQL数据库时, Django对mysqlclient版本有使用要求,
打开Django的源码查看mysqlclient的版本要求, 如图2-13所示.

2024-04-06_194239

2-13 mysqlclient版本要求
一般情况下, 使用pip安装mysqlclient模块就能符合Django的使用要求.
如果在开发过程中发现Django提示mysqlclient过低, 那么可以对Django的源码进行修改, 将图2-13的if条件判断注释即可.

2.4.2 pymysql连接MySQL

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

2.4.3 多个数据库的连接方式

在一个项目里可能需要使用多个数据库才能满足开发需求, 特别对于数据量过大的系统,
单个数据库存储的数据越多就会使服务器负载越大, 因此会将数据划分成多个数据库服务器共同存储,
若Django想利用这些数据开发功能系统, 则需要对各个数据库服务器进行连接.
从Django单个数据库连接信息看到, 配置属性DATABASES的属性值是以字典的格式表示的, 字典里的每一对键值代表连接某一个数据库.
因此, 我们在配置属性DATABASES里设置多对键值对即可实现多个数据库连接, 实现代码如下:
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',
    }
}

image-20240406195929504

上述代码共连接了三个数据库,分别是django_db, mydjango_db和sqlite3.
django_db和mydjango_db均属于MySQL数据库系统, sqlite3属于Sqlite3数据库系统.
配置属性DATABASES设有3个键值对: default, MyDjango和MySqlite3, 每个键值对代表Django连接了某个数据库.

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

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

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

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

我们在MyDjango的目录下创建配置文件my.cnf, 然后在配置文件my.cnf写入MySQL数据库的连接信息, 代码如下所示:
# my.cnf
[client]
database=django_db
user=root
password=123456
host=127.0.0.1
port=3306

image-20240406200631715

配置文件my.cnf中必须设置[client], [client]在配置信息中代表分组的意思, 它是将一个或多个配置信息划分到某一个分组里面.
[client]里面, 每个配置信息分别代表MySQL的数据库名称, 用户名, 密码, IP地址和端口信息.
下一步在Django的配置文件settings.py中编写DATABASES的配置信息, 其代码如下:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {'read_default_file': str(BASE_DIR / 'my.cnf')}
    },
}

2024-04-06_203549

从DATABASES的配置信息看到, 我们只需在default->OPTIONS->read_default_file设置配置文件my.cnf的地址路径即可,
Django会自动读取配置文件my.cnf的数据库连接信息, 从而实现数据库连接.

为了验证能否使用配置文件my.cnf实现数据库连接, 在MyDjango2的urls.py中设置路由indexView,
路由的视图函数indexView()在项目应用index的view.py中定义, 代码如下:
# 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')
]
在项目应用index的view.py中定义路由index的视图函数indexView(), 代码如下:
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')
视图函数indexView()读取并输出Django内置模型ContentType的数据, 并从模板文件夹templates的index.html作为当前请求的响应内容.
启动MyDjango之前, 需要使用Django内置指令创建数据表, 打开PyChram的Terminal窗口, 
确保窗口的当前路径是MyDjango目录, 然后输入python manage.py migrate指令, Django会自动创建内置数据表, 如图2-14所示.
# 提示: 直接执行会提示没有任何待应用的迁移文件,
# 因为这个库中已经执行过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.

# 需要先将所有表格删除后, 才能执行成功.

2-14 创建数据表
数据表创建成功后, 我们启动MyDjango, 然后在浏览器访问: http://127.0.0.1:8000/ ,
在PyChram的Run窗口下看到当前的请求信息以及视图函数indexView()输出模型ContentType的数据信息, 如图2-15所示.

2024-04-06_205134

2-15 输出信息
注意: Django使用配置文件my.cnf连接数据库, 必须确保项目的绝对路径不能出现中文,
否则Django无法连接数据库并提示OperationalError异常信息, 如图2-16所示.
* 1. 在d盘下新建文件夹'使用配件文件动态连接数据库'.
* 2. 复制一份Django项目到改文件下.
* 3. 打开项目并运行.

image-20240406205919295

2024-04-06_210047

2-16 异常信息

2.4.5 通过远程连接MySQL

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

为了清楚理解SSH连接数据库的实现过程, 我们使用数据库可视化工具Navicat Premium演示如何通过SSH连接数据库.
首先打开Navicat Premium连接MySQL的界面, 然后单击'SSH'选项, 在SSH连接界面输入服务器的连接信息, 如图2-17所示.

image-20240406211118249

image-20240406211521395

2-17 SSH连接信息
然后切换到'常规'界面, 输入服务器里面MySQL的连接信息, 如图2-18所示.
最后单击'确定'按钮即可完成整个连接过程.

image-20240406212041307

2-18 MySQL连接信息
既然数据库只允许SSH方式连接, 我们只能通过这种方式实现数据库连接,
首先使用pip指令下载sshtunnel模块, 该模块能通过SSH方式连接到目标服务器, 生成服务器的SSH连接对象
然后在Django的配置文件settings.py的DATABASES中设置数据库连接, 实现过程如下:
# 数据库服务器的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(),
    }
上述代码中, 我们分别设定了两组不同的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 中间件

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

当用户在网站中进行某个操作时, 这个过程是用户向网站发送HTTP请求(Request);
而网站会根据用户的操作返回相关的网页内容, 这个过程称为响应处理(Response).
从请求到响应的过程中, 当Django接收到用户请求时, 首先经过中间件处理请求信息, 执行相关的处理, 然后将处理结果返回给用户.
中间件的执行流程如图2-19所示.

2024-04-06_220942

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

2.6 本章小结

项目配置是根据实际开发需求对整个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, 但配置信息有固定的写法, 如下所示:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'USER': 'root',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '3306'
    }
}
中间件由属性MIDDLEWARE完成配置, 属性MIDDLEWARE的数据格式为列表类型,
每个中间件的设置顺序是固定的, 如果随意变更中间件, 就很容易导致程序异常.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/521473.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

xss.pwnfunction-Jefff

在eval中可以直接执行命令所以直接把"直接闭合在结尾再加上一个"因为后面的"没闭和会报错 ?jeffa";alert(1);" 或 ?jeffa"-alert(1)-" -是分隔符

根据状态转移表实现时序电路

描述 某同步时序电路转换表如下&#xff0c;请使用D触发器和必要的逻辑门实现此同步时序电路&#xff0c;用Verilog语言描述。 电路的接口如下图所示。 输入描述 input A ,input clk ,input rst_n 输出描述 output …

Windows11下Docker使用记录(二)

Docker使用记录&#xff08;二&#xff09; 1. 常用指令2. Dockerfile示例3. 构建docker image Docker中container&#xff0c;image&#xff0c;dockerfile 以及docker hub的关系如图所示&#xff0c;详细可见上一篇帖子。 本文主要记录Dockerfile相关。 1. 常用指令 常用指令…

matlab:五点中心差分求解Navier边界的Biharmonic方程(具有纳维尔边界的双调和方程)

我们考虑如下形式的双调和方程的数值解 其中&#xff0c;Ω是欧氏空间中的多边形或多面体域&#xff0c;在其中&#xff0c;d为维度&#xff0c;具有分段利普希茨边界&#xff0c;满足内部锥条件&#xff0c;f(x) ∈ L2(Ω)是给定的函数&#xff0c;∆是标准的拉普拉斯算子。算…

Open3D (C++) 从.txt文件中读取数据到矩阵

目录 一、算法概述二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法概述 在进行实验的时候有时需要借助不同的工具来实现一些比较复杂的操作,比如使用matlab中自带的拉…

竞赛 交通目标检测-行人车辆检测流量计数 - 竞赛

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

AI大语言模型GPT —— R 生态环境领域数据统计分析

自2022年GPT&#xff08;Generative Pre-trained Transformer&#xff09;大语言模型的发布以来&#xff0c;它以其卓越的自然语言处理能力和广泛的应用潜力&#xff0c;在学术界和工业界掀起了一场革命。在短短一年多的时间里&#xff0c;GPT已经在多个领域展现出其独特的价值…

卫星遥感影像如何选择合适的分辨率

​ 卫星遥感影像的分辨率是影响其应用效果的关键因素之一。分辨率越高&#xff0c;所获取的图像细节越丰富&#xff0c;能够更准确地反映地物的特征和变化。因此&#xff0c;在选择卫星遥感影像时&#xff0c;需要根据实际需求和数据可获取性来选择合适的分辨率。 一、分辨…

好看流光风格个人主页HTML源码

这是一款好看流光风格个人主页HTML源码&#xff0c;感觉挺喜欢的&#xff0c;需要的自行下载&#xff01; 源码下载 好看流光风格个人主页源码

90天玩转Python-02-基础知识篇:初识Python与PyCharm

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

2-3多交换机静态流表控制原理与实现

实现目标环境下的静态流表设置&#xff1a; 1 单个ovs上实现多个主机hosts之间的通信 2多ovs上多主机之间的通信 1 单个ovs上实现多个主机hosts之间的通信 使用函数定义的方式创建一个如下的拓扑&#xff0c;并使用静态流表 from mininet.net import Mininet from mininet.n…

智过网:非安全专业能否报考注安?哪些专业可以报考?

近年来&#xff0c;随着社会对安全生产管理的日益重视&#xff0c;注册安全工程师&#xff08;简称注安&#xff09;这一职业逐渐受到广大从业人员的青睐。然而&#xff0c;对于许多非安全专业的朋友来说&#xff0c;他们可能会困惑&#xff1a;非安全专业是否可以报考注安&…

【51单片机入门记录】RTC(实时时钟)-DS1302概述

目录 一、基于三线通信的RTC-DS1302 &#xff08;1&#xff09;简介 &#xff08;2&#xff09;特性 &#xff08;3&#xff09;引脚介绍 &#xff08;4&#xff09;控制字的格式 &#xff08;5.0&#xff09;日历时钟寄存器介绍 &#xff08;5.1&#xff09;日历时钟寄存…

配置vscode链接linux

1.安装 remote SSH 2.按F1 ssh ljh服务器公网ip 3. 选择保存远端host到本地 某位置 等待片刻后 4. 切换到远程资源管理器中 应该可以看到一台电脑&#xff0c;右键在当前窗口链接&#xff0c;输入你的服务器用户密码后电脑变绿说明远程连接成功 5.一定要登陆上云服务器后再…

“进击的巨人”:服务器硬件基础知识解析

引言&#xff1a; 服务器是网络环境中负责处理数据、运行应用程序和服务多用户的高性能计算机系统。了解服务器的硬件构成有助于更好地管理和优化IT资源。 服务器和普通PC的差异&#xff1a; 服务器具有比个人电脑更高的处理能力、稳定性和可靠性&#xff0c;它们通常运行在没…

Flutter开发进阶之错误信息

Flutter开发进阶之错误信息 在Flutter开发中错误信息通常是由Exception和Error表示&#xff0c;Error表示严重且不可恢复的错误&#xff0c;一般会导致程序直接终止&#xff0c;而Exception可以被显式抛出&#xff0c;一般为代码逻辑错误&#xff0c;根据Flutter的解释说Excep…

Vue3调试

如何对vue3项目进行调试 调试是开发过程中必备的一项技能&#xff0c;掌握了这项技能&#xff0c;可以很好的定义bug所在。一般在开发vue3项目时&#xff0c;有三种方式。 代码中添加debugger;使用浏览器调试&#xff1a;sourcemap需启用vs code 调试&#xff1a;先开启node服…

ARM、X86、RISC-V三分天下

引入&#xff1a; 简单的介绍一下X86、ARM、RISC-V三种cpu架构的区别和应用场景。 目录 简单概念讲解 1. X86架构 2. ARM架构 3. RISC-V架构 应用场景 X86、ARM和RISC-V是三种不同的CPU架构&#xff0c;它们在设计理念、指令集和应用场景上有一些区别。 简单概念讲解 1. X…

【Frida】【Android】 工具篇:ProxyPin抓包详解

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

如何在nuxt中优雅使用swiper,实现过渡反向+贴合无缝+循环播放【核心代码分析】

视频效果 20240402-1723 图片效果 技术栈 Nuxt3 + Swiper11 Nuxt3 Nuxt: The Intuitive Vue Framework Nuxt Swiper11 Swiper - The Most Modern Mobile Touch Slider (swiperjs.com) 当然你也可以是使用nuxt-swiper Nuxt-Swiper GitHub - cpreston321/nuxt-swiper: Swi…