【Javaer学习Python】2、Django的MVT设计模式,完成CRUD小应用

系列文章:学习Python

Django的MVT设计模式由Model(模型), View(视图) 和Template(模板)三部分组成,分别对应单个app目录下的models.py, views.py和templates文件夹。它们看似与MVC设计模式不太一致,其实本质是相同的;
实践是检验学习成果的最好方法,完成初级开发人员最熟悉的 CRUD 来练手,实现创建(Create)一个任务,查看(Retrieve)任务清单和单个任务详情,更新(Update)一个任务和删除(Delete)一个任务;

MVC 模型

MVC 模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC 以一种插件式的、松耦合的方式连接在一起。

  • 模型(M)- 编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
  • 视图(V)- 图形界面,负责与用户的交互(页面)。
  • 控制器(C)- 负责转发请求,对请求进行处理。

简易图:
ModelViewControllerDiagramZh.png
用户操作流程图:
1589776521-2356-JxrlTyMyPgYnQpOV.png
熟悉的 Java MVC 的味道,异曲同工:在MVC框架中创建一个接收所有请求的Servlet,通常我们把它命名为DispatcherServlet,它总是映射到/,然后,根据不同的Controller的方法定义的@Get或@Post的Path决定调用哪个方法,最后,获得方法返回的ModelAndView后,渲染模板,写入HttpServletResponse,即完成了整个MVC的处理。

HTTP Request    	 ┌─────────────────┐
──────────────────>│DispatcherServlet│
                   └─────────────────┘
                            │
               ┌────────────┼────────────┐
               ▼            ▼            ▼
         ┌───────────┐┌───────────┐┌───────────┐
         │Controller1││Controller2││Controller3│
         └───────────┘└───────────┘└───────────┘
               │            │            │
               └────────────┼────────────┘
                            ▼
   HTTP Response ┌────────────────────┐
<────────────────│render(ModelAndView)│
                 └────────────────────┘

MTV 模型

Django 的 MTV 模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django 的 MTV 分别是指:

  • M 表示模型(Model):编写程序应有的功能,负责业务对象与数据库的映射(ORM)。
  • T 表示模板 (Template):负责如何把页面(html)展示给用户。
  • V 表示视图(View):负责业务逻辑,并在适当时候调用 Model和 Template。

除了以上三层之外,还需要一个 URL 分发器,它的作用是将一个个 URL 的页面请求分发给不同的 View 处理,View 再调用相应的 Model 和 Template,MTV 的响应模式如下所示:
简易图:
MTV-Diagram.png
用户操作流程图:
1589777036-2760-fs1oSv4dOWAwC5yW.png
解析:
用户通过浏览器向我们的服务器发起一个请求(request),这个请求会去访问视图函数:

  • a.如果不涉及到数据调用,那么这个时候视图函数直接返回一个模板也就是一个网页给用户。
  • b.如果涉及到数据调用,那么视图函数调用模型,模型去数据库查找数据,然后逐级返回。

视图函数把返回的数据填充到模板中空格,最后返回网页给用户。

完成CRUD 小应用

crud.gif

1、创建Django项目,tasks应用

在 PyCharm 中 new Project,并创建应用:python manage.py startapp tasks并把它加入 settings.pyINSTALLED_APPS 中;
然后把app下的urls路径添加到项目文件夹的urls.py里去:

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

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

2、创建Task模型及其关联表单

# tasks/models.py
 from django.db import models

 class Status(models.TextChoices):
    UNSTARTED = 'u', "未开始"
    ONGOING = 'o', "进行中"
    FINISHED = 'f', "已结束"


 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

 # tasks/forms.py
 from .models import Task
 from django import forms

 class TaskForm(forms.ModelForm):

     class Meta:
         model = Task
         fields = "__all__"

3、编写路由URLConf及视图

我们需要创建5个urls, 对应5个函数视图。

 from django.urls import path, re_path
 from . import views

 # namespace
 app_name = 'tasks'

 urlpatterns = [
     # Create a task
     path('create/', views.task_create, name='task_create'),

     # Retrieve task list
     path('', views.task_list, name='task_list'),

     # Retrieve single task object
     re_path(r'^(?P<pk>\d+)/$', views.task_detail, name='task_detail'),

     # Update a task
     re_path(r'^(?P<pk>\d+)/update/$', views.task_update, name='task_update'),

     # Delete a task
     re_path(r'^(?P<pk>\d+)/delete/$', views.task_delete, name='task_delete'),
 ]

