网站首页/ 信息中心/ 档案百科/

基于Django快速构建鄂州档案管理系统的实战指南

发布时间:2026年08月28日 13:20:28 浏览量:0

系统架构与核心技术选型

本系统采用Django作为后端框架,PostgreSQL作为数据库,前端使用Bootstrap 5。这种组合能快速搭建稳定、可扩展的归档系统。Django自带强大的Admin管理后台和ORM,能极大简化数据模型和权限管理开发。

环境准备与项目初始化

开发环境配置

在Ubuntu 20.04或Windows 10+ WSL2环境下执行以下命令:

安装Python 3.9和必要依赖:

``` sudo apt update sudo apt install python3.9 python3.9-venv python3.9-dev postgresql postgresql-contrib ```

创建并激活虚拟环境:

``` python3.9 -m venv ezhou_env source ezhou_env/bin/activate Windows: ezhou_env\Scripts\activate ```

安装Django和相关包:

``` pip install django==4.2 psycopg2-binary django-crispy-forms crispy-bootstrap5 ```

项目创建与数据库配置

创建Django项目和应用:

``` django-admin startproject ezhou_archive cd ezhou_archive python manage.py startapp archive ```

配置PostgreSQL数据库,首先登录PostgreSQL:

``` sudo -u postgres psql ```

在PostgreSQL命令行中执行:

``` CREATE DATABASE ezhou_archive_db; CREATE USER archive_user WITH PASSWORD 'YourSecurePassword123!'; ALTER ROLE archive_user SET client_encoding TO 'utf8'; ALTER ROLE archive_user SET default_transaction_isolation TO 'read committed'; ALTER ROLE archive_user SET timezone TO 'Asia/Shanghai'; GRANT ALL PRIVILEGES ON DATABASE ezhou_archive_db TO archive_user; \q ```

修改ezhou_archive/settings.py中的数据库配置:

``` DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'ezhou_archive_db', 'USER': 'archive_user', 'PASSWORD': 'YourSecurePassword123!', 'HOST': 'localhost', 'PORT': '5432', } } ```

在INSTALLED_APPS中添加应用:

``` INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'archive', 'crispy_forms', 'crispy_bootstrap5', ] CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" CRISPY_TEMPLATE_PACK = "bootstrap5" ```

数据模型设计与实现

核心模型定义

编辑archive/models.py,定义档案管理核心模型:

``` from django.db import models from django.contrib.auth.models import User class ArchiveCategory(models.Model): """档案分类""" name = models.CharField(max_length=100, verbose_name="分类名称") code = models.CharField(max_length=20, unique=True, verbose_name="分类代码") description = models.TextField(blank=True, verbose_name="分类描述") parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, verbose_name="上级分类") class Meta: verbose_name = "档案分类" verbose_name_plural = "档案分类" def __str__(self): return self.name class ArchiveFile(models.Model): """档案文件""" STATUS_CHOICES = [ ('draft', '草稿'), ('review', '审核中'), ('approved', '已归档'), ('borrowed', '借阅中'), ('destroyed', '已销毁'), ] file_number = models.CharField(max_length=50, unique=True, verbose_name="档案编号") title = models.CharField(max_length=200, verbose_name="档案标题") category = models.ForeignKey(ArchiveCategory, on_delete=models.PROTECT, verbose_name="所属分类") content = models.TextField(verbose_name="档案内容") keywords = models.CharField(max_length=200, verbose_name="关键词") secret_level = models.CharField(max_length=20, choices=[ ('public', '公开'), ('internal', '内部'), ('secret', '秘密'), ('confidential', '机密') ], default='internal', verbose_name="密级") create_date = models.DateField(verbose_name="形成日期") archive_date = models.DateField(auto_now_add=True, verbose_name="归档日期") storage_location = models.CharField(max_length=100, verbose_name="存放位置") storage_period = models.IntegerField(verbose_name="保管期限(年)") status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft', verbose_name="状态") creator = models.ForeignKey(User, on_delete=models.PROTECT, related_name='created_files', verbose_name="创建人") reviewer = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='reviewed_files', verbose_name="审核人") attachment = models.FileField(upload_to='archive_attachments/%Y/%m/', blank=True, verbose_name="附件") class Meta: verbose_name = "档案文件" verbose_name_plural = "档案文件" indexes = [ models.Index(fields=['file_number']), models.Index(fields=['title']), models.Index(fields=['category']), models.Index(fields=['create_date']), ] def __str__(self): return f"{self.file_number} - {self.title}" class BorrowRecord(models.Model): """借阅记录""" archive_file = models.ForeignKey(ArchiveFile, on_delete=models.CASCADE, verbose_name="档案文件") borrower = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="借阅人") borrow_date = models.DateTimeField(auto_now_add=True, verbose_name="借阅日期") expected_return = models.DateField(verbose_name="应还日期") actual_return = models.DateField(null=True, blank=True, verbose_name="实际归还日期") purpose = models.TextField(verbose_name="借阅用途") class Meta: verbose_name = "借阅记录" verbose_name_plural = "借阅记录" ```

