ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python+Django疫情数据可视化毕设:从环境搭建到数据清洗全流程

Python+Django疫情数据可视化毕设:从环境搭建到数据清洗全流程 简介这份资源是面向计算机专业学生与Web开发初学者的毕业设计完整项目包基于Python与Django框架实现疫情数据可视化分析系统帮助读者理解数据采集、处理与前端展示的完整链路。压缩包共745个文件约15.81MB涵盖40个py后端源码、43个vue组件、39个html页面、53个css样式及大量js与svg资源另附sql数据库脚本、bat启动脚本与docx开发说明结构完整便于按模块查阅。已有61人学习下载可作为课程设计或毕设选题的实战参考。读者可获得可运行的完整源码、数据库文件与配置教程并借助开发说明理解系统设计思路与功能实现逻辑同时学习Pandas、NumPy等库在疫情数据处理中的应用以及Django的MVC架构与MySQL后端存储方案适合需要快速上手并二次扩展的开发者。1. 从一份疫情数据看板源码说起这套 Django 毕设到底能跑出什么去年帮两个学弟看毕设一个用 Flask 拼了个只能本地跑的表格页答辩时被问“数据从哪来、怎么更新”直接卡壳另一个拿到的就是这类PythonDjango 疫情数据可视化分析系统同样时间交上去老师追问的是“ECharts 的异步刷新怎么做的、MySQL 索引加在哪”。差距不在代码量在于这套东西把「数据采集 → 入库 → 接口 → 可视化」整条链路都串起来了而不是只画几张静态图。这份资源是一套完整的毕业设计工程包技术栈是 Python Django MySQL 前端可视化库附带完整源码、配置教程和开发说明。它能解决的核心问题是让你在有限时间里拿出一套结构完整、能演示、能讲清楚技术选型的系统而不是从零纠结“用什么框架、表怎么设计”。适合正在做毕设的计算机相关专业学生也适合想拿一个真实 Django 项目练手、熟悉 MTV 模式和前后端数据交互的初学者。下面我按实际拆包和跑通的顺序把关键环节讲透。2. 环境搭建与项目启动从 Python 到 Django 的依赖链怎么配拿到压缩包别急着双击运行这类毕设项目翻车最多的地方就是环境。我一般先把目录结构扫一遍确认manage.py、requirements.txt、settings.py的位置再决定用虚拟环境还是全局装。下面按顺序走。2.1 Python 与 Django 版本对齐先确认本机 Python 版本。Django 对 Python 版本有硬性要求比如 Django 3.2 支持 Python 3.63.10Django 4.x 要求 Python 3.8 以上。项目里requirements.txt通常会写死版本先看它再装别自己拍脑袋装最新版。# 查看本机 Python 版本确认在项目要求范围内 python --version # 如果系统同时有 python2 和 python3用 python3 显式调用 python3 --version # 创建独立虚拟环境避免污染全局包 python -m venv venv # Windows 激活 venv\Scripts\activate # macOS / Linux 激活 source venv/bin/activate # 按项目锁定的版本安装依赖 pip install -r requirements.txt逻辑说明虚拟环境是隔离依赖的标准做法毕设项目依赖往往包含Django、mysqlclient、pandas、requests等全局装容易和别的项目冲突。参数上-m venv是 Python 3 内置模块不需要额外装virtualenv激活后命令行前缀会出现(venv)看到它才说明生效。如果requirements.txt里没写版本常见做法是手动指定一个稳定组合比如Django3.2.18配mysqlclient2.1.1这两个搭配在 Windows 和 Linux 上都比较省心。2.2 MySQL 建库与 Django 数据库配置疫情数据可视化系统一般用 MySQL 存结构化数据比如省份、日期、确诊数、治愈数、死亡数。先建库再改settings.py里的DATABASES。-- 登录 MySQL 后创建数据库字符集用 utf8mb4 支持中文和特殊符号 CREATE DATABASE epidemic_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 建议单独建一个项目用户不要直接用 root CREATE USER epi_userlocalhost IDENTIFIED BY 你的密码; GRANT ALL PRIVILEGES ON epidemic_db.* TO epi_userlocalhost; FLUSH PRIVILEGES;# settings.py 中的数据库配置片段 DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: epidemic_db, USER: epi_user, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: {charset: utf8mb4}, } }逻辑说明ENGINE必须指向 MySQL 后端写错成sqlite3会导致迁移时表建到本地文件里后面换库数据全丢。OPTIONS里的charset不加中文省份名可能变问号。参数HOST用127.0.0.1比localhost更稳避免某些系统下 socket 连接报错。2.3 迁移、建超级用户与启动数据库通了之后执行迁移生成表结构再建后台账号最后runserver看首页。# 生成迁移文件并写入数据库 python manage.py makemigrations python manage.py migrate # 创建后台管理账号按提示输入用户名密码 python manage.py createsuperuser # 启动开发服务器默认 8000 端口 python manage.py runserver逻辑说明makemigrations根据models.py生成迁移脚本migrate才真正执行建表。两步分开是为了让你能检查迁移内容别跳过第一步直接 migrate。createsuperuser建的账号用于登录/admin后台录入或查看数据。启动后浏览器访问http://127.0.0.1:8000/能看到页面说明主链路通了。提示如果migrate报mysqlclient安装失败Windows 上常见原因是缺少编译工具改用pip install pymysql并在__init__.py里加pymysql.install_as_MySQLdb()也能跑但要注意版本兼容。3. 数据模型与可视化接口疫情数据怎么从表走到图表环境跑通只是第一步毕设答辩真正被问的是数据怎么组织、接口怎么给前端。这一章拆models.py的表设计和前后端数据交互。3.1 疫情数据表结构设计这类系统通常至少两张核心表一张存每日各省数据一张存省份基础信息。字段设计直接决定后面查询和可视化的效率。# models.py 中的核心模型示例 from django.db import models class Province(models.Model): name models.CharField(省份, max_length32, uniqueTrue) code models.CharField(行政区划码, max_length12, blankTrue) class Meta: db_table province class EpidemicDaily(models.Model): province models.ForeignKey(Province, on_deletemodels.CASCADE, verbose_name省份) date models.DateField(日期, db_indexTrue) confirmed models.IntegerField(累计确诊, default0) cured models.IntegerField(累计治愈, default0) dead models.IntegerField(累计死亡, default0) new_confirmed models.IntegerField(新增确诊, default0) class Meta: db_table epidemic_daily unique_together (province, date) # 同省同天只允许一条 indexes [models.Index(fields[date, province])]逻辑说明ForeignKey把每日数据和省份关联避免省份名重复存储。db_indexTrue加在date上是因为可视化查询几乎都按时间范围过滤没索引数据量一大就慢。unique_together防止同省同天重复录入这是数据清洗的第一道防线。indexes里的联合索引适合“某天全国”或“某省某段时间”两类查询。参数上max_length按实际字段定省份名 32 够用on_deletemodels.CASCADE表示省份删除时关联数据一起删毕设场景够用生产环境一般用PROTECT。3.2 可视化数据接口的编写前端图表不会直接读数据库而是通过 Django 视图返回 JSON。常见做法是用JsonResponse或 DRF 的APIView。# views.py 中返回某省趋势数据的接口 from django.http import JsonResponse from django.db.models import Sum from .models import EpidemicDaily def province_trend(request): province_id request.GET.get(province_id) if not province_id: return JsonResponse({code: 400, msg: 缺少 province_id}, status400) qs (EpidemicDaily.objects .filter(province_idprovince_id) .order_by(date) .values(date, confirmed, cured, dead)) data { dates: [item[date].strftime(%Y-%m-%d) for item in qs], confirmed: [item[confirmed] for item in qs], cured: [item[cured] for item in qs], dead: [item[dead] for item in qs], } return JsonResponse({code: 200, data: data})逻辑说明values()只取需要的字段减少数据传输量。order_by(date)保证前端折线图时间轴顺序正确漏了这步图表会乱。返回结构拆成dates和三个数值数组正好对应 ECharts 折线图的xAxis.data和series.data。参数province_id从 GET 取前端切换省份时重新请求即可。如果要做全国地图热力图接口返回的应该是[{name: 广东, value: 1234}, ...]这种格式用values(province__name).annotate(totalSum(confirmed))聚合。3.3 前端图表对接与静态资源配置Django 的静态文件配置是新手高频翻车点。STATIC_URL、STATICFILES_DIRS、模板里{% static %}三者要一致。# settings.py 静态文件配置 STATIC_URL /static/ STATICFILES_DIRS [BASE_DIR / static]!-- 模板中引入 ECharts 和自定义脚本 -- script src{% static js/echarts.min.js %}/script script fetch(/api/province_trend/?province_id1) .then(res res.json()) .then(res { if (res.code ! 200) return; const chart echarts.init(document.getElementById(trend)); chart.setOption({ xAxis: { type: category, data: res.data.dates }, yAxis: { type: value }, series: [ { name: 确诊, type: line, data: res.data.confirmed }, { name: 治愈, type: line, data: res.data.cured } ] }); }); /script逻辑说明STATICFILES_DIRS告诉 Django 去哪个目录找静态文件模板里用{% static %}生成正确 URL。fetch拿到 JSON 后先判断code再初始化图表避免数据异常时页面白屏。echarts.init的容器必须有明确宽高否则图表不显示这是最常见的“代码没错但图出不来”的原因。注意开发模式下 Django 会自动服务静态文件但DEBUGFalse后需要配 Nginx 或whitenoise答辩演示用runserver就行别提前折腾部署。4. 避坑与排查跑这套毕设源码最容易卡住的五个地方这套项目我前后帮人跑过几次问题集中在环境和数据上。下面五条按「现象 → 原因 → 解决」写都是真实踩过的。第一条pip install mysqlclient报错提示缺少Microsoft Visual C 14.0。现象是安装中断命令行一堆红色错误。原因是 Windows 上没有 C 编译环境mysqlclient需要编译。解决办法有两个装 Visual Studio Build Tools 勾选 C 组件或者改用pymysql并在项目__init__.py里加两行替换。后者更快但要注意pymysql某些版本对 Django 4.x 支持不完整优先降 Django 版本。第二条migrate成功但页面查不到数据图表空白。现象是后台能看到表前端接口返回空数组。原因是数据库里根本没数据源码包通常只带表结构不带数据。解决办法是写一个数据导入脚本从 CSV 或 JSON 读入或者手动在 admin 后台录几条测试数据。别以为是接口写错了先python manage.py shell里EpidemicDaily.objects.count()看一眼。第三条中文省份名显示成乱码或问号。现象是页面文字正常但数据库里存的是??。原因是建库时没指定utf8mb4或者连接没配charset。解决办法是重建数据库指定字符集并在settings.py的OPTIONS里加charset。已经存了乱码的数据只能清掉重导。第四条runserver启动报Port 8000 is already in use。现象是端口被占。原因是上一次的进程没退干净或者别的服务占了 8000。解决办法是换端口python manage.py runserver 8001或者用netstat -ano | findstr 8000找到进程号再结束。macOS/Linux 用lsof -i:8000。第五条ECharts 图表容器有高度但图不显示。现象是 div 在页面上占位但里面空白。原因是echarts.init执行时容器还没渲染完或者容器宽高为 0。解决办法是把初始化放到DOMContentLoaded之后或者给容器写死height: 400px。用chart.resize()监听窗口变化也能避免缩放后变形。5. 从能跑到能讲数据清洗脚本与答辩演示的加分技巧把系统跑起来只是及格线答辩时老师更想看你对数据的处理能力。这类疫情数据可视化项目原始数据往往来自公开渠道的 CSV字段名不统一、日期格式混乱、有缺失值。我一般会写一个独立的清洗脚本放在scripts/目录下和 Django 解耦用pandas处理完再批量入库。# scripts/import_data.py 数据清洗与批量导入示例 import pandas as pd import os import django os.environ.setdefault(DJANGO_SETTINGS_MODULE, epidemic.settings) django.setup() from app.models import Province, EpidemicDaily def clean_and_import(csv_path): df pd.read_csv(csv_path) # 统一列名兼容不同来源的字段命名 df df.rename(columns{省份: province, 日期: date, 确诊: confirmed, 治愈: cured}) # 日期标准化非法日期置空后丢弃 df[date] pd.to_datetime(df[date], errorscoerce) df df.dropna(subset[date, province]) # 数值列填充 0避免入库报错 for col in [confirmed, cured, dead]: if col in df.columns: df[col] df[col].fillna(0).astype(int) for _, row in df.iterrows(): province, _ Province.objects.get_or_create(namerow[province]) EpidemicDaily.objects.update_or_create( provinceprovince, daterow[date].date(), defaults{confirmed: row[confirmed], cured: row.get(cured, 0), dead: row.get(dead, 0)} ) if __name__ __main__: clean_and_import(data/raw_epidemic.csv)逻辑说明django.setup()让脚本能独立使用 ORM不用启动服务器。rename统一列名是为了兼容不同数据源pd.to_datetime(errorscoerce)把无法解析的日期变成NaT再丢弃避免脏数据入库。update_or_create配合模型的unique_together重复导入不会产生重复记录这是增量更新的关键。参数上fillna(0)处理缺失数值astype(int)保证类型匹配IntegerField。答辩演示时我建议准备两条数据线一条是“全国趋势”展示聚合查询和折线图一条是“单省对比”展示筛选和柱状图。演示前先跑一遍清洗脚本确保数据是最新的。老师如果问“数据量大了怎么办”可以答date字段已加索引联合索引覆盖常见查询进一步可以按时间分区或引入缓存。这种回答比背概念有说服力。从那以后我每次拿到这类毕设源码都强制先跑一遍数据清洗脚本再启动服务因为空库演示和满库演示完全是两个效果。希望这套拆解能帮你少走弯路把时间花在讲清楚技术上而不是和环境较劲。本文还有配套的精品资源点击获取
返回列表