Python全栈项目--基于Django的项目管理系统

项目概述

项目管理系统是企业日常运营中不可或缺的工具,它能够帮助团队高效地组织、跟踪和管理各类项目任务。本文将介绍如何使用Django框架构建一个功能完善的项目管理系统,涵盖从需求分析到部署的完整开发流程。

技术栈选型

后端技术

  • Django 4.2+: 成熟的Python Web框架,提供完整的ORM、认证系统和管理后台
  • Django REST Framework: 构建RESTful API,支持前后端分离
  • Celery: 异步任务队列,处理邮件通知、报表生成等耗时操作
  • Redis: 缓存和消息队列
  • PostgreSQL: 生产环境数据库

前端技术

  • Vue.js 3: 现代化的前端框架
  • Element Plus: UI组件库
  • Axios: HTTP客户端
  • ECharts: 数据可视化

核心功能模块

1. 用户认证与权限管理

系统需要支持多角色用户体系,包括系统管理员、项目经理、开发人员和访客等角色。使用Django内置的认证系统,结合django-guardian实现对象级权限控制。

from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): ROLE_CHOICES = ( ('admin', '系统管理员'), ('pm', '项目经理'), ('dev', '开发人员'), ('guest', '访客'), ) role = models.CharField(max_length=20, choices=ROLE_CHOICES) avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) phone = models.CharField(max_length=20, blank=True) department = models.CharField(max_length=100, blank=True) class Meta: db_table = 'users'

2. 项目管理

项目是系统的核心实体,需要记录项目的基本信息、状态、成员和时间线。

class Project(models.Model): STATUS_CHOICES = ( ('planning', '规划中'), ('active', '进行中'), ('suspended', '已暂停'), ('completed', '已完成'), ('cancelled', '已取消'), ) name = models.CharField(max_length=200, verbose_name='项目名称') description = models.TextField(verbose_name='项目描述') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='planning') owner = models.ForeignKey(User, on_delete=models.PROTECT, related_name='owned_projects') members = models.ManyToManyField(User, related_name='projects', through='ProjectMember') start_date = models.DateField() end_date = models.DateField(null=True, blank=True) budget = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'projects' ordering = ['-created_at']

3. 任务管理

任务是项目的最小执行单元,支持任务的创建、分配、状态跟踪和优先级设置。

class Task(models.Model): PRIORITY_CHOICES = ( ('low', '低'), ('medium', '中'), ('high', '高'), ('urgent', '紧急'), ) STATUS_CHOICES = ( ('todo', '待办'), ('in_progress', '进行中'), ('review', '待审核'), ('done', '已完成'), ('blocked', '已阻塞'), ) project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='tasks') title = models.CharField(max_length=200) description = models.TextField(blank=True) assignee = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='assigned_tasks') creator = models.ForeignKey(User, on_delete=models.PROTECT, related_name='created_tasks') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='todo') priority = models.CharField(max_length=20, choices=PRIORITY_CHOICES, default='medium') due_date = models.DateTimeField(null=True, blank=True) estimated_hours = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True) actual_hours = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True) parent_task = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='subtasks') tags = models.ManyToManyField('Tag', blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'tasks' ordering = ['-priority', '-created_at']

4. 文档管理

项目过程中会产生大量文档,需要提供文档的上传、版本管理和权限控制功能。

class Document(models.Model): project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='documents') task = models.ForeignKey(Task, on_delete=models.CASCADE, null=True, blank=True, related_name='documents') name = models.CharField(max_length=200) file = models.FileField(upload_to='documents/%Y/%m/%d/') file_size = models.BigIntegerField() file_type = models.CharField(max_length=50) version = models.CharField(max_length=20, default='1.0') uploader = models.ForeignKey(User, on_delete=models.PROTECT) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'documents'

API设计

使用Django REST Framework构建RESTful API,提供清晰的接口文档和版本管理。

from rest_framework import viewsets, permissions from rest_framework.decorators import action from rest_framework.response import Response class ProjectViewSet(viewsets.ModelViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): user = self.request.user if user.role == 'admin': return Project.objects.all() return user.projects.all() @action(detail=True, methods=['get']) def statistics(self, request, pk=None): project = self.get_object() stats = { 'total_tasks': project.tasks.count(), 'completed_tasks': project.tasks.filter(status='done').count(), 'total_members': project.members.count(), 'progress': self.calculate_progress(project), } return Response(stats) def calculate_progress(self, project): total = project.tasks.count() if total == 0: return 0 completed = project.tasks.filter(status='done').count() return round(completed / total * 100, 2)

