Django 从 0 到 1 打造完整电商平台:项目基础配置与静态文件处理

IT策士 | 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在公众号、今日头条持续发布最新文章,助你少走弯路。


大家好,我是IT策士。前面四节课,我们完成了项目骨架、数据库设计、Admin 后台,还灌入了第一批数据,项目已经有了"里子"。这一篇我们要给项目穿上一件"漂亮的外衣"——整合 Bootstrap 5,搭建统一的前端基础框架。

你可能会问:做后端开发,为什么要学静态文件处理?实际上,Django 是一个全栈框架,模板和静态文件的管理贯穿整个项目。CSS、JS、图片该怎么放?开发环境如何访问用户上传的文件?模板继承怎么设计?这些都是开发初期必须搞定的基础配置,后面写视图时才能行云流水。


一、静态文件与媒体文件——分清两个概念

Django 将"文件"分为两类,很多初学者会混淆:

类型 来源 典型文件 配置项
静态文件 开发者提供,属于项目的一部分 CSS、JS、字体、Logo STATIC_URL / STATICFILES_DIRS
媒体文件 用户上传,运行时产生 商品图片、用户头像 MEDIA_URL / MEDIA_ROOT

简单记法:静态文件是你给项目的,媒体文件是用户给项目的。


二、配置模板目录

第 1 篇我们创建了空的 templates/ 目录,现在是时候让它发挥作用了。

打开 django_ecommerce/settings.py,找到 TEMPLATES 配置,确保 DIRS 中有模板目录的路径:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],   # 全局模板目录
        'APP_DIRS': True,                    # 同时查找各 app 下的 templates
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

APP_DIRS: True 意味着 Django 也会在每个已注册 app 的 templates/ 子目录下查找模板。后面我们会为每个 app 创建专属模板,但公共的基础模板放在全局 templates/ 中。


三、配置静态文件

3.1 下载 Bootstrap 5

访问 Bootstrap 官网 下载编译好的 CSS 和 JS 文件,或者直接用我提供的 CDN 方式(生产环境建议本地化)。

我们先采用本地化的方式,把文件放在项目里,这样离线也能开发。

在项目根目录创建静态文件目录结构:

mkdir -p static/css
mkdir -p static/js
mkdir -p static/images

然后把下载的 bootstrap.min.css 放到 static/css/bootstrap.bundle.min.js 放到 static/js/

如果你不想手动下载,也可以暂时用 CDN 链接,我们在模板里直接用 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> 这样的方式引入。本文两种方式都会演示。

3.2 配置 settings.py

django_ecommerce/settings.py 中添加静态文件与媒体文件的配置(通常放在文件末尾):

# 静态文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static',   # 全局静态文件目录
]
# 生产环境收集静态文件的目录
STATIC_ROOT = BASE_DIR / 'staticfiles'

# 媒体文件配置
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

解释:

  • STATICFILES_DIRS:告诉 Django 开发时去哪里找静态文件。

  • STATIC_ROOT:生产环境下执行 collectstatic 后所有静态文件汇总到的目录。

  • MEDIA_ROOT:用户上传文件存储的物理路径。

  • MEDIA_URL:访问用户上传文件的 URL 前缀。


四、创建基础模板 base.html

前端页面通常有共同的头部(导航栏)和底部,我们可以通过 Django 的模板继承机制来避免重复代码。

templates/ 下创建 base.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Django 电商平台{% endblock %}</title>
    <!-- Bootstrap 5 本地静态文件 -->
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <!-- 自定义全局样式 -->
    <style>
        body {
            padding-top: 70px;
            background-color: #f8f9fa;
        }
        .navbar-brand {
            font-weight: bold;
            letter-spacing: 1px;
        }
    </style>
    {% block extra_css %}{% endblock %}
