Skip to content

完整代码清单

本章汇总 Example 案例模块涉及的全部文件,便于开发时快速查阅和复制。

后端文件清单

1. 数据模型 application/example/models.py

python
from django.db import models
from application.models import BaseModel
from utils.common import get_table_name


class Example(BaseModel):
    """案例模型类"""
    name = models.CharField(null=False, max_length=100, db_index=True,
        verbose_name="案例名称", db_comment='案例名称')
    avatar = models.CharField(null=True, blank=True, max_length=255,
        verbose_name="案例图片", db_comment='案例图片')
    TYPE_CHOICES = ((1, "类型1"), (2, "类型2"), (3, "类型3"), (4, "类型4"),)
    type = models.IntegerField(null=False, choices=TYPE_CHOICES,
        verbose_name="案例类型", db_comment='案例类型')
    STATUS_CHOICES = ((1, "正常"), (2, "禁用"),)
    status = models.IntegerField(null=False, choices=STATUS_CHOICES,
        verbose_name="案例状态", db_comment='案例状态')
    sort = models.IntegerField(null=False,
        verbose_name="排序", db_comment='排序')

    class Meta:
        db_table = get_table_name('example')
        db_table_comment = "案例表"
        verbose_name = "案例表"
        verbose_name_plural = verbose_name
        ordering = ("sort",)

2. 表单验证 application/example/forms.py

python
from django import forms
from application.example import models


class ExampleForm(forms.ModelForm):
    """案例表单验证类"""
    name = forms.CharField(required=True, max_length=100, error_messages={
        'required': '案例名称不能为空', 'max_length': '案例名称长度不得超过100个字符'})
    avatar = forms.CharField(required=False, max_length=255, error_messages={
        'max_length': '案例图片长度不得超过255个字符'})
    type = forms.IntegerField(required=True, min_value=1, max_value=4, error_messages={
        'required': '案例类型不能为空', 'min_value': '案例类型值不能小于1', 'max_value': '案例类型值不能大于4'})
    status = forms.IntegerField(required=True, min_value=1, max_value=2, error_messages={
        'required': '案例状态不能为空', 'min_value': '案例状态值不能小于1', 'max_value': '案例状态值不能大于2'})
    sort = forms.IntegerField(required=True, error_messages={'required': '排序不能为空'})

    class Meta:
        model = models.Example
        fields = ['name', 'avatar', 'type', 'status', 'sort']

3. 业务逻辑层 application/example/services.py

python
import json
import logging
from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage, EmptyPage
from application.example import forms
from application.example.models import Example
from config.env import DJANGO_FILE_URL
from constant.constants import PAGE_SIZE
from utils import R, regular
from utils.common import get_file_url, format_datetime, parse_request_body, save_file
from utils.security import get_username


def get_example_page(request):
    """查询案例分页数据"""
    try:
        page_no = int(request.GET.get('pageNo', 1))
        page_size = int(request.GET.get('pageSize', PAGE_SIZE))
        query = Example.objects.filter(is_delete=False)
        query = _apply_filters(query, request)
        query = query.order_by("sort")
        paginator = Paginator(query, page_size)
        try:
            page_list = paginator.page(page_no)
        except (PageNotAnInteger, InvalidPage, EmptyPage):
            page_list = paginator.page(1)
            page_no = 1
        page_data = _build_page_data(page_list, paginator, page_no, page_size)
        return R.ok(data=page_data)
    except Exception as e:
        logging.error(f"查询案例分页数据异常: {str(e)}")
        return R.failed(msg="查询失败,请稍后重试")


def add_example(request):
    """添加案例"""
    data, error = parse_request_body(request)
    if error:
        return R.failed(msg=error)
    form = forms.ExampleForm(data)
    if not form.is_valid():
        return R.failed(msg=regular.get_err(form))
    try:
        cleaned_data = form.cleaned_data
        avatar = cleaned_data.get('avatar')
        if avatar:
            avatar = save_file(avatar, "example")
        Example.objects.create(
            name=cleaned_data.get('name'), avatar=avatar,
            type=cleaned_data.get('type'), status=cleaned_data.get('status'),
            sort=cleaned_data.get('sort'),
            create_user=get_username(request), update_user=get_username(request))
        return R.ok(msg="创建成功")
    except Exception as e:
        logging.error(f"添加案例异常: {str(e)}")
        return R.failed(msg="添加失败,请稍后重试")


