资讯中心

基于Python Django的宠物服务管理系统毕设全攻略

📅 2026/9/27 23:14:29
基于Python Django的宠物服务管理系统毕设全攻略
简介基于Python的宠物服务管理系统是一份面向计算机相关专业毕业设计、课程设计及项目实战练习的完整毕设资料。以Python为主要开发语言搭配Vue前端与JavaScript交互覆盖宠物服务业务的后台管理、信息展示与数据维护等典型模块适合希望从零完成可演示系统并对接论文撰写的学生使用。压缩包共636个文件包括142个vue页面组件、60个py源码文件、58个js交互脚本、15个css样式以及sql数据库脚本、docx设计文档、png/jpg界面截图和项目图标等整体约28.66MB目录结构清晰便于按代码、文档和脚本分类查阅。已有218人学习下载。项目为经导师指导并通过评审的毕业设计附完整部署教程、设计论文、安装/运行/初始化数据库等批处理脚本源码经过本地编译调试可运行。下载后可快速搭建环境结合文档理解模块划分与实现思路也可作为二次开发或论文参考底稿。1. 宠物服务管理系统为什么它是Python毕设里最稳的选择每年到了毕设开题季总有人跑来问我有没有“能直接过答辩”的Web系统选题。基于Python的宠物服务管理系统是我这些年带过的方向里最稳的选择之一用户、宠物、服务、订单四个核心对象把数据库设计、权限控制、状态流转这些常考点全占住了。源码配合教程和论文目标不是让你躺平而是用最短时间跑通系统、立起论文结构答辩时被追问也有东西讲。这篇笔记面向两类人手上已经有类似毕设包但不知道怎么消化的人以及还在开题、想评估这个方向值不值得投入的人。后面按选型、建库、写代码、写论文、避坑、加分项的顺序走每一步都给能直接落地的判断。2. 技术选型与库表设计Django还是Flask表怎么画才经得起答辩这个系统业务不算难难的是答辩时能不能把“为什么这么选”讲清楚。技术选型这一步选对了能省下一周时间选错了后面每一步都在还债。2.1 框架选择Django为什么比Flask更适合做成毕设项目Flask胜在灵活一个文件就能启动服务看起来比Django轻很多。但宠物服务管理系统至少要包含用户登录、宠物档案、预约订单、后台管理这几块拿Flask做的话你得自己接Flask-SQLAlchemy做ORM接Flask-Login管登录状态接Flask-WTF做表单校验还要想数据库迁移方案。这些插件拼在一起写出来确实很酷但每多一个依赖就多一批潜在的版本冲突和兼容性问题。Django恰好把这一整套都内置了ORM直接操作数据库User模型搞定认证模板引擎渲染页面自带Admin后台可以维护数据。论文里写“基于Django框架的MVC开发模式”评审挑不出硬毛病答辩时被问到“认证怎么做的”你直接回答用的是Django内置User模型和login_required装饰器干净利落。对比项DjangoFlask数据库操作内置ORM字段改动靠makemigrations记录需额外集成Flask-SQLAlchemy用户认证自带User模型与装饰器需额外集成Flask-Login表单处理内置forms组件做校验和渲染需额外集成Flask-WTFAdmin后台自带注册模型即用需额外集成Flask-Admin毕设参考生态教程多、报错案例多资料相对少所以我的建议很直接这个项目用Django。另一个现实原因是网上可参考的Python毕设代码和教程绝大多数是Django写的你中途报错搜一句话五分钟就能找到类似场景Flask版本相对少踩坑后只能硬啃官方文档。选生态更厚的那一个本身就是一种风险管理。版本上我习惯固定Django 4.2 LTS不追最新大版本理由会在避坑章节细说。2.2 环境搭建与项目初始化从Python安装到Django项目跑起来环境搭建这一步拦住了不少人而且越着急越装不上。我的建议是先把Python版本锁在3.8到3.10之间。虽然官网已经能下载更新的版本但一些提供底层能力的第三方库在Windows下的预编译包更新没那么快用最新解释器常常触发源码编译然后被缺少C构建工具的提示卡住。锁版本后创建虚拟环境再装依赖项目依赖和系统环境彻底隔离。# 建议固定在 Python 3.83.10太新的版本常要现场编译三方库 python -m venv venv # Windows 下激活虚拟环境 venv\Scripts\activate # macOS / Linux 下激活虚拟环境 source venv/bin/activate # 安装核心依赖Django 用 4.2 LTS别追最新 pip install Django4.2,4.3 mysqlclient python-dotenv # 在当前目录生成项目这个“.”别漏掉 django-admin startproject pet_service . # 按业务拆成三个子应用账号、宠物、订单 python manage.py startapp accounts python manage.py startapp pets python manage.py startapp orders # 第一次迁移确认数据库配置无误 python manage.py migrate python manage.py runserver逐条解释下关键参数。python -m venv venv会在当前目录创建venv文件夹之后激活和运行命令都用它Windows激活命令运行venv\Scripts\activatemacOS和Linux则执行source venv/bin/activate两者路径不同混用就会报找不到命令。django-admin startproject pet_service .后面那个点代表“以当前目录为项目根目录”这样manage.py直接就在顶层配置路径和静态文件都会少绕一层。依赖里最值得注意的就是mysqlclient。这个包在macOS和Linux上一般能装上Windows偶尔会报“需要Visual C 14.0”意思是你得装几百MB的编译工具。常见做法是改用pymysql并在项目的settings.py文件里写入import pymysql; pymysql.install_as_MySQLdb()让Django连接MySQL时走PyMySQL驱动。性能上略逊但毕设量级完全无所谓。提示运行runserver之前先确认MySQL服务已启动且settings.py里写的库名真实存在。很多第一次跑的人把库名写错报的却是连接失败排半天才发现是手滑。2.3 数据库表设计四张核心表与模型字段细节进入库表设计之前多说一句表结构是论文里数据库设计章节的灵魂宁可多花半小时画清楚也不要等代码都写完了再补。整个系统的核心对象就四个用户、宠物档案、服务项目、预约订单。用户直接用Django内置的auth_user表不要自己建用户表能避开大量安全编码工作。数据表关键字段说明auth_userDjango内置存储登录账号密码自动加密pets_petprofileuser_id、name、breed、age、avatar宠物档案一对多关联用户orders_serviceitemname、price、duration服务项目如洗护、寄养、疫苗orders_orderuser_id、pet_id、service_id、status、appointment_time预约订单核心业务表订单表里的status字段最值得设计。我不建议用字符串存“待确认”“已完成”中文放在数据库里既占空间一旦状态口径需要调整历史数据也跟着遭殃。用整型枚举更稳模型里定义可读映射页面展示时再翻译。下面是精简后的模型定义# orders/models.py from django.db import models from django.contrib.auth.models import User class ServiceItem(models.Model): name models.CharField(max_length50, verbose_name服务名称) price models.DecimalField(max_digits8, decimal_places2, verbose_name价格) duration models.IntegerField(help_text服务时长单位分钟) def __str__(self): return self.name class Order(models.Model): STATUS_CHOICES ( (0, 待确认), (1, 已确认), (2, 服务中), (3, 已完成), (4, 已取消), ) user models.ForeignKey(User, on_deletemodels.CASCADE, verbose_name主人) pet models.ForeignKey(pets.PetProfile, on_deletemodels.CASCADE, verbose_name宠物) service models.ForeignKey(ServiceItem, on_deletemodels.CASCADE, verbose_name服务项目) status models.SmallIntegerField(choicesSTATUS_CHOICES, default0, verbose_name状态) appointment_time models.DateTimeField(verbose_name预约时间) remark models.TextField(blankTrue, verbose_name备注) created_at models.DateTimeField(auto_now_addTrue, verbose_name创建时间)几个字段参数说细一点。on_deletemodels.CASCADE表示用户、宠物或服务项目被删掉后关联订单也一起删毕设系统这样处理逻辑简单如果论文里想体现“保留历史数据”可以改成SET_NULL但对应外键字段必须有nullTrue。choices把status的取值范围限制在提前定义好的元组里但它只是Django层面的约束数据库底层存的仍然是小整数。auto_now_add只在记录创建时写入时间后续更新不会改它适合订单生成时间这类字段。模型写完之后我建议顺手注册管理后台。这对中期演示和论文截图非常省事不需要额外写管理页面就能看到所有数据还能在Admin里直接修改订单状态。# orders/admin.py from django.contrib import admin from .models import Order admin.register(Order) class OrderAdmin(admin.ModelAdmin): list_display (id, user, pet, service, status, appointment_time) list_filter (status, service) search_fields (user__username, pet__name)list_display决定后台列表展示哪些列list_filter为列表右侧增加筛选器search_fields支持按关联字段搜索。注意user__username是Django的跨表查询写法表示沿着user外键取auth_user表里的username字段。这行设计好后面测试和答辩演示都能省不少事。3. 核心功能落地用户、宠物档案、预约订单三块代码一次跑通技术选型和表结构只是地基。如果拿到的源码包里有现成项目你首先要做的不是花时间通读每一行而是顺着用户、宠物、订单这三条主线把核心流程捋一遍确认每条链路都通才能放心地去改、去加功能。3.1 用户注册与登录别自己存明文密码有些教程会把用户表设计成自定义表注册视图里直接用User.objects.create(username..., password...)。这里藏着一个大坑create不会调用密码加密逻辑密码会以明文落库。正确做法是使用create_user方法或者先拿到实例再调用set_password。Django的User模型自带这套机制你要做的是别绕过它。# accounts/views.py from django.contrib.auth import login, authenticate from django.contrib.auth.models import User from django.shortcuts import render, redirect def register(request): if request.method POST: username request.POST.get(username) password request.POST.get(password) password2 request.POST.get(password2) if password ! password2: return render(request, accounts/register.html, {error: 两次密码输入不一致}) if User.objects.filter(usernameusername).exists(): return render(request, accounts/register.html, {error: 用户名已存在}) # create_user 会自动加密密码create 不会 user User.objects.create_user(usernameusername, passwordpassword) login(request, user) return redirect(pets:list) return render(request, accounts/register.html) def login_view(request): if request.method POST: username request.POST.get(username) password request.POST.get(password) user authenticate(request, usernameusername, passwordpassword) if user is not None: login(request, user) return redirect(pets:list) return render(request, accounts/login.html, {error: 用户名或密码错误}) return render(request, accounts/login.html)逻辑说明注册先做两次密码一致性和用户名唯一性校验前两条是页面交互的必要检查省掉的话要么体验差要么数据库报唯一约束错误。create_user是这一步的关键它内部走set_password把明文密码用PBKDF2算法哈希后入库。登录时authenticate负责核对密码核验成功返回User对象再交给login把会话写进session。参数说明redirect(pets:list)是反向解析只要在pets/urls.py给列表页设置namelist这里写路由名即可。别把路径写死成/pets/list/后面调整路由时容易断开。request.POST.get返回的全是字符串空值需要单独判断这里为简洁只在视图做了查询校验模板里给input加required属性更稳。除了注册和登录所有需要登录的操作都要加装饰器。Django内置的login_required判断用户是否登录未登录会跳转到settings.py里配置的LOGIN_URL一般指向登录页路由名。用在被保护视图头部from django.contrib.auth.decorators import login_required login_required def dashboard(request): return render(request, accounts/dashboard.html, {pets: request.user.petprofile_set.all()})这里request.user.petprofile_set.all()是反向查询。外键定义在PetProfile里指向User后Django会给User自动加上petprofile_set属性取出当前用户的所有宠物档案。这一句话正好对上了论文里“一对多关联查询”的写法答辩时可以作为ORM实际例子。3.2 宠物档案ModelForm与图片上传的边界宠物档案页维护的是PetProfile表通常包含一个头像图片字段。我习惯用ModelForm它把模型字段校验和表单渲染合并在一起模板里写{{ form.as_p }}就能渲染一整组带标签的输入控件省去手写大量HTML。# pets/forms.py from django import forms from .models import PetProfile class PetProfileForm(forms.ModelForm): class Meta: model PetProfile fields [name, breed, age, avatar] # pets/views.py from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from .forms import PetProfileForm login_required def pet_create(request): if request.method POST: form PetProfileForm(request.POST, request.FILES) if form.is_valid(): pet form.save(commitFalse) pet.user request.user pet.save() return redirect(pets:list) else: form PetProfileForm() return render(request, pets/pet_form.html, {form: form})这里最容易被忽略的是request.FILES。模板表单里一旦出现input typefile视图必须把上传文件对象单独传给表单否则form.is_valid()永远是False还很难找到原因。form.save(commitFalse)的意思是先构造模型实例但先不落库留出窗口把user字段填成当前登录用户再真正保存。不给用户传user值的机会是为了防止越权不然别人可以把宠物挂到其他账号下面。图片上传还需要在settings.py里配置存储位置# settings.py MEDIA_URL /media/ MEDIA_ROOT BASE_DIR / mediaMEDIA_ROOT是文件实际写入磁盘的目录MEDIA_URL是浏览器访问这些文件时的URL前缀。开发阶段调试模式还要在顶层urls.py挂载media目录否则图片会404这段我在避坑章节会再讲一次因为它是翻车重灾区。ModelForm会自动处理非图片文件。只要avatar字段类型是ImageField上传一个.txt文件会被校验器直接拒绝。别忘了模板的form标签设置enctypemultipart/form-data文件上传表单少了这个属性浏览器不会把文件内容发给服务端。3.3 预约下单状态流转是系统的命脉订单是连接用户和服务的核心业务。预约创建之后状态变化需要被约束。我见过最头大的翻车写法是管理后台直接把状态改到任意值从“待确认”直接跳到“已完成”整个订单生命周期失去可信度。下面给一个简单的状态机判断# orders/views.py from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect, get_object_or_404 from django.utils import timezone from django.utils.dateparse import parse_datetime from .models import Order, ServiceItem from pets.models import PetProfile # 状态迁移表0待确认 - 1已确认/4已取消1已确认 - 2服务中2服务中 - 3已完成 ALLOWED_TRANSITIONS {0: [1, 4], 1: [2], 2: [3]} login_required def order_create(request): if request.method POST: pet get_object_or_404(PetProfile, idrequest.POST.get(pet_id), userrequest.user) service get_object_or_404(ServiceItem, idrequest.POST.get(service_id)) dt parse_datetime(request.POST.get(appointment_time)) if dt is None or dt timezone.now(): return render(request, orders/order_form.html, {error: 预约时间必须晚于当前时间}) order Order.objects.create( userrequest.user, petpet, serviceservice, status0, appointment_timedt, remarkrequest.POST.get(remark, ), ) return redirect(orders:detail, order_idorder.id) return render(request, orders/order_form.html) login_required def order_update_status(request, order_id): order get_object_or_404(Order, idorder_id, userrequest.user) new_status int(request.POST.get(status)) if new_status not in ALLOWED_TRANSITIONS.get(order.status, []): return render(request, orders/order_detail.html, {order: order, error: 非法状态流转}) order.status new_status order.save() return redirect(orders:detail, order_idorder.id)代码里有几个值得细说的地方。get_object_or_404在对象不存在时返回404但这里真正的关键是userrequest.user这个过滤条件即使别人拿到订单id也查不到数据这是粗粒度的越权防护。parse_datetime把表单提交的字符串转成datetime对象解析失败返回None所以要先判空再和时间比较。预约时间用dt timezone.now()拒绝过去时间等于号也判非法因为预约至少要留出一点准备间隙。状态流转规则集中在ALLOWED_TRANSITIONS里每个状态对应它允许跳转的目标状态集。比如0 - 1是商家确认1 - 2是开始服务2 - 3是完成。这样做的优势是调度逻辑一目了然论文里放这张表也很好看。如果你想让用户取消把4加到0状态的可达列表里即可。数据库层的约束是后话毕设做到视图层已经够用。代码里的redirect(orders:detail, order_idorder.id)对应URL配置# orders/urls.py from django.urls import path from . import views urlpatterns [ path(create/, views.order_create, namecreate), path(int:order_id/update-status/, views.order_update_status, nameupdate_status), path(int:order_id/, views.order_detail, namedetail), ]int:order_id是Django的路径转换器它先从URL里解析出整数再作为关键字参数传给视图。三个路由共用同一个order_id变量名是因为视图函数形参必须和URL转换器里的名字对齐。4. 论文写作与答辩配套需求分析到系统测试的完整骨架系统代码能跑只是毕设的一半另一半是论文。很多学生代码写得不错但论文被退回是因为结构散、测试章节凑字数。这里给你一套可以直接套用的章节骨架和写作要点让它和源码对应起来。4.1 论文大纲从绪论到总结的七章结构论文章节写作要点第1章 绪论背景意义、国内外现状、论文组织结构第2章 相关技术Python、Django、MySQL、前后端交互第3章 需求分析功能性需求、非功能性需求、用例图第4章 系统设计总体架构、功能模块设计、数据库ER图与表结构第5章 系统实现三个核心模块的实现过程、核心代码、界面截图第6章 系统测试测试环境、测试用例表、测试结果与问题第7章 总结与展望完成的工作、不足、后续改进方向写作时要把源码对应进去。第3章需求分析里提到的每一个功能点在第5章实现里都必须有对应代码和界面这是评委老师最容易检查的逻辑闭环。第2章相关技术不要写成一堆概念堆砌要落到“本系统用了Django的哪个组件、解决了什么问题”上。比如ORM对应数据库操作User认证对应登录模块。4.2 三张图撑起核心观点用例图、ER图、时序图论文里最值得花时间画的图是三张用例图、ER图、时序图。它们分别解决“系统有哪些角色和功能”“数据之间什么关系”“一次完整业务怎么走”三个问题。用例图重点是两个角色宠物主人和店家管理员。主人能注册登录、维护宠物档案、查看服务项目、创建预约、取消预约管理员能确认订单、开始服务、完成订单、管理服务项目。两张用例图放在需求分析章节能明显提升专业感。ER图描述四个核心实体的关系。这里的要点是把外键关联画清楚宠物主人与宠物是一对多宠物主人与订单是一对多服务项目与订单也是一对多。用draw.io或者ProcessOn都行画完导出图片插入论文即可。时序图的建议画一个完整的预约下单流程。从主人在前端提交表单开始到视图层接收参数、校验时间、创建订单、跳转详情页结束。一个泳道图把请求流向写清楚答辩时直接对着它讲能省去大量口头发散。4.3 测试部分测试用例表与报告写法很多论文的测试章节只是放几张运行截图这是容易被扣分的地方。正规写法是给出测试用例表每条用例对应模块、操作步骤、预期结果、实际结果。下面这张表可以直接扩展使用用例编号模块测试操作预期结果实测结果TC-01注册新用户名两次相同密码注册成功并自动登录通过TC-02注册两次密码不一致提示密码不一致通过TC-03宠物档案上传非图片文件表单拒绝提交并提示格式错误通过TC-04预约下单选择过去时间提示 “预约时间必须晚于当前时间”通过TC-05订单状态待确认直接改为已完成提示“非法状态流转”通过TC-06越权访问用A账号访问B账号订单id返回404订单不展示通过“实际结果”栏一定用“通过/不通过”不要写“正常”。遇到不通过的用例要在测试结果分析里说明原因和修改方案这部分能体现你真正做过调试。性价比很高的做法把避坑章节那5个问题挑两个写进“开发过程中遇到的问题”小节比空谈体会真实得多。5. 复现避坑指南环境、数据库、依赖和部署的5个翻车点下面这5条是我和学生在这个项目方向上反复踩过的雷按“现象、原因、解决”写清楚。每条都能让你在复现时少走几小时弯路。5.1 Python版本太新装不上依赖现象按照教程激活虚拟环境并安装依赖运行python manage.py runserver时报ModuleNotFoundError: No module named django或者装Django本身没问题但装mysqlclient时报“需要Visual C 14.0”。原因Python 3.11以后的版本很多带C扩展的三方库在Windows下没有现成的预编译包pip会尝试拉源码本地编译环境里又缺编译工具链直接失败。还有情况是虚拟环境没有真正激活当前终端用的还是全局Python装的东西落到了venv里但命令行没有引用它。解决把Python版本固定在3.8到3.10之间重装虚拟环境。激活后先检查命令行前面有没有(venv)标记macOS/Linux下执行which python确认路径在venv/bin目录。如果只是Django装不上先执行python -m pip install --upgrade pip再重试很多“幽灵问题”是pip版本太旧导致的。5.2 MySQL8认证插件导致连接失败现象settings.py配置没问题MySQL服务也在运行但一启动项目访问数据库就报Authentication plugin caching_sha2_password cannot be loaded。原因MySQL 8默认的认证插件换成了caching_sha2_password而Django驱动mysqlclient的旧版本只认老的mysql_native_password。两边版本不对付不是密码错了也不是库名错了。解决推荐换用pymysql在settings.py顶部加import pymysql; pymysql.install_as_MySQLdb()。如果想保留mysqlclient可以在MySQL里创建一个使用旧认证插件的专用账号CREATE USER pet_userlocalhost IDENTIFIED WITH mysql_native_password BY your_password; GRANT ALL PRIVILEGES ON pet_service.* TO pet_userlocalhost; FLUSH PRIVILEGES;用这个账号连接Django就不会再报认证插件错误。注意把settings.py里的数据库用户名改成pet_user。5.3 图片上传成功但访问返回404现象宠物头像在表单里能上传后台也显示文件已保存到media目录但浏览器访问图片地址始终404或者Admin后台样式全部丢失。原因项目settings.py里配置了MEDIA_URL和MEDIA_ROOT但Django开发服务器默认只自动服务static目录不会自动服务media目录。图片文件确实写到了磁盘上只是URL到文件系统之间缺了一条路由。解决在项目的顶层urls.py里加上一行挂载配置# pet_service/urls.py from django.conf import settings from django.conf.urls.static import static urlpatterns [ # ... 已有路由 ] if settings.DEBUG: urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)document_root指向的就是settings里的MEDIA_ROOT。这样访问/media/xxx.jpg时Django会从磁盘读取对应文件。上线部署时这一步可以让Nginx处理但在毕设演示阶段这段配置是必须的。5.4 中文乱码和预约时间差8小时现象在页面填写中文后存入数据库显示为乱码预约时间在后台看是正常的页面展示时却比实际时间早了8小时。原因数据库表用的默认字符集不是utf8mb4Django往表里写中文时连接字符集对不上时间则是时区问题settings.py里USE_TZTrue时Django把所有时间按UTC存储模板直接输出会少8小时。解决建库时指定字符集命令是CREATE DATABASE pet_service CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。在settings.py里把语言和时区改成中文LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai USE_TZ True模板渲染时间字段时用{{ order.appointment_time|localtime }}过滤器把存储的UTC时间转成北京时间。已经写入的乱码数据清理后按新字符集重建表再重新录入。5.5 中途自定义用户模型导致迁移冲突现象一开始用Django默认用户表代码写了一部分后又想给用户增加手机号字段于是继承AbstractUser重写用户模型执行makemigrations和migrate时报出一堆依赖错误。原因Django的自定义用户模型必须在第一次migrate之前指定中途更换会让迁移链路的依赖关系完全错位旧迁移引用的是旧模型新模型又改掉了表结构。解决如果是半路想加上扩展字段最省心的方法是用单独的资料表关联默认用户表不建议动auth_user本身。如果非要自定义用户模型方法是在settings.py里加AUTH_USER_MODEL accounts.User在accounts/models.py继承AbstractUser然后从零开始删除原数据库并重新执行makemigrations和migrate。对毕设来说默认User表够用不必折腾自定义。6. 进阶给宠物服务管理系统加上预约提醒答辩演示更有说服力基础功能跑通之后想提升系统完成度最划算的加分项是加一个预约提醒。它能说明你考虑了真实业务场景而且实现成本不高。我习惯用APScheduler这个轻量调度库不需要额外部署Redis也不需要配置消息队列。# reminders.py from apscheduler.schedulers.background import BackgroundScheduler def send_reminder(): from django.utils import timezone from orders.models import Order now timezone.now() upcoming Order.objects.filter( status1, appointment_time__ltenow timezone.timedelta(hours2), appointment_time__gtnow, ) for order in upcoming: # 真实项目可换成短信或公众号模板消息 print(f提醒{order.user} 的宠物“{order.pet}”将在 {order.appointment_time} 开始服务) scheduler BackgroundScheduler() scheduler.add_job(send_reminder, interval, minutes30)scheduler.add_job的参数里interval表示按固定间隔执行minutes30是每30分钟扫一遍未来两小时内的已确认订单。实际部署时可以把print替换成调用短信服务或公众号模板消息的接口业务逻辑不变。启动调度器要注意Django的runserver会带自动重载进程代码在apps.py的ready方法里启动时会跑两份解决方案是加一个RUN_MAIN判断import os from django.apps import AppConfig class OrdersConfig(AppConfig): default_auto_field django.db.models.BigAutoField name orders def ready(self): if os.environ.get(RUN_MAIN) true: from reminders import scheduler scheduler.start()手动验证时往orders_order表里插一条状态为1、预约时间在当前时间后1小时内的订单等待调度器触发日志里出现提醒文本即通过。再加两个污点用例状态为0的订单不提醒预约时间在2小时外的订单不提醒。这三个用例写进论文测试章节会把“调度模块测试”这个小节填得比较完整。这个提醒是我带这个毕设方向时最常建议加的改动代码量不大但演示时能直观看到订单状态与时间的联动导师问起来你能绕回状态机和真实业务场景。希望这个项目的选型思路、核心代码和这些调试记录能帮到你把毕设从“能跑”做到“能讲清楚”。本文还有配套的精品资源点击获取

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案