从零搭建第一个 Django 网站:一场真实项目的实战记录

掘金独行侠
2025-06-15 23:23
阅读 582

引言:为什么我决定用 Django 来开始我的网站项目?

引言:为什么我决定用 Django 来开始我的网站项目?

去年年底,我接了一个小需求——为客户做一个内部使用的内容管理系统(CMS),用于管理他们的产品信息、促销活动和员工资料。客户希望这个系统能在几个月内上线,并且要稳定可靠。

一开始,我考虑过很多技术栈,比如 Flask 自己搭轮子、Node.js + Express 的方案等等。但综合评估下来,Django 成为了最终的选择。原因很简单:快速开发、内置 Admin、ORM 方便、生态成熟。

这虽然不是我第一次接触 Python Web 开发,却是我第一次真正意义上从零开始搭建一个完整的 Django 项目。这篇技术文章,就记录下我当时的整个过程、遇到的坑、踩过的雷,以及最后的收获。


问题描述:如何在一个星期之内交付一个可用的 CMS 系统?

问题描述:如何在一个星期之内交付一个可用的 CMS 系统?

客户的项目周期紧张,要求在一周内完成基本功能开发。而我的挑战不仅仅是时间,还包括:

  • 对 Django 的熟悉程度停留在理论阶段,实际动手不多;
  • 需要同时处理后端 API 和前端页面展示;
  • 数据模型设计需要兼顾扩展性和维护性;
  • 没有专职前端同学支持,只能自己搞定前后端联调;
  • 希望部署到云服务器上,方便后续运维和升级。

这些问题让我一度很焦虑。于是我制定了一个清晰的时间计划,先把重点放在数据结构的设计和接口实现上,再逐步补全前端交互。


解决思路:以 Django 为基石,架构先行

解决思路:以 Django 为基石,架构先行

我决定按照以下步骤进行:

  1. 先定义清楚业务逻辑与数据模型
  2. 快速搭建 RESTful 接口
  3. 使用 Django Admin 实现基础后台管理
  4. 基于模板系统渲染前端页面
  5. 简单集成静态资源和前端样式
  6. 部署上线前做性能优化

整个系统的架构如下图所示(文字描述):

[浏览器]
   |
[前端模板页面] ←→ [Django 模板引擎]
   |
[RESTful API] ←→ [DRF 路由/序列化器]
   |
[数据库] ←→ [Django ORM]
   |
[Admin 后台] ←→ [用户权限管理]

关键代码实践:从 Model 到 View 的完整流程

关键代码实践:从 Model 到 View 的完整流程

第一步:定义数据模型

以“商品”为例,我首先设计了如下的 models:

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100, verbose_name="商品名称")
    description = models.TextField(verbose_name="商品描述", blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="价格")
    stock = models.PositiveIntegerField(default=0, verbose_name="库存")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "商品"
        ordering = ["-created_at"]

这一段定义非常标准,但值得注意的是,我在每个字段都加上了 verbose_name,这是为了后期在 Admin 上显示得更友好。另外还加了排序规则,提升用户体验。

第二步:配置 DRF 序列化器和视图

我采用 Django REST Framework(DRF)来构建 API,这样可以让前后端分离更容易:

from rest_framework import serializers, viewsets
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

路由部分直接用了 DRF 提供的 router:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register(r'products', ProductViewSet)

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

第三步:启用 Admin 并添加数据模型

admin.py 中添加注册信息即可:

from django.contrib import admin
from .models import Product

admin.site.register(Product)

登录 /admin 页面后,你就可以看到自动构建的商品管理界面,不需要写任何 UI 代码,非常省事!

第四步:使用模板系统构建页面

为了展示商品列表,我创建了简单的模板页面:

在 views.py 中编写视图函数:

from django.shortcuts import render
from .models import Product

def product_list(request):
    products = Product.objects.all()
    return render(request, 'product/list.html', {'products': products})

添加 URL 映射:

from .views import product_list

urlpatterns += [
    path('products/', product_list, name='product_list'),
]