下面5个函数视图代码是本应用的核心代码:

 from django.shortcuts import render, redirect, get_object_or_404
 from django.urls import reverse
 from .models import Task
 from .forms import TaskForm
 
 # Create a task
 def task_create(request):
     # 如果用户通过POST提交,通过request.POST获取提交数据
     if request.method == "POST":
         # 将用户提交数据与TaskForm表单绑定
         form = TaskForm(request.POST)
         # 表单验证,如果表单有效,将数据存入数据库
         if form.is_valid():
             form.save()
             # 跳转到任务清单
             return redirect(reverse("tasks:task_list"))
     else:
         # 否则空表单
         form = TaskForm()
     return render(request, "tasks/task_form.html", { "form": form, })

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

 # Retrieve a single task
 def task_detail(request, pk):
     # 从url里获取单个任务的pk值,然后查询数据库获得单个对象
     task = get_object_or_404(Task, pk=pk)
     return render(request, "tasks/task_detail.html", { "task": task, })

 # Update a single task
 def task_update(request, pk):
     # 从url里获取单个任务的pk值,然后查询数据库获得单个对象实例
     task_obj = get_object_or_404(Task, pk=pk)
     if request.method == 'POST':
         form = TaskForm(instance=task_obj, data=request.POST)
         if form.is_valid():
             form.save()
             return redirect(reverse("tasks:task_detail", args=[pk,]))
     else:
         form = TaskForm(instance=task_obj)
     return render(request, "tasks/task_form.html", { "form": form, "object": task_obj})


 # Delete a single task
 def task_delete(request, pk):
     # 从url里获取单个任务的pk值,然后查询数据库获得单个对象
     task_obj = get_object_or_404(Task, pk=pk)
     task_obj.delete() # 删除然后跳转
     return redirect(reverse("tasks:task_list"))

4、编写模板

# 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 }}
         (<a href="{% url 'tasks:task_update' task.id %}">Update</a> |
         <a href="{% url 'tasks:task_delete' task.id %}">Delete</a>)
     </p>
 {% endfor %}
 <p> <a href="{% url 'tasks:task_create' %}"> + Add A New Task</a></p>
 </body>
 </html>


 # tasks/templates/tasks/task_detail.html
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Task Detail</title>
 </head>
 <body>
 <p> Task Name: {{ task.name }} | <a href="{% url 'tasks:task_update' task.id %}">Update</a> |
     <a href="{% url 'tasks:task_delete' task.id %}">Delete</a>
 </p>
 <p> Task Status: {{ task.get_status_display }} </p>
 <p> <a href="{% url 'tasks:task_list' %}">View All Tasks</a> |
     <a href="{% url 'tasks:task_create'%}">New Task</a>
 </p>
 </body>
 </html>


 # tasks/templates/tasks/task_form.html
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>{% if object %}Edit Task {% else %} Create New Task {% endif %}</title>
 </head>
 <body>
 <h3>{% if object %}Edit Task {% else %} Create New Task {% endif %}</h3>
     <form action="" method="post" enctype="multipart/form-data">
         {% csrf_token %}
         {{ form.as_p }}
         <p><input type="submit" class="btn btn-success" value="Submit"></p>
     </form>
 </body>
 </html> 

第五步:运行项目,查看效果

运行如下命令,访问http://localhost/tasks/就应该看到文初效果了。
image.png

参考文档

Django 简介 | 菜鸟教程
Django CRUD小应用
MVC高级开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/632273.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW静止无功补偿监控系统

LabVIEW静止无功补偿监控系统 随着电力系统和电力电子技术的快速发展&#xff0c;静止无功补偿器作为提高电网质量和稳定性的关键设备&#xff0c;其监控系统的研发显得非常重要。详细介绍基于LabVIEW的SVC监控系统的设计与实现过程&#xff0c;可为电力系统的优化和电力电子技…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt 驾校管理系统 设计与实现

一.项目介绍 系统角色&#xff1a;管理员、驾校教练、学员 管理员&#xff1a; 个人中心&#xff1a;修改密码以及个人信息修改 学员管理&#xff1a;维护学员信息&#xff0c;维护学员成绩信息 驾校教练管理&#xff1a;驾校教练信息的维护 驾校车辆管理&…

Android 触摸事件分离原理

什么是触摸事件分离&#xff1f; 屏幕上存在多个窗口时&#xff0c;多指触摸的情况下&#xff0c;多个手指的触摸事件可以分给不同的窗口&#xff0c;以下面的图为例&#xff0c;第一个手指按下&#xff0c;window1可以响应这个事件&#xff0c;第二个手指按下&#xff08;第一…

AI应用案例:吸烟打电话行为识别推理

使用百度PaddlePaddle&#xff08;现更名为PaddlePaddle-GPU或PaddlePaddle-CPU&#xff09;框架来构建精准的人员抽烟、打电话动作识别模型&#xff0c;并将其应用于加油站监控场景&#xff0c;你可以遵循以下步骤&#xff1a; 数据准备&#xff1a; 收集抽烟和打电话行为的图…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑网络重构和应急资源的灾后配电网信息物理系统协调恢复方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【Maven】Nexus私服简介_下载安装_登录

1、简介 1.1介绍 Nexus私服&#xff0c;也被称为Maven仓库管理器&#xff0c;是许多公司在自己的局域网内搭建的远程仓库服务器。提供了强大的仓库管理功能和构件搜索功能&#xff0c;使得开发人员能够更方便地管理和使用Maven项目中的依赖库。 1.2作用 内网访问&#xff1…

总台,电视台媒体邀约现场报道,应注意以下几点?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请中央电视台&#xff08;总台&#xff09;这样的权威媒体来报道会议活动&#xff0c;需要注意以下几个关键要点&#xff1a; 提前规划&#xff1a;由于总台的新闻选题流程较为严格和…

