语音测评网站项目总结

整体使用 django,配合 mysql 搭建的数据库、单独运行的测评打分模型,放在同一台服务器上跑。

django 前后端

django 有 app 的概念,一个 app 里不同文件需要配置。主要是 admin, urls, models, views。而项目的文件在 app 之间共享,需要配置的工程文件有 settings, urls。

另外,还有 statics 静态文件,templates 网页模板等。

setting 的配置

我使用了 ssl 来使用 https,否则会因为浏览器安全设置,无法上传音频。

要想使用 https,需要购买 ssl 证书,并和域名绑定,可以跟随阿里云的教程一步一步来。

1
2
3
4
5
6
7
8
9
# SECURITY安全设置 - 支持http时建议开启
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True # 将所有非SSL请求永久重定向到SSL
SESSION_COOKIE_SECURE = True # 仅通过https传输cookie
CSRF_COOKIE_SECURE = True # 仅通过https传输cookie
SECURE_HSTS_INCLUDE_SUBDOMAINS = True # 严格要求使用https协议传输
SECURE_HSTS_PRELOAD = True # HSTS为
SECURE_HSTS_SECONDS = 60
SECURE_CONTENT_TYPE_NOSNIFF = True # 防止浏览器猜测资产的内容类型

我使用了 django 提供的登录管理(因为我懒的一匹不想管那些细节)。

要想使用,需要在 templates 中给出对应模板(我后面会细说)。AUTHENTICATION_BACKENDS 是设置需要使用的验证后端。

AUTH_USER_MODEL 是用于存储学生身份信息的数据库,和models中的类对应。

AUTH_PASSWORD_VALIDATORS 用于验证修改密码的时候,密码的强度,如果太弱了就会被要求重新输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
LOGIN_REDIRECT_URL = '/profile/' # 给出登录成功之后的跳转目标
LOGIN_URL = '' # 如果不设置这个,登录时会跳转到accounts/login/?next=/去,操


AUTHENTICATION_BACKENDS =[
'rest_framework.authentication.TokenAuthentication',
'django.contrib.auth.backends.AllowAllUsersModelBackend',
]

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
'rest_framework_simplejwt.authentication.JWTAuthentication',

],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2

}


AUTH_USER_MODEL = 'project_app.stu_info'

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", },
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", },
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", },
]

DEBUG 模式的开关,DEBUG 模式下,很多地方与正式环境不同,例如最让我头痛的静态文件。DEBUG模式下,程序会自己寻找静态文件自己用,但是正式环境不会。

1
2
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

允许从哪一个host访问。例如,如果域名是 114514.com,那么需要在这里设置 ALLOWED_HOSTS = [‘114514.com’]

1
ALLOWED_HOSTS = [ ]

INSTALLED_APPS 配置已安装的 app,包括你写的,也包括django给出、需要使用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Application definition

INSTALLED_APPS = [
"project_app",
# 'project_app.ProjectNLPAppConfig',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles", # 用于管理静态文件
"django.contrib.sites",
"django.contrib.redirects",
"sslserver",
'rest_framework',
]

如果不设置 SITE_ID,可能会产生 502 错误。

1
SITE_ID = 1

所谓中间件,中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

每个中间件组件负责做一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话将用户与请求关联起来。

他的文档解释了中间件是如何工作的,如何激活中间件,以及如何编写自己的中间件。Django 具有一些内置的中间件,你可以直接使用。它们被记录在 built-in middleware reference 中。

————来自 django 官方文档。

1
2
3
4
5
6
7
8
9
10
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
# "django.middleware.csrf.CsrfResponseMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

字面含义,是否每次请求都更新一次session,设置session使用的引擎。

1
2
3
SESSION_SAVE_EVERY_REQUEST = True

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎,加密

对网页模板的一些配置,会自动生成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 模板
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
os.path.join(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",
"django.template.context_processors.static",
],
# "builtins":["django.templatetags.static"],# 让模板不需要手动添加static
},
},
]

