Django 從 0 到 1 打造完整電商平臺:項目基礎(chǔ)配置與靜態(tài)文件處理

IT策士 | 10余年一線大廠經(jīng)驗,專注 IT 思維、架構(gòu)、職場進階。我會在公眾號、今日頭條持續(xù)發(fā)布最新文章,助你少走彎路。


大家好,我是IT策士。前面四節(jié)課,我們完成了項目骨架、數(shù)據(jù)庫設(shè)計、Admin 后臺,還灌入了第一批數(shù)據(jù),項目已經(jīng)有了"里子"。這一篇我們要給項目穿上一件"漂亮的外衣"——整合 Bootstrap 5,搭建統(tǒng)一的前端基礎(chǔ)框架。

你可能會問:做后端開發(fā),為什么要學靜態(tài)文件處理?實際上,Django 是一個全??蚣?,模板和靜態(tài)文件的管理貫穿整個項目。CSS、JS、圖片該怎么放?開發(fā)環(huán)境如何訪問用戶上傳的文件?模板繼承怎么設(shè)計?這些都是開發(fā)初期必須搞定的基礎(chǔ)配置,后面寫視圖時才能行云流水。


一、靜態(tài)文件與媒體文件——分清兩個概念

Django 將"文件"分為兩類,很多初學者會混淆:

類型 來源 典型文件 配置項
靜態(tài)文件 開發(fā)者提供,屬于項目的一部分 CSS、JS、字體、Logo STATIC_URL / STATICFILES_DIRS
媒體文件 用戶上傳,運行時產(chǎn)生 商品圖片、用戶頭像 MEDIA_URL / MEDIA_ROOT

簡單記法:靜態(tài)文件是你給項目的,媒體文件是用戶給項目的。


二、配置模板目錄

第 1 篇我們創(chuàng)建了空的 templates/ 目錄,現(xiàn)在是時候讓它發(fā)揮作用了。

打開 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 創(chuàng)建專屬模板,但公共的基礎(chǔ)模板放在全局 templates/ 中。


三、配置靜態(tài)文件

3.1 下載 Bootstrap 5

訪問 Bootstrap 官網(wǎng) 下載編譯好的 CSS 和 JS 文件,或者直接用我提供的 CDN 方式(生產(chǎn)環(huán)境建議本地化)。

我們先采用本地化的方式,把文件放在項目里,這樣離線也能開發(fā)。

在項目根目錄創(chuàng)建靜態(tài)文件目錄結(jié)構(gòu):

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 > 這樣的方式引入。本文兩種方式都會演示。

3.2 配置 settings.py

django_ecommerce/settings.py 中添加靜態(tài)文件與媒體文件的配置(通常放在文件末尾):

# 靜態(tài)文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / 'static',   # 全局靜態(tài)文件目錄
]
# 生產(chǎn)環(huán)境收集靜態(tài)文件的目錄
STATIC_ROOT = BASE_DIR / 'staticfiles'

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

解釋:

  • STATICFILES_DIRS:告訴 Django 開發(fā)時去哪里找靜態(tài)文件。

  • STATIC_ROOT:生產(chǎn)環(huán)境下執(zhí)行 collectstatic 后所有靜態(tài)文件匯總到的目錄。

  • MEDIA_ROOT:用戶上傳文件存儲的物理路徑。

  • MEDIA_URL:訪問用戶上傳文件的 URL 前綴。


四、創(chuàng)建基礎(chǔ)模板 base.html

前端頁面通常有共同的頭部(導航欄)和底部,我們可以通過 Django 的模板繼承機制來避免重復代碼。

templates/ 下創(chuàng)建 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 本地靜態(tài)文件 -->
    {% 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>

    <!-- 主體內(nèi)容 -->
    <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 電商平臺 | 實戰(zhàn)項目系列</p>
        </div>
    </footer>

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

模板關(guān)鍵點解讀:

  • {% load static %}:加載靜態(tài)文件標簽庫,之后才能用 {% static 'path' %} 引用靜態(tài)文件。

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

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

  • {% if user.is_authenticated %}:Django 模板自帶變量 user,可直接判斷登錄狀態(tài)。

  • {% block extra_css %} / {% block extra_js %}:預留給子頁面引入各自的樣式和腳本。


五、配置首頁路由與視圖

一個網(wǎng)站總得有個首頁,現(xiàn)在就來創(chuàng)建最簡單的首頁。

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),
    # 臨時首頁,后續(xù)會替換為真正的首頁視圖
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
]

