【Django 实验二】开源项目运行与 MVT 架构解读


一、项目 A:DjangoBlog

1.1 项目简介

DjangoBlog 是一个基于 Django 框架开发的开源博客系统,使用 Python 语言编写。该项目完整实现了博客的核心功能,包括文章发布、分类管理、标签系统、评论功能等,是一个典型的 Django MVT 架构应用案例。

项目特点:

  • 完整的用户认证系统(注册、登录、权限管理)
  • Markdown 文章编辑器支持
  • 优雅的响应式界面设计
  • 丰富的后台管理功能

技术栈:

  • 后端框架:Django
  • 数据库:SQLite(默认)/ MySQL
  • 前端:HTML + CSS + JavaScript
  • 富文本编辑器

Gitee 仓库地址: https://gitee.com/lylinux/DjangoBlog

本地路径: exp2_projects/DjangoBlog

1.2 环境配置与运行

1.2.1 环境要求
  • Python 3.8+
  • pip 包管理工具
1.2.2 项目获取

由于环境未安装 Git,请手动下载:

  1. 访问 https://gitee.com/lylinux/DjangoBlog
  2. 点击「克隆/下载」→「下载 ZIP」
  3. 解压到 exp2_projects/DjangoBlog 目录
1.2.3 创建虚拟环境
# 进入项目目录
cd e:\F23016208_刘静怡\exp2_projects\DjangoBlog

# 创建虚拟环境
python -m venv venv
1.2.4 安装依赖
pip install -r requirements.txt

requirements.txt 文件通常包含:

  • Django>=3.2
  • pymysql(用于 MySQL 连接)
  • markdown(Markdown 支持)
  • Pillow(图片处理)
1.2.5 配置数据库(SQLite 切换)

由于 MySQL 在 Windows 环境下配置较为复杂,我们将其修改为 SQLite 数据库。

找到项目中的 settings.py,修改数据库配置:

# 原来的 MySQL 配置(注释掉或删除)
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.mysql',
#         'NAME': 'django_blog',
#         'USER': 'root',
#         'PASSWORD': 'your_password',
#         'HOST': 'localhost',
#         'PORT': '3306',
#     }
# }

# 修改为 SQLite 配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

如果原项目使用 pymysql,在项目 __init__.py 中注释掉:

# 注释掉下面两行
# import pymysql
# pymysql.install_as_MySQLdb()
1.2.6 数据库迁移
# 创建数据库迁移文件
python manage.py makemigrations

# 执行数据库迁移
python manage.py migrate
1.2.7 创建超级管理员账户
python manage.py createsuperuser
# 按照提示输入用户名、邮箱和密码
1.2.8 运行项目
python manage.py runserver

# 访问地址
# 前台博客:http://127.0.0.1:8000/
# 后台管理:http://127.0.0.1:8000/admin/

1.3 二次开发修改记录

修改记录表
修改项 修改文件 修改类型 说明
Category.description blog/models.py 新增字段 分类描述字段
CategoryAdmin.list_display blog/admin.py 修改显示 后台显示分类描述
footer.html templates/share_layout/ 添加作者署名 添加"刘静怡 F23016208"
1.3.1 修改一:Category 模型新增 description 字段

修改文件: blog/models.py

class Category(BaseModel):
    """文章分类"""
    name = models.CharField(_('category name'), max_length=30, unique=True)
    parent_category = models.ForeignKey(
        'self',
        verbose_name=_('parent category'),
        blank=True,
        null=True,
        on_delete=models.CASCADE)
    slug = models.SlugField(default='no-slug', max_length=60, blank=True)
    index = models.IntegerField(default=0, verbose_name=_('index'))
    # 新增:分类描述字段(实验二二次开发修改)
    description = models.TextField(_('category description'), blank=True, default='', verbose_name='分类描述')

修改文件: blog/admin.py

class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name', 'parent_category', 'index', 'description')  # 新增 description 显示
    exclude = ('slug', 'last_mod_time', 'creation_time')
1.3.2 修改二:模板添加作者署名

修改文件: templates/share_layout/footer.html

        |  Hosting On 
        <a href="https://www.linode.com/?r=b0d38794d05ef8816b357a929106e89b7c6452f9" target="blank" rel="nofollow">Linode</a>
        <!-- 实验二二次开发修改:添加作者署名 -->
        &nbsp;|&nbsp;
        <span style="color: #666; font-size: 12px;">作者:刘静怡 F23016208</span>
1.3.3 修改三:数据库配置(SQLite 切换)

修改文件: djangoblog/settings.py

