从零到一:我用 Django 搭建的第一个网站

首席-唐思宇-学者
2025-06-23 23:49
阅读 424

引言:一个需求催生的尝试

引言:一个需求催生的尝试

去年公司要做一个内部的知识管理系统,用于整理产品资料、技术文档和项目复盘内容。前端已经决定用 Vue 来开发,但后端选型上大家一时拿不准主意。当时我们团队虽然主要是 Java 栈出身,但也一直在寻找快速构建原型的方式。Python 在数据分析领域的强大生态吸引了不少关注,而 Django 作为一个成熟的 Web 框架,也被列入了候选名单。

作为团队里对 Python 比较熟悉的一员,我就接下了这个任务:用 Django 快速搭出一套基础架构,支撑起整个系统的核心功能。那也是我第一次真正意义上独立完成一个完整的网站项目,过程中踩了不少坑,也积累了很多经验。今天写这篇文章,不是为了展示多么高深的技术,而是想以第一人称的角度,把那些实际遇到的问题、解决的思路以及学到的经验分享出来,希望能帮到刚开始学习 Django 的你。

项目背景与挑战:不只是一个小网站

项目背景与挑战:不只是一个小网站

我们最初的需求很明确:

  1. 用户可以注册、登录
  2. 可以上传文档(PDF、Markdown 等格式)
  3. 文档支持分类、标签管理
  4. 支持全文搜索(模糊匹配 + 关键词)
  5. 基础权限控制:管理员、普通用户角色区分

听起来似乎不复杂,但真实开发中才发现问题远没那么简单。首先是时间压力 —— 上线周期只有三周;其次,我们还要考虑后期扩展性,毕竟谁也不能保证这个知识库未来不会承载更多业务场景。

更现实的是,团队成员大多是 Java 出身,我对 Django 的了解其实还停留在“会看懂示例代码”的阶段,并没有真正开发过大型项目。怎么在有限的时间内搭建起结构清晰、易于维护的系统,成了我面临的首要问题。

为什么选择 Django?

微服务架构示意图-1

为什么选择 Django?

在综合考量了几个方案之后,我最终选择了 Django。原因有以下几点:

  • 开发效率高:自带 ORM 和 Admin 后台,很多重复的工作可以直接跳过。
  • 安全性好:内置 CSRF、SQL 注入防护等机制,避免新手犯低级错误。
  • 成熟稳定:社区活跃,文档齐全,遇到问题基本上都能找到答案。
  • 适合中小型项目:Django 的整体设计非常适合快速迭代,尤其适合初创或 MVP 场景。

另外,在部署方面,Django 对主流服务器(比如 Nginx + Gunicorn)的支持也很完善,运维成本不高,这对我们这样一个非全栈 Python 团队来说非常重要。

技术方案设计:先画蓝图再动手

架构设计

我们的整体架构采用前后端分离模式:

Vue.js (前端) <-> REST API (Django) <-> PostgreSQL / Redis

前端负责渲染页面、调用接口;后端通过 DRF(Django REST framework)提供标准化接口;数据库使用 PostgreSQL,Redis 用于缓存搜索结果和 Token 管理。

数据库设计

数据模型围绕“用户-文档-分类-标签”四个核心实体展开:

  • 用户表:继承 Django 内置 User 模型,添加头像、手机号字段
  • 文档表:存储文件路径、元数据、标签关系、所属分类等信息
  • 分类表:树状结构,支持多级分类(使用 django-mptt 实现)
  • 标签表:扁平结构,与文档形成多对多关联

其中文档与标签的关系是典型的 ManyToManyField,这里需要注意中间表的设计是否合理,是否支持额外属性(例如权重)。

接口设计原则

RESTful 是基本原则,同时遵循一些实用主义做法:

  • 返回统一结构:{ "code": 0, "data": {}, "message": "" }
  • 使用 JWT 做认证鉴权(借助 djangorestframework-simplejwt)
  • 分页统一为 offset/limit 形式
  • 所有增删改操作返回完整对象,避免客户端二次查询

代码实践:关键模块实现

接下来我会贴一些关键代码片段,帮助你理解如何落地这些设计。

初始化项目结构

django-admin startproject knowledge_base
cd knowledge_base
python manage.py startapp documents users

推荐每个功能模块单独建 app,方便解耦和后期迁移。我们在主项目的 settings.py 中配置 app:

INSTALLED_APPS = [
    'rest_framework',
    'rest_framework_simplejwt',
    'drf_yasg',  # 接口文档工具
    'users.apps.UsersConfig',
    'documents.apps.DocumentsConfig',
]

用户模型自定义

为了让用户支持头像、手机号等字段,我们需要继承默认的 User 模型:

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

class CustomUser(AbstractUser):
    avatar = models.ImageField(upload_to='avatars/')
    phone = models.CharField(max_length=20)

别忘了在 settings.py 中指定:

AUTH_USER_MODEL = 'users.CustomUser'

文档模型定义

from django.db import models
from users.models import CustomUser

class Document(models.Model):
    name = models.CharField("标题", max_length=200)
    file = models.FileField(upload_to="documents/%Y/%m/%d")
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    tags = models.ManyToManyField('Tag')
    upload_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    create_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

序列化器(DRF)

from rest_framework import serializers
from documents.models import Document

class DocumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Document
        fields = "__all__"

视图逻辑(基于 GenericAPIView)

from rest_framework.generics import ListCreateAPIView
from documents.models import Document
from .serializers import DocumentSerializer

class DocumentList(ListCreateAPIView):
    queryset = Document.objects.all()
    serializer_class = DocumentSerializer

URL 路由配置

from django.urls import path
from documents.views import DocumentList

urlpatterns = [
    path('documents/', DocumentList.as_view()),
]

整个流程走下来你会发现,Django+DRF 的组合真的非常高效,尤其是在 CRUD 场景下几乎不用手动写 SQL。

遇到的坑和解决方案

下面是一些我在实际开发中遇到的真实问题及解决方式:

1. 大文件上传超时

初期我们用普通的 FileField 存储文档,但由于有些 PDF 文件较大(超过 100MB),前端上传时常出现超时。我们最终采用了两种方式优化:

  • 客户端分片上传(Vue + Dropzone.js 实现)
  • 后端使用 chunked_upload 插件处理断点续传
pip install drf-chunked-upload

然后配置路由即可,这部分插件封装得非常好,集成简单。

2. 全文搜索性能差

一开始我们用简单的 contains 做关键词搜索,但在数据量达到几千条后明显变慢。后来引入了 Elasticsearch 做搜索引擎:

  • 利用 django-elasticsearch-dsl 同步数据到 ES
  • 单独建立索引类:
from django_elasticsearch_dsl.documents import Document
from documents.models import Document as DocModel

@registry.register_document
class DocDocument(Document):
    class Index:
        name = 'documents'

    class Django:
        model = DocModel
        fields = [
            'name',
            'content',  # 文档内容
        ]

搜索接口就变成了直接调用 ES,性能提升非常明显。

3. JWT Token 刷新逻辑混乱

起初我们用 DRF SimpleJWT 默认的刷新机制,但由于前端需要定时刷新 Token,导致部分请求失败。我们后来统一用 Axios 封装了一层拦截器来自动刷新:

axios.interceptors.response.use(
  response => response,
  async error => {
    if (error.response.status === 401) {
      const refreshToken = localStorage.getItem('refresh');
      // 请求刷新Token
      const res = await refreshTokenApi(refreshToken);
      localStorage.setItem('access', res.access);
      // 重新发送原请求
      return axios(error.config);
    }
    return Promise.reject(error);
  }
)

这样用户体验更好,也能减少因 Token 过期带来的请求失败。

效果总结:系统上线后的表现

项目最终如期上线,运行至今已将近一年。目前支撑了公司内部的几十个部门使用,每天活跃用户约 200 多人,文档总量突破 8000 篇。

从运维角度看,Django 表现得很稳定。部署环境是 Ubuntu + Nginx + Gunicorn,通过 supervisor 管理进程。内存占用控制得也不错,一台 4GB 的机器就能轻松应付日常请求。日志、错误监控我们用的是 Sentry,排查问题也方便。

我的一些建议和注意事项

如果你正准备开始自己的第一个 Django 项目,以下几点是我亲身体会后的建议:

1. 结构清晰比代码短更重要

Django 的灵活性有时候反而容易让人陷入“随意组织目录”的误区。我的建议是:

  • 功能模块按功能拆分为不同 app
  • 每个 app 内部保持一致性结构(models、views、urls、serializers 等)
  • 不要怕文件多,合理的拆分反而更容易维护

2. ORM 虽好,但别滥用

Django ORM 确实非常强大,但有些复杂的查询还是建议用 raw 或者用数据库函数。记得定期用 query.count() 查看执行次数,避免产生 N+1 查询问题。

3. 认证鉴权早做规划

一开始就应该确定认证机制,不要等到后期再去补。JWT 是一个很好的选择,但也要注意 Token 的管理和刷新策略。

4. 接口文档一定要做

不要小看接口文档的作用。我们项目一开始就引入了 Swagger UI(drf-yasg),这对前后端协作起到了很大帮助。即使你是单兵作战,也建议坚持写注释文档,后期维护的时候你会感谢自己。

5. 性能优化要趁早

虽然 Django 本身性能不错,但在数据量增长后,如果不做任何优化,还是会慢慢“卡起来”。建议:

  • 数据库加合适的索引
  • 查询尽量 select_related/prefetch_related
  • 缓存常用数据(Redis)
  • 耗时操作异步化(Celery)

6. 学会看日志、查文档

Django 的报错信息通常都很详细,遇到问题不妨先看看日志。官方文档和 Stack Overflow 是解决问题的最好资源。此外,GitHub 上的 Issues 区域往往藏着意想不到的答案。

结语:每一个大工程都是从一行代码开始的

回过头来看,当初那个紧张兮兮地照着教程一步步来的我,现在也慢慢有了自己的开发习惯和判断力。Django 确实是一个值得投入学习的框架,它不仅帮你节省时间,更是在潜移默化中让你养成良好的工程思维。

希望这篇实战经验分享能给你带来一些启发和信心。无论你现在处于什么水平,只要你肯动手写,坚持查文档、问问题、解决问题,相信你很快也能写出属于自己的第一个 Django 网站。

愿你在技术路上越走越稳,码出精彩人生!

评论 0

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