生成数据库迁移并应用

创建数据库迁移文件:

``` python manage.py makemigrations archive python manage.py migrate ```

基于Django快速构建鄂州档案管理系统的实战指南

创建超级用户用于管理后台:

``` python manage.py createsuperuser ```

按照提示输入用户名、邮箱和密码。

管理后台配置与优化

Admin界面定制

编辑archive/admin.py,配置管理后台:

``` from django.contrib import admin from .models import ArchiveCategory, ArchiveFile, BorrowRecord @admin.register(ArchiveCategory) class ArchiveCategoryAdmin(admin.ModelAdmin): list_display = ['code', 'name', 'parent'] list_filter = ['parent'] search_fields = ['name', 'code'] ordering = ['code'] @admin.register(ArchiveFile) class ArchiveFileAdmin(admin.ModelAdmin): list_display = ['file_number', 'title', 'category', 'secret_level', 'status', 'create_date'] list_filter = ['category', 'secret_level', 'status', 'create_date'] search_fields = ['file_number', 'title', 'keywords'] readonly_fields = ['archive_date'] fieldsets = ( ('基本信息', { 'fields': ('file_number', 'title', 'category', 'content') }), ('档案属性', { 'fields': ('keywords', 'secret_level', 'create_date', 'storage_location', 'storage_period') }), ('流程状态', { 'fields': ('status', 'creator', 'reviewer', 'attachment') }), ) def save_model(self, request, obj, form, change): if not change: 新建时自动设置创建人 obj.creator = request.user super().save_model(request, obj, form, change) @admin.register(BorrowRecord) class BorrowRecordAdmin(admin.ModelAdmin): list_display = ['archive_file', 'borrower', 'borrow_date', 'expected_return', 'actual_return'] list_filter = ['borrow_date', 'expected_return'] search_fields = ['archive_file__file_number', 'archive_file__title', 'borrower__username'] ```

前端界面开发

基础模板创建

archive/templates目录下创建基础模板base.html

``` 鄂州档案管理系统 - {% block title %}{% endblock %} {% block extra_css %}{% endblock %}
{% block content %}{% endblock %}
{% block extra_js %}{% endblock %} ```

档案列表视图

创建archive/templates/archive/list.html

``` {% extends 'base.html' %} {% load crispy_forms_tags %} {% block title %}档案查询{% endblock %} {% block content %}

档案查询

重置
{% for file in files %} {% empty %} {% endfor %}
档案编号 标题 分类 密级 形成日期 状态
{{ file.file_number }} {{ file.title }} {{ file.category.name }} {{ file.get_secret_level_display }} {{ file.create_date }} {{ file.get_status_display }}
未找到相关档案
{% include 'pagination.html' with page=files %} {% endblock %} ```

视图函数实现

编辑archive/views.py