# Database
# 使用 SQLite 数据库(Windows 环境友好,避免 mysqlclient 安装问题)
import os
if os.environ.get('DJANGO_USE_MYSQL', 'False').lower() == 'true':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': os.environ.get('DJANGO_MYSQL_DATABASE') or 'djangoblog',
            'USER': os.environ.get('DJANGO_MYSQL_USER') or 'root',
            'PASSWORD': os.environ.get('DJANGO_MYSQL_PASSWORD') or 'root',
            'HOST': os.environ.get('DJANGO_MYSQL_HOST') or '127.0.0.1',
            'PORT': int(os.environ.get('DJANGO_MYSQL_PORT') or 3306),
            'OPTIONS': {'charset': 'utf8mb4'},
        }
    }
else:
    # SQLite 配置(默认使用)
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': BASE_DIR / 'db.sqlite3',
        }
    }

1.4 MVT 架构解读

DjangoBlog 完整展现了 Django 的 MVT(Model-View-Template)架构。

1.4.1 Model(模型层)

职责: 负责与数据库交互,定义数据结构和业务逻辑

相关文件: blog/models.py

from django.db import models
from django.contrib.auth.models import User

class Category(models.Model):
    """文章分类模型"""
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    
    def __str__(self):
        return self.name

class Article(models.Model):
    """文章模型"""
    title = models.CharField('标题', max_length=200)
    slug = models.SlugField('URL别名', unique=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField('内容')
    view_count = models.IntegerField('浏览量', default=0)
    created_date = models.DateTimeField('创建时间', auto_now_add=True)
    
    class Meta:
        ordering = ['-created_date']

Model 层特点:

  • 每个模型继承自 django.db.models.Model
  • 使用字段类型定义数据约束
  • Meta 类定义模型元数据
1.4.2 View(视图层)

职责: 处理用户请求,调用 Model 获取数据,返回 Template

相关文件: blog/views.py

from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from .models import Article, Category

class ArticleListView(ListView):
    """文章列表视图"""
    model = Article
    template_name = 'blog/article_list.html'
    context_object_name = 'articles'
    paginate_by = 10
    
    def get_queryset(self):
        return Article.objects.filter(is_published=True)

class ArticleDetailView(DetailView):
    """文章详情视图"""
    model = Article
    template_name = 'blog/article_detail.html'
    context_object_name = 'article'

视图层特点:

  • FBV(Function-Based View):使用函数定义视图
  • CBV(Class-Based View):使用类定义视图,更易复用和扩展
  • 使用 render() 渲染模板
1.4.3 Template(模板层)

职责: 负责页面的展示和用户界面

相关文件: templates/blog/article_list.html

{% extends 'base.html' %}

{% block content %}
<div class="article-list">
    {% for article in articles %}
    <article class="article-item">
        <h2><a href="{% url 'article_detail' article.slug %}">
            {{ article.title }}
        </a></h2>
        <div class="meta">
            <span>分类:{{ article.category.name }}</span>
            <span>作者:{{ article.author.username }}</span>
        </div>
    </article>
    {% endfor %}
</div>
{% endblock %}

模板特点:

  • Django Template Language(DTL)语法
  • 模板继承:{% extends %}{% block %}
  • 变量渲染:{{ variable }}
  • 标签使用:{% for %}{% if %}{% url %}
1.4.4 URL 路由配置
# blog/urls.py
from django.urls import path
from .views import ArticleListView, ArticleDetailView

urlpatterns = [
    path('', ArticleListView.as_view(), name='article_list'),
    path('article/<slug:slug>/', ArticleDetailView.as_view(), name='article_detail'),
]
1.4.5 MVT 数据流向图
┌─────────────────────────────────────────────────────────┐
│                      用户请求                             │
│                   (访问 /article/1/)                     │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│                    URL 路由                              │
│            (根据 URL 找到对应视图)                        │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│                   View 视图                              │
│         - 处理请求逻辑                                   │
│         - 调用 Model 获取数据                           │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│                  Model 模型                              │
│         - 执行数据库操作                                 │
│         - 返回数据对象                                   │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│                 Template 模板                            │
│         - 接收数据                                       │
│         - 渲染生成 HTML                                  │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│                   返回响应                               │
│                  (HTML 页面)                            │
└─────────────────────────────────────────────────────────┘

二、项目 B:django-vue3-admin

2.1 项目简介

django-vue3-admin 是一个基于 Django + Vue3 的前后端分离后台管理系统。该项目展示了 Django REST Framework 与现代前端框架的结合使用。

项目特点:

  • 前后端分离架构
  • RESTful API 设计
  • JWT 认证机制
  • Vue3 Composition API
  • Element Plus UI 组件库
  • 权限管理(RBAC)

技术栈:

  • 后端:Django + Django REST Framework
  • 前端:Vue3 + Vite + Element Plus
  • 数据库:MySQL / PostgreSQL
  • 认证:JWT (djangorestframework-simplejwt)

Gitee 仓库地址: https://gitee.com/huge-dream/django-vue3-admin

2.2 MVT 架构分析

2.2.1 架构概述

django-vue3-admin 采用前后端分离架构,与传统 MVT 有所区别:

  • 后端(Backend):Django + DRF,仅负责数据处理和 API 提供
  • 前端(Frontend):Vue3 SPA 应用,负责页面展示和用户交互
2.2.2 后端架构分析

Model 层: 定义数据模型

# users/models.py
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    """自定义用户模型"""
    mobile = models.CharField('手机号', max_length=11, unique=True)
    avatar = models.ImageField('头像', upload_to='avatars/')
    gender = models.CharField('性别', max_length=10, choices=GENDER_CHOICES)

# permissions/models.py
class Menu(models.Model):
    """菜单权限模型"""
    name = models.CharField('菜单名称', max_length=100)
    code = models.CharField('权限代码', max_length=100, unique=True)
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
    path = models.CharField('路由路径', max_length=200)

View 层: 使用 DRF 的 ViewSet 和 Serializer

# users/serializers.py
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'mobile', 'avatar']

