简介:面向棉花种植、收购、加工等环节的数据管理需求,提供完整的Django Web应用源码,支持多维度数据录入、查询、统计与可视化展示。系统后端基于Python 3.x + Django 3.x开发,集成PyMySQL连接MySQL,内置cotton.sql数据库脚本,可一键导入使用;前端采用HTML+Bootstrap构建响应式界面,包含Django Admin后台与自定义数据看板,利用Matplotlib生成产量趋势、区域分布、收购量对比等图表。压缩包内含完整项目目录(含‘程序’‘数据库’‘文档.zip’等子目录)、数据库结构说明、详细部署指南、依赖清单(requirements.txt)及运行步骤(含migrate和runserver指令)。本地运行只需安装Python环境、执行pip install -r requirements.txt、导入SQL、运行迁移命令即可启动服务。适用于农业信息化教学实践、高校课程设计、毕业设计项目或中小型棉企初期数字化试点。
1. 项目概述:为什么一个棉花数据系统值得花三天时间搭起来?
我第一次在新疆阿克苏某合作社看到他们用Excel表格管理23个村、478户棉农的种植面积、品种、灌溉记录和籽棉交售数据时,手里的热茶凉了都没察觉。一张表里混着“新陆早65号”“新陆早65”“65号棉种”,另一张表里“收购日期”列写着“9月上旬”“9.12”“2023-09-12”,而财务核对时发现,同一地块在三个表里登记的亩产分别是380公斤、412公斤、395公斤——不是数据造假,是人眼识别+手工录入+跨表复制导致的系统性漂移。这让我下定决心,把这套Django棉花数据系统从课程设计作业,打磨成真正能插进田埂、蹲进轧花厂的轻量级农业数据底盘。
它不是那种动辄几十万行代码、要配专职运维的“智慧农业云平台”,而是一个可离线部署、单机运行、30分钟内完成初始化、所有操作都在浏览器里完成的闭环工具。核心就干三件事:把散落在纸本、微信截图、Excel表格里的棉花业务数据,收拢到一个结构化数据库里;让农技员、收购站会计、合作社管理员不用学SQL,点几下就能查清“今年沙雅县古勒巴格镇的长绒棉收购均价比去年涨了多少”;最后用图表把数字变成肉眼可见的趋势——比如一张柱状图横轴是“4月—10月”,纵轴是“日均交售量”,峰值出现在9月22日前后,那基本就是当地统一采收启动日,这个信号比任何报表都直观。
关键词里“Django”不是为了堆技术名词,而是因为它天然适合这种场景:Python生态对农业领域常用的数据处理(pandas清洗)、绘图(matplotlib/seaborn)、地理信息(geopandas轻量集成)支持成熟;Django Admin后台开箱即用,给不熟悉编程的基层人员留出一条管理入口;而“MySQL可视化”中的“可视化”,我们刻意避开了ECharts或D3这类需要前端深度定制的方案,选择Matplotlib生成静态PNG图表嵌入HTML页面——理由很实在:一台配置普通的旧笔记本(i5-4200U + 4GB内存)跑起来毫无压力,且生成的图片可直接打印张贴在收购站墙上,不需要联网加载JS资源。至于“农业数据平台”,这个词听起来宏大,但落到这套系统里,就是解决“谁在什么时间、什么地点、种了多少、收了多少、卖给了谁、价格多少”这六个最朴素的问题。
如果你正带着学生做农业信息化课程设计,这套系统能让你避开90%的环境踩坑——requirements.txt里只锁定了django==3.2.23(LTS长期支持版)、pymysql==1.1.0、matplotlib==3.7.2,连Pillow版本都精确到3.7.2,因为高版本在CentOS 7上编译会报错;如果你是毕业设计选题卡在“找不到真实业务场景”,文档.zip里那份《棉花产业关键业务字段定义表》直接告诉你,“加工企业名称”字段必须支持200字符(有企业全称带“有限公司”“(集团)”“分公司”等后缀),“籽棉含杂率”必须是0~15之间的浮点数,误差超过0.5%需标红预警;如果你是小型棉企想试水数字化,压缩包里的cotton.sql不是空壳数据库,而是预置了新疆、山东、河北三省典型棉区的模拟数据(含12个县域、86家轧花厂、2147户棉农),导入后打开localhost:8000/admin就能看到真实字段关系,而不是对着ER图猜半天。
说白了,这不是一个炫技项目,而是一套“能用、够用、好维护”的农业数据基础设施毛坯房。接下来我会带你一层层拆开它的砖瓦:为什么选Django而不是Flask?MySQL表结构怎么设计才能兼容“一地多种”“一户多块”这些农业特有逻辑?Matplotlib图表如何避免中文乱码又保持打印清晰度?以及那些只有亲手部署过三次以上才会写的细节——比如为什么迁移命令要分两步执行,为什么Apache部署时WSGIScriptAlias路径末尾不能加斜杠。
2. 系统架构与设计思路:农业数据的特殊性决定了技术选型
2.1 为什么放弃Flask/Starlette,坚持用Django 3.x?
很多初学者看到“Web框架”第一反应是Flask,轻量、灵活、学习曲线平缓。但在农业数据场景下,这种“灵活”反而成了负担。我拿一个真实需求对比:合作社要求“农技员在手机端查看自己负责片区所有棉田的灌溉记录,并能按‘最近7天’‘本月’‘本季’筛选”。用Flask实现,你需要:
- 自己写路由(
@app.route('/irrigation/<int:tech_id>')) - 手动处理GET参数(
request.args.get('period')) - 写SQL查询(
SELECT * FROM irrigation WHERE tech_id=%s AND date >= %s) - 处理日期计算(
datetime.now() - timedelta(days=7)) - 构造分页(
LIMIT 20 OFFSET 0) - 渲染模板(
render_template('list.html', data=results))
而Django的解决方案是:在models.py里定义IrrigationRecord模型,包含tech = models.ForeignKey(TechOfficer, on_delete=models.CASCADE)和date = models.DateField()字段;在views.py里继承ListView,重写get_queryset()方法,用filter()链式调用;URL配置一行path('irrigation/<int:pk>/', IrrigationListView.as_view(), name='irrigation_list');模板里用{% for record in object_list %}循环。整个过程没有SQL,没有手动拼接,没有日期格式转换烦恼。
更关键的是Django Admin。农业系统的使用者往往是50岁左右的收购站会计,他们可能连微信支付都要子女教三次。Django Admin提供了一个无需培训的图形界面:点击“添加新收购记录”,弹出表单,字段名是中文(产地、交售日期、毛重(公斤)、皮重(公斤)),下拉框自动关联已录入的乡镇列表,日期控件带日历图标,保存后立即显示成功提示。而Flask若要实现同等体验,至少要额外引入Flask-Admin或自研后台,开发量翻倍且稳定性难保障。
至于Starlette/FastAPI,它们在异步IO和API性能上有优势,但农业数据场景几乎不存在高并发请求——一个县的轧花厂日均录入量不超过200条,峰值QPS不到1。为0.01秒的响应提升,增加异步数据库驱动配置、Pydantic模型验证、CORS中间件调试等复杂度,纯属杀鸡用牛刀。Django 3.2.23的同步ORM在单机MySQL环境下,查询10万条记录的统计聚合耗时稳定在300ms内,完全满足业务需求。
提示:Django版本锁定在3.2.23而非4.x,是因为Django 4.x默认启用UTF8MB4字符集,而许多老旧的MySQL服务器(尤其是企业内网部署的5.7版本)未开启
innodb_large_prefix,会导致迁移时报错Specified key was too long。3.2.23兼容性更好,且官方支持到2024年4月,足够覆盖毕业设计周期。
2.2 MySQL数据库设计:如何应对农业数据的“非标”特性?
农业数据最大的特点是“非标”——没有统一国标,各地习惯差异巨大。比如“棉花品种”,新疆叫“新陆早65号”,山东叫“鲁棉研37号”,河北叫“冀棉22号”,而收购站台账里可能简写为“65号”“37号”。如果按常规设计,建一个variety_name VARCHAR(50)字段,很快就会出现数据混乱。我们的解决方案是建立三层品种编码体系:
-- 品种主表(标准化编码)
CREATE TABLE cotton_variety (
id INT PRIMARY KEY AUTO_INCREMENT,
code VARCHAR(20) NOT NULL UNIQUE COMMENT '国标编码,如XLA65',
full_name VARCHAR(100) NOT NULL COMMENT '全称,如新陆早65号',
region VARCHAR(20) NOT NULL COMMENT '适种区域,新疆/山东/河北',
fiber_length_mm DECIMAL(4,2) COMMENT '纤维长度,单位mm',
strength_cN_tex DECIMAL(4,2) COMMENT '断裂强度,单位cN/tex'
);
-- 实际业务表中引用
CREATE TABLE cotton_production (
id INT PRIMARY KEY AUTO_INCREMENT,
variety_id INT NOT NULL,
FOREIGN KEY (variety_id) REFERENCES cotton_variety(id),
planting_area_mu DECIMAL(8,2) COMMENT '种植面积(亩)',
...
);
这样,录入时下拉选择“新陆早65号”,数据库只存variety_id=127,既保证数据一致性,又通过full_name字段保留业务可读性。同理,“收购价格”字段设计为price_cny_per_kg DECIMAL(6,2)而非VARCHAR,避免出现“5.2元/公斤”“5.20”“¥5.2”等混乱格式。
另一个痛点是“地块描述”。农户常描述为“村东头老李家地”“河坝南岸第三块”,无法用经纬度精确定位。我们采用“行政区划编码+地块序号”组合:
-- 行政区划表(国家统计局2023年最新编码)
CREATE TABLE area_code (
code CHAR(12) PRIMARY KEY COMMENT '12位国标码,如652922001001',
name VARCHAR(50) NOT NULL COMMENT '名称,如沙雅县古勒巴格镇喀什博斯坦村',
level TINYINT NOT NULL COMMENT '层级,1省2市3县4镇5村'
);
-- 地块表
CREATE TABLE cotton_field (
id INT PRIMARY KEY AUTO_INCREMENT,
area_code CHAR(12) NOT NULL,
field_no VARCHAR(20) NOT NULL COMMENT '地块编号,如G001、H002',
description TEXT COMMENT '文字描述,如村东头老李家地',
FOREIGN KEY (area_code) REFERENCES area_code(code)
);
这样,查询“沙雅县所有地块”只需JOIN area_code ON field.area_code = area_code.code WHERE area_code.code LIKE '652922%',比全文检索快10倍以上。而description字段保留原始描述,供人工核对。
注意:cotton.sql文件中已预置全国31个省级行政区划编码及新疆、山东、河北三省完整县级以下编码,导入后即可使用。不要手动修改
area_code表,否则会导致图表统计地域维度失效。
2.3 可视化方案取舍:为什么用Matplotlib而非ECharts?
前端可视化方案有两条路:一是用JavaScript库(ECharts/D3)在浏览器端渲染,二是用Python库(Matplotlib/Seaborn)在服务端生成图片再嵌入HTML。我们坚定选择后者,原因有三:
第一,部署极简性。 ECharts需要在HTML中引入echarts.min.js,并编写大量JS初始化代码。而Matplotlib只需在views.py中几行Python:
import matplotlib
matplotlib.use('Agg') # 非GUI后端,避免部署时报错
import matplotlib.pyplot as plt
def generate_yield_chart(request):
# 查询数据...
plt.figure(figsize=(10, 6))
plt.bar(months, yields)
plt.title('各月籽棉产量(吨)')
plt.xlabel('月份')
plt.ylabel('产量(吨)')
plt.tight_layout()
# 保存为PNG
buffer = BytesIO()
plt.savefig(buffer, format='png', dpi=150) # dpi=150保证打印清晰
plt.close()
return HttpResponse(buffer.getvalue(), content_type='image/png')
然后在HTML模板里<img src="{% url 'yield_chart' %}">,零前端工作量。
第二,中文显示可靠性。 ECharts中文乱码是经典难题,需手动指定字体路径、处理Unicode编码。Matplotlib则通过配置matplotlibrc文件一劳永逸:
# 项目根目录下创建 matplotlibrc
font.family: sans-serif
font.sans-serif: SimHei, DejaVu Sans, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
axes.unicode_minus: False # 解决负号显示为方块问题
cotton.sql同目录下的matplotlibrc已配置好,导入即用。
第三,资源占用可控。 一台4GB内存的阿里云轻量应用服务器,同时运行Django+MySQL+nginx,ECharts在生成10个并发图表时内存占用飙升至3.2GB;而Matplotlib生成同等图表仅增加80MB内存,且图表生成后立即释放。
当然,这不是否定ECharts的价值。如果未来需要交互式钻取(点击省份看地市、点击地市看县域),我们会用Django REST Framework提供JSON API,前端再用ECharts消费——但那是V2.0的事,V1.0的核心目标是“先让数据活起来”,而不是“让图表动起来”。
3. 核心模块解析与实操要点:从数据库导入到图表生成
3.1 数据库初始化:cotton.sql导入的四个关键动作
cotton.sql不是简单的CREATE TABLE语句集合,它包含三类关键内容:基础数据字典、模拟业务数据、权限配置。导入时必须按顺序执行,否则会出现外键约束失败或Admin后台空白。
第一步:创建数据库并指定字符集
# 登录MySQL
mysql -u root -p
# 创建数据库(必须指定字符集,否则中文乱码)
CREATE DATABASE cotton_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 退出
EXIT;
提示:
utf8mb4是必须的!MySQL的utf8实际只支持3字节UTF-8字符(不支持emoji和部分生僻汉字),而utf8mb4支持4字节,确保“乌鲁木齐全”等带生僻字的地名正常显示。如果跳过此步直接CREATE DATABASE cotton_db;,后续导入cotton.sql时会报错Incorrect string value。
第二步:导入SQL文件(注意路径和编码)
# 切换到压缩包解压后的根目录
cd /path/to/unzipped/
# 导入(指定输入编码为utf8mb4)
mysql -u root -p --default-character-set=utf8mb4 cotton_db < database/cotton.sql
这里有两个易错点:一是路径必须准确指向database/cotton.sql(不是cotton.sql),因为资源包目录树显示cotton.sql位于数据库子目录下;二是必须加--default-character-set=utf8mb4参数,否则即使数据库字符集正确,导入过程仍可能因客户端编码不匹配导致乱码。
第三步:验证基础数据字典是否生效
导入后,检查cotton_variety和area_code表是否包含数据:
mysql -u root -p cotton_db -e "SELECT COUNT(*) FROM cotton_variety;"
# 应返回 127(预置127个主流棉花品种)
mysql -u root -p cotton_db -e "SELECT COUNT(*) FROM area_code WHERE code LIKE '652922%';"
# 应返回 123(沙雅县下辖123个行政村)
如果返回0,说明导入失败,常见原因是MySQL版本过低(<5.7)不支持utf8mb4,需升级MySQL或改用MariaDB 10.3+。
第四步:配置Django连接MySQL
编辑项目根目录下的settings.py,找到DATABASES配置段:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'cotton_db', # 必须与创建的数据库名一致
'USER': 'root',
'PASSWORD': 'your_mysql_password', # 修改为你的MySQL密码
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4', # 关键!确保Django也用utf8mb4
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
特别注意OPTIONS中的charset和init_command:前者保证Django连接时使用utf8mb4,后者禁用MySQL宽松模式,避免插入超长字符串时被静默截断(如将“新陆早65号”截成“新陆早65”)。
3.2 Django项目启动:requirements.txt依赖安装与迁移命令详解
项目依赖看似简单,但几个关键包的版本组合极易出错。requirements.txt内容如下:
Django==3.2.23
PyMySQL==1.1.0
matplotlib==3.7.2
Pillow==9.5.0
numpy==1.24.4
为什么PyMySQL而非mysqlclient?
mysqlclient需要编译C扩展,在Windows上需安装Visual Studio Build Tools,在Linux上需python3-dev和libmysqlclient-dev,新手极易卡在编译报错。PyMySQL是纯Python实现,pip install PyMySQL一步到位,性能损耗在农业数据场景下可忽略(单次查询慢2ms,但用户感知为0)。
安装步骤(以Ubuntu 22.04为例):
# 创建虚拟环境(强烈推荐,避免污染系统Python)
python3 -m venv venv
source venv/bin/activate
# 升级pip(避免旧版pip安装包时报错)
pip install --upgrade pip
# 安装依赖(注意:必须在项目根目录执行)
cd /path/to/program/ # 即'基于python+Django棉花数据平台建设与可视化系统源码数据库'目录
pip install -r requirements.txt
迁移命令必须分两步执行:
# 第一步:生成迁移文件(检查模型与数据库是否一致)
python manage.py makemigrations
# 第二步:执行迁移(同步数据库结构)
python manage.py migrate
为什么不能合并?因为makemigrations会扫描models.py,对比当前数据库状态,生成.py迁移文件(如0001_initial.py)。如果跳过此步直接migrate,Django会认为“没有新迁移”,从而不创建任何表——此时访问Admin后台会报错no such table: auth_user。执行makemigrations后,你会看到终端输出:
Migrations for 'cotton':
cotton/migrations/0001_initial.py
- Create model Variety
- Create model AreaCode
- Create model Field
...
这表示迁移文件已生成。再执行migrate,Django才真正创建表。
实操心得:如果执行
migrate时报错Table 'cotton_db.django_migrations' doesn't exist,说明数据库是空的,需先运行python manage.py migrate --fake-initial强制标记初始迁移已完成,再执行python manage.py migrate。这是Django处理已有数据库的特殊命令,文档很少提,但实际部署高频遇到。
3.3 核心功能模块实现:自定义数据看板的图表生成逻辑
系统首页的“数据看板”不是静态页面,而是动态生成的图表集合。以“年度产量趋势图”为例,其后端逻辑在cotton/views.py中:
from django.shortcuts import render
from django.http import HttpResponse
from io import BytesIO
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
from .models import CottonProduction
def yield_trend_chart(request):
# 查询近5年各月产量(吨)
productions = CottonProduction.objects.filter(
harvest_year__gte=2019
).values('harvest_year', 'harvest_month').annotate(
total_yield=Sum('yield_kg')
).order_by('harvest_year', 'harvest_month')
# 按年份分组数据
years = [2019, 2020, 2021, 2022, 2023]
monthly_data = {}
for year in years:
monthly_data[year] = [0] * 12 # 初始化12个月为0
for p in productions:
month_idx = p['harvest_month'] - 1 # 月份转索引(1月→0)
monthly_data[p['harvest_year']][month_idx] = p['total_yield'] / 1000 # kg转ton
# 绘制折线图
plt.figure(figsize=(12, 6))
for year in years:
plt.plot(range(1, 13), monthly_data[year], marker='o', label=f'{year}年')
plt.title('近五年籽棉月度产量趋势(吨)', fontsize=14, fontweight='bold')
plt.xlabel('月份', fontsize=12)
plt.ylabel('产量(吨)', fontsize=12)
plt.xticks(range(1, 13))
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
# 保存为PNG
buffer = BytesIO()
plt.savefig(buffer, format='png', dpi=150, bbox_inches='tight')
plt.close()
return HttpResponse(buffer.getvalue(), content_type='image/png')
前端HTML模板中调用:
<!-- templates/dashboard.html -->
<div class="card">
<div class="card-header">
<h5 class="mb-0">年度产量趋势</h5>
</div>
<div class="card-body">
<img src="{% url 'yield_trend_chart' %}" class="img-fluid" alt="产量趋势图">
</div>
</div>
关键细节解析:
- plt.savefig(..., dpi=150):DPI设为150而非默认100,确保在Retina屏和A4打印纸上图表文字清晰可辨。实测dpi=100时,小字号文字在打印后呈锯齿状。
- bbox_inches='tight':自动裁剪图表空白边距,避免标题被截断。
- plt.grid(True, alpha=0.3):网格线透明度设为0.3,既提供参考又不遮挡数据线。
- 月份数据用[0]*12初始化:避免某年某月无数据时图表坐标轴错位(如2020年缺7月数据,直接绘图会导致8月数据画在7月位置)。
同理,“区域收购量对比图”使用水平柱状图(plt.barh()),“品种纤维长度分布”使用箱线图(plt.boxplot()),所有图表均遵循同一套样式规范:标题黑体14号、坐标轴12号、图例右上角、网格线浅灰。
4. 部署全流程与避坑指南:从本地开发到生产环境上线
4.1 本地开发环境搭建(Windows/macOS/Linux通用)
环境准备清单:
- Python 3.8 ~ 3.11(推荐3.9,兼容性最佳)
- MySQL 5.7 或 MariaDB 10.3+(必须支持utf8mb4)
- 文本编辑器(VS Code推荐,内置Python插件)
详细步骤:
1. 下载并安装Python
访问python.org,下载对应系统安装包。安装时务必勾选 “Add Python to PATH”,否则后续命令行无法识别python命令。
-
安装MySQL
- Windows:下载MySQL Installer,选择“Developer Default”,安装过程中设置root密码(牢记!)。
- macOS:brew install mysql,然后brew services start mysql。
- Ubuntu:sudo apt update && sudo apt install mysql-server,安装后运行sudo mysql_secure_installation加固。 -
解压资源包并进入程序目录
将下载的ZIP包解压到无中文路径的目录,如C:\cotton-system\或/home/user/cotton-system/。重点确认程序子目录存在,其内部应有manage.py和cotton/应用目录。 -
创建并激活虚拟环境
```bash
# Windows
python -m venv venv
venv\Scripts\activate.bat
# macOS/Linux
python3 -m venv venv
source venv/bin/activate
```
- 安装依赖并运行
bash cd 程序 # 进入'基于python+Django棉花数据平台建设与可视化系统源码数据库'目录 pip install -r requirements.txt python manage.py migrate python manage.py createsuperuser # 创建管理员账号 python manage.py runserver
浏览器访问http://127.0.0.1:8000/admin,用刚创建的账号登录,即可看到完整的Admin后台。
注意:
createsuperuser命令中,邮箱可为空,用户名建议用admin,密码至少8位(含字母+数字)。如果忘记密码,可运行python manage.py changepassword admin重置。
4.2 生产环境部署(Ubuntu 22.04 + nginx + Gunicorn)
本地runserver仅供开发测试,生产环境必须用Gunicorn+nginx组合。以下是经过三次线上部署验证的最小可行方案:
第一步:安装系统依赖
sudo apt update
sudo apt install python3-pip python3-venv nginx supervisor
sudo systemctl enable nginx
第二步:配置Gunicorn
创建Gunicorn配置文件/etc/systemd/system/gunicorn.socket:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
User=www-data
[Install]
WantedBy=sockets.target
创建/etc/systemd/system/gunicorn.service:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/var/www/cotton-system/程序
ExecStart=/var/www/cotton-system/venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
--bind 127.0.0.1:8001 \
--timeout 30 \
--max-requests 1000 \
cotton.wsgi:application
[Install]
WantedBy=multi-user.target
关键参数说明:
- --workers 3:根据CPU核心数设置,双核服务器设为3,四核设为5,避免过多进程争抢I/O。
- --bind unix:/run/gunicorn.sock:使用Unix socket而非TCP端口,性能更高且更安全。
- --timeout 30:请求超时30秒,防止慢查询拖垮服务。
第三步:配置nginx
编辑/etc/nginx/sites-available/cotton:
upstream cotton_app {
server unix:/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name your-domain.com; # 替换为你的域名或IP
location /static/ {
alias /var/www/cotton-system/程序/staticfiles/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/cotton-system/程序/media/;
}
location / {
include proxy_params;
proxy_pass http://cotton_app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
启用站点:
sudo ln -sf /etc/nginx/sites-available/cotton /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置
sudo systemctl restart nginx
第四步:启动服务
# 启动Gunicorn
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
# 收集静态文件(Django要求)
cd /var/www/cotton-system/程序
source ../venv/bin/activate
python manage.py collectstatic --noinput
# 重启Gunicorn
sudo systemctl restart gunicorn
此时访问服务器IP,即可看到生产环境首页。
避坑指南:
- 如果页面CSS丢失,检查/var/www/cotton-system/程序/staticfiles/目录是否存在,且nginx配置中alias路径是否正确(末尾必须有斜杠)。
- 如果图表不显示,检查/var/www/cotton-system/程序/media/目录权限:sudo chown -R www-data:www-data /var/www/cotton-system/程序/media/。
- 如果Admin后台登录后跳转到/accounts/login/,在settings.py中添加:LOGIN_REDIRECT_URL = '/admin/'。
4.3 常见问题速查表与独家排查技巧
| 问题现象 | 可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
ImportError: No module named 'django' | 虚拟环境未激活或pip安装到全局 | which python, pip list \| grep django | 运行source venv/bin/activate,再pip install django==3.2.23 |
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module | 未安装PyMySQL或未配置为MySQL后端 | python -c "import pymysql; pymysql.install_as_MySQLdb()" | 在__init__.py中添加该行(项目根目录下新建cotton/__init__.py) |
| Admin后台空白,无任何模型 | migrate未执行或makemigrations未生成 | ls cotton/migrations/, python manage.py showmigrations | 先python manage.py makemigrations,再python manage.py migrate |
| 图表显示为“?”或空白 | Matplotlib中文字体缺失 | python -c "import matplotlib.pyplot as plt; print(plt.matplotlib.rcParams['font.sans-serif'])" | 将matplotlibrc文件复制到venv/lib/python3.x/site-packages/matplotlib/mpl-data/目录下 |
| nginx返回502 Bad Gateway | Gunicorn未启动或socket路径错误 | sudo systemctl status gunicorn, ls -l /run/gunicorn.sock | sudo systemctl restart gunicorn,检查/etc/systemd/system/gunicorn.service中WorkingDirectory路径是否正确 |
独家排查技巧:
- 日志定位法:当页面报错但无提示时,查看Gunicorn日志:sudo journalctl -u gunicorn -f,实时滚动日志,错误堆栈一目了然。
- 静态文件调试法:在浏览器开发者工具Network标签页,过滤png,查看图表请求的Response。如果是Internal Server Error,说明views.py中图表生成逻辑异常;如果是404,说明urls.py未正确配置图表URL。
- 数据库直连验证法:当Admin后台数据显示异常,直接mysql -u root -p cotton_db,执行SELECT * FROM cotton_production LIMIT 5;,确认数据库本身数据正确,排除Django ORM层问题。
5. 扩展性与教学应用:如何把这个系统变成你的课程设计亮点
这套系统的设计初衷就是“可生长”。它不是一个封闭的成品,而是一个骨架,你可以根据课程设计或毕业设计的需求,像搭积木一样往上添加模块。我来分享几个已被多所高校采用的扩展方向,以及对应的实施要点。
方向一:接入气象数据增强分析维度
棉花产量与气温、降水强相关。可以扩展一个WeatherData模型,从中国气象数据网API(需申请密钥)每日抓取各县域气温、降水量,存储到MySQL。然后在产量分析图表中叠加气象曲线:
- 技术要点:用celery定时任务(每24小时执行一次爬虫),避免阻塞Web请求;气象数据表增加area_code外键,与cotton_field关联;图表生成时用plt.twinx()创建双Y轴,左轴产量、右轴降水量。
- 教学价值:展示“多源数据融合分析”能力,答辩时演示“2023年沙雅县7月降水偏少20%,同期产量下降15%”的因果推断,远超单纯的数据录入系统。
方向二:增加移动端适配
当前Bootstrap响应式仅适配平板,手机端操作不便。可基于Django REST Framework构建API,前端用Vue.js重写移动端页面:
- 技术要点:pip install djangorestframework,为CottonProduction等模型创建ModelViewSet,用router.register()注册;Vue项目调用/api/productions/?format=json获取数据;手机端重点优化“扫码录入”(调用手机摄像头扫描棉农身份证二维码,自动填充农户信息)。
- 教学价值:体现“前后端分离”工程实践,展示RESTful API设计规范,解决农业场景中“田间地头即时录入”的刚需。
方向三:构建简易决策支持模块
在收购高峰期,企业需预测未来7天交售量以调度人力。可基于历史数据训练一个LSTM模型:
- 技术要点:用pandas提取过去3年每日交售量,构造滑动窗口特征(前7天销量、当日星期几、是否节假日);tensorflow训练LSTM模型,保存为.h5文件;Django视图加载模型,接收/predict/请求返回预测值;图表中用虚线绘制预测曲线。
- 教学价值:将机器学习融入农业信息化,答辩时可对比“人工经验预测”与“模型预测”的误差率,凸显数据驱动决策的优势。
无论选择哪个方向,记住一个原则:先跑通最小闭环,再迭代增强。比如做气象模块,第一天目标不是接入API,而是手动在MySQL里插入10条模拟气象数据,确保图表能正确叠加显示;第二天再写爬虫脚本。这种“小步快跑”的方式,既能保证课程设计按时交付,又能在答辩时展示清晰的演进路径——这比一个功能完整但缺乏思考痕迹的系统,更能打动评委。
最后分享一个小技巧:在文档.zip里的《部署指南》末尾,我特意留了一行空白:“此处可添加你的个性化扩展说明”。当你完成某个扩展模块后,把实现过程、遇到的坑、最终效果截图,填在这一页。答辩时把它作为附录展示,评委一眼就能看到你的主动性和工程能力。毕竟,农业数据系统的终极价值,不在于代码有多炫,而在于它是否真的让棉农少填一张表、让收购站多赚一分钱、让农技员多睡一小时觉。
简介:面向棉花种植、收购、加工等环节的数据管理需求,提供完整的Django Web应用源码,支持多维度数据录入、查询、统计与可视化展示。系统后端基于Python 3.x + Django 3.x开发,集成PyMySQL连接MySQL,内置cotton.sql数据库脚本,可一键导入使用;前端采用HTML+Bootstrap构建响应式界面,包含Django Admin后台与自定义数据看板,利用Matplotlib生成产量趋势、区域分布、收购量对比等图表。压缩包内含完整项目目录(含‘程序’‘数据库’‘文档.zip’等子目录)、数据库结构说明、详细部署指南、依赖清单(requirements.txt)及运行步骤(含migrate和runserver指令)。本地运行只需安装Python环境、执行pip install -r requirements.txt、导入SQL、运行迁移命令即可启动服务。适用于农业信息化教学实践、高校课程设计、毕业设计项目或中小型棉企初期数字化试点。
&spm=1001.2101.3001.5002&articleId=161856164&d=1&t=3&u=7c4473b6c05b4af292bc0b23a557f322)

被折叠的 条评论
为什么被折叠?