``` from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator from .models import ArchiveFile, ArchiveCategory, BorrowRecord from .forms import BorrowForm def archive_list(request): """档案列表""" files = ArchiveFile.objects.filter(status='approved').order_by('-archive_date') 搜索过滤 query = request.GET.get('q', '') if query: files = files.filter(file_number__icontains=query) | files.filter(title__icontains=query) category_id = request.GET.get('category') if category_id: files = files.filter(category_id=category_id) 分页 paginator = Paginator(files, 20) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) categories = ArchiveCategory.objects.all() return render(request, 'archive/list.html', { 'files': page_obj, 'categories': categories, }) @login_required def archive_detail(request, pk): """档案详情""" file = get_object_or_404(ArchiveFile, pk=pk, status='approved') if request.method == 'POST': form = BorrowForm(request.POST) if form.is_valid(): borrow = form.save(commit=False) borrow.archive_file = file borrow.borrower = request.user borrow.save() 更新档案状态 file.status = 'borrowed' file.save() else: form = BorrowForm() return render(request, 'archive/detail.html', { 'file': file, 'form': form, }) @login_required def my_borrow(request): """我的借阅记录""" borrows = BorrowRecord.objects.filter(borrower=request.user).order_by('-borrow_date') return render(request, 'archive/my_borrow.html', {'borrows': borrows}) ```

URL路由配置

创建archive/urls.py

``` from django.urls import path from . import views urlpatterns = [ path('', views.archive_list, name='archive_list'), path('file//', views.archive_detail, name='archive_detail'), path('my-borrow/', views.my_borrow, name='my_borrow'), ] ```

修改项目主ezhou_archive/urls.py

``` from django.contrib import admin from django.urls import path, include from django.contrib.auth import views as auth_views urlpatterns = [ path('admin/', admin.site.urls), path('', include('archive.urls')), path('login/', auth_views.LoginView.as_view(template_name='registration/login.html'), name='login'), path('logout/', auth_views.LogoutView.as_view(next_page='/'), name='logout'), ] ```

表单与验证

创建archive/forms.py

``` from django import forms from django.core.exceptions import ValidationError from datetime import date, timedelta from .models import BorrowRecord class BorrowForm(forms.ModelForm): class Meta: model = BorrowRecord fields = ['expected_return', 'purpose'] widgets = { 'expected_return': forms.DateInput(attrs={'type': 'date'}), 'purpose': forms.Textarea(attrs={'rows': 3}), } def clean_expected_return(self): expected_return = self.cleaned_data['expected_return'] today = date.today() if expected_return <= today: raise ValidationError("应还日期必须晚于今天") if expected_return > today + timedelta(days=30): raise ValidationError("借阅期限不能超过30天") return expected_return ```

静态文件与部署配置

静态文件配置

settings.py中添加:

``` STATIC_URL = 'static/' STATIC_ROOT = BASE_DIR / 'staticfiles' MEDIA_URL = 'media/' MEDIA_ROOT = BASE_DIR / 'media' ```

收集静态文件:

``` python manage.py collectstatic ```

生产环境部署配置

安装Gunicorn和Nginx:

``` pip install gunicorn sudo apt install nginx ```

创建Gunicorn服务文件/etc/systemd/system/ezhou-archive.service

``` [Unit] Description=Gunicorn daemon for Ezhou Archive After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/path/to/your/ezhou_archive ExecStart=/path/to/your/ezhou_env/bin/gunicorn --workers 3 --bind unix:/tmp/ezhou_archive.sock ezhou_archive.wsgi:application [Install] WantedBy=multi-user.target ```

配置Nginx站点/etc/nginx

职业学校档案培训:别让档案成为你职业路上的绊脚石
职业学校档案培训:别让档案成为你职业路上的绊脚石
这事儿吧,我干了这么多年,见过太多职业学校的同学,毕业时技能证书拿了一堆,结果在档案上栽了跟头。档案这东西,平时感觉不到它的存在,一到关键时刻——考公、评职称、进国企——它立马就能让你体会到什么叫“一...
2026年08月28日 13:20:28
微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818