前端实现

项目列表页面

使用Vue 3的Composition API和Element Plus构建响应式界面。

<template> <div class="project-list"> <el-card> <template #header> <div class="card-header"> <span>项目列表</span> <el-button type="primary" @click="handleCreate">新建项目</el-button> </div> </template> <el-table :data="projects" style="width: 100%"> <el-table-column prop="name" label="项目名称" /> <el-table-column prop="status" label="状态"> <template #default="{ row }"> <el-tag :type="getStatusType(row.status)"> {{ getStatusText(row.status) }} </el-tag> </template> </el-table-column> <el-table-column prop="owner.username" label="负责人" /> <el-table-column prop="start_date" label="开始日期" /> <el-table-column label="操作"> <template #default="{ row }"> <el-button size="small" @click="handleEdit(row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button> </template> </el-table-column> </el-table> </el-card> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import { getProjects, deleteProject } from '@/api/project'; import { ElMessage } from 'element-plus'; const projects = ref([]); const loadProjects = async () => { try { const response = await getProjects(); projects.value = response.data; } catch (error) { ElMessage.error('加载项目列表失败'); } }; const getStatusType = (status) => { const typeMap = { planning: 'info', active: 'success', suspended: 'warning', completed: '', cancelled: 'danger', }; return typeMap[status]; }; onMounted(() => { loadProjects(); }); </script>

高级特性

1. 实时通知系统

使用WebSocket实现实时消息推送,当任务状态变更或有新评论时及时通知相关用户。

# consumers.py from channels.generic.websocket import AsyncWebsocketConsumer import json class NotificationConsumer(AsyncWebsocketConsumer): async def connect(self): self.user_id = self.scope['user'].id self.group_name = f'user_{self.user_id}' await self.channel_layer.group_add( self.group_name, self.channel_name ) await self.accept() async def disconnect(self, close_code): await self.channel_layer.group_discard( self.group_name, self.channel_name ) async def notification_message(self, event): await self.send(text_data=json.dumps({ 'type': 'notification', 'message': event['message'] }))

2. 数据统计与可视化

提供项目进度、任务分布、成员工作量等多维度的数据分析和图表展示。

from django.db.models import Count, Q from datetime import datetime, timedelta class ProjectStatisticsView(APIView): def get(self, request, pk): project = get_object_or_404(Project, pk=pk) # 任务状态分布 task_status = project.tasks.values('status').annotate(count=Count('id')) # 成员工作量统计 member_workload = project.tasks.values( 'assignee__username' ).annotate( total=Count('id'), completed=Count('id', filter=Q(status='done')) ) # 最近30天任务完成趋势 thirty_days_ago = datetime.now() - timedelta(days=30) daily_completion = project.tasks.filter( status='done', updated_at__gte=thirty_days_ago ).extra( select={'day': 'date(updated_at)'} ).values('day').annotate(count=Count('id')) return Response({ 'task_status': task_status, 'member_workload': member_workload, 'daily_completion': daily_completion, })

3. 导出功能

支持将项目数据导出为Excel或PDF格式,方便生成报告和归档。

from openpyxl import Workbook from django.http import HttpResponse class ProjectExportView(APIView): def get(self, request, pk): project = get_object_or_404(Project, pk=pk) wb = Workbook() ws = wb.active ws.title = "项目任务清单" # 写入表头 headers = ['任务名称', '负责人', '状态', '优先级', '截止日期'] ws.append(headers) # 写入数据 for task in project.tasks.all(): ws.append([ task.title, task.assignee.username if task.assignee else '', task.get_status_display(), task.get_priority_display(), task.due_date.strftime('%Y-%m-%d') if task.due_date else '', ]) response = HttpResponse( content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) response['Content-Disposition'] = f'attachment; filename={project.name}_tasks.xlsx' wb.save(response) return response

部署方案

Docker容器化部署

使用Docker Compose编排多个服务,简化部署流程。

version: '3.8' services: db: image: postgres:14 environment: POSTGRES_DB: project_management POSTGRES_USER: admin POSTGRES_PASSWORD: password123 volumes: - postgres_data:/var/lib/postgresql/data redis: image: redis:7 command: redis-server --appendonly yes volumes: - redis_data:/data web: build: . command: gunicorn config.wsgi:application --bind 0.0.0.0:8000 volumes: - static_volume:/app/staticfiles - media_volume:/app/media ports: - "8000:8000" depends_on: - db - redis environment: - DATABASE_URL=postgresql://admin:password123@db:5432/project_management - REDIS_URL=redis://redis:6379/0 celery: build: . command: celery -A config worker -l info depends_on: - db - redis nginx: image: nginx:latest ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf - static_volume:/app/staticfiles - media_volume:/app/media depends_on: - web volumes: postgres_data: redis_data: static_volume: media_volume:

