208 lines
6.5 KiB
Markdown
208 lines
6.5 KiB
Markdown
# View层规范
|
||
|
||
## 概述
|
||
|
||
View 层负责处理 HTTP 请求和返回响应,使用 Django 类视图(Class-Based Views)。每个视图类对应一个 API 端点,通过装饰器实现登录验证、权限检查和操作日志记录。
|
||
|
||
:::tip 设计原则
|
||
- 使用类视图(继承 `View`)
|
||
- 通过 `@method_decorator(check_login)` 验证登录
|
||
- 通过 `PermissionRequired` mixin 检查权限
|
||
- 通过 `@operation_log` 记录操作日志
|
||
- 写操作检查 `DJANGO_DEMO` 演示模式
|
||
:::
|
||
|
||
## 完整示例
|
||
|
||
以案例模块为例,`application/example/views.py`:
|
||
|
||
```python
|
||
from django.utils.decorators import method_decorator
|
||
from django.views import View
|
||
from application.example import services
|
||
from config.env import DJANGO_DEMO
|
||
from middleware.login_middleware import check_login
|
||
from middleware.permission_middleware import PermissionRequired
|
||
from utils import R
|
||
from application.operation_log.constants import LogType
|
||
from application.operation_log.decorators import operation_log
|
||
|
||
|
||
# =============================================================
|
||
# 分页查询视图
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="get")
|
||
class ExamplePageView(PermissionRequired, View):
|
||
"""案例分页数据查询视图"""
|
||
permission_required = ("sys:example:page",)
|
||
|
||
@operation_log(title="案例管理-查询分页列表", log_type=LogType.QUERY)
|
||
def get(self, request):
|
||
result = services.get_example_page(request)
|
||
return result
|
||
|
||
|
||
# =============================================================
|
||
# 详情查询视图
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="get")
|
||
class ExampleDetailView(PermissionRequired, View):
|
||
"""案例详情查询视图"""
|
||
permission_required = ("sys:example:detail",)
|
||
|
||
@operation_log(title="案例管理-查询记录详情", log_type=LogType.QUERY)
|
||
def get(self, request, id):
|
||
data = services.get_example_detail(id)
|
||
return R.ok(data=data)
|
||
|
||
|
||
# =============================================================
|
||
# 添加视图
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="post")
|
||
class ExampleAddView(PermissionRequired, View):
|
||
"""添加案例视图"""
|
||
permission_required = ("sys:example:add",)
|
||
|
||
@operation_log(title="案例管理-添加记录", log_type=LogType.ADD)
|
||
def post(self, request):
|
||
# 演示环境禁止操作
|
||
if DJANGO_DEMO:
|
||
return R.failed("演示环境,暂无操作权限")
|
||
|
||
result = services.add_example(request)
|
||
return result
|
||
|
||
|
||
# =============================================================
|
||
# 更新视图
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="put")
|
||
class ExampleUpdateView(PermissionRequired, View):
|
||
"""更新案例视图"""
|
||
permission_required = ('sys:example:update',)
|
||
|
||
@operation_log(title="案例管理-更新记录", log_type=LogType.UPDATE)
|
||
def put(self, request):
|
||
# 演示环境禁止操作
|
||
if DJANGO_DEMO:
|
||
return R.failed("演示环境,暂无操作权限")
|
||
|
||
result = services.update_example(request)
|
||
return result
|
||
|
||
|
||
# =============================================================
|
||
# 删除视图(支持批量)
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="delete")
|
||
class ExampleDeleteView(PermissionRequired, View):
|
||
"""删除案例视图"""
|
||
permission_required = ('sys:example:delete',)
|
||
|
||
@operation_log(title="案例管理-删除记录", log_type=LogType.DELETE)
|
||
def delete(self, request, id):
|
||
# 演示环境禁止操作
|
||
if DJANGO_DEMO:
|
||
return R.failed("演示环境,暂无操作权限")
|
||
|
||
result = services.delete_examples(id)
|
||
return result
|
||
|
||
|
||
# =============================================================
|
||
# 状态更新视图
|
||
# =============================================================
|
||
|
||
@method_decorator(check_login, name="put")
|
||
class ExampleStatusView(PermissionRequired, View):
|
||
"""设置案例状态视图"""
|
||
permission_required = ('sys:example:status',)
|
||
|
||
def put(self, request):
|
||
# 演示环境禁止操作
|
||
if DJANGO_DEMO:
|
||
return R.failed("演示环境,暂无操作权限")
|
||
|
||
result = services.update_example_status(request)
|
||
return result
|
||
```
|
||
|
||
## 装饰器说明
|
||
|
||
### @method_decorator(check_login)
|
||
|
||
验证 JWT 登录状态,从 `Authorization: Bearer <token>` 头解析用户信息。未登录返回 401。
|
||
|
||
```python
|
||
@method_decorator(check_login, name="get") # 验证 GET 请求
|
||
@method_decorator(check_login, name="post") # 验证 POST 请求
|
||
@method_decorator(check_login, name="put") # 验证 PUT 请求
|
||
@method_decorator(check_login, name="delete") # 验证 DELETE 请求
|
||
```
|
||
|
||
### PermissionRequired
|
||
|
||
权限检查 mixin,用户 ID 为 1 的超级管理员自动跳过权限检查。
|
||
|
||
```python
|
||
class ExamplePageView(PermissionRequired, View):
|
||
permission_required = ("sys:example:page",) # 权限标识
|
||
```
|
||
|
||
### @operation_log
|
||
|
||
操作日志记录装饰器,自动记录请求参数、响应结果、执行时间等。
|
||
|
||
```python
|
||
@operation_log(title="案例管理-添加记录", log_type=LogType.ADD)
|
||
```
|
||
|
||
日志类型:
|
||
|
||
| 类型 | 说明 |
|
||
|:----|:----|
|
||
| `LogType.QUERY` | 查询操作 |
|
||
| `LogType.ADD` | 添加操作 |
|
||
| `LogType.UPDATE` | 更新操作 |
|
||
| `LogType.DELETE` | 删除操作 |
|
||
|
||
## 演示模式检查
|
||
|
||
写操作(add/update/delete/status)需检查 `DJANGO_DEMO` 配置:
|
||
|
||
```python
|
||
if DJANGO_DEMO:
|
||
return R.failed("演示环境,暂无操作权限")
|
||
```
|
||
|
||
## 权限标识规范
|
||
|
||
| 操作 | 权限标识 | 说明 |
|
||
|:----|:----|:----|
|
||
| 分页查询 | `sys:{module}:page` | 查询分页数据 |
|
||
| 列表查询 | `sys:{module}:list` | 查询列表数据 |
|
||
| 详情查询 | `sys:{module}:detail` | 查询单条详情 |
|
||
| 添加 | `sys:{module}:add` | 添加记录 |
|
||
| 更新 | `sys:{module}:update` | 更新记录 |
|
||
| 删除 | `sys:{module}:delete` | 删除记录 |
|
||
| 状态 | `sys:{module}:status` | 更新状态 |
|
||
|
||
## View 层职责
|
||
|
||
View 层只负责:
|
||
1. 接收 HTTP 请求
|
||
2. 调用 Service 层函数
|
||
3. 返回 R 响应
|
||
|
||
禁止在 View 层直接操作数据库或编写业务逻辑。
|
||
|
||
## 总结
|
||
|
||
View 层使用 Django 类视图,通过装饰器实现登录验证(`check_login`)、权限检查(`PermissionRequired`)和操作日志记录(`operation_log`)。写操作检查 `DJANGO_DEMO` 演示模式。View 层只负责请求分发和响应返回,业务逻辑集中在 Service 层。
|