# 開發(fā)環(huán)境下提供媒體文件的訪問路由
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

關(guān)鍵點static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 這行代碼,僅在 DEBUG=True 時生效,讓開發(fā)服務器能夠直接響應 /media/ 路徑下的文件請求。生產(chǎn)環(huán)境應交給 Nginx 處理,第 27 篇會講到。

5.2 創(chuàng)建首頁模板

templates/ 下創(chuàng)建 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>本項目涵蓋用戶系統(tǒng)、商品管理、購物車、訂單支付、部署上線等完整功能。</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 設(shè)計、分類管理、圖片展示</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">增刪改查、勾選結(jié)算、庫存校驗</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">支付寶沙箱支付、狀態(tài)同步</p>
            </div>
        </div>
    </div>
</div>
{% endblock %}

5.3 啟動服務器看效果

python manage.py runserver

訪問 http://127.0.0.1:8000/,你會看到一個漂亮的首頁,頂部導航欄固定在頂端,中間是歡迎語和功能卡片,底部是頁腳。

瀏覽器中應看到:

  • 深色導航欄,顯示"Django商城"和菜單項。

  • 主標題"歡迎來到 Django 商城"居中展示。

  • 下方三張功能卡片:商品管理、購物車、支付集成。

  • 底部版權(quán)信息。


六、驗證靜態(tài)文件是否正確加載

6.1 檢查控制臺輸出

啟動服務器時,留意終端輸出。當你訪問首頁時,Django 會處理靜態(tài)文件請求,你應該看到類似:

[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 意味著靜態(tài)文件都被正確加載了。

6.2 瀏覽器開發(fā)者工具驗證

打開 Chrome 開發(fā)者工具(F12),切換到 Network 標簽,刷新頁面,你應該看到 bootstrap.min.cssbootstrap.bundle.min.js 都返回 200。如果出現(xiàn) 404,檢查文件是否放對了位置,以及 STATICFILES_DIRS 配置是否正確。

6.3 媒體文件測試

我們在 media/ 目錄下放一張測試圖片:

mkdir -p media/test
# 隨便復制一張圖片過來,比如 test.jpg

然后訪問 http://127.0.0.1:8000/media/test/test.jpg,如果能顯示圖片,說明媒體文件配置也正確。


七、模板繼承實戰(zhàn)——為后續(xù) app 做準備

后面每個 app 都會有各自的模板,我們來提前建立好目錄結(jié)構(gòu):

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 的同名模板沖突。


八、一個小優(yōu)化——自定義 404 和 500 頁面

趁熱打鐵,我們在全局 templates/ 下創(chuàng)建兩個錯誤頁面,提升用戶體驗。

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 關(guān)鍵配置一覽

為了方便你檢查,我整理了到本篇為止 settings.py 中新增的關(guān)鍵配置(不含 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,
        # ...
    },
]

# 靜態(tài)文件
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 = "電商后臺管理系統(tǒng)"
ADMIN_SITE_TITLE = "電商管理"
ADMIN_INDEX_TITLE = "歡迎使用電商管理后臺"

十、總結(jié)與下集預告

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

  • ? 配置了模板目錄與靜態(tài)文件目錄

  • ? 引入 Bootstrap 5,編寫了全局 base.html 基礎(chǔ)模板

  • ? 創(chuàng)建了首頁視圖和路由,體驗了模板繼承機制

  • ? 配置了媒體文件訪問,測試了靜態(tài)文件加載

  • ? 提前為各 app 建好了模板子目錄,預留 404/500 頁面

現(xiàn)在你的項目打開瀏覽器不再是一片空白,而是一個有導航欄、有卡片、有頁腳的漂亮頁面。從下一篇開始,我們終于要進入用戶系統(tǒng)的實戰(zhàn)開發(fā)了。第 6 篇,我們將實現(xiàn)用戶注冊功能,包括手機號驗證碼、郵箱激活等核心流程,真正寫出第一個業(yè)務視圖。

有任何疑問歡迎留言。

想了解更多還可以去公眾號、今日頭條搜索「IT策士」,一起升級 IT 思維 !


本文為《Django 從 0 到 1 打造完整電商平臺》系列第 5 篇,作者:IT策士,未經(jīng)授權(quán)禁止轉(zhuǎn)載。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容