def update_example(request):
    """更新案例"""
    data, error = parse_request_body(request)
    if error:
        return R.failed(msg=error)
    instance_id = data.get('id')
    if not instance_id or not str(instance_id).isdigit() or int(instance_id) <= 0:
        return R.failed("案例ID无效")
    instance_id = int(instance_id)
    form = forms.ExampleForm(data)
    if not form.is_valid():
        return R.failed(msg=regular.get_err(form))
    try:
        instance = Example.objects.filter(id=instance_id, is_delete=False).first()
        if not instance:
            return R.failed("案例不存在")
        cleaned_data = form.cleaned_data
        avatar = cleaned_data.get('avatar')
        if avatar and avatar != instance.avatar:
            avatar = save_file(avatar, "example")
        else:
            avatar = instance.avatar
        instance.name = cleaned_data.get('name')
        instance.avatar = avatar
        instance.type = cleaned_data.get('type')
        instance.status = cleaned_data.get('status')
        instance.sort = cleaned_data.get('sort')
        instance.update_user = get_username(request)
        instance.save()
        return R.ok(msg="更新成功")
    except Exception as e:
        logging.error(f"更新案例异常,ID: {instance_id}, 错误: {str(e)}")
        return R.failed(msg="更新失败,请稍后重试")


def delete_examples(instance_ids):
    """删除案例(批量删除)"""
    if not instance_ids:
        return R.failed("记录ID不存在")
    try:
        id_list = [int(id_str.strip()) for id_str in instance_ids.split(',') if id_str.strip()]
        if not id_list:
            return R.failed("无效的记录ID")
        updated_count = Example.objects.filter(id__in=id_list, is_delete=False).update(is_delete=True)
        return R.ok(msg=f"本次共删除{updated_count}条数据")
    except ValueError:
        return R.failed("记录ID格式错误")


def update_example_status(request):
    """更新案例状态"""
    data, error = parse_request_body(request)
    if error:
        return R.failed(msg=error)
    instance_id = data.get('id')
    if not instance_id or not str(instance_id).isdigit() or int(instance_id) <= 0:
        return R.failed("案例ID无效")
    instance_id = int(instance_id)
    status = data.get('status')
    if status is None:
        return R.failed("状态值不能为空")
    try:
        status = int(status)
        if status not in [1, 2]:
            return R.failed("状态值无效")
    except ValueError:
        return R.failed("状态值格式错误")
    try:
        instance = Example.objects.filter(id=instance_id, is_delete=False).first()
        if not instance:
            return R.failed("案例不存在")
        instance.status = status
        instance.update_user = get_username(request)
        instance.save()
        return R.ok(msg="状态更新成功")
    except Exception as e:
        logging.error(f"更新案例状态异常,ID: {instance_id}, 错误: {str(e)}")
        return R.failed(msg="状态更新失败,请稍后重试")

4. 视图层 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):
        return services.get_example_page(request)


@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("演示环境,暂无操作权限")
        return services.add_example(request)


@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("演示环境,暂无操作权限")
        return services.update_example(request)


@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("演示环境,暂无操作权限")
        return services.delete_examples(id)

5. 路由配置 application/example/urls.py

python
from django.urls import path
from application.example import views

urlpatterns = [
    path('page', views.ExamplePageView.as_view()),
    path('list', views.ExampleListView.as_view()),
    path('detail/<int:id>', views.ExampleDetailView.as_view()),
    path('add', views.ExampleAddView.as_view()),
    path('update', views.ExampleUpdateView.as_view()),
    path('delete/<str:id>', views.ExampleDeleteView.as_view()),
    path('status', views.ExampleStatusView.as_view()),
    path('list', views.ExampleDataView.as_view()),
]