数据库的配置,设置种类帐号密码ip端口。
1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'exam',
'USER': 'root',
'PASSWORD': '123123',
'HOST': '127.0.0.1',
'PORT': 3306
}
}

语言和时区,注意时区很重要,默认并不是使用电脑的时区,而是使用芝加哥时区;这个配置甚至没有在 settings 里默认生成。

1
2
3
4
5
6
7
8
9
LANGUAGE_CODE = "en-us"

# TIME_ZONE = "UTC"
USE_TZ = False
TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True
# 多語言


静态文件相关的一些设置,指引 django 应该去哪里寻找静态文件。

总之就是我到现在还没摸透,能跑就行,捏马的。

1
2
3
4
5
6
7
STATIC_URL = "/static/"  # 不需要拼接前面的路径,这边的事相对路径

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

STATICFILES_FINDERS = ['django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

urls 的设置

urls 其实可以有多个,工程一个,每个app一个。

urls.py 中,重点设置的只有 urlpatterns 这个列表:

1
2
3
4
5
6
urlpatterns = [
path("admin/", admin.site.urls),
path("favicon.ico", RedirectView.as_view(url=staticfiles_storage.url("favicon.ico")),),
url("", include('project_app.urls')),
# path('api-auth/', include('rest_framework.urls'))
]

如上所示,

`path("admin/", admin.site.urls)`:设置管理员后台。

`path("favicon.ico", RedirectView.as_view(url=staticfiles_storage.url("favicon.ico")),)`:设置网站图标。

`url("", include('project_app.urls')),`:将 app 的 urls 拼接到自己后面。

App 中 models 的设置

models 是 django 和数据库的对接,里面的每一个类都对应一张表单。

未完待续

App 中 views 的设置

这是重头戏,前端的呈现和逻辑都在这里完成。

未完待续

statics 和 templates

网页模板,本质是在 html 中插入形如 {{ for i in list }}、{% static "asd/asd/asd" %} 之类的模板语法,通过 django 的 render(渲染)函数,配合传递的参数,生成一个标准 html 页面。

传递的参数是一个字典,组织方式类似于变量和值的一一对应;其中的变量可以是绝大多数 python 支持的变量,但似乎不支持自己定义的类。

未完待续

数据库

由 models 定义绝大多数使用到的表单,包括但不限于成绩存储,学生帐号信息,题库。

表单的定义

未完待续

初始化

未完待续

中途调整

未完待续

在 views.py 中增删查改(访问)数据

未完待续

总结

未完待续

打分测评模型

另一位同学负责的部分,具体表现为一个时刻监控数据库的神经网络模型程序。

django 完成一次测评,向一张表单中写入测评数据;打分模型检测到表单新增数据,则会自动处理。处理完成后,会向该学生对应的表中写入数据,如果表不存在,则创建表格。

输出的分数有两种情况,视题型而定,可能是单个分数,可能是四个分数。

前端读取到数据时会判断题型,在计算均分时,会对只有一个分数的题型特殊处理。

未完待续

部署

通过 https 方式启动 django 的大致指令:

1
python3 ./project/manage.py runsslserver 0.0.0.0:8000 --certificate /etc/apache2/ssl/xxx.com.crt --key /etc/apache2/ssl/xxx.com.key

如果是 DEBUG 状态,可以加入 --no-static 参数。

0.0.0.0:8000 是广播的目标地址,意思是对所有 ip 通过 8000 端口广播。值得注意的是,如果改为 443,80 等https,http默认端口,则会和本地服务器程序冲突。要想通过 443、80 广播,应当使用 nginx 之类的反向代理应用。

--certificate--key 都是 ssl 所需参数。

总结

未完待续


语音测评网站项目总结
http://petertan303.github.io/2023/09/20/语音测评网站项目总结/
作者
peter?
发布于
2023年9月20日
许可协议