用Django搭建你的第一个Python网站:从零到上线的实战记录
开篇:为什么我决定写这篇文章?

去年年初,我在公司接到一个任务:用最短的时间开发一个内部使用的项目管理看板。这个看板不需要特别复杂的功能,但需要快速上线,并且具备可扩展性,以便后续添加更多模块。
我们团队当时主流的后端技术栈是Node.js,但那次我决定尝试一下一直想学但没来得及深入的Django。说实话,刚开始我心里还挺忐忑的。毕竟之前只是了解过Django是个“大而全”的框架,没有真正做过完整的项目。
不过,最终结果还不错,不仅按时交付了项目,还在后来几个月里不断迭代出新功能。这个项目的成功也让我对Django有了更深刻的理解和信心。所以今天我想以一个实际的小项目为例,带你一起入门Django,看看怎么用它快速搭建一个实用的Web应用。
如果你是第一次接触Django,或者正准备入门Python Web开发,这篇实战经验分享可能会对你有帮助。
问题描述:为什么选Django?遇到了哪些挑战?


首先,我先说说我为什么会选择Django而不是Flask或其他框架。
- 时间紧、任务急:不想从零搭起,希望有一个开箱即用的框架
- 数据结构比较明确:一开始就有清晰的业务模型(用户、项目、任务)
- 需要自带后台系统:产品同学提出要能直接通过后台修改数据,不想再自己造轮子
- 安全性和维护性:虽然是内部系统,但也要考虑基本的安全机制
但在使用过程中,我也确实遇到了一些典型的“新手坑”。
比如:
- 模型迁移(migrations)机制不理解,导致数据库版本混乱
- URL路由配置方式搞错了,接口访问404
- 视图层与模板混在一起,代码不好维护
- 后台界面太丑,领导看了摇头
- 静态资源路径问题,前端样式加载不出来
- 线上部署的时候各种依赖版本不对
这些问题在文档中其实都有说明,但作为一个刚入门的新手,很多地方还是需要亲自踩一遍才明白到底怎么回事。
解决方案:整体架构设计思路

这个项目的最终目标是做一个支持简单项目管理的看板页面。核心功能包括:
- 用户注册/登录
- 创建/编辑项目
- 添加/更新任务
- 任务状态变更(进行中、已完成等)
基于这些需求,我大致规划了整个系统的结构:
project_board/
│
├── manage.py
├── board/ # 核心业务app
│ ├── models.py
│ ├── views.py
│ ├── urls.py
│ ├── admin.py
│ └── ...
├── users/ # 用户相关逻辑
│ ├── models.py
│ ├── views.py
│ └── ...
├── templates/ # HTML模板目录
├── static/ # 静态资源目录
├── settings.py # 全局配置
├── urls.py # 主路由入口
└── wsgi.py / asgi.py # 启动入口
架构设计亮点
- 模块化分离:
- 把不同的功能拆成多个
app,便于后期维护和复用
- 把不同的功能拆成多个
- DRY原则贯穿始终:
- 尽量少写重复代码,尤其是表单验证、通用视图等方面
- 前后端分离初步探索:
- 虽然是个简单的页面,但我开始用Vue.js写前端部分,跟Django仅通过REST API交互
- 安全性考虑:
- 使用Django内置的权限机制限制用户操作权限
- CSRF防护默认启用

这样做的好处是,在之后的几个小迭代中,新增功能变得非常快,代码结构也比较清晰。
代码实践:核心功能实现示例

