从零搭建教材档案管理系统:技术选型与实战部署指南
一、技术栈选型与核心组件
教材档案管理系统需要处理结构化数据存储、文件上传、权限控制和检索功能。我们采用以下经过验证的技术组合:
1.1 后端技术栈
使用Python + Django框架,它自带Admin管理后台,能快速搭建CRUD功能:
- Django 4.2.7 - 主框架
- Django REST Framework 3.14.0 - API接口
- Pillow 10.0.0 - 图片处理
- django-filter 23.2 - 数据过滤
1.2 数据库选择
使用PostgreSQL 15,支持全文检索和JSON字段:
- 教材元数据存储在关系表中
- 文件路径存储在FileField字段
- 检索历史使用JSONField存储
1.3 前端技术栈
采用Vue 3 + Element Plus构建管理界面:
- Vue 3.3.4 - 前端框架
- Element Plus 2.3.5 - UI组件库
- axios 1.5.0 - HTTP客户端
二、环境准备与项目初始化
2.1 系统环境配置
创建项目目录并安装Python环境:
``` mkdir textbook_archive && cd textbook_archive python -m venv venv source venv/bin/activate Linux/Mac 或 venv\Scripts\activate Windows ```2.2 依赖包安装
创建requirements.txt文件并安装:
``` requirements.txt Django==4.2.7 djangorestframework==3.14.0 psycopg2-binary==2.9.7 Pillow==10.0.0 django-filter==23.2 django-cors-headers==4.2.0 ```执行安装命令:
``` pip install -r requirements.txt ```2.3 数据库配置
安装PostgreSQL并创建数据库:
``` sudo apt-get install postgresql postgresql-contrib Ubuntu brew install postgresql Mac ```创建数据库和用户:
``` sudo -u postgres psql CREATE DATABASE textbook_db; CREATE USER textbook_user WITH PASSWORD 'YourPassword123'; GRANT ALL PRIVILEGES ON DATABASE textbook_db TO textbook_user; \q ```三、Django项目配置与模型设计
3.1 创建Django项目
初始化项目和应用:
``` django-admin startproject textbook_project . python manage.py startapp archive ```3.2 数据库连接配置
修改textbook_project/settings.py:
``` settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'textbook_db', 'USER': 'textbook_user', 'PASSWORD': 'YourPassword123', 'HOST': 'localhost', 'PORT': '5432', } } INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'corsheaders', 'archive', ] 文件上传配置 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 静态文件配置 STATIC_URL = 'static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') ```3.3 设计数据模型
在archive/models.py中定义核心模型:
``` archive/models.py from django.db import models from django.contrib.auth.models import User class Textbook(models.Model): ISBN = models.CharField(max_length=20, unique=True, verbose_name='ISBN号') title = models.CharField(max_length=200, verbose_name='教材名称') author = models.CharField(max_length=100, verbose_name='作者') publisher = models.CharField(max_length=100, verbose_name='出版社') publish_date = models.DateField(verbose_name='出版日期') edition = models.CharField(max_length=50, verbose_name='版次') price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='定价') subject = models.CharField(max_length=100, verbose_name='学科分类') grade_level = models.CharField(max_length=50, verbose_name='适用年级') cover_image = models.ImageField(upload_to='covers/', verbose_name='封面图片') pdf_file = models.FileField(upload_to='pdfs/', verbose_name='PDF文件') description = models.TextField(verbose_name='内容简介') stock_count = models.IntegerField(default=0, verbose_name='库存数量') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['-created_at'] verbose_name = '教材档案' verbose_name_plural = '教材档案' def __str__(self): return self.title class ArchiveRecord(models.Model): textbook = models.ForeignKey(Textbook, on_delete=models.CASCADE, related_name='records') operator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) action = models.CharField(max_length=50, choices=[ ('入库', '入库'), ('借出', '借出'), ('归还', '归还'), ('报废', '报废') ]) quantity = models.IntegerField() notes = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-created_at'] ```3.4 生成数据库表
执行数据库迁移:
``` python manage.py makemigrations python manage.py migrate python manage.py createsuperuser 按提示输入管理员账号信息 ```四、API接口开发
4.1 序列化器定义
创建archive/serializers.py:
``` archive/serializers.py from rest_framework import serializers from .models import Textbook, ArchiveRecord class TextbookSerializer(serializers.ModelSerializer): class Meta: model = Textbook fields = '__all__' read_only_fields = ['created_at', 'updated_at'] class ArchiveRecordSerializer(serializers.ModelSerializer): textbook_title = serializers.CharField(source='textbook.title', read_only=True) operator_name = serializers.CharField(source='operator.username', read_only=True) class Meta: model = ArchiveRecord fields = '__all__' read_only_fields = ['created_at'] ```4.2 视图集配置
创建archive/views.py:
``` archive/views.py from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend from .models import Textbook, ArchiveRecord from .serializers import TextbookSerializer, ArchiveRecordSerializer class TextbookViewSet(viewsets.ModelViewSet): queryset = Textbook.objects.all() serializer_class = TextbookSerializer filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_fields = ['subject', 'grade_level', 'publisher'] search_fields = ['title', 'author', 'ISBN', 'description'] ordering_fields = ['publish_date', 'price', 'created_at'] class ArchiveRecordViewSet(viewsets.ModelViewSet): queryset = ArchiveRecord.objects.all() serializer_class = ArchiveRecordSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['action', 'operator', 'textbook'] ```4.3 URL路由配置