</head>
<body>
    <!-- 顶部导航栏 -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
        <div class="container">
            <a class="navbar-brand" href="{% url 'home' %}">🛒 Django商城</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                    data-bs-target="#navbarNav" aria-controls="navbarNav"
                    aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'home' %}">首页</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">商品</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">购物车</a>
                    </li>
                    {% if user.is_authenticated %}
                        <li class="nav-item">
                            <span class="nav-link text-light">欢迎,{{ user.username }}</span>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'admin:index' %}">后台</a>
                        </li>
                    {% else %}
                        <li class="nav-item">
                            <a class="nav-link" href="#">登录</a>
                        </li>
                    {% endif %}
                </ul>
            </div>
        </div>
    </nav>

    <!-- 消息框架占位(第 10 篇会用) -->
    <div class="container mt-3">
        {% if messages %}
            {% for message in messages %}
                <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
                    {{ message }}
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            {% endfor %}
        {% endif %}
    </div>

    <!-- 主体内容 -->
    <main class="container">
        {% block content %}{% endblock %}
    </main>

    <!-- 页脚 -->
    <footer class="bg-dark text-light text-center py-3 mt-5">
        <div class="container">
            <p class="mb-0">&copy; 2026 Django 电商平台 | 实战项目系列</p>
        </div>
    </footer>

    <!-- Bootstrap JS -->
    <script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
    {% block extra_js %}{% endblock %}
</body>
</html>

模板关键点解读:

  • {% load static %}:加载静态文件标签库,之后才能用 {% static 'path' %} 引用静态文件。

  • {% block title %} / {% block content %}:定义可被子模板覆盖的"插槽"。

  • {% url 'home' %}:命名路由,我们稍后在 urls.py 中配置。

  • {% if user.is_authenticated %}:Django 模板自带变量 user,可直接判断登录状态。

  • {% block extra_css %} / {% block extra_js %}:预留给子页面引入各自的样式和脚本。


五、配置首页路由与视图

一个网站总得有个首页,现在就来创建最简单的首页。

5.1 编辑项目 urls.py

打开 django_ecommerce/urls.py

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    # 临时首页,后续会替换为真正的首页视图
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
]

# 开发环境下提供媒体文件的访问路由
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

关键点static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 这行代码,仅在 DEBUG=True 时生效,让开发服务器能够直接响应 /media/ 路径下的文件请求。生产环境应交给 Nginx 处理,第 27 篇会讲到。

5.2 创建首页模板

templates/ 下创建 home.html

{% extends 'base.html' %}
{% load static %}

{% block title %}首页 - Django 电商平台{% endblock %}

{% block content %}
<div class="text-center py-5">
    <h1 class="display-4 fw-bold">欢迎来到 Django 商城</h1>
    <p class="lead text-muted">从 0 到 1,用 Django 打造完整电商平台</p>
    <hr class="my-4">
    <p>本项目涵盖用户系统、商品管理、购物车、订单支付、部署上线等完整功能。</p>
    <a class="btn btn-primary btn-lg me-2" href="#" role="button">浏览商品</a>
    <a class="btn btn-outline-secondary btn-lg" href="#" role="button">了解更多</a>
</div>

<!-- 功能特色卡片 -->
<div class="row mt-5 g-4">
    <div class="col-md-4">
        <div class="card shadow-sm h-100">
            <div class="card-body text-center">
                <h5 class="card-title">📦 商品管理</h5>
                <p class="card-text">SPU/SKU 设计、分类管理、图片展示</p>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="card shadow-sm h-100">
            <div class="card-body text-center">
                <h5 class="card-title">🛒 购物车</h5>
                <p class="card-text">增删改查、勾选结算、库存校验</p>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="card shadow-sm h-100">
            <div class="card-body text-center">
                <h5 class="card-title">💳 支付集成</h5>
                <p class="card-text">支付宝沙箱支付、状态同步</p>
            </div>
        </div>
    </div>
</div>
{% endblock %}

5.3 启动服务器看效果

python manage.py runserver

访问 http://127.0.0.1:8000/,你会看到一个漂亮的首页,顶部导航栏固定在顶端,中间是欢迎语和功能卡片,底部是页脚。

浏览器中应看到:

  • 深色导航栏,显示"Django商城"和菜单项。

  • 主标题"欢迎来到 Django 商城"居中展示。

  • 下方三张功能卡片:商品管理、购物车、支付集成。

  • 底部版权信息。


六、验证静态文件是否正确加载

6.1 检查控制台输出

启动服务器时,留意终端输出。当你访问首页时,Django 会处理静态文件请求,你应该看到类似:

