news 2026/9/11 7:59:42

基于Django 2.2的资产管理系统源码解析与部署实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Django 2.2的资产管理系统源码解析与部署实践

简介:这是一套基于Python 3.7与Django 2.2.3开发的资产管理系统完整源码包,适合正在学习Django框架的开发者,以及需要完成毕业设计或课程设计的计算机专业学生。项目涵盖资产管理、分类与位置维护、用户权限控制、Admin后台管理等典型业务模块,清晰演示了Django的MVT设计模式、模型迁移、视图与URL配置、模板渲染和表单处理等核心流程。压缩包共1369个文件,以JS、CSS、HTML等前端静态资源为主,同时包含Python源码、模板配置、SQLite数据库、启动脚本run.bat、AdminLTE后台界面模板以及图片字体等媒体资源,整体约15.05MB,目录结构完整,便于直接运行和二次开发。目前已有158人学习下载。通过该资源可快速理解企业级Web应用的工程组织方式,掌握从环境搭建、数据建模、后台开发到部署上线的全栈实践思路,是一份兼具教学与实用价值的Django项目范例。

1. 拿到压缩包的第一件事:先搞清楚它根本不是“源码堆”

打开这个基于 python 3.7 + django 2.2.3 实现的资产管理系统.zip,你会看到run.bat一马当先,后面跟着一串adminlte.cssiziModal.min.cssfontawesome.css。这不是普通的静态文件堆砌,而是一个已经帮你配好前端皮肤和后端框架的 Django 2.2.3 资产管理系统。它解决的是传统固定资产管理用 Excel 记录导致的“数据不同步、查询靠翻表、权责不清晰”问题,把资产信息、分类、位置、状态统一落到数据库里,通过 Web 界面进行增删改查。对于正在找课程设计、毕业设计模板,或者想在公司内部快速搭一套轻量级 CMDB 的开发者来说,这个包的价值在于“可运行、可改造、前端已集成”。

最不济,它也能当一份 Django 1.x 迁移到 2.2 时代的实战参考。下面我从运行机制讲起,逐步拆到模型、视图、模板和部署,每一层都会给出可复现的命令和代码。

2. 环境选型与一键启动原理:Python 3.7 和 Django 2.2.3 到底卡在哪

2.1 为什么是这个组合,而不是 Django 4.x

Python 3.7 引入的dataclasses、改进的nonlocal和字典访问优化,让它在 2019 年是“生产级”的版本;Django 2.2 是当年的 LTS(长期支持)版本,2.2.3 修复了若干安全漏洞,比如反序列化问题。这个组合放在今天仍然能跑,而且很多企业内部遗留项目就停在这个栈上。如果你后续要接手这类项目,先确认 Python 版本不是 3.8+,因为 Django 2.2 官方支持到 3.7,用 3.9 以上可能会遇到distutils兼容性问题。

从运行角度看,这个 zip 的核心在于run.bat。它通常做的事情就是激活虚拟环境、检查依赖、执行数据库迁移,最后启动开发服务器。常见的写法和我们手动敲命令是等价的。

@echo off cd /d %~dp0 if not exist venv ( python -m venv venv call venv\Scripts\activate pip install -r requirements.txt ) else ( call venv\Scripts\activate ) python manage.py makemigrations python manage.py migrate python manage.py runserver 0.0.0.0:8000

逻辑说明:%~dp0获取批处理所在目录,保证无论从哪里双击运行,工作目录都切换正确;虚拟环境不存在时自动创建,并安装requirements.txt中锁定的Django==2.2.3。每次启动先迁移数据库,再启动监听0.0.0.0:8000的服务器,这样做是为了避免你手动敲一堆命令。

参数说明:0.0.0.0表示监听所有网卡,局域网内其他机器可以访问;如果你只本机调试,改成127.0.0.1更安全。

2.2 项目结构与静态文件职责

zip 里出现的 CSS 文件不是乱放的。adminlte.cssadminlte.min.css对应后台管理框架 AdminLTE 的压缩和未压缩版本;iziModal.min.css是弹窗组件样式;all.cssfontawesome.cssv4-shims.css属于 FontAwesome 图标库的各个变体。它们被放在static/目录下,最终通过模板里的{% load static %}引入。

下表列出了这个系统典型的文件结构,你解压后应该对照检查:

路径作用
manage.pyDjango 项目操作入口,所有命令的起点
run.batWindows 一键启动脚本
cmdb/主应用,存放 models、views、admin
templates/base.html公共骨架,集成 AdminLTE 布局
static/adminlte/AdminLTE 的 CSS/JS 文件
static/fontawesome/图标字体文件
static/iziModal/弹窗组件
requirements.txt依赖清单,含django==2.2.3