创建 HTML 模板(templates/product/list.html):

<!DOCTYPE html>
<html>
<head>
    <title>商品列表</title>
</head>
<body>
    <h1>我们的商品</h1>
    {% for product in products %}
        <div>
            <h2>{{ product.name }}</h2>
            <p>{{ product.description }}</p>
            <p>价格: {{ product.price }} 元</p>
        </div>
    {% endfor %}
</body>
</html>

通过这种方式,前后端都可以复用 API 和模板,效率大大提升。


踩坑经验分享:那些让人崩溃又值得总结的瞬间

坑一:迁移失败导致本地 DB 无法同步

在本地调试时,经常修改字段或重命名表,有时候会忘记运行 makemigrations,或者误删了 migration 文件。结果就是出现各种 relation does not exist 错误。

解决办法:

  1. 备份数据库后清空并重新生成迁移文件
  2. 使用 migrate --fake-initial 命令绕过某些历史错误
  3. 更好的做法是统一版本,避免多人协作中的冲突

坑二:静态文件部署不生效

上线之后发现 CSS、JS 文件访问 404。

原因:
生产环境下 Django 不会自动处理静态文件。必须使用 Nginx 或设置 STATIC_ROOT,并执行 collectstatic。

解决方法:

python manage.py collectstatic

并且在 settings.py 中配置:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

如果你用的是 Gunicorn + Nginx 架构,记得让 Nginx 托管静态资源。

坑三:跨域请求被浏览器拦截

我原本打算把前端单独拆出来做一个单页应用(SPA),但由于时间限制,临时决定还是走模板渲染。但在实验过程中,尝试用 fetch 请求 Django API 时遇到了 CORS 报错。

解决方式:
安装 django-cors-headers 插件,在 settings.py 中加入:

INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

CORS_ORIGIN_ALLOW_ALL = True  # 生产建议配置白名单

效果总结:一周完成了不可能的任务?

最终我们按期上线了系统,虽然还有些粗糙,但也足够支撑客户初期的需求。他们反馈说:

“比之前外包公司做的快多了,而且界面简洁直观。”

对于我来说,这次项目不仅是对 Django 快速开发能力的一次验证,也让我深刻体会到:

  • 架构设计的重要性远大于编码本身
  • Django 的 batteries-included 特性极大地提升了开发效率
  • 即使没有前端,也可以通过模板系统满足基本需求
  • 合理利用社区插件可以少造很多轮子

经验分享:给刚入门 Django 的朋友几点建议

  1. 从模型设计出发,明确数据关系
    Django 的 ORM 很强大,但前期设计得好才能减少后续改表痛苦。

  2. 优先使用 Admin,别急着写后台页面
    Admin 是快速验证业务逻辑的好工具,尤其适合 MVP 阶段。

  3. 结合 DRF,打造标准化的接口体系
    如果未来想前后端分离,现在就把 API 接口规范起来。

  4. 合理使用中间件和第三方库
    比如 logging、debug_toolbar、drf-spectacular 自动生成文档等。

  5. 关注性能,尤其是 QuerySet 使用方式
    尽量少嵌套查询、多用 select_related、prefetch_related。

  6. 尽早部署测试环境
    有些坑只有在线上才能发现,提前跑通一遍部署流程能节省大量时间。


最后的话:选择 Django,是技术也是信心的选择

作为一位从 Spring 过渡过来的开发者,我可以负责任地说:Django 确实是一个非常适合快速开发的框架。它不像 Node.js 那样自由散漫,也不像 Java 那样笨重复杂,它刚好站在合适的位置上——够灵活,又不失约束力

如果你正准备进入 Web 开发领域,或者正在寻找一个能帮助你高效完成功能的工具,那么 Django 绝对值得一试。

当然,它不是万能的,但它绝对是你通往专业 Python 开发者道路上的必经之路。


作者注:
本文基于我在 2023 年底的一个真实项目经历整理而成,内容经过简化与提炼,但仍保留核心实现思路。如有疏漏欢迎留言交流。

评论 0

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