[20/May/2026 10:30:15] "GET / HTTP/1.1" 200 2845
[20/May/2026 10:30:15] "GET /static/css/bootstrap.min.css HTTP/1.1" 200 232148
[20/May/2026 10:30:15] "GET /static/js/bootstrap.bundle.min.js HTTP/1.1" 200 80245

HTTP 200 意味着静态文件都被正确加载了。

6.2 浏览器开发者工具验证

打开 Chrome 开发者工具(F12),切换到 Network 标签,刷新页面,你应该看到 bootstrap.min.cssbootstrap.bundle.min.js 都返回 200。如果出现 404,检查文件是否放对了位置,以及 STATICFILES_DIRS 配置是否正确。

6.3 媒体文件测试

我们在 media/ 目录下放一张测试图片:

mkdir -p media/test
# 随便复制一张图片过来,比如 test.jpg

然后访问 http://127.0.0.1:8000/media/test/test.jpg,如果能显示图片,说明媒体文件配置也正确。


七、模板继承实战——为后续 app 做准备

后面每个 app 都会有各自的模板,我们来提前建立好目录结构:

mkdir -p apps/users/templates/users
mkdir -p apps/products/templates/products
mkdir -p apps/cart/templates/cart
mkdir -p apps/orders/templates/orders
mkdir -p apps/payment/templates/payment

每个 app 下的模板遵循 Django 的命名约定:app名称/模板名.html。这样在视图里用 render(request, 'users/login.html') 就能正确找到模板,且不会与其他 app 的同名模板冲突。


八、一个小优化——自定义 404 和 500 页面

趁热打铁,我们在全局 templates/ 下创建两个错误页面,提升用户体验。

templates/404.html:

{% extends 'base.html' %}
{% block title %}页面未找到 - 404{% endblock %}
{% block content %}
<div class="text-center py-5">
    <h1 class="display-1 text-muted">404</h1>
    <p class="lead">抱歉,您访问的页面不存在。</p>
    <a href="{% url 'home' %}" class="btn btn-primary">返回首页</a>
</div>
{% endblock %}

templates/500.html:

{% extends 'base.html' %}
{% block title %}服务器错误 - 500{% endblock %}
{% block content %}
<div class="text-center py-5">
    <h1 class="display-1 text-muted">500</h1>
    <p class="lead">服务器开小差了,请稍后重试。</p>
    <a href="{% url 'home' %}" class="btn btn-primary">返回首页</a>
</div>
{% endblock %}

Django 会在这个路径下自动查找 404.html500.html(需要 DEBUG=False 才能看到 500 页面,但提前建好准没错)。


九、当前完整的 settings.py 关键配置一览

为了方便你检查,我整理了到本篇为止 settings.py 中新增的关键配置(不含 Django 默认项):

import os
import sys
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

# ... INSTALLED_APPS 中包含 users, products, cart, orders, payment ...

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

AUTH_USER_MODEL = 'users.User'

# 模板
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        # ...
    },
]

# 静态文件
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles'

# 媒体文件
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# Admin 定制
ADMIN_SITE_HEADER = "电商后台管理系统"
ADMIN_SITE_TITLE = "电商管理"
ADMIN_INDEX_TITLE = "欢迎使用电商管理后台"

十、总结与下集预告

今篇我们把项目的前端"地基"搭好了,完成了:

  • ✅ 配置了模板目录与静态文件目录

  • ✅ 引入 Bootstrap 5,编写了全局 base.html 基础模板

  • ✅ 创建了首页视图和路由,体验了模板继承机制

  • ✅ 配置了媒体文件访问,测试了静态文件加载

  • ✅ 提前为各 app 建好了模板子目录,预留 404/500 页面

现在你的项目打开浏览器不再是一片空白,而是一个有导航栏、有卡片、有页脚的漂亮页面。从下一篇开始,我们终于要进入用户系统的实战开发了。第 6 篇,我们将实现用户注册功能,包括手机号验证码、邮箱激活等核心流程,真正写出第一个业务视图。

有任何疑问欢迎留言。

想了解更多还可以去公众号、今日头条搜索「IT策士」,一起升级 IT 思维 !


本文为《Django 从 0 到 1 打造完整电商平台》系列第 5 篇,作者:IT策士,未经授权禁止转载。

posted @ 2026-05-20 19:23  IT策士  阅读(4)  评论(0)    收藏  举报