如果你的 zip 里没有requirements.txt,请先执行pip install django==2.2.3,然后看settings.pyINSTALLED_APPS是否注册了cmdb应用。这里最常见的坑是静态文件路径配置:

# settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [ BASE_DIR / "static", ]

如果不配置STATICFILES_DIRS,模板里的{% static 'adminlte/adminlte.css' %}会直接 404。这也是为什么很多人双击run.bat后页面能用,但没有样式的原因。

2.3 数据库迁移与初始数据

开发阶段默认使用 SQLite,它不需要额外安装数据库服务,适合课程设计和内部小系统。进入项目根目录后,依次执行以下命令:

python manage.py makemigrations cmdb python manage.py migrate python manage.py createsuperuser

逻辑说明:makemigrations会把models.py里的变更生成迁移文件,migrate将迁移文件应用到db.sqlite3createsuperuser创建管理员账号,之后才能登录 Django Admin 管理资产数据。如果run.bat已经在启动时执行了这些,你只需要补建超级用户。

3. 资产数据模型设计:从 Asset、Category 到 Location 的字段规划

3.1 模型之间的关系

资产管理系统最核心的是资产表Asset,它关联分类Category和位置Location。分类描述“这是什么类的东西”,位置描述“东西放在哪”,资产表本身记录“这个东西的归属和状态”。这种多对一关系是资产系统的标准做法,避免在每条资产记录里重复写字符串,也方便按分类和位置做统计。

下面是一个可直接运行的models.py示例:

from django.db import models class Category(models.Model): name = models.CharField(max_length=50, verbose_name="分类名称") def __str__(self): return self.name class Location(models.Model): building = models.CharField(max_length=100, verbose_name="楼栋") room = models.CharField(max_length=100, verbose_name="房间号") def __str__(self): return f"{self.building}-{self.room}" class Asset(models.Model): name = models.CharField(max_length=100, verbose_name="资产名称") category = models.ForeignKey(Category, on_delete=models.PROTECT, verbose_name="分类") location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True, verbose_name="位置") sn = models.CharField(max_length=100, unique=True, verbose_name="资产编号") status = models.CharField( max_length=20, choices=[("in_use", "使用中"), ("idle", "闲置"), ("repair", "维修中")], default="idle", verbose_name="状态", ) purchase_date = models.DateField(verbose_name="购买日期") price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="价格") owner = models.CharField(max_length=50, blank=True, verbose_name="领用人") remark = models.TextField(blank=True, verbose_name="备注") def __str__(self): return self.name

逻辑说明:CategoryPROTECT保护,分类下如果还有资产,删除分类会被阻止,避免产生孤儿数据;LocationSET_NULL,删除位置后资产保留,但位置字段置空,这在资产报废后删除位置时更友好。DecimalField用于货币金额,不能用FloatField,否则在求和时会出现浮点误差。

3.2 字段与迁移的对照

字段类型关键点
nameCharField不为空,长度 100
snCharFieldunique 唯一约束,保证资产编号不重复
purchase_dateDateField日期格式,方便按年份过滤
priceDecimalField保留两位小数
statusCharField + choices限定可选状态

设计字段时注意,verbose_name是 Django 管理后台和表单自动生成的标签名,建议全部写上中文,不然后台会显示英文变量名。生成并执行迁移,命令与 2.3 节一致,只是要确保在models.py所在的 app 下执行:

python manage.py makemigrations cmdb python manage.py migrate cmdb

执行后可以通过sqlite3 db.sqlite3 ".schema cmdb_asset"查看实际建表语句,用于核对索引和约束。

3.3 在 Django Admin 中注册和优化

Django 自带的后台是这个系统最省力的部分。在cmdb/admin.py中注册三个模型,并配置列表展示字段:

from django.contrib import admin from .models import Asset, Category, Location @admin.register(Asset) class AssetAdmin(admin.ModelAdmin): list_display = ("sn", "name", "category", "location", "status", "owner") search_fields = ("sn", "name") list_filter = ("status", "category") list_editable = ("status",)

参数说明:list_display控制后台列表页显示的列;search_fields会生成一个搜索框,并对 Sn 和名称做 LIKE 查询;list_filter在右侧生成状态和分类筛选条;list_editable可以不用进入详情页直接修改状态,这对于批量盘点非常好用。注册后,登录http://127.0.0.1:8000/admin就能看到资产表。