性能优化

1. 数据库查询优化

使用select_related和prefetch_related减少数据库查询次数。

def get_queryset(self): return Project.objects.select_related('owner').prefetch_related( 'members', 'tasks__assignee', 'documents' )

2. 缓存策略

对频繁访问的数据使用Redis缓存。

from django.core.cache import cache def get_project_statistics(project_id): cache_key = f'project_stats_{project_id}' stats = cache.get(cache_key) if stats is None: stats = calculate_statistics(project_id) cache.set(cache_key, stats, 300) # 缓存5分钟 return stats

3. 异步任务处理

将耗时操作放入Celery异步队列。

from celery import shared_task @shared_task def send_task_notification(task_id, user_id): task = Task.objects.get(id=task_id) user = User.objects.get(id=user_id) send_mail( subject=f'新任务分配: {task.title}', message=f'您有新的任务需要处理', from_email='noreply@example.com', recipient_list=[user.email], )

安全考虑

1. 数据验证

在序列化器层面进行严格的数据验证。

from rest_framework import serializers class TaskSerializer(serializers.ModelSerializer): class Meta: model = Task fields = '__all__' def validate_due_date(self, value): if value and value < timezone.now(): raise serializers.ValidationError("截止日期不能早于当前时间") return value

2. 权限控制

实现细粒度的权限控制。

from rest_framework import permissions class IsProjectMember(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.user.role == 'admin': return True return obj.members.filter(id=request.user.id).exists()

3. API限流

防止恶意请求攻击。

REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ], 'DEFAULT_THROTTLE_RATES': { 'anon': '100/hour', 'user': '1000/hour' } }

总结

本项目管理系统基于Django框架构建,提供了完整的项目生命周期管理功能。通过合理的架构设计、清晰的代码组织和完善的功能模块,可以满足中小型团队的日常项目管理需求。在实际开发中,还可以根据具体业务场景扩展更多功能,如甘特图展示、看板视图、移动端适配等。

这个系统不仅是一个实用的工具,也是学习Django全栈开发的优秀实践项目,涵盖了Web开发中的核心技术点,包括ORM使用、RESTful API设计、前后端分离、异步任务处理、缓存优化、Docker部署等,对提升全栈开发能力很有帮助。

项目代码

下载链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1119389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot分页不分页情况

资源链接 https://download.csdn.net/download/hashiqimiya/92539595 该资源的项目有两个接口 GetMapping("/page")public R page(RequestParam int page,RequestParam int size) {Page<Product> p new Page<>(page, size);System.out.println("p…

深度学习毕设选题推荐:基于python深度学习的手势识别数字机器学习

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

如何通过模具智能管理降低汽车生产线的停机时间?

在工业4.0深度演进的背景下&#xff0c;模具智能管理正成为制造业提质增效的核心引擎&#xff0c;尤其在汽车这一高度精密、高节奏的产业中&#xff0c;其价值尤为凸显。传统依赖人工经验、固定周期保养的模具管理模式&#xff0c;早已难以应对现代汽车生产对稳定性、一致性与响…

深度学习计算机毕设之深度学习基于python-CNN的常见鱼类分类识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【毕业设计】基于python深度学习的手势识别数字

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

自由职业者如何在AI浪潮中破局?这份「考证+实战」进阶指南请收好!

手握认证&#xff0c;更要手握真本事在 ChatGPT、Sora 等 AI 工具席卷全球的今天&#xff0c;无论你是设计师、程序员、撰稿人还是营销顾问&#xff0c;都会感受到一个明确信号&#xff1a;不懂点人工智能&#xff0c;未来职业道路可能越走越窄。特别是自由职业者&#xff0c;既…

【课程设计/毕业设计】机器学习 基于python深度学习的手势识别数字

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

英矽智能与赛诺菲签署8.88亿美元AI新药研发合作协议

在去年底完成IPO后&#xff0c;英矽智能&#xff08;Insilico Medicine&#xff09;继续扩大其合作伙伴网络&#xff0c;与赛诺菲&#xff08;Sanofi&#xff09;签署新联盟协议&#xff0c;交易总价值高达8.88亿美元。该合作协议前期付款达3200万美元&#xff0c;将专注于利用…

