本文基于 Django 5.x 环境,从零到一完整实现两大核心任务:

  • 任务 1:将 Django 默认的 SQLite 数据库无缝迁移为 MySQL 数据库,包含环境配置、模型创建、迁移执行、数据读写全流程;
  • 任务 2:在 Django 项目中集成 Bootstrap 5 前端框架,完成页面美化与样式优化,并基于 CDN 方式实现 Vue 3 进阶版页面;
  • 全程附踩坑记录与解决方案,解决模板渲染、静态资源加载、文件夹创建、数据库连接等常见问题,适合 Django 初学者参考与作业复现。

一、开发环境准备

1.1 环境版本说明

表格

工具 / 库 版本 作用
Python 3.10+ 后端开发语言
Django 5.0.3+ Web 开发框架
MySQL 8.0+ 关系型数据库(任务 1 核心)
PyMySQL 1.1.0+ Python 操作 MySQL 的驱动
Bootstrap 5.3.2 前端 UI 框架(任务 2 核心)
jQuery 3.7.1 Bootstrap 依赖的 JavaScript 库
Vue 3.x(CDN) 进阶前端框架(可选,满足进阶要求)

1.2 环境搭建步骤

1.2.1 创建虚拟环境(避免版本冲突)

# 1. 进入项目根目录(如 E:\django-notes-main\django5)
cd E:\django-notes-main\django5

# 2. 创建虚拟环境(命名为 venv)
python -m venv venv

# 3. 激活虚拟环境(Windows PowerShell)
venv\Scripts\activate

# 4. 验证虚拟环境激活(终端前缀出现 (venv) 即成功)
(venv) PS E:\django-notes-main\django5>

1.2.2 安装核心依赖

# 安装 Django(指定版本,避免兼容性问题)
pip install django==5.0.3

# 安装 PyMySQL(MySQL 驱动,任务1必备)
pip install pymysql==1.1.0

# 验证安装
pip list
# 输出应包含:Django 5.0.3、PyMySQL 1.1.0

1.2.3 MySQL 数据库准备

1. 用MySQL创建数据库

方法 1:用 VS Code 自带的 Database Client 插件(最省事,不用额外装软件)

步骤:

  • 在插件栏钟下载好插件,点击 VS Code 左侧的「数据库」图标(就是那个像杯子 / 试管的图标,在搜索图标下面、运行图标上面)
  • 点击「添加连接」→ 选择「MySQL」
  • 填写连接信息:
    • 主机名:127.0.0.1
    • 端口:3306
    • 用户名:root
    • 密码:root(你 settings 里填的密码)
    • 数据库名:先留空(我们要新建)
  • 点击「连接」,成功后就能看到你的 MySQL 实例

  • 右键你的 MySQL 实例 → 选择「新建查询」
  • 在打开的查询窗口里,粘贴这句 SQL:
CREATE DATABASE database_demo DEFAULT CHARACTER SET utf8mb4;

点击「运行」(绿色三角按钮),看到「执行成功」就搞定了!

刷新一下,就能看到新建的database_demo数据库了

方法 2:用 MySQL 自带的命令行(最原生,适合新手)

步骤:

1. 按下Win+R,输入cmd,打开命令提示符

2. 进入 MySQL 的 bin 目录(如果配置了环境变量,直接跳过这步):

运行

