所有步骤中的账号密码仅供参考,千万不要在自己的生产环境中使用,否则产生的安全问题由您自己承担。
1. 项目思考
鉴于这是一个较大的项目,不建议一上来就直接写代码,应该首先思考一下项目的组织和管理问题。个人认为要考虑以下几个问题:
- 代码托管:代码托管关系到团队的协作问题和代码安全问题,常用的代码托管平台有:Github和码云,推荐使用码云,因为国内网络码云更快。
- 版本控制:越大的项目涉及的文件越多,代码逻辑也越复杂,因此出错的概率也越高,所以应该使用版本控制系统,方便出现问题时回滚,推荐使用git。
- 文档编写:为了以后能进行项目拓展和问题复现,项目文档必不可少,同时项目文档也是团队交流的重要工具。项目编写方式有手动和自动两种方式,自动方式适用于编写API文档,可以使用一些文档工具根据程序中的文档注释(如:docstring)来自动生成,例如swagger-ui;手动方式适用于程序逻辑设计和架构部分。
- 测试:个人认为测试环境可以分为本地测试环境和线上测试环境。本地测试环境主要用于进行α测试,线上测试环境主要用于进行beta测试。由于Django 自带一个用于开发的简易服务器(不要在生产环境中使用),因此α测试环境不用自己搭建,这里只考虑β测试环境的搭建(详细见测试部分章节)。其次,开发中一个非常重要的环节就是编写单元测试,因此当开发完某个模块(或功能)后要及时编写对应的单元测试程序,及时发现一些显而易见的bug,避免bug产生雪崩效应,由小bug转化为大bug。最后,线上测试环境和生产环境应该隔离开,以免给生产环境造成危险。
α测试是指软件开发公司组织内部人员模拟各类用户对即将面市软件产品(称为α版本)进行测试,试图发现错误并修正。α测试的关键在于尽可能逼真地模拟实际运行环境和用户对软件产品的操作并尽最大努力涵盖所有可能的用户操作方式。经过α测试调整的软件产品称为β版本。
β测试是由软件的多个用户在实际使用环境下进行的测试,这些用户返回有关错误信息给开发者。测试时,开发者通常不在测试现场。因而,β测试是在开发者无法控制的环境下进行的软件现场应用测试。在β测试中,由用户记下遇到的所有问题,包括真实的以及主观认定的,定期向开发者报告。β测试主要衡量产品的FLURPS,着重于产品的支持性,包括文档,客户培训和支持产品生产能力。
只有当α测试达到一定的可靠程度时,才能开始β测试。
- 代码复用:代码复用对于大型项目很有价值,因为可以节省很多时间和精力,并且极大的缩减了文档数量,降低了项目的学习成本,因此在开发时要时刻注意代码重构,抽取出功能重复的代码作为独立的模块以实现代码复用。
- 模块化:模块化和代码复用的目的有一定的重复,但是个人认为模块化最主要的目的是将一个大型应用程序划分成各个彼此独立的模块,将对大程序的维护转化为对小模块的维护,减轻代码耦合,模块的划分标准应该是:将能实现某项功能的最少程序划分为一个模块,但是模块的数量也不是越多越好,通常将重大功能划分成一个独立模块。
- 敏感信息安全:不要在代码中明文保存任何敏感信息(即可能带来安全问题的信息,例如开发者账号和密码),如果无法避免,一定要进行加密存储或者通过系统环境变量指定。
- 代码规范:规范的代码对于减少bug,降低维护成本和文档生成有重要意义,开发时不仅要遵循python和django的代码规范,同时在关键部分应该加上文档注释或者单行注释,特别是文档注释一定要认真编写,这样后期可以使用自动文档工具来生成项目文档,减少工作量。
- 配置常量安全:Django中存在大量系统配置常量,位于项目的settings.py 中,但是这些常量仅仅是名称大写,仍然可以通过外部程序修改,如果在引用过程中不慎修改了这些常量,就有可能出现重大错误(比如修改了DEBUG标志量会导致安全风险),因此使用django 常量时不要直接从settings.py中引入,应该引入django.conf.settings对象,通过该对象使用这些常量。参见:https://docs.djangoproject.com/zh-hans/3.1/topics/settings/#envvar-DJANGO_SETTINGS_MODULE
- 开发工具:选用优秀的开发工具可以达到事半功倍的效果,本次使用的开发工具如下:
Pycharm 2020、Django3.0、django-oauth-toolkit 1.4.0、djangorestframework 3.12.2、python3.9
2. 创建Django projects和app
pycharm 默认安装django ,因此不需要自己使用pip安装,如果使用django-admin,需要事先使用pip 安装django。为了避免命名冲突,建议项目和app名称加个自定义前缀,这里使用kaopu作为项目和app名称前缀。
创建projects(也可以直接在项目目录下使用django-admin startproject project_name 创建),项目路径是:D:\KaopuBackendDoNotDelete。
创建完django project 还需要创建django app,每个django app对应一个网站。在pycharm Terminal下运行django命令创建app:
注册app:app创建完还需要注册才能让django框架发现它,在django 项目目录KaopuBackendDoNotDelete 文件夹下settings.py 的INSTALLED_APPS 字段中添加:
INSTALLED_APPS = [
......,
'kaopu_shop',
.....
]
3.配置资源数据库和缓存数据库
Django 默认使用的数据库是sqlite,对于轻量应用已经足够了,但是生产环境可能不够用,由于资源数据库更加注重数据的一致性,因此采用著名的关系型数据库MYSQL,缓存数据库更加注重读取速度,因此采用Redis作为缓存数据库。关于关系型数据库和非关系型数据库的特点参见文章:https://www.jianshu.com/p/fd7b422d5f93。
MYSQL的安装
参见: https://www.cnblogs.com/xiaokang01/p/12092160.html
Redis 安装
参见: https://www.cnblogs.com/yechangzhong-826217795/p/11202316.html
Django 数据库配置
参见:https://docs.djangoproject.com/zh-hans/3.1/ref/databases/#mysql-notes
Django 缓存配置
参见:https://docs.djangoproject.com/zh-hans/3.0/topics/cache/#cache-key-transformation
3.1 配置MYSQL数据库
为了数据库安全,应该避免使用root 用户直接操作数据库,因此首先创建一个名为KaopuBackendDataManager的MySQL用户给我们的django 项目连接MySQL使用。打开windows CMD ,输入以下命令以root用户身份连接MySQL。
然后执行创建用户命令:
CREATE USER 'KaopuBackendDataManager'@'localhost' IDENTIFIED BY 'password';
为了数据库安全,只允许KaopuBackendDataManager这个用户从本地主机连接数据库,不允许从远程主机连接。创建完用户还需要创建数据库,执行以下SQL语句创建数据库KaopuBackendDataBase
CREATE DATABASE KaopuBackendDataBase CHARACTER SET utf8;
接下来需要将我们创建的数据库授权新建的用户,使得这个用户可以操作这个数据库。执行以下的SQL语句:
GRANT ALL ON KaopuBackendDataBase.* TO 'KaopuBackendDataManager'@'localhost';
上述SQL表示允许用户KaopuBackendDataManager对数据库KaopuBackendDataBase中的所有数据表进行增删查改操作,为了数据安全,只允许该用户从本地主机登录数据库时才能操作数据库。
接下还需要配置数据库连接部分,使得Django可以自动连接上数据库。Django 官方推荐使用的数据库中间件是:mysql-connector-python 和mysqlclient ,使用pip安装这两个中间件:
pip install mysql-connector-python mysqlclient
然后配置KaopuBackendDoNotDelete 文件夹下settings.py 的DATABASES 字段。
Tips:为了避免数据库配置越来越多时导致我们的settings.py文件非常庞大和杂乱,把DATABASES 字段独立成一个文件放在database_settings包(和settings.py处于同一个文件夹下)中,然后导入到settings.py中。
新建database_settings和database_settings.py包
在database_settings.py中配置DATABASES字段:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "KaopuBackendDataBase",
'USER': "KaopuBackendDataManager",
"PASSWORD": "password",
"OPTIONS": {
# sql 模式
'sql_mode': 'STRICT_ALL_TABLES',
# 隔离级别
'isolation_level': 'read committed',
}
}
}
sql_mode:从 MySQL 5.7 开始,以及在 MySQL 5.6 的新版本上,sql_mode
选项的默认值包含 STRICT_TRANS_TABLES
。当数据插入后被截断时,该选项会将警告升级为错误,所以 Django 强烈建议激活 MySQL 的严格模式 ,以防止数据丢失(无论是 STRICT_TRANS_TABLES
还是 STRICT_ALL_TABLES
)。详细参见:https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sql-mode-strict
isolation_level:隔离等级是一种设置,用于在多个事务同时进行更改和执行查询时结果的可靠性,一致性和可重复性之间的平衡。详细参见:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
配置完之后在settings.py中导入数据库设置:
from .database_settings.database_settings import *
3.2 配置Redis缓存数据库
在配置缓存数据库之前首先思考一下哪些数据是我们需要缓存的。对于这里涉及的六个API(参见3.1 开发目标一节),我们需要缓存的是产品数据,即只有查询资源数据时才需要读取缓存,因此我们使用redis缓存产品数据。为了能让我们的django 应用连接redis,需要安装django-redis中间件:
pip install django-redis
django-redis使用参考:https://django-redis-chs.readthedocs.io/zh_CN/latest/
为了数据安全,打开CMD给我们的redis访问设置一个密码:password
这样访问redis必须使用密码验证后redis才会执行命令。然后配置settings.py中的CACHES字段,同样我们将其独立为一个文件cache_settings.py。设置缓存超时时间为3600秒,并且最大容量是1000条。
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
'TIMEOUT': 3600,
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "password",
'MAX_ENTRIES': 1000
}
}
最后在settings.py中导入我们的缓存设置:
from .cache_settings.cache_settings import *
3.3 小结
资源数据库mysql配置:
(1) 安装mysql ;(2) 创建用户和数据库;(3)数据库授权给用户;(4)修改Django 项目的settings.py中的DATABASES字段,配置数据连接。
缓存数据库mysql配置:
(1) 安装redis;(2)为了缓存数据安全,给redis连接设置密码;(3)修改settings.py中的CACHES字段,配置缓存数据库连接。
4.安装rest framework 和OAuth2.0 支持库
参考:https://www.w3cschool.cn/lxraw/lxraw-8kq335ob.html,https://django-oauth-toolkit.readthedocs.io/en/latest/install.html
在pycharm Terminal下运行:
pip install djangorestframework django-oauth-toolkit
djangorestframework用来构建Restful API,django-oauth-toolkit 用来进行OAuth2.0 验证。
然后在django 项目的settings.py INSTALLED_APPS 字段中启用
INSTALLED_APPS = [
......,
'rest_framework',
'oauth2_provider',
.....
]
然后进行数据库迁移:
5. 版本控制
git 操作参见:http://git.oschina.net/progit/
5.1 git分支
git仓库创建时默认创建一个主分支master,每个仓库应该有一个、且仅有一个主分支,所有提供给用户使用的正式版本,都在这个主分支上发布。主分支只用来发布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。在建立git仓库后还需另外创建一个开发分支。各个分支的功能如下:
- 本地master分支:本地代码的稳定版本。
- 本地develop分支:正在进行开发的本地代码。
- 远程master分支:最终代码稳定版本,达到可以发布的水平。
- 远程develop分支:完整代码的开发版本,可以用来进行整个项目的测试。
注意:本地develop,master和远程的develop,master内容不一定一致,例如:整个项目由A,B,C三部分组成,甲负责C部分的开发,那么甲本地master可能只是C部分代码的稳定版本,甲本地develop分支只是C部分代码的开发版本,而远程master是包含A,B,C三部分代码的稳定版本,远程develop是包含A,B,C三部分代码的开发版本。
5.2 创建码云代码托管仓库(远程仓库)
打开码云:https://gitee.com/,注册账号,然后根据码云给的教程创建SSH密匙对和代码仓库KaopuBackend。具体操作参看文档:https://gitee.com/help#article-header0。
5.3 创建本地仓库
使用pycharm自带的版本控制系统进行版本控制。首先创建git本地仓库:
5.4 配置.gitignore文件
接着先排除不需要版本控制的文件和文件夹,主要有以下几个:
- venv文件夹:存储的是python虚拟环境的配置文件。
- migrations文件夹:存储的是数据库迁移相关文件。
得到以下.gitignore文件:
/venv/
/kaopu_shop/migrations/
5.5 添加需要跟踪的文件到暂存区
选中要跟踪的目录或者文件,然后右键选择Git->Add,让git跟踪这些文件。
5.6 规范提交信息和提交代码到本地仓库
为了方便以后回溯,推荐使用Pycharm插件自动生成提交信息模板。在Pycharm 工具栏File->settings->Plugin打开插件窗口搜索安装:
然后打开提交窗口和提交模板编辑窗口:
创建提交消息并提交项目文件到本地仓库Master分支上。接下来创建Develop分支:
如果默认选中checkout branch,那新建完分支后就会切换到新建的分支,接下来我们的开发都将在本地develop分支中进行。
5.7 推送代码到远程仓库
远程仓库就是我们在码云创建的仓库,复制远程仓库链接然后使用Pycharm配置远程仓库:
然后将我们本地master分支的代码推送到远程仓库的master分支上。首先切换本地当前分支为master:
因为本地master分支不是从远程master分支克隆的,所以可能存在冲突,所以我们首先执行rebase命令,将远程分支合并到本地分支,解决冲突:
然后推送本地matser代码到远程master:
现在我们完成了版本控制系统的配置。随后我们将本地分支切换为本地develop分支,在这个分支下进行开发,接下来每个开发阶段完成后都会提交一次代码到本地仓库,以跟踪开发进程。
5.8小结
搭建版本控制系统总共分以下几步:
(1)注册码云账号,配置SSH密匙对,创建远程仓库;
(2)创建本地仓库(可以直接克隆远程仓库创建);
(3)配置.gitignore文件,排除不需要跟踪的文件;
(4)添加要跟踪文件到暂存区;
(5)规范提交信息,提交代码到本地仓库;
(6)配置远程仓库并推送代码到远程仓库。
日常开发都在本地develop分支上进行,开发完一项重大功能并经过α测试后提交到本地master,然后将本地master推送到远程master上。本地develop分支也可以推送到远程develop分支上形成整个项目的开发版