从零开始搭建第一个Django项目:一个真实项目的思考与实践

日志里找真相
2025-06-17 19:57
阅读 589

开篇:为什么写这篇文章?

开篇:为什么写这篇文章?

去年年初,我参与了一个内部系统重构的项目,需要为公司搭建一个后台管理平台。原本这套系统是基于老PHP框架搭建的,维护成本高且缺乏扩展性。领导决定采用Python生态的技术栈来替代,最终选择了Django作为基础框架。

在开始前,我对Django的了解并不深,仅停留在“它是一个强大的Python Web框架”的层面。但在实际开发过程中,我深刻体会到它的设计哲学、灵活性以及社区资源的强大。这篇文章就是希望通过我的亲身经历,带你一步步完成第一个属于你的Django网站,不仅“会用”,还要理解“为什么要这么用”。


问题描述:从无到有的第一道坎

问题描述:从无到有的第一道坎

负载均衡配置-2

我们接下的是一个企业内部员工信息管理平台,需求不算复杂:实现员工信息录入、查询、修改、导出等功能,并集成权限控制。

作为一个刚接触Django的人,我在项目初期遇到了几个典型问题:

  1. 工程结构不清晰:不知道该从哪开始新建文件和目录。
  2. 模型设计不合理:比如一开始将员工的信息全部放在一张表里,后续发现很多字段重复冗余。
  3. 接口路由混乱:URL设计随意,命名不统一,后期难以维护。
  4. 权限边界模糊:不同角色(HR、管理员)访问的数据范围没区分好,导致安全风险。
  5. 本地开发与生产环境差异:本地运行没问题,部署后数据库配置出错,日志也看不清发生了什么。

这些问题让我意识到:Django虽然是“开箱即用”,但要真正把它用好,不是靠文档堆出来的,而是要在实践中不断踩坑、总结。


解决方案:一步步搭建我们的Django应用

解决方案:一步步搭建我们的Django应用

第一步:创建项目与App

我先使用django-admin startproject命令创建项目主目录,比如叫company_portal,接着按照模块划分创建不同的App,例如employeesdepartmentsaccounts等。

django-admin startproject company_portal
cd company_portal
python manage.py startapp employees

小贴士:App的拆分建议以功能模块为单位,避免大一统的设计。这样方便后期复用和解耦。


第二步:设计数据库模型(Model)

我最开始犯的一个错误是把所有字段都塞进Employee这个model里,后来才发现其实DepartmentJobTitleLocation这些字段完全可以单独抽象成表,再通过外键关联。

合理的做法是:

