从零开始搭建第一个Django项目:一个真实项目的思考与实践
开篇:为什么写这篇文章?

去年年初,我参与了一个内部系统重构的项目,需要为公司搭建一个后台管理平台。原本这套系统是基于老PHP框架搭建的,维护成本高且缺乏扩展性。领导决定采用Python生态的技术栈来替代,最终选择了Django作为基础框架。
在开始前,我对Django的了解并不深,仅停留在“它是一个强大的Python Web框架”的层面。但在实际开发过程中,我深刻体会到它的设计哲学、灵活性以及社区资源的强大。这篇文章就是希望通过我的亲身经历,带你一步步完成第一个属于你的Django网站,不仅“会用”,还要理解“为什么要这么用”。
问题描述:从无到有的第一道坎


我们接下的是一个企业内部员工信息管理平台,需求不算复杂:实现员工信息录入、查询、修改、导出等功能,并集成权限控制。
作为一个刚接触Django的人,我在项目初期遇到了几个典型问题:
- 工程结构不清晰:不知道该从哪开始新建文件和目录。
- 模型设计不合理:比如一开始将员工的信息全部放在一张表里,后续发现很多字段重复冗余。
- 接口路由混乱:URL设计随意,命名不统一,后期难以维护。
- 权限边界模糊:不同角色(HR、管理员)访问的数据范围没区分好,导致安全风险。
- 本地开发与生产环境差异:本地运行没问题,部署后数据库配置出错,日志也看不清发生了什么。
这些问题让我意识到:Django虽然是“开箱即用”,但要真正把它用好,不是靠文档堆出来的,而是要在实践中不断踩坑、总结。
解决方案:一步步搭建我们的Django应用

第一步:创建项目与App
我先使用django-admin startproject命令创建项目主目录,比如叫company_portal,接着按照模块划分创建不同的App,例如employees、departments、accounts等。
django-admin startproject company_portal
cd company_portal
python manage.py startapp employees
小贴士:App的拆分建议以功能模块为单位,避免大一统的设计。这样方便后期复用和解耦。
第二步:设计数据库模型(Model)
我最开始犯的一个错误是把所有字段都塞进Employee这个model里,后来才发现其实Department、JobTitle、Location这些字段完全可以单独抽象成表,再通过外键关联。
合理的做法是:
# 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的组合。
生产环境常见坑点包括:
静态文件路径问题
- 本地调试的时候用
runserver自动处理了静态文件,但部署后必须配置STATIC_ROOT并运行collectstatic。 - Django本身不适合直接提供静态文件服务,应该交给Nginx处理。
- 本地调试的时候用
环境变量管理
- 使用
.env文件配合python-decouple库来统一管理敏感配置,比如SECRET_KEY、DATABASE_URL、EMAIL_HOST等。
- 使用
异步任务队列
- 导出数据是个耗时操作,我们接入了Celery + Redis做异步处理。
日志监控
- 部署后出现异常不能只靠打印print,我们接入了Sentry来收集错误日志。
- 同时也在
settings.py中配置了LOGGING项,将日志记录输出到文件,供排查问题使用。
效果总结:项目上线后的变化

经过约两个月的开发和迭代,项目顺利上线,带来以下几个显著的变化:
- 原来的PHP系统需要多人维护,现在一个人就能搞定新功能开发;
- 接口响应速度提升明显,页面加载时间从平均2秒降至不到500ms;
- 权限体系更清晰,不同角色的访问权限不再混乱;
- 搭建起一套完整的自动化流程(CI/CD、日志监控、邮件提醒等),提高了运维效率;
- 最关键的是——同事对这套系统满意度大幅提升,再也不用吐槽“卡”和“找不到人”。
我的经验分享:给新手几点建议

如果你是第一次使用Django,以下是我总结的几条实用经验:
✅ 1. 不要一开始就追求完美架构
很多新手喜欢先把各种第三方库装齐,比如DRF、DRY-Rest-Mixin、Graphene等等。但其实越早动手越好,先跑起来再说。架构可以在迭代中慢慢优化,代码也可以随时重构,但关键是先把想法落地。
✅ 2. Model设计是核心中的核心
我见过太多初学者随便扔一堆字段进去就完事,结果后面维护时头疼不已。请记住一句话:
“好的模型设计,胜过一百行业务逻辑。”
✅ 3. 把API设计当成产品来看
每个接口要做什么、怎么调用、返回什么格式、是否需要鉴权……这些都要有明确的文档说明。推荐使用Swagger或Redoc来自动生成文档,提高协作效率。
✅ 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