2024CCPC郑州邀请赛暨河南省赛(A,B,C,D,F,G,H,J,K,L,M)

2024 National Invitational of CCPC (Zhengzhou), 2024 CCPC Henan Provincial Collegiate Programming Contest 2024 年中国大学生程序设计竞赛全国邀请赛&#xff08;郑州&#xff09;暨第六届 CCPC 河南省大学生程序设计竞赛 比赛链接 这场的题说实话难度其实都不大&…

24个AI写作网站汇总,免费ai工具,把AI用好工作效率真的能提高300%!

从去年到今年&#xff0c;可谓是AI爆发之年&#xff0c;各种AI工具也是层出不穷。随着openai的暴堆算力以及chatgpt人工智能算法的不断进步&#xff0c;ai正在大跨步的向前迈进。 ai可说是集中了全人类的智慧&#xff0c;未来ai的发展我是不敢想象的。不过在今天&#xff0c;如…

element select下拉框编辑时回显已经删除的数据

<el-form-item label"是否激活" prop"activationId"><el-selectv-model"formParams.activationId"style"width: 140px"clearableplaceholder"请选择"><el-optionv-for"item in activationList":ke…

CentOS7使用Docker安装Redis图文教程

1.拉取Redis镜像 这里制定了版本&#xff0c;不指定默认latest最新版 docker pull redis:6.0.8提示信息如下即为下载成功 2.上传配置文件 官方配置文件&#xff08;找自己对应的版本&#xff09;&#xff1a;reids.conf 或者将如下配置文件命名为redis.conf&#xff0c;上…

Kubernetes的Service类型详解

1. Service详解 1.1 Service介绍 在Kubernetes中&#xff0c;Service资源解决了Pod IP地址不固定的问题&#xff0c;提供了一种更稳定和可靠的服务访问方式。以下是Service的一些关键特性和工作原理&#xff1a; Service的稳定性&#xff1a;由于Pod可能会因为故障、重启或扩…

文件批量改名神器:轻松实现导入文件筛选与批量重命名,提升文件管理效率新体验!

电脑中的文件堆积如山&#xff0c;你是否曾为寻找某个特定文件而头疼不已&#xff1f;是否曾因为文件命名不规范而错失重要信息&#xff1f;别担心&#xff0c;现在有了这款文件批量改名神器&#xff0c;一切问题都将迎刃而解&#xff01; 第一步&#xff0c;我们打开需要改名文…

【ONE·基础算法 || 队列(宽搜运用) 优先级队列(堆运用) 】

总言 主要内容&#xff1a;编程题举例&#xff0c;熟悉理解宽搜类题型&#xff0c;队列、堆此类STL容器使用。       文章目录 总言1、 宽搜2、N 叉树的层序遍历&#xff08;medium&#xff09;2.1、题解 3、二叉树的锯齿形层序遍历&#xff08;medium&#xff09;3.1、题解…

【永洪BI】精确不同值计数

一、功能演示 二、使用说明 1、 功能简介 精确不同值计数&#xff0c;即统计所有数据行中不同数据值的总数量&#xff0c;数据值相同时只计算一次&#xff0c;如果存在维度字段&#xff0c;会按照不同类别分别计数。 2、 应用场景 想要统计数据中不同值出现的次数时可以使用…

Metasploit基本命令

1. 开启控制台 命令&#xff1a; msfconsole2. 搜索模块 命令&#xff1a; search ms17-010 # 模块名这里以搜索 ms17-010 为例&#xff0c; auxiliary 开头的为测试模块&#xff0c;也就是 POC&#xff0c;看看存不存在漏洞&#xff0c; exploit 开头的为攻击模块 3. 调…

DCMM(数据管理能力成熟度模型)对企业的价值

随着大数据时代的来临&#xff0c;数据已成为企业发展的重要驱动力。为了有效地管理和利用数据&#xff0c;企业需要建立一套完善的数据管理体系&#xff0c;而DCMM&#xff08;数据管理能力成熟度模型&#xff09;正是这样一个帮助企业构建和优化数据管理能力的框架。 DCMM结构…

芯片固定环氧胶有什么优点?

芯片固定环氧胶有什么优点&#xff1f; 芯片固定环氧胶在电子封装和芯片固定应用中具有多种显著优点&#xff0c;以下是其中的一些关键优势&#xff1a; 高粘接强度&#xff1a;环氧胶能够牢固地粘合芯片和基板&#xff0c;提供出色的粘接强度&#xff0c;确保芯片在各种环境条…

webpack优化构建速度示例-IgnorePlugin:

IgnorePlugin是webpack的一个内置插件&#xff0c;允许你忽略某些特定的模块或文件 webpack.config.jsconst config {entry: ./src/index.js,output: {filename: main.js},mode: development, }module.exports config;src/index.js import moment from moment console.log(mo…

剑指Offer打卡day34——AcWing 66. 两个链表的第一个公共结点

AcWing 66. 两个链表的第一个公共结点 暴力做法&#xff0c;两层for循环 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ class Solutio…