深度学习计算机毕设之人工智能基于python深度学习的手势识别数字

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

基于Dify+数据库+Echarts搭建的数据可视化助手(含自然语言转SQL)

参考 https://blog.csdn.net/youmaob/article/details/148766806 https://www.cnblogs.com/xiao987334176/p/18912784 你是一名专业的数据需求提炼师。请仔细阅读用户的自然语言问题{{#context#}}&#xff0c;只保留与数据查询直接相关的核心需求。自动忽略与数据查询无关的内…

【剑斩OFFER】算法的暴力美学——最长公共前缀

一、题目描述二、算法原理思路&#xff1a;先找前两个字符串的公共前缀&#xff0c;再拿着这个公共前缀的&#xff0c;去跟剩余的字符串比较&#xff0c;然后不断的更新这个公共前缀&#xff1a;三、代码实现第一种解法&#xff1a;class Solution { public:string longestComm…

从ACPI!ParseArg函数中的ACPI!Buffer和ACPI!ParseOpcode到ACPI!Name中的ACPI!MoveObjData

从ACPI!ParseArg函数中的ACPI!Buffer和ACPI!ParseOpcode到ACPI!Name中的ACPI!MoveObjData0: kd> t Breakpoint 9 hit eax00000000 ebx899b23cc ecx899b23cc edx00000000 esi00000043 edi8997c000 eipf74271e8 espf789a0f4 ebpf789a110 iopl0 nv up ei pl zr na pe n…

vllm笔记(1):最基础的离线推理

vllm是一个知名的推理框架&#xff0c;也是开始尝试接触vllm了。 本代码来源https://github.com/vllm-project/vllm/blob/main/examples/offline_inference/basic/basic.py #LLM 是用于运行 vLLM 引擎离线推理的主类。 #SamplingParams 指定了采样过程的参数。 from vllm imp…

拒绝繁琐配置,推荐一款简洁易用的项目管理工具Kanass

为了保证项目高效、有序地推进&#xff0c;我们通常使用如Jira等项目管理工具。Jira整体功能完善&#xff0c;自定义能力强大&#xff0c;但配置繁琐&#xff0c;上手难度大&#xff0c;同时随着Atlassian销售策略调整Jira server中国区即将停止维护&#xff0c;今天给大家推荐…

2核2G3M的云服务器有哪些用途?适合部署小型网站或博客吗?

阿里云近期推出的经济型e实例&#xff0c; 2核2G、3M带宽、独立公网IP、不限流量&#xff0c; 99元/年&#xff0c;续费同价&#xff0c;我自己也买了&#xff0c;用了有几年了。 价格低到让人怀疑&#xff1a; 这样的配置&#xff0c;到底能干点什么&#xff1f; 部署个人博客…

Lua 函数教程

Lua 函数 1. 课程信息 课题&#xff1a;Lua 函数基础与进阶用法课时建议&#xff1a;60 ~ 90 分钟适合对象&#xff1a;已掌握 Lua 变量、流程控制&#xff08;if/for/while&#xff09;与 table 基础的学习者 2. 教学目标 理解函数的作用&#xff1a;封装逻辑、复用代码、提升…

1核2GB服务器运行Nginx + MySQL + PHP(LNMP)会有性能瓶颈吗?

很多新手在搭建网站时&#xff0c; 会选最便宜的云服务器——比如1核2GB配置。 然后装上 Nginx MySQL PHP&#xff08;即 LNMP 环境&#xff09;&#xff0c; 想着“先试试看”。 但很快发现&#xff1a; 网站偶尔打不开、后台卡顿、数据库连接超时…… 是配置太低&#xff…

计算机深度学习毕设实战-基于python的海洋生物识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

这里还有8个“Manus”:1亿美元ARR,都是ToC

Meta刚掏出20亿美元把Manus收入囊中的同时&#xff0c;一份名单也随即在VC圈疯传—— “1亿美元ARR俱乐部”。 上榜公司不多&#xff0c;但个个鼎鼎大名&#xff1a; Perplexity&#xff1a;200亿美元ElevenLabs&#xff1a;66亿美元Lovable&#xff1a;66亿美元Replit&…

汽车制造质量大数据分析如何助力企业创新发展?

在汽车制造业转型升级的关键阶段&#xff0c;质量大数据分析正成为企业提升核心竞争力的重要抓手。随着市场竞争日趋激烈&#xff0c;消费者对汽车产品的要求不断提高&#xff0c;传统的质量管理方法已经难以满足现代生产的需求。质量大数据分析通过整合多源异构数据&#xff0…