详解Django的MVT设计模式


Posted in Python onApril 29, 2021

经典的MVC设计模式及其优点

MVC即 Model-View-Controller(模型-视图-控制器) ,是经典的软件开发设计模式。

  • **Model (模型) **: 简而言之即数据模型。模型不是数据本身(比如数据库里的数据),而是抽象的描述数据的构成和逻辑关系。通常模型包括了数据表的各个字段(比如人的年龄和出生日期)和相互关系(单对单,单对多关系等)。Web开发框架会根据模型的定义来自动生成数据表。
  • View (视图): 主要用于显示数据,用来展示用户可以看到的内容或提供用户可以输入或操作的界面。数据来源于哪里?当然是数据库啦。那么用户输入的数据给谁? 当然是给控制器啦。
  • Controller(控制器):应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据(比如增加或更新数据表)。

如果把MVC比喻成一个粽子,那么View就是最外面一层的绿色玉米叶,是吃货们可以直接看到的。Controller就是中间那层熟糯米,而粽子的核心自然是最里面那一层的肉馅Model模型了。现在大家知道中学和大学数学建模的重要性了吧?

MVC最大的优点是实现了软件或网络应用开发过程中数据、业务逻辑和用户界面的分离,使软件开发更清晰,也是维护变得更容易。这与静态网页设计中使用html和css实现了内容和样式的分离是同一个道理。

Django是如何遵循MVC设计模式的?

Django的MVT设计模式由Model(模型), View(视图) 和Template(模板)三部分组成,分别对应单个app目录下的models.py, views.py和templates文件夹。它们看似与MVC设计模式不太一致,其实本质是相同的。Django的MVT设计模式与经典的MVC对应关系如下。

  • Django Model(模型): 这个与经典MVC模式下的模型Model差不多。
  • Django View(视图): 这个与MVC下的控制器Controller更像。视图不仅负责根据用户请求从数据库读取数据、指定向用户展示数据的方式(网页或json数据), 还可以指定渲染模板并处理用户提交的数据。
  • Django Template(模板): 这个与经典MVC模式下的视图View一致。模板用来呈现Django view传来的数据,也决定了用户界面的外观。Template里面也包含了表单,可以用来搜集用户的输入内容。

Django MVT设计模式中最重要的是视图(view), 因为它同时与模型(model)和模板(templates)进行交互。当用户发来一个请求(request)时,Django会对请求头信息进行解析,解析出用户需要访问的url地址,然后根据路由urls.py中的定义的对应关系把请求转发到相应的视图处理。视图会从数据库读取需要的数据,指定渲染模板,最后返回响应数据。这个过程如下图所示:

详解Django的MVT设计模式

示例

现在我们以示例演示Django的MVT三部分是如何工作的。

新建app并注册

假如你有一个mysite项目,希望新增一个任务管理小应用,你首先要使用python manage.py startapp tasks的命令创建一个名为tasks的app,将它加入到settings.py中的INSTALLED_APP中去。

# mysite/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tasks',
]

然后把tasks应用的urls添加到到项目的urls中去。

# mysite/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('tasks/', include('tasks.urls'))
]

创建模型(M)

编辑tasks目录下models.py创建Task模型, Task模型包含里名称name和状态status两个字段。当你使用python manage.py makemigrations和python manage.py migrate命令时,Django会自动为你在数据库创建数据表(默认使用的数据库是免费的sqlite),表名为tasks_task。

# tasks/models.py
    
    from django.db import models
    
    class Status(models.TextChoices):
        UNSTARTED = 'u', "Not started yet"
        ONGOING = 'o', "Ongoing"
        FINISHED = 'f', "Finished"
    
    # Task模型
    class Task(models.Model):
        name = models.CharField(verbose_name="Task name", max_length=65, unique=True)
        status = models.CharField(verbose_name="Task status", max_length=1, choices=Status.choices)
    
        def __str__(self):
            return self.name

编写视图并配置路由URL(V)

接下来我们要编辑视图views.py,并新增一个视图函数 task_list, 用于展示任务清单。该视图函数从数据库读取了Task对象列表,指定了渲染模板并向模板传递了数据。

# tasks/views.py
from django.shortcuts import render
from .models import Task

# 任务清单
def task_list(request):
    # 从数据库获取Task对象列表
    tasks = Task.objects.all()
    # 指定渲染模板并向模板传递数据
    return render(request, "tasks/task_list.html", { "tasks": tasks,})

光编写视图(views.py)还不够,我们还得为写好的视图函数配置路由,这样才能将视图函数与用户的请求地址建立好对应关系。编辑或创建tasks/urls.py, 添加如下代码:

这样当用户访问/tasks/时,Django将调用task_list视图函数。这个视图函数将同时与数据库和模板进行交互。

