从零开始,用 Django 搭建我的第一个 Python 网站

微服务迷航
2025-06-24 08:45
阅读 558

开篇:为什么是 Django?

开篇:为什么是 Django?

我是一名在互联网公司工作的后端开发工程师,主要负责服务端架构设计和系统搭建。说起第一次使用 Django 搭建网站的经历,我还挺感慨的。那会儿刚入职一家创业公司,业务要得急,时间又紧张,技术选型上不能有太多试错空间。

当时我们准备快速上线一个内部使用的任务管理后台,用来支撑市场团队和产品团队的协作流程。这个项目不需要太复杂的功能,但要有完整的用户体系、权限控制、数据可视化能力,同时要求开发周期短、后期易维护。

摆在面前的选择有两个:Flask 和 Django。

Flask 更轻量,灵活性高,适合小项目或定制化程度高的场景。但缺点也很明显:很多功能需要自己写轮子,比如用户认证、后台界面这些。Django 就不一样了,它是“自带电池”的全栈框架,内置了 admin 后台、ORM、用户系统、模板引擎等等,开箱即用,能大幅缩短初期开发时间。

最后我们果断选择了 Django,事实也证明这步选对了。这篇文章就来分享一下我当时是如何一步步搭起这个后台系统的,以及在这个过程中踩过的坑和学到的经验。


问题描述:时间紧,压力大,新人难上手

问题描述:时间紧,压力大,新人难上手

项目的难点其实不在于功能多复杂,而是在于资源有限 + 时间紧迫 + 团队新人多

  • 时间:产品经理只给了两周时间原型+前后端实现;
  • 人力:前端是我拉了一个实习生临时帮忙切页面,后端就我一个人撑着;
  • 经验不足:虽然我个人对 Python 相对熟悉,但之前都是做一些脚本或数据处理的工作,Web 框架这块还是第一次实战,尤其是 Django。

最头疼的是当时完全没有头绪,不知道如何组织结构,也不清楚如何利用好 Django 提供的那些便捷工具。如果一切从零造轮子,肯定来不及。

所以必须找到一套既能快速启动,又能为未来扩展留有余地的开发方式。


解决方案:Django 的模块化架构 + 内置 Admin 系统

解决方案:Django 的模块化架构 + 内置 Admin 系统

技术选型理由:

  • 开发效率优先:Django 自带 ORM 可以快速映射模型,Admin 管理后台可以自动生成基本的CRUD操作,这对快速验证业务逻辑非常友好;
  • 可维护性考虑:Django 遵循 MVT 设计模式(Model-View-Template),代码结构清晰,便于后期多人协作;
  • 社区生态成熟:插件丰富,比如 django-crispy-forms、django-guardian、rest_framework 等,满足不同阶段的扩展需求;
  • 部署成本低:配合 Gunicorn + Nginx 的组合部署,在生产环境中表现稳定,且容易调试。

我们最终决定采用以下基础技术栈:

  • Web 框架:Django(3.2)
  • 数据库:PostgreSQL
  • 前端:Bootstrap + jQuery(少量 Vue.js 用于组件化)
  • 用户权限:Django 自带的 auth 模块 + Group 分组控制
  • 部署工具:Docker + Gunicorn + Nginx

代码实践:搭建第一步 —— 创建你的第一个项目

API接口文档-1

代码实践:搭建第一步 —— 创建你的第一个项目

先来看看最基本的项目初始化步骤。

# 安装 django
pip install django

# 创建项目
django-admin startproject task_dashboard

# 进入目录并运行服务器
cd task_dashboard
python manage.py runserver

这时访问 http://localhost:8000,你应该能看到 Django 默认的欢迎页。

接下来创建我们的核心 app:

python manage.py startapp tasks

settings.py 中注册该 app:

INSTALLED_APPS = [
    ...
    'tasks',
]

然后定义第一个模型类,假设我们要记录每个任务的信息:

# tasks/models.py
from django.db import models
from django.contrib.auth.models import User

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)
    assignee = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    due_date = models.DateField()
    status_choices = (
        ('pending', 'Pending'),
        ('in_progress', 'In Progress'),
        ('completed', 'Completed')
    )
    status = models.CharField(max_length=20, choices=status_choices, default='pending')

    def __str__(self):
        return self.title

接着生成数据库迁移文件,并执行:

python manage.py makemigrations
python manage.py migrate

别忘了创建超级管理员账号:

python manage.py createsuperuser

这时候你可以登录 http://localhost:8000/admin 查看自动为我们生成的任务管理界面了!

是不是很神奇?一行数据接口都没写,就已经有了可视化的 CRUD 功能。


接口设计:REST API 快速接入前端

随着前端同学完成页面设计,我们需要提供 RESTful 风格的接口进行数据交互。于是引入了 Django REST Framework。

安装:

pip install djangorestframework

添加到 INSTALLED_APPS 中:

INSTALLED_APPS = [
    ...
    'rest_framework',
]

编写简单的视图和序列化器:

# tasks/serializers.py
from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = '__all__'
# tasks/views.py
from rest_framework import viewsets
from .models import Task
from .serializers import TaskSerializer

class TaskViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

配置路由:

# tasks/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import TaskViewSet

router = DefaultRouter()
router.register(r'tasks', TaskViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

再全局导入到主 urls.py:

# task_dashboard/urls.py
from django.urls import path, include

urlpatterns = [
    path('api/', include('tasks.urls')),
]

现在访问 /api/tasks/ 就可以看到 JSON 格式的任务列表了,甚至还有网页版的 API 浏览器!再也不用手写 View 返回 JsonResponse 了。


踩坑经验:真实开发中遇到的问题及解决方案

1. ORM 查询性能问题

早期我为了简单方便,直接用了 .all() 获取全部任务:

Task.objects.all()

结果上线后发现数据库查询特别慢,特别是当任务数量变多之后。

后来通过分析日志,发现没有加任何过滤条件的情况下,每次请求都会拉取全表数据,而且没有分页机制。

解决办法

  • 使用 Django REST Framework 的分页组件;
  • 对外暴露的接口加上查询参数支持;
  • 关键字段增加索引(如 assignee、due_date);

示例:

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

class TaskViewSet(viewsets.ModelViewSet):
    pagination_class = StandardResultsSetPagination
    ...

同时,我还在 PostgreSQL 表中为经常查询的字段添加了索引:

CREATE INDEX idx_assignee ON tasks_task (assignee_id);

大大提升了查询效率。


2. 权限控制没想清楚,上线后权限混乱

我们一开始用的是默认的 Django auth 用户体系,但在分配任务时,出现了权限越权的问题:A 组用户能看到 B 组用户的任务数据。

这个问题是因为我们在写 API 的时候并没有限制只能查询当前用户的数据。

解决方案

  • 在 TaskViewSet 中重写 get_queryset 方法,限制用户只能查看自己的任务;
  • 引入 django-guardian 实现对象级权限控制(更细粒度的权限管理);
  • 配合 Group 机制,实现角色划分和权限隔离。

代码简化示例如下:

def get_queryset(self):
    user = self.request.user
    if user.is_superuser:
        return Task.objects.all()
    return Task.objects.filter(assignee=user)

3. 生产环境部署踩坑

本地测试没问题,一上生产就报错:静态文件加载失败,500 错误满天飞。

排查了一圈才发现:

  • 静态资源路径配置不对:Django 的 STATIC_ROOT 和 STATICFILES_DIRS 需要区分清楚;
  • Gunicorn 启动命令错误:忘记加 --chdir 到项目根目录;
  • Nginx 配置漏掉了 media 文件的代理;
  • PostgreSQL 版本与开发机不一致导致部分字段不兼容。

最后统一用 Docker 打包部署,解决了版本差异的问题,整个流程标准化了不少。


效果总结:两周完成 MVP 并上线生产环境

项目按时上线后,市场和产品团队反馈良好,UI 简洁直观、后台操作流畅。虽然功能不算复杂,但后续基于这个框架,我们又陆续加了通知中心、消息订阅机制、权限分级等高级功能,系统变得越来越完整。

最关键的是:

  • 新人接手快,Django 的结构让他们很快理解项目逻辑;
  • 扩展能力强,很多功能可以直接通过集成第三方 App 实现;
  • 部署运维稳定,几乎没有出过大的故障;
  • 性能优化到位,响应时间一直保持在合理范围内。

经验分享:给初学者的几点建议

如果你也在学习 Django 或者刚开始用它做项目,我这里给你几个实用建议:

1. 合理使用内置功能,避免重复造轮子

比如 admin 后台、auth 系统、form 表单验证、DRF、中间件等,都是经过社区打磨多年的优质组件,不要轻易舍弃它们去自己实现类似功能。

2. 注重数据库设计,提前规划索引和表结构

尤其是在项目中后期,一旦表结构定下来,调整起来成本很高。建议初期就画 E-R 图,明确表之间的关系。

3. 善用中间件和信号(signals)解耦逻辑

比如记录用户行为日志、触发异步任务等都可以用 signals 实现,让核心业务逻辑保持干净。

4. 学会用缓存提升性能

Django 提供了 cache 框架,对于频繁读取的接口可以加缓存,减少 DB 压力。

5. 考虑容器化部署,提高交付效率

像我们后来用的 Docker + Kubernetes 方案,不仅保证环境一致性,还可以通过 CI/CD 实现自动化部署,节省大量沟通和调试成本。


写在最后:Django 是个值得深入学习的好工具

说实话,刚开始接触 Django 的时候我也觉得它有点“笨重”,不如 Flask 灵活。但真正投入进去之后,你会发现它的成熟性和稳定性远胜于其他轻量级框架。

特别是在团队协作、系统维护、长期迭代等方面,Django 给你提供的不仅仅是功能上的便利,更是一种工程思维和规范——而这才是作为开发者最应该掌握的能力。

希望这篇文章能帮你少走弯路,顺利搭建起你的第一个 Python Web 项目。如果你有任何问题或者遇到了什么奇怪的 bug,也欢迎留言交流,我们一起成长。

共勉。

评论 0

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