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">© 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.css 和 bootstrap.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.html 和 500.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策士,未经授权禁止转载。

静态文件、媒体文件傻傻分不清?模板继承怎么写才不重复?这篇带你理顺 Django 静态资源全配置,整合 Bootstrap 5 搭建统一前端骨架,写出可复用的 base 模板,为后续业务开发铺好路!
浙公网安备 33010602011771号