ITM-0011 draft

This commit is contained in:
cyx0706
2021-12-17 21:22:53 +08:00
parent 23dfb75ea3
commit b098f8be4d
+173
View File
@@ -0,0 +1,173 @@
ITM: 11
Title: 爱特工作室程序部后端开发规范
Author: Yuixiang Cai <caiyuxiang@itstudio.club>, Liu Yang <liuyang@itstudio.club>
Created: 2021-12-17
Status: draft
简介
====================
爱特程序部主要工作是后端开发,基于 `Django` 框架: https://www.djangoproject.com/
多数情况下和前端部门合作进行前后端分离的开发。
目录
====================
0. 项目组织
1. settings.py
2. models.py
3. serializers.py
4. views.py
5. urlpatterns && Router
正文
====================
0. 项目组织
在大多数时候,项目可能包括不止一个 APP,将这些 APP 全部收录到一个 `apps` 文件夹中,并将该文件夹设置为 Python 的包。
一个项目的目录树大体如下:
```
.
├── apps
│   ├── __init__.py
│   └── <app_name>
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── serializers.py
│   ├── tests.py
│   └── views.py
├── <project_name>
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── .gitignore
├── manage.py
└── config.json
```
这样的好处在于:
- 便于统一化管理,减少根目录下的文件数。
1. settings.py
`settings.py` 里的敏感配置信息如: `SECRET_KEY`,数据库的账号密码,STMP 等服务的账号密码,禁止明文写在文件中,请使用配置文件的方式读入并在 `.gitignore` 文件中忽略配置文件。
示例代码:
```
import json
# Configuration File
with open('./conf.json', 'r') as f:
config = json.load(f)
SECRET_KEY = config.get('SECRET_KEY')
MYSQL_DATABASE_NAME = config.get('MYSQL_DATABASE_NAME')
MYSQL_DATABASE_USER = config.get('MYSQL_DATABASE_USER')
MYSQL_DATABASE_PASSWORD = config.get('MYSQL_DATABASE_PASSWORD')
```
这样的好处在于:
- 避免上传到 GitHub 等平台时密码泄露。
2. Model 层规范
Model 类应该写在每个 app 下的 `models.py` 文件中,同时每个 Model 的每个字段应添加文字描述,例如:
`content = models.TextField('内容')`
对于常量使用 `ChoiceField` 类型,例如:
```
GENDER_CHOICES = (
(0, '女'),
(1, '男'),
(2, '隐藏')
)
class Person(models.Model):
gender = models.IntegerField('性别', choices=GENDER_CHOICES, default=2)
```
这样的好处在于:
- 直观,只需要看 Model 类就可以理解数据库内的表。
- 集中管理映射关系,外部显示的改变不会影响数据库内的字段。
3. serializers.py
Django RestFrameWork(drf) 中增加了序列化器,它可以代替表单快捷的完成校验和对数据库的操作。
在校验中如果出现字段错误,抛出异常而不是返回 False。异常对应的状态信息参考 View 层对返回值设置的规范。
4. views.py
使用基于类的视图 `ViewSet` 或者 `APIView` 而不是函数。并在每个类中增加对整体模块逻辑的描述注释,在函数上增加函数功能的描述注释。
注释参考示例:
```
class <ClassName>(APIView):
"""
用户博客模块的逻辑
"""
def post(self, request, *args, **kwargs):
"""
:description: 对当前用户新增一篇博客
:author: ctwo
:date: 2021/12/17
:param request: 请求
:return: Response
"""
pass
```
这样的好处在于:
- 基于类的视图更符合面向对象和 Restful 规范,能更好的将接口归档。
在和前端交互的过程中,以 Json 数据格式为主,后端的返回格式应该如下:
```json
{
"code": 200, // 状态码
"msg": "OK", // 必要的返回描述信息
"data": {} // 数据
}
```
同时,使用枚举类型绑定状态码和返回描述信息,如:
```python
class ResponseStatus(Enum):
OK = (20000, '成功')
UNEXPECTED_ERROR = (50000, '意外错误')
METHOD_NOT_ALLOWED_ERROR = (40000, '请求方法错误')
```
这样的好处在于:
- 避免了重复的在视图函数中写返回信息的字符串,也便于规范接口文档
4. urlpatterns 和 Router 规范
使用 POST 方法或者带有参数的 GET 方法而不是将要查询的字段如 id 拼在 URL 中。
不推荐的写法:`path("^blog/(?P<user_id>.*)$", <view_get_func>, name=<url_name>)`
而采用 `path("blog/", <view_post_func>, name=<url_name>)`
这样的好处在于:
- 降低路由复杂性,少写复杂正则表达式,增强可读性