第一步:创建Django项目
# 安装Django
pip install django
# 创建项目
django-admin startproject project_board
进入项目目录,执行:
python manage.py runserver
看到熟悉的“Welcome to Django”页面,表示项目初始化成功!
接下来我们创建两个主要的App:
python manage.py startapp users
python manage.py startapp board
然后别忘了在settings.py中的INSTALLED_APPS中添加这两个App。
第二步:定义模型(Models)
在board/models.py中,我设计了两个核心模型:
from django.db import models
from users.models import CustomUser
class Project(models.Model):
name = models.CharField(max_length=100)
owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Task(models.Model):
STATUS_CHOICES = [
('pending', '待处理'),
('in_progress', '进行中'),
('completed', '已完成')
]
project = models.ForeignKey(Project, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
assigned_to = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
这里有几个关键点:
- 使用了自定义用户模型(
CustomUser),方便未来扩展字段 - 任务状态用了枚举字段
choices - 外键引用时注意
on_delete参数的设置
运行迁移命令生成数据库表:
python manage.py makemigrations
python manage.py migrate
小提示:在做makemigrations的时候,如果出现报错,可以加个
--fake试试,尤其在重构旧项目的时候。
第三步:构建Admin后台
为了让运营或产品经理能快速上手,我需要让Board模块能在admin后台管理。在board/admin.py中添加:
from django.contrib import admin
from .models import Project, Task
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
list_display = ('name', 'owner', 'created_at')
@admin.register(Task)
class TaskAdmin(admin.ModelAdmin):
list_display = ('title', 'project', 'status', 'assigned_to', 'created_at')
list_filter = ('status',)
启动服务后访问/admin,就能看到自动生成的后台管理系统了。
第四步:搭建基础API接口
为了让前端调用,我还写了几个基础的REST API接口。这里我用了djangorestframework库:
pip install djangorestframework
在board/serializers.py中定义序列化器:
from rest_framework import serializers
from .models import Project, Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = '__all__'
class ProjectSerializer(serializers.ModelSerializer):
tasks = TaskSerializer(many=True, read_only=True)
class Meta:
model = Project
fields = ['id', 'name', 'tasks']
在views.py中:
from rest_framework import viewsets
from .models import Project
from .serializers import ProjectSerializer
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
最后在主urls.py中添加router:
from rest_framework.routers import DefaultRouter
from board.views import ProjectViewSet
router = DefaultRouter()
router.register(r'projects', ProjectViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
现在可以通过GET http://localhost:8000/api/projects/获取所有项目信息啦!
踩坑经验:那些让我崩溃又成长的时刻
坑1:Migrations冲突
在开发早期,我对migrations机制不了解,频繁删除migration文件导致同步失败。后来才知道要用:
python manage.py migrate --fake-initial
或者手动去数据库删掉django_migrations里的对应条目。
教训:不要手动删migration文件,除非你知道后果!
坑2:静态资源加载失败
线上部署的时候遇到一个巨坑:CSS和JS加载不出来。查了很久才发现是STATIC_ROOT配置的问题。
正确做法是在生产环境部署前运行:
python manage.py collectstatic
并且确保服务器配置指向正确的静态资源目录。
坑3:DEBUG模式泄露
本地开发的时候一直开着DEBUG = True没问题,但一部署到测试服务器就出事了——出错信息会暴露数据库细节!
所以记得部署时务必关闭调试模式:
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
还要配合Nginx设置404/500页面。
效果总结:项目上线后的效果如何?
经过大约2周的开发+优化,看板系统顺利上线。初期只是给部门内部试用,后来陆续有其他小组申请使用。系统支持了以下能力:
- 快速查看项目进度
- 实时同步任务状态
- 支持跨项目协作
- 后台自动发送每日提醒邮件
- 自动统计工作完成率和效率趋势图
性能方面:
- 单机部署,QPS约150~200之间
- 数据库压力不大,PostgreSQL CPU占用率小于20%
- 接口平均响应时间 < 100ms
随着团队规模变大,后续我们还做了负载均衡、CDN加速等优化,但那是另一回事了 😄
经验分享:给新手的建议
1. 别怕“重”,Django就是适合做大型项目
很多人会觉得Django太重,不如Flask灵活。但如果你要做一个真正的企业级应用,Django自带的认证、后台、ORM、安全控制等模块会让你省下大量时间。
2. 学会分App,提前规划好目录结构
良好的结构比漂亮的代码更重要。把不同功能分开App,有利于团队合作和代码维护。
3. 多动手,少看书
虽然官方文档很详细,但最好的学习方式还是边敲代码边犯错。当你遇到某个bug不知道怎么解决的时候,去翻文档才最有收获。
4. 不要一开始就想着高性能
作为新手,先完成基本功能最重要。等到用户量上去之后再去考虑缓存、异步、微服务才是正路。
5. 注意生产环境配置
Django开发环境下非常友好,但真正部署时一定要注意:
- 关闭调试模式
- 正确配置静态资源和媒体资源目录
- 设置合适的中间件和安全策略
- 用gunicorn/uwsgi + Nginx部署
- 做好日志监控
结语:Django依然是值得掌握的现代Web框架
这一年多来,我用Django开发了好几个项目,最大的感受是:“一旦你适应了它的风格,它真的能让你非常高效地开发复杂Web应用。”
Django的生态系统非常成熟,社区活跃,文档全面。像DRF(Django REST framework)、Django Channels(WebSocket)、Celery(任务队列)这些工具都已经成为标准标配。
如果你是Python开发者,或者正在寻找一个稳定、易用、成熟的Web框架,那么不妨从今天开始跟着这篇教程,迈出第一步吧!
希望这篇文章能帮你少走一些弯路,也希望你能享受到用Django开发的乐趣 😊
如果你还有关于Django的问题,或者想要进阶内容(比如部署到Kubernetes、用GraphQL替代REST API),欢迎留言讨论~

评论 0