# 视图层(View) 视图层是模块开发的第四步,负责处理 HTTP 请求并调用 Service 层的业务逻辑。项目使用 Django 的类视图(Class-Based Views),每个视图类对应一个 API 端点。 ## 文件位置 ``` 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 ExampleListView(View): """案例列表获取视图(支持筛选,不分页)""" def get(self, request): result = services.get_example_list(request) return R.ok(data=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, name='get') class ExampleDataView(View): """案例列表获取视图""" def get(self, request): result = services.get_example_data() return R.ok(data=result) ``` ## 代码解析 ### 视图类继承 ```python @method_decorator(check_login, name="get") class ExamplePageView(PermissionRequired, View): ``` | 基类/装饰器 | 来源 | 提供能力 | |:----|:----|:----| | `View` | Django 内置 | 类视图基类,提供 get/post/put/delete 方法分发 | | `PermissionRequired` | `middleware/permission_middleware.py` | 权限控制混入类 | | `@method_decorator(check_login, name="get")` | `middleware/login_middleware.py` | JWT 登录认证 | ### 三层防护机制 ``` 请求 → check_login(登录校验) → PermissionRequired(权限校验) → operation_log(操作日志) → 业务逻辑 ``` #### 1. 登录校验(check_login) ```python @method_decorator(check_login, name="get") ``` `check_login` 装饰器从请求头 `Authorization: Bearer ` 中提取 JWT token,验证其有效性。验证失败返回 `401 Unauthorized`。 ```python def check_login(func): def wrapper(request, *args, **kwargs): ignoreURL = ['/login', '/captcha'] if request.path not in ignoreURL: access_token = request.headers['Authorization'] access_token = access_token.replace('Bearer ', "") result = parse_payload(access_token) code = result['code'] if code != 0: return R.failed(code=401, msg=result['msg']) return func(request, *args, **kwargs) return wrapper ``` #### 2. 权限校验(PermissionRequired) ```python class ExamplePageView(PermissionRequired, View): permission_required = ("sys:example:page",) ``` `PermissionRequired` 混入类重写了 `has_permission()` 方法,检查当前用户是否拥有所需的权限节点。用户 ID 为 1 的超级管理员自动放行。 ```python class PermissionRequired(PermissionRequiredMixin): def has_permission(self): permissions = self.get_permission_required() user_id = get_user_id(self.request) # 超级管理员自动放行 if user_id and user_id != 1: from application.menu import services permission_list = services.get_user_permissions(user_id) for permission in permissions: if permission not in permission_list: return False return True def handle_no_permission(self): return R.failed("暂无操作权限", 401) ``` #### 3. 操作日志(operation_log) ```python @operation_log(title="案例管理-查询分页列表", log_type=LogType.QUERY) def get(self, request): ... ``` `@operation_log` 装饰器自动记录操作日志,包括操作标题、操作类型、请求参数、响应结果、耗时等信息。 | 参数 | 说明 | |:----|:----| | `title` | 操作标题,如"案例管理-添加记录" | | `log_type` | 操作类型,参考 `LogType` 常量 | | `source` | 操作来源,0=后台系统 | ### 操作类型常量 ```python class LogType: OTHER = 0 # 其他操作 QUERY = 1 # 查询操作 ADD = 2 # 新增操作 UPDATE = 3 # 修改操作 SAVE = 4 # 保存操作 DELETE = 5 # 删除操作 BATCH_DELETE = 6 # 批量删除 STATUS = 7 # 设置状态 RESET_PWD = 8 # 重置密码 IMPORT = 9 # 导入操作 EXPORT = 10 # 导出操作 UPLOAD = 11 # 上传操作 ``` ### 演示环境检查 ```python if DJANGO_DEMO: return R.failed("演示环境,暂无操作权限") ``` 写操作(add、update、delete、status)需要检查 `DJANGO_DEMO` 配置。当 `.env` 中设置 `DJANGO_DEMO=True` 时,所有写操作返回失败提示。 ### 视图类分类 | 视图类 | HTTP 方法 | 权限 | 说明 | |:----|:----|:----|:----| | `ExamplePageView` | GET | `sys:example:page` | 分页查询 | | `ExampleListView` | GET | 无(仅登录) | 列表查询(不分页) | | `ExampleDetailView` | GET | `sys:example:detail` | 详情查询 | | `ExampleAddView` | POST | `sys:example:add` | 添加记录 | | `ExampleUpdateView` | PUT | `sys:example:update` | 更新记录 | | `ExampleDeleteView` | DELETE | `sys:example:delete` | 删除记录 | | `ExampleStatusView` | PUT | `sys:example:status` | 状态更新 | | `ExampleDataView` | GET | 无(仅登录) | 数据列表(下拉选择) | ### 权限节点格式 ``` sys:: ``` | 部分 | 说明 | 示例 | |:----|:----|:----| | `sys` | 固定前缀 | `sys` | | `` | 模块名称 | `example` | | `` | 操作类型 | `page`、`list`、`detail`、`add`、`update`、`delete`、`status` | ## 开发要点 1. **每个视图类只处理一个 HTTP 方法**:单一职责原则 2. **使用 `@method_decorator(check_login, name="方法名")` 进行登录校验**:确保用户已登录 3. **需要权限控制的视图继承 `PermissionRequired`**:并设置 `permission_required` 4. **写操作必须检查 `DJANGO_DEMO`**:演示环境禁止写操作 5. **使用 `@operation_log` 记录操作日志**:便于审计和追踪 6. **视图层只做请求分发**:业务逻辑全部委托给 Service 层 7. **直接返回 Service 层的结果**:不要在视图层处理业务逻辑 ## 总结 视图层使用 Django 类视图,组合三层防护机制:登录校验(check_login)、权限控制(PermissionRequired)、操作日志(operation_log)。每个视图类只处理一个 HTTP 方法,写操作需要检查 DJANGO_DEMO 配置。视图层只做请求分发,业务逻辑全部委托给 Service 层。