创建archive/urls.py:
``` archive/urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'textbooks', views.TextbookViewSet) router.register(r'records', views.ArchiveRecordViewSet) urlpatterns = [ path('', include(router.urls)), ] ```修改项目主路由textbook_project/urls.py:
``` textbook_project/urls.py from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('archive.urls')), path('api-auth/', include('rest_framework.urls')), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ```五、前端界面开发
5.1 Vue项目初始化
在项目根目录创建frontend目录并初始化:
``` cd .. npx create-vue@latest frontend 选择TypeScript、Router、Pinia cd frontend npm install npm install element-plus axios ```5.2 配置Element Plus
修改frontend/src/main.ts:
``` // main.ts import { createApp } from 'vue' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) app.use(router) app.use(ElementPlus) app.mount('app') ```5.3 创建教材列表组件
创建frontend/src/views/TextbookList.vue:
```
教材档案列表
新增教材
5.4 配置API代理
创建frontend/vite.config.ts:
``` import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], server: { proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, }, }, }, }) ```六、系统部署与运行
6.1 启动后端服务
在项目根目录启动Django开发服务器:
``` python manage.py runserver ```6.2 启动前端服务
在frontend目录启动Vue开发服务器:
``` npm run dev ```6.3 生产环境部署配置
创建生产环境配置文件textbook_project/settings_prod.py:
``` settings_prod.py from .settings import DEBUG = False ALLOWED_HOSTS = ['your-domain.com', 'localhost'] 静态文件配置 STATIC_ROOT = '/var/www/textbook/static' MEDIA_ROOT = '/var/www/textbook/media' 数据库配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'textbook_db', 'USER': 'textbook_user', 'PASSWORD': 'YourProductionPassword', 'HOST': 'localhost', 'PORT': '5432', } } 安全配置 SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True ```6.4 Nginx配置
创建/etc/nginx/sites-available/textbook:
``` server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /api { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /media { alias /var/www/textbook/media; } location /static { alias /var/www/textbook/static; } } ```6.5 启动生产服务
使用Gunicorn启动Django:
``` pip install gunicorn gunicorn --workers 3 textbook_project.wsgi:application ```构建前端生产版本:
``` cd frontend npm run build ```七、系统功能验证
7.1 基础功能测试
访问以下地址验证系统功能:
- http://localhost:3000 - 前端管理界面
- http://localhost:8000/admin - 后台管理
- http://localhost:8000/api/textbooks/ - API接口
7.2 数据操作验证
执行以下操作确保系统正常工作:
- 通过前端界面添加教材信息
- 上传教材封面图片和PDF文件
- 测试教材检索功能
- 验证入库、借出记录操作
7.3 性能检查
检查关键接口响应时间:
- 教材列表加载:应小于500ms
- 文件上传:支持大文件分片上传
- 数据库查询:使用索引优化