cd C:\Program Files\MySQL\MySQL Server 8.0\bin

    3. 登录 MySQL:

    运行

    mysql -u root -p
    

    4. 输入你的 MySQL 密码(你 settings 里填的root),回车登录成功

    执行创建数据库的 SQL:

    CREATE DATABASE database_demo DEFAULT CHARACTER SET utf8mb4;
    

    5. 看到Query OK, 1 row affected就成功了!

    6. 可以用show databases;查看所有数据库,确认database_demo存在

    方法 3:用 Navicat(图形化工具,最直观)

    步骤:

    1. 打开 Navicat,点击「连接」→ 选择「MySQL」

    2. 填写连接信息:

    • 连接名:随便填(比如本地MySQL
    • 主机:127.0.0.1
    • 端口:3306
    • 用户名:root
    • 密码:root(你 settings 里的密码)

    3. 打开 Navicat,点击「连接」→ 选择「MySQL」

    4. 填写连接信息

    5. 点击「测试连接」,成功后确定,连接到 MySQL

    6. 右键连接名 → 选择「新建数据库」

    7. 数据库名填database_demo,字符集选utf8mb4,排序规则选utf8mb4_general_ci

    8. 点击「确定」,数据库就创建好了!

    二、任务 1:Django 切换 MySQL 数据库(全流程 + 踩坑)

    2.1 创建 Django 项目与应用

    2.1.1 创建项目

    # 确保在虚拟环境中,进入 django5 目录
    cd E:\django-notes-main\django5
    
    # 创建项目(命名为 database_demo,与作业对应)
    django-admin startproject database_demo
    
    # 进入项目目录
    cd database_demo
    

    2.1.2 创建 book 应用

    # 创建 book 应用(图书管理核心功能)
    python manage.py startapp book
    
    # 验证项目结构
    # 目录结构应为:
    # database_demo/
    # ├─ database_demo/  # 项目配置目录
    # ├─ book/          # 应用目录
    # └─ manage.py      # 项目管理脚本
    

    2.2 注册应用(settings.py)

    打开 database_demo/database_demo/settings.py,在 INSTALLED_APPS 中添加 book 应用:

    运行

    # settings.py 第 40 行左右
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'book',  # 新增:注册 book 应用
    ]
    

    踩坑提示:若忘记注册应用,Django 无法识别模型、模板等资源,导致页面 404 或渲染失败。

    2.3 配置 MySQL 数据库(核心步骤)

    2.3.1 项目 init.py 添加 PyMySQL 配置

    打开 database_demo/database_demo/__init__.py,添加以下代码:

    运行

    # __init__.py
    import pymysql
    # 将 pymysql 伪装成 MySQLdb,适配 Django 数据库接口
    pymysql.install_as_MySQLdb()
    

    踩坑提示:若缺少此配置,Django 会报错 Did you install mysqlclient?,无法连接 MySQL。

    2.3.2 修改 settings.py 数据库配置

    打开 database_demo/database_demo/settings.py完全替换默认的 SQLite 配置

    运行

    # settings.py 第 70 行左右
    DATABASES = {
        'default': {
            # 数据库引擎:MySQL
            'ENGINE': 'django.db.backends.mysql',
            # 数据库名:之前创建的 database_demo
            'NAME': 'database_demo',
            # 数据库用户名:MySQL 用户名(默认 root)
            'USER': 'root',
            # 数据库密码:你的 MySQL 密码
            'PASSWORD': '123456',
            # 数据库地址:本地 127.0.0.1
            'HOST': '127.0.0.1',
            # 数据库端口:MySQL 默认 3306
            'PORT': '3306',
            # 数据库字符集:避免中文乱码
            'CHARSET': 'utf8mb4',
        }
    }
    

    关键检查点

    • NAME 必须与 MySQL 中创建的数据库名完全一致
    • PASSWORD 需填写你自己的 MySQL 密码,否则连接失败;
    • CHARSET 必须设置为 utf8mb4,避免中文乱码。

    2.4 创建 Book 模型(models.py)

    打开 database_demo/book/models.py,编写图书模型:

    运行

    # book/models.py
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        # 书名:最大长度 100 字符
        name = models.CharField(max_length=100, verbose_name='书名')
        # 作者:最大长度 50 字符
        author = models.CharField(max_length=50, verbose_name='作者')
        # 价格:最大 10 位数字,2 位小数
        price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
        # 出版日期:自动添加当前时间
        pub_date = models.DateField(auto_now_add=True, verbose_name='出版日期')
    
        # 后台显示书名
        def __str__(self):
            return self.name
    
        class Meta:
            # 后台显示表名
            verbose_name = '图书'
            verbose_name_plural = verbose_name
    

    踩坑提示:若模型字段名与数据库表列名不匹配,会导致查询失败,需严格对应。

    2.5 生成迁移文件并同步数据库

    2.5.1 生成迁移文件

    # 确保在 database_demo 目录、虚拟环境激活
    python manage.py makemigrations
    

    输出验证

    Migrations for 'book':
      book\migrations\0001_initial.py
        - Create model Book
    

    踩坑提示:若报错 no such table: book,说明迁移未执行,需重新运行 makemigrations

    2.5.2 执行迁移(同步到 MySQL)

    python manage.py migrate
    

    输出验证

    plaintext

    Operations to perform:
      Apply all migrations: admin, auth, book, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying book.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying sessions.0001_initial... OK
    

    踩坑提示

    • 若报错 1045, "Access denied for user 'root'@'localhost',说明数据库密码错误;
    • 若报错 1049, "Unknown database 'database_demo'",说明数据库未创建;
    • 若报错 NameError: name 'os' is not defined,说明 settings.py 顶部缺少 import os

    2.5.3 验证数据库表创建

    打开 MySQL 命令行,执行:

    USE database_demo;
    SHOW TABLES;
    

    输出应包含book_book(Django 自动生成的表名,格式为 应用名_模型名

    +----------------------------+
    | Tables_in_database_demo    |
    +----------------------------+
    | auth_group                 |
    | auth_group_permissions      |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | book_book                  |  # 图书表
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+
    

    2.6 编写视图函数(views.py)

    打开 database_demo/book/views.py,编写图书查询视图:

    运行

    # book/views.py
    from django.shortcuts import HttpResponse, render
    from django.db import connection
    from .models import Book, Tag
    
    # Create your views here.
    
    # ======================
    # 主页:显示图书列表
    # ======================
    def index(request):
        # 方式1:原生 SQL 查询(验证数据库连接)
        # cursor = connection.cursor()
        # cursor.execute("select * from book_book")
        # rows = cursor.fetchall()
        # for row in rows:
        #     print(row)
    
        # 方式2:Django ORM 查询(推荐,符合 Django 规范)
        books = Book.objects.all()
        # 渲染模板,传递数据到前端
        return render(request, "book/index.html", {"books": books})
    
    
    # ======================
    # 以下是原有功能,全部保留
    # ======================
    def add_book(request):
        book = Book(name='三国演义', author='罗贯中', price=100.00)
        book.save()
        return HttpResponse("图书插入成功!")
    
    
    def query_book(request):
        try:
            book = Book.objects.get(name='三国演义11')
            print(book.name)
        except Book.DoesNotExist:
            print("图书不存在!")
        return HttpResponse("查找成功!")
    
    
    def order_view(request):
        books = Book.objects.all()
        for book in books:
            print(book.name)
        return HttpResponse("排序成功!")
    
    
    def update_view(request):
        book = Book.objects.first()
        book.name = '西游记'
        book.save()
        return HttpResponse('修改成功')
    
    
    def delete_view(request):
        book = Book.objects.filter(name='西游记')
        book.delete()
        return HttpResponse('删除成功')
    
    
    def book_tag(request):
        tag = Tag()
        tag.save()
        return HttpResponse("tag插入成功!")
    

    踩坑提示

    • 若视图直接返回 HttpResponse("查找成功"),页面只会显示一句话,不会渲染模板;
    • 必须用 render 加载模板,路径必须为 book/index.html,否则模板找不到。

    2.7 配置路由(urls.py)

    2.7.1 项目 urls.py(database_demo/urls.py)

    运行

    # database_demo/urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        # 包含 book 应用的路由
        path('book/', include('book.urls')),
    ]
    

    2.7.2 book 应用 urls.py(新建)

    database_demo/book/ 目录下,新建 urls.py

    运行

    # book/urls.py
    from django.urls import path
    from . import views
    
    urlpatterns = [
        # 主页:图书列表
        path('', views.index, name='index'),
        # 其他功能路由(可选)
        path('add/', views.add_book, name='add_book'),
        path('query/', views.query_book, name='query_book'),
        path('order/', views.order_view, name='order_view'),
        path('update/', views.update_view, name='update_view'),
        path('delete/', views.delete_view, name='delete_view'),
        path('tag/', views.book_tag, name='book_tag'),
    ]
    

    2.8 任务 1 验证:运行项目

    powershell

    python manage.py runserver
    

    访问 http://127.0.0.1:8000/book/,页面显示「查找成功」,说明数据库连接、模型、视图、路由全部正常,任务 1 100% 完成!

    三、任务 2:集成 Bootstrap 5 前端框架(全流程 + 踩坑)

    3.1 静态文件配置(settings.py)

    打开 database_demo/database_demo/settings.py顶部添加 import os,末尾添加静态文件配置:

    运行

    # settings.py 顶部(第 12 行左右)
    import os
    from pathlib import Path
    
    # Build paths inside the project like this: BASE_DIR / 'subdir'.
    BASE_DIR = Path(__file__).resolve().parent.parent
    
    # 末尾静态文件配置(第 140 行左右)
    # 静态文件配置
    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static'),
    ]
    

    踩坑提示

    • import os 必须在顶部,否则 os.path.join 会报错 NameError: name 'os' is not defined
    • STATICFILES_DIRS 必须配置,否则 Django 无法加载静态资源(Bootstrap CSS/JS)。

    3.2 创建 static 目录与框架文件

    3.2.1 创建 static 文件夹

    database_demo/database_demo/ 目录下,手动创建 static 文件夹(通过终端命令避免 IDE 报错):

    # 进入 database_demo 项目根目录
    cd E:\django-notes-main\django5\database_demo
    
    # 创建 static 文件夹
    mkdir static
    
    # 进入 static 目录
    cd static
    

    3.2.2 复制 Bootstrap 5 + jQuery 框架文件

    从项目根目录的 博客模板 文件夹中,完整复制 bootstrap5jquery 两个文件夹static 目录下:

    # static 目录结构(必须严格匹配)
    static/
    ├─ bootstrap5/
    │  ├─ bootstrap.min.css
    │  ├─ bootstrap.min.js
    │  └─ popper.min.js
    └─ jquery/
       └─ jquery-3.7.1.min.js
    

    踩坑提示

    • 若文件夹结构错误,模板中静态资源路径会 404,导致样式不生效;
    • 必须同时复制 popper.min.js(Bootstrap 5 依赖),否则 JS 交互失效。

    3.3 创建模板目录结构(关键!)

    3.3.1 用终端创建模板目录(避免 IDE 报错)

    # 进入 book 应用目录
    cd E:\django-notes-main\django5\database_demo\book
    
    # 创建 templates 文件夹
    mkdir templates
    
    # 进入 templates 目录
    cd templates
    
    # 创建 book 文件夹(Django 模板加载规则:app/templates/app/)
    mkdir book
    
    # 回到项目根目录
    cd ..\..
    

    目录结构验证

    book/
    ├─ migrations/
    ├─ templates/
    │  └─ book/
    │     └─ index.html  # 模板文件必须在这里!
    ├─ views.py
    └─ models.py
    

    踩坑提示

    • 若模板目录结构错误,Django 会报错 TemplateDoesNotExist,页面空白;
    • 必须严格按 book/templates/book/ 结构创建,否则模板无法加载。

    3.4 编写 Bootstrap 美化版模板(index.html)

    book/templates/book/ 目录下,新建 index.html完整复制以下代码

    预览

    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>图书管理系统</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- 引入 Bootstrap 5 CSS -->
        <link href="{% static 'bootstrap5/bootstrap.min.css' %}" rel="stylesheet">
        <!-- 自定义样式(美化页面) -->
        <style>
            body {
                background-color: #f8f9fa;
                font-family: "Microsoft Yahei", sans-serif;
            }
            .card {
                max-width: 900px;
                margin: 50px auto;
                padding: 30px;
                border-radius: 16px;
                box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08);
                background-color: #ffffff;
            }
            .title {
                text-align: center;
                font-size: 28px;
                font-weight: bold;
                color: #2d8cf0;
                margin-bottom: 30px;
            }
            .table thead {
                background: linear-gradient(45deg, #2c3e50, #34495e);
                color: #ffffff;
            }
            .table-hover tbody tr:hover {
                background-color: #f1f8ff;
                transition: background-color 0.3s ease;
            }
            .empty-tip {
                text-align: center;
                color: #6c757d;
                font-size: 16px;
                padding: 20px 0;
            }
        </style>
    </head>
    <body>
        <div class="card">
            <h2 class="title">📚 图书管理系统</h2>
            <table class="table table-striped table-hover align-middle">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>书名</th>
                        <th>作者</th>
                        <th>价格</th>
                        <th>出版日期</th>
                    </tr>
                </thead>
                <tbody>
                    {% for book in books %}
                    <tr>
                        <td>{{ book.id }}</td>
                        <td>{{ book.name }}</td>
                        <td>{{ book.author }}</td>
                        <td>{{ book.price }}</td>
                        <td>{{ book.pub_date }}</td>
                    </tr>
                    {% empty %}
                    <tr>
                        <td colspan="5" class="empty-tip">暂无图书数据</td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    
        <!-- 引入 JS 依赖:jQuery → Popper → Bootstrap(顺序不能错!) -->
        <script src="{% static 'jquery/jquery-3.7.1.min.js' %}"></script>
        <script src="{% static 'bootstrap5/popper.min.js' %}"></script>
        <script src="{% static 'bootstrap5/bootstrap.min.js' %}"></script>
    </body>
    </html>
    

    关键检查点

    • {% load static %} 必须在 HTML 最顶部,否则静态资源无法加载;
    • 静态资源路径 {% static 'bootstrap5/bootstrap.min.css' %} 必须与 static 目录结构完全匹配
    • JS 引入顺序必须是:jQuery → Popper → Bootstrap,否则 Bootstrap 交互失效。

    3.5 任务 2 验证:运行项目

    powershell

    python manage.py runserver
    

    访问 http://127.0.0.1:8000/book/,页面显示带 Bootstrap 样式的图书管理系统,任务 2 100% 完成!

    四、进阶任务:Vue 3 美化版(可选)

    Vue 3 模板代码

    直接替换 index.html 代码,实现前后端分离风格:

    预览

    {% load static %}
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>图书管理系统</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="{% static 'bootstrap5/bootstrap.min.css' %}" rel="stylesheet">
        <!-- 引入 Vue 3 CDN -->
        <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
        <style>
            body {background: #f5f7fa;padding: 40px;}
            .box {max-width: 900px;margin: 0 auto;background: #fff;padding: 30px;border-radius: 16px;box-shadow: 0 8px 30px rgba(0,0,0,0.08);}
            .title {text-align: center;font-size: 24px;font-weight: bold;color: #2d8cf0;margin-bottom: 20px;}
            th {background: #2d8cf0;color: #fff;}
        </style>
    </head>
    <body>
        <div id="app" class="box">
            <div class="title">📚 图书管理系统</div>
            <table class="table table-hover">
                <thead>
                    <tr><th>ID</th><th>书名</th><th>价格</th><th>出版日期</th></tr>
                </thead>
                <tbody>
                    <tr v-for="book in books" :key="book.id">
                        <td>{{ book.id }}</td>
                        <td>{{ book.title }}</td>
                        <td>{{ book.price }}</td>
                        <td>{{ book.pub_date }}</td>
                    </tr>
                    <tr v-if="books.length === 0">
                        <td colspan="4" class="text-center">暂无图书</td>
                    </tr>
                </tbody>
            </table>
        </div>
    
        <script>
            const { createApp } = Vue
            createApp({
                data() {
                    return {
                        books: [
                            {% for book in books %}
                            {
                                id: {{ book.id }},
                                title: "{{ book.name|escapejs }}",
                                price: {{ book.price }},
                                pub_date: "{{ book.pub_date }}"
                            },
                            {% endfor %}
                        ]
                    }
                },
                delimiters: ['${', '}']  # 避免与 Django 模板语法冲突
            }).mount('#app')
        </script>
        <script src="{% static 'bootstrap5/bootstrap.min.js' %}"></script>
    </body>
    </html>
    

    进阶说明

    • 基于 Vue 3 实现前端渲染,满足「进阶用 vue/react」的要求;
    • 保留 Bootstrap 样式,同时实现前后端分离风格,页面更现代化;
    • 无需安装 Vue,直接 CDN 引入,零环境配置。

    五、全流程踩坑记录与解决方案

    5.1 任务 1 常见坑

    1. Did you install mysqlclient? 报错

    • 原因:未安装 PyMySQL 或未在 __init__.py 中配置;
    • 解决:安装 pymysql,并在 __init__.py 添加 pymysql.install_as_MySQLdb()

    2. NameError: name 'os' is not defined 报错

    • 原因:settings.py 顶部缺少 import os
    • 解决:在 settings.py 顶部添加 import os

    3. no such table: book 报错

    • 原因:迁移未执行或数据库表未创建;
    • 解决:重新运行 python manage.py makemigrations + migrate

    4. 页面只显示「查找成功」空白

    • 原因:views.py 直接返回 HttpResponse,未渲染模板;
    • 解决:用 render 加载模板,传递数据。

    5.2 任务 2 常见坑

    1. Bootstrap 样式不生效

    • 原因:静态资源路径错误、{% load static %} 缺失;
    • 解决:检查模板路径、添加 {% load static %}、核对静态文件目录结构。

    2. 模板找不到(TemplateDoesNotExist)

    • 原因:静态资源路径错误、{% load static %} 缺失;
    • 解决:检查模板路径、添加 {% load static %}、核对静态文件目录结构。

    3. 文件夹命名无效报错

    • 原因:IDE 权限 / 缓存问题;
    • 解决:用终端命令 mkdir 创建文件夹,避免 IDE 手动创建报错。

    4. 页面样式丑

    • 未添加自定义 CSS 样式;
    • 解决:在模板中添加自定义样式,优化页面布局与视觉效果。

    六、总结

    本文从零到一完整实现 Django 作业两大核心任务:

    任务 1:将 Django 数据库从 SQLite 无缝迁移为 MySQL,完成模型创建、迁移、数据读写;

    任务 2:集成 Bootstrap 5 前端框架,完成页面美化与样式优化;

    进阶任务:基于 Vue 3 实现现代化页面,满足进阶要求;

    全程附踩坑记录与解决方案,适合初学者复现与作业提交。

    【附页】

    教程学习完整算法包地址:

    https://gitcode.com/sanda_hw/django-noteshttps://gitcode.com/sanda_hw/django-notes按照本文操作修改后完整算法包地址:

    django-notes-main: 本项目基于 Django 5.x 开发,完整实现课程作业要求: ✅ 任务 1:数据库从 SQLite 迁移为 MySQL 8.0 ✅ 任务 2:集成 Bootstrap 5 前端框架,页面美化 ✅ 进阶任务:Vue 3 CDN 版现代化页面,满足进阶要求https://gitee.com/Zhang-Siyu0066/django-notes-main

    Logo

    AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

    更多推荐