编辑模板(T)

最后我们要创建task_list.html用于展示视图传来的任务列表数据。这个文件的完整路径为tasks/templates/tasks/task_list.html。至于模板为什么放这里,我们后续会专门介绍。Django还提供了自己的模板语言,包括常见的判断和循环,专门用来渲染模板。

# tasks/templates/tasks/task_list.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Task List</title>
</head>
<body>
<h3>Task List</h3>
{% for task in tasks %}
    <p>{{ forloop.counter }}. {{ task.name }} - {{ task.get_status_display }}
    </p>
{% endfor %}
</body>
</html>

当然此时如果你通过浏览器访问/tasks/, 还看不到任何内容,这是因为你的数据表里还没有任何数据。你可以通过django的admin添加或新增task_create视图实现。

小结

Django的MVT设计模式也遵循了软件设计经典的MVC设计模式。事实上我们在日常Django项目开发过程中一般也是先编写M,再编写V,最后才写T。

以上就是详解Django的MVT设计模式的详细内容,更多关于Django的MVT设计模式的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python用模块zlib压缩与解压字符串和文件的方法
Dec 16 Python
python微信跳一跳系列之自动计算跳一跳距离
Feb 26 Python
pandas每次多Sheet写入文件的方法
Dec 10 Python
Keras自定义IOU方式
Jun 10 Python
Python单元测试及unittest框架用法实例解析
Jul 09 Python
Python包资源下载路径报404解决方案
Nov 05 Python
Python实现淘宝秒杀功能的示例代码
Jan 19 Python
Spy++的使用方法及下载教程
Jan 29 Python
python利用xpath爬取网上数据并存储到django模型中
Feb 26 Python
python 解决微分方程的操作(数值解法)
May 26 Python
撤回我也能看到!教你用Python制作微信防撤回脚本
Jun 11 Python
Python+OpenCV实现在图像上绘制矩形
Mar 21 Python
Django如何与Ajax交互
Apr 29 #Python
Python爬虫进阶之Beautiful Soup库详解
Apr 29 #Python
win10+anaconda安装yolov5的方法及问题解决方案
Python图像处理之图像拼接
4种非常实用的python内置数据结构
Apr 28 #Python
Python基础详解之描述符
Apr 28 #Python
详解Python 3.10 中的新功能和变化
Apr 28 #Python
You might like
PHP配置文件中最常用四个ini函数
2007/03/19 PHP
php+mysql分页代码详解
2008/03/27 PHP
php中使用redis队列操作实例代码
2013/02/07 PHP
Laravel5框架自定义错误页面配置操作示例
2019/04/17 PHP
JScript中使用ADODB.Stream判断文件编码的代码
2008/06/09 Javascript
jQuery动态添加的元素绑定事件处理函数代码
2011/08/02 Javascript
js用Date对象处理时间实现思路及代码
2013/01/31 Javascript
java与javascript之间json格式数据互转介绍
2013/10/29 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
2014/07/21 Javascript
微信WeixinJSBridge API使用实例
2015/05/25 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
jQuery自制提示框tooltip改进版
2016/08/01 Javascript
微信小程序 数据访问实例详解
2016/10/08 Javascript
详解JavaScript时间处理之几个月前或几个月后的指定日期
2016/12/21 Javascript
Angular指令之restict匹配模式的详解
2017/07/27 Javascript
html中通过JS获取JSON数据并加载的方法
2017/11/30 Javascript
ExtJs整合Echarts的示例代码
2018/02/27 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
2018/10/11 Javascript
详解vue几种主动刷新的方法总结
2019/02/19 Javascript
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
vue-video-player视频播放器使用配置详解
2020/10/23 Javascript
[26:21]浴火之凤-TI4世界冠军Newbee战队纪录片
2014/08/07 DOTA
python在ubuntu中的几种安装方法(小结)
2017/12/08 Python
python+selenium实现163邮箱自动登陆的方法
2017/12/31 Python
python实现爬虫抓取小说功能示例【抓取金庸小说】
2019/08/09 Python
修改 CentOS 6.x 上默认Python的方法
2019/09/06 Python
彪马俄罗斯官网:PUMA俄罗斯
2019/07/13 全球购物
用Java语言将一个键盘输入的数字转化成中文输出
2013/01/25 面试题
实习护理工作自我评价
2013/09/25 职场文书
2014两会学习心得:时代的发展
2014/03/17 职场文书
工伤事故赔偿协议书
2014/04/15 职场文书
献爱心活动总结
2014/05/07 职场文书
创先争优活动承诺书
2014/08/30 职场文书
黑暗中的舞者观后感
2015/06/18 职场文书
Win11筛选键导致键盘失灵怎么解决? Win11关闭筛选键的技巧
2022/04/08 数码科技