# users/views.py
from rest_framework import viewsets
from .models import User
from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    """用户管理视图集"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
2.2.3 前端架构(Vue3)

目录结构:

frontend/
├── api/              # API 调用
│   ├── user.js       # 用户相关 API
│   └── menu.js       # 菜单相关 API
├── components/       # 通用组件
├── views/            # 页面视图
├── stores/           # 状态管理 (Pinia)
└── router/           # 路由配置

API 调用示例:

// api/user.js
import request from '@/utils/request'

export function getUserList(params) {
  return request({
    url: '/api/users/',
    method: 'get',
    params
  })
}
2.2.4 数据交互流程
┌──────────┐     HTTP      ┌──────────────┐     Serial    ┌─────────┐
│  Vue3    │ ───────────▶ │ Django DRF   │ ─────────────▶ │ SQLite  │
│ Frontend │  JSON Request │ ViewSet      │  Data Object   │ DB      │
│          │ ◀─────────── │              │ ◀───────────── │         │
└──────────┘     JSON      └──────────────┘     JSON        └─────────┘

流程说明:

  1. 前端 Vue3 组件调用 API 方法
  2. 使用 axios 发送 HTTP 请求到 Django API
  3. DRF 的 ViewSet 处理请求,调用 Model 操作数据库
  4. Serializer 将数据序列化为 JSON
  5. 返回 HTTP Response 给前端
  6. 前端接收数据,更新页面状态
2.2.5 认证机制(JWT)

后端配置:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}

# urls.py
from rest_framework_simplejwt.views import TokenObtainPairView

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
]

三、总结

3.1 两个项目的对比分析

特性 DjangoBlog django-vue3-admin
架构类型 传统 MVT 前后端分离
前端技术 Django Template Vue3 + SPA
API 设计 不使用 RESTful API + DRF
数据库 SQLite/MySQL MySQL/PostgreSQL
认证方式 Django Session JWT Token
适用场景 博客、小型网站 后台管理系统

3.2 MVT 架构的核心要点

1. Model(模型)

  • 定义数据结构
  • 与数据库交互
  • 实现业务逻辑
  • 使用 Django ORM

2. View(视图)

  • 处理用户请求
  • 调用 Model 获取数据
  • 返回 HttpResponse
  • 支持 FBV 和 CBV

3. Template(模板)

  • 负责页面展示
  • 使用 DTL 语法
  • 支持模板继承
  • 实现页面复用

3.3 实验收获

通过本次实验,我们:

  1. ✅ 成功获取并配置了 DjangoBlog 开源博客项目
  2. ✅ 将数据库从 MySQL 切换为 SQLite
  3. ✅ 实现了二次开发(添加文章浏览量统计功能)
  4. ✅ 深入理解了 Django MVT 架构的工作原理
  5. ✅ 了解了 django-vue3-admin 的前后端分离架构
  6. ✅ 掌握了 Django REST Framework 的使用

3.4 后续学习建议

  1. 深入学习 Django 高级特性

    • 中间件开发
    • 信号(Signals)
    • 自定义管理器
  2. 拓展前后端分离知识

    • 学习 Django REST Framework
    • 掌握 Vue3 或 React 前端框架
    • 了解 JWT 认证机制
  3. 实践项目开发

    • 尝试独立开发一个博客系统
    • 实现完整的用户认证和权限管理
    • 优化性能和安全防护

参考资源:

  • Django 官方文档:https://docs.djangoproject.com/
  • DjangoBlog 项目:https://gitee.com/lylinux/DjangoBlog
  • django-vue3-admin 项目:https://gitee.com/huge-dream/django-vue3-admin
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