6. 应用配置 application/example/apps.py

python
from django.apps import AppConfig


class ExampleConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'application.example'

7. 主路由注册(追加到 application/urls.py

python
# 案例模块路由
path('example/', include('application.example.urls')),

8. settings.py 注册应用

INSTALLED_APPS 中添加:

python
INSTALLED_APPS = [
    ...
    'application.example',
]

前端文件清单

9. API 请求 ui/src/api/tool/example.ts

typescript
import { http } from '@/utils/http/axios';

export function getExamplePage(params?) {
  return http.request({ url: '/example/page', method: 'GET', params });
}

export function getExampleList(params?) {
  return http.request({ url: '/example/list', method: 'GET', params });
}

export function getExampleDetail(id) {
  return http.request({ url: '/example/detail/' + id, method: 'get' });
}

export function exampleAdd(data: any) {
  return http.request({ url: '/example/add', method: 'POST', data });
}

export function exampleUpdate(data: any) {
  return http.request({ url: '/example/update', method: 'PUT', data });
}

export function exampleDelete(id) {
  return http.request({ url: '/example/delete/' + id, method: 'DELETE' });
}

10. 页面视图(5 个文件)

文件说明
ui/src/views/tool/example/index.vue主页面:搜索 + 表格 + 操作
ui/src/views/tool/example/edit.vue编辑弹窗:新增/编辑表单
ui/src/views/tool/example/detail.vue详情弹窗:查看记录详情
ui/src/views/tool/example/columns.ts表格列定义
ui/src/views/tool/example/querySchemas.ts搜索表单 Schema

参考 前端页面视图 中的完整代码。

文件总览

后端(application/example/)
├── models.py          # 数据模型
├── forms.py           # 表单验证
├── services.py        # 业务逻辑层
├── views.py           # 视图层
├── urls.py            # 路由配置
├── apps.py            # 应用配置
├── admin.py           # Django Admin 注册
└── migrations/        # 数据库迁移文件

前端(ui/src/)
├── api/tool/
│   └── example.ts     # API 请求封装
└── views/tool/example/
    ├── index.vue      # 主页面
    ├── edit.vue       # 编辑弹窗
    ├── detail.vue     # 详情弹窗
    ├── columns.ts     # 表格列定义
    └── querySchemas.ts # 搜索表单 Schema

注册文件
├── application/urls.py      # 主路由注册
├── application/settings.py  # INSTALLED_APPS 注册
└── 数据库菜单表              # 菜单和权限节点

开发检查清单

完成后端开发后,按顺序检查:

  • [ ] models.py 已定义模型,表名使用 get_table_name() 加前缀
  • [ ] forms.py 已定义表单类,中文错误提示
  • [ ] services.py 已实现所有 CRUD 函数
  • [ ] views.py 已定义视图类 + 权限装饰器 + 操作日志
  • [ ] urls.py 已配置路由
  • [ ] application/urls.py 已注册模块路由
  • [ ] application/settings.py 已注册应用
  • [ ] 菜单管理中已添加权限节点

完成前端开发后,按顺序检查:

  • [ ] api/tool/example.ts 已封装所有接口
  • [ ] views/tool/example/index.vue 主页面已实现
  • [ ] views/tool/example/edit.vue 编辑弹窗已实现
  • [ ] views/tool/example/detail.vue 详情弹窗已实现
  • [ ] views/tool/example/columns.ts 列定义已配置
  • [ ] views/tool/example/querySchemas.ts 搜索 Schema 已配置
  • [ ] 后端菜单已配置组件路径
  • [ ] 页面可正常访问和操作

总结

完整模块涉及后端 6 个文件(models/forms/services/views/urls/apps)+ 路由注册 + 应用注册 + 权限配置,前端 5 个文件(index.vue/edit.vue/detail.vue/columns.ts/querySchemas.ts)+ API 文件。代码生成器可根据数据库表自动生成全套代码。

小蚂蚁云团队 · 提供技术支持