# models.py

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Department(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return self.name

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.ForeignKey(Department, on_delete=models.PROTECT)
    job_title = models.CharField(max_length=100)
    hire_date = models.DateField()
    salary = models.DecimalField(max_digits=10, decimal_places=2)
    
    def __str__(self):
        return self.user.get_full_name()

经验教训:

  • 使用外键时,要注意on_delete的行为,不要随便设为CASCADE,否则删除父表数据可能连带子表也被删了。
  • 使用OneToOneField连接用户信息是一种常见的做法,利于权限管理和扩展。

第三步:设计RESTful风格的API接口

虽然Django自带模板渲染能力,但我们这次前端采用Vue.js来做前后端分离,所以重点放在API接口的设计上。

我用了Django REST Framework(DRF),它极大简化了序列化和视图逻辑的工作量。

# views.py
from rest_framework import viewsets
from .models import Employee, Department
from .serializers import EmployeeSerializer, DepartmentSerializer

class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer

class DepartmentViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer

对应的urls.py通过Router自动生成:

from rest_framework.routers import DefaultRouter
from employees.views import EmployeeViewSet, DepartmentViewSet

router = DefaultRouter()
router.register(r'employees', EmployeeViewSet)
router.register(r'departments', DepartmentViewSet)

urlpatterns = router.urls

小插曲:上线前测试时,突然发现某些部门返回的员工数量特别大,结果发现是N+1查询的问题。于是我加上了select_related()优化:

queryset = Employee.objects.select_related('department')

第四步:权限与认证机制

我们使用JWT作为认证方式,借助djangorestframework-simplejwt库来实现。

对于不同角色的访问控制,我采用了DRF提供的permissions.py模块:

from rest_framework.permissions import BasePermission

class IsHRAdminOrReadOnly(BasePermission):
    def has_permission(self, request, view):
        if request.method in ['GET']:
            return True
        return request.user.is_authenticated and request.user.groups.filter(name='hr').exists()

然后在view中引用:

permission_classes = [IsHRAdminOrReadOnly]

思考点:最初直接用了内置的IsAdminUser,但发现不够灵活,所以自己封装了一套权限类,便于未来扩展更多角色。


第五步:部署与运维小细节

我们采用的是Docker + Nginx + Gunicorn + PostgreSQL + Redis的组合。

生产环境常见坑点包括

  1. 静态文件路径问题

    • 本地调试的时候用runserver自动处理了静态文件,但部署后必须配置STATIC_ROOT并运行collectstatic
    • Django本身不适合直接提供静态文件服务,应该交给Nginx处理。
  2. 环境变量管理

    • 使用.env文件配合python-decouple库来统一管理敏感配置,比如SECRET_KEY、DATABASE_URL、EMAIL_HOST等。
  3. 异步任务队列

    • 导出数据是个耗时操作,我们接入了Celery + Redis做异步处理。
  4. 日志监控

    • 部署后出现异常不能只靠打印print,我们接入了Sentry来收集错误日志。
    • 同时也在settings.py中配置了LOGGING项,将日志记录输出到文件,供排查问题使用。

效果总结:项目上线后的变化

效果总结:项目上线后的变化

经过约两个月的开发和迭代,项目顺利上线,带来以下几个显著的变化:

  • 原来的PHP系统需要多人维护,现在一个人就能搞定新功能开发;
  • 接口响应速度提升明显,页面加载时间从平均2秒降至不到500ms;
  • 权限体系更清晰,不同角色的访问权限不再混乱;
  • 搭建起一套完整的自动化流程(CI/CD、日志监控、邮件提醒等),提高了运维效率;
  • 最关键的是——同事对这套系统满意度大幅提升,再也不用吐槽“卡”和“找不到人”。

我的经验分享:给新手几点建议

数据流转过程-1

如果你是第一次使用Django,以下是我总结的几条实用经验:

✅ 1. 不要一开始就追求完美架构

很多新手喜欢先把各种第三方库装齐,比如DRF、DRY-Rest-Mixin、Graphene等等。但其实越早动手越好,先跑起来再说。架构可以在迭代中慢慢优化,代码也可以随时重构,但关键是先把想法落地。

✅ 2. Model设计是核心中的核心

我见过太多初学者随便扔一堆字段进去就完事,结果后面维护时头疼不已。请记住一句话:

“好的模型设计,胜过一百行业务逻辑。”

✅ 3. 把API设计当成产品来看

每个接口要做什么、怎么调用、返回什么格式、是否需要鉴权……这些都要有明确的文档说明。推荐使用SwaggerRedoc来自动生成文档,提高协作效率。

✅ 4. 别怕出错,多查日志和Stack Overflow

Django报错一般都很详细,别急着百度乱搜,先看看终端报什么,去Google或者GitHub Issues找类似问题。很多时候你遇到的,别人已经踩过了。

✅ 5. 拓展思路,不局限于Django本身

除了Django官方的功能之外,有很多优秀的工具可以让你事半功倍:

  • django-debug-toolbar:帮助你检查SQL执行情况
  • django-extensions:提供更多管理命令和工具函数
  • djcelery 或者 celery-beat:处理定时任务和异步任务
  • sorl-thumbnail:图片缩略图生成神器
  • coverage.py:测试覆盖率检测工具

结语:写在最后

写这篇教程的时候,我一直想让内容更像是一段真实的开发日记,而不是干巴巴的教程。因为我知道,真正的成长不是读了多少文档,而是踩了多少坑之后还能站起来。

Django是一个非常成熟的框架,它不会给你炫酷的概念炒作,但它能让你专注解决问题,把精力花在真正重要的地方。

也许有一天你会选择FastAPI或者其他框架,但在构建完整Web系统这条路上,Django依然是最值得掌握的基础之一。

希望你在学Django的过程中少走弯路,早日写出让自己满意的第一个Python网站!

如果你喜欢这类实战文章,欢迎留言告诉我,我会继续分享更多从项目中学到的经验。

—— 一位热爱技术也爱折腾的开发者

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