4. 视图、URL 与 AdminLTE 模板的整合流程

4.1 路由映射方式

cmdb/urls.py中,采用传统 FBV 方式映射视图:

from django.urls import path from . import views urlpatterns = [ path("", views.asset_list, name="asset_list"), path("add/", views.asset_add, name="asset_add"), path("edit/<int:pk>/", views.asset_edit, name="asset_edit"), path("delete/<int:pk>/", views.asset_delete, name="asset_delete"), ]

<int:pk>是 Django 2.0 以后的 path 转换器,它会把 URL 中的数字自动转换成 Python int 类型,并在视图函数中作为参数接收。相比旧版正则写法,更简洁且类型安全。

对应视图函数views.asset_list需要处理分页和搜索:

from django.core.paginator import Paginator from django.shortcuts import render from .models import Asset def asset_list(request): qs = Asset.objects.select_related("category", "location").all() keyword = request.GET.get("keyword", "") if keyword: qs = qs.filter(name__icontains=keyword) paginator = Paginator(qs, 10) page_obj = paginator.get_page(request.GET.get("page")) return render(request, "cmdb/asset_list.html", {"page_obj": page_obj})

逻辑说明:select_related在查询 Asset 的同时用 JOIN 把关联的 Category 和 Location 一次性查出来,避免逐条查询产生 N+1 问题;filter(name__icontains=keyword)实现前后缀模糊搜索。分页器每页 10 条,page_obj在模板中可以调用page_obj.has_previous()page_obj.has_next()控制翻页按钮。

4.2 AdminLTE 模板引用方式

这个系统采用 AdminLTE 风格,模板继承关系为base.html->asset_list.htmlbase.html中需要先加载静态文件:

{% load static %} <!DOCTYPE html> <html lang="zh-hans"> <head> <meta charset="UTF-8"> <title>{% block title %}资产管理系统{% endblock %}</title> <link rel="stylesheet" href="{% static 'adminlte/adminlte.css' %}"> <link rel="stylesheet" href="{% static 'fontawesome/all.css' %}"> <link rel="stylesheet" href="{% static 'iziModal/iziModal.min.css' %}"> </head> <body> {% block content %}{% endblock %} <script src="{% static 'iziModal/iziModal.min.js' %}"></script> </body> </html>

注意href="{% static '...' %}"不可写成href="/static/...",因为前者会根据部署环境自动处理 CDN 或自定义静态服务器 URL。下表是这些 css 在页面中的角色:

文件模块用途
adminlte.css整体布局侧边栏、导航、卡片、表格基础样式
all.css图标菜单图标、按钮图标
iziModal.min.css弹窗资产详情弹出层
style.css自定义覆盖覆盖 AdminLTE 默认颜色和间距

asset_list.html中,使用page_obj渲染表格:

{% extends "base.html" %} {% block content %} <div class="card"> <table class="table table-bordered"> <tr> <th>编号</th><th>名称</th><th>分类</th><th>状态</th> </tr> {% for asset in page_obj %} <tr> <td>{{ asset.sn }}</td> <td>{{ asset.name }}</td> <td>{{ asset.category.name }}</td> <td>{{ asset.get_status_display }}</td> </tr> {% empty %} <tr><td colspan="4">暂无数据</td></tr> {% endfor %} </table> </div> <div class="pagination"> {% if page_obj.has_previous %} <a href="?page={{ page_obj.previous_page_number }}">上一页</a> {% endif %} </div> {% endblock %}

get_status_display是 Django 对choices字段自动生成的方法,返回中文状态而不是存储值。如果页面没有 css,优先检查STATICFILES_DIRS是否指向了实际解压目录,这个我在 2.2 节已经强调过。

4.3 表单提交与 CSRF 防护

要实现新增资产,模板里必须带上{% csrf_token %}

<form method="post" action="{% url 'asset_add' %}"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="btn btn-primary">提交</button> </form>

Django 2.2.3 默认启用 CSRF 中间件,如果不加这个 token,POST请求会被 403 拒掉。这里form.as_p由 Django 的 ModelForm 自动渲染字段,省去手写每个输入框的 HTML。视图函数里校验逻辑为:

from django.shortcuts import redirect from .forms import AssetForm def asset_add(request): if request.method == "POST": form = AssetForm(request.POST) if form.is_valid(): form.save() return redirect("asset_list") else: form = AssetForm() return render(request, "cmdb/asset_form.html", {"form": form})

form.is_valid()会执行字段非空、类型判断和唯一约束检查,只要模型里定义了unique=True,重复的sn会被自动拦截。

5. 部署到宝塔的要点和二次开发的两个小技巧

5.1 用 Gunicorn 和 Nginx 跑起来

如果在 Linux 服务器上部署,不要直接用run.bat。安装 Python 3.7 后,通过宝塔面板的 Python 项目管理器创建虚拟环境,然后安装依赖,执行:

pip install gunicorn python manage.py collectstatic --noinput gunicorn cmdb.wsgi:application -b 0.0.0.0:8000 --workers 3

参数说明:--workers 3表示 3 个 worker 进程,对于小系统够用;collectstatic会把所有 app 的静态文件复制到STATIC_ROOT指定的目录,比如/www/wwwroot/your_project/static_assets。然后在 Nginx 配置中把/static/请求转发到这个目录:

location /static/ { alias /www/wwwroot/your_project/static_assets/; }

cmdb.wsgi:application是 Django 项目默认生成的 WSGI 入口,宝塔的 Python 管理器通常会让你填这个路径,不要写错成settings.py

5.2 静态文件 404 的排查顺序

部署后页面无样式,90% 是collectstatic没有执行,或 Nginx 的alias路径末尾少了一个斜杠。还有一种情况是settings.py里没有配置STATIC_ROOT,导致collectstatic直接报错。建议在部署前先在本地执行一次python manage.py collectstatic --dry-run,它会列出将要复制的文件清单,用来验证目录映射是否正确。

5.3 给系统加一个资产导出模块

在当前基础上快速增加 Excel 导出功能,可以在views.py中写一个使用csv模块的导出视图:

import csv from django.http import HttpResponse def export_assets(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="assets.csv"' writer = csv.writer(response) writer.writerow(['编号', '名称', '分类', '状态']) for asset in Asset.objects.all(): writer.writerow([asset.sn, asset.name, asset.category.name, asset.get_status_display()]) return response

content_type='text/csv'让浏览器识别为下载文件,Content-Disposition里的filename指定下载名。把这函数加入 URL 后,就可以在列表页加一个导出按钮,点击后直接下载 csv,用 Excel 打开不会乱码(注意 Windows 下可能需要改成 UTF-8 with BOM)。

最后提醒一点,Asset 模型中用DecimalField存价格,导出时asset.price是 Decimal 对象,直接写到 csv 会变成字符串,不影响正确性,但如果你要累加统计,务必在视图里做sum(asset.price for asset in qs),而不是在模板里执行计算。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 7:51:47

5 分钟写出第一个移动 UI 自动化用例:Maestro 上手实录

5 分钟写出第一个移动 UI 自动化用例&#xff1a;Maestro 上手实录 【免费下载链接】Maestro Painless E2E Automation for Mobile and Web 项目地址: https://gitcode.com/GitHub_Trending/ma/Maestro 写移动 UI 自动化用例&#xff0c;动画一多就 flaky&#xff0c;An…

作者头像 李华
网站建设 2026/9/11 7:45:36

SmartMediaKit与YOLO融合:实现低延迟视频播放与实时目标检测

做流媒体播放和做视觉分析&#xff0c;这两拨人平时很少坐在一起。但这两年越来越多的项目要求“边播放边看懂画面”&#xff0c;尤其是安防、智慧工厂、零售统计这类场景&#xff0c;不仅是把视频流拉出来给人看&#xff0c;还希望系统能自动识别画面里的目标。最开始我习惯用…

作者头像 李华
网站建设 2026/9/11 7:45:05

医疗知识图谱+BERT双塔:构建可解释临床推理引擎

简介&#xff1a;这是一套面向Python开发者与医疗AI初学者的智能诊断问答系统实战项目&#xff0c;聚焦知识图谱构建与向量检索技术在健康医疗场景的落地应用&#xff0c;帮助用户掌握从医学知识建模、语义向量化到端到端问答服务部署的完整链路。资源包共188个文件&#xff0c…

作者头像 李华
网站建设 2026/9/11 7:45:03

Agent记忆系统实战:从短期窗口到长期向量库

1. Agent 记忆问题&#xff0c;比你想的更像人类的遗忘曲线 到现在还有不少人问我&#xff0c;Agent 不就是“大模型 提示词 工具调用”串起来吗&#xff1f;这句话对了一半。串起来只是让 Agent 有了“动手能力”&#xff0c;但真正决定一个 Agent 是“演示玩具”还是“能持…

作者头像 李华