(二十五)Flask之MTVMVC架构模式Demo【重点:原生session使用及易错点!】

目录:

  • 每篇前言:
  • MTV&MVC
  • 构建一个基于MTV模式的Demo项目:
    • 蹦出一个问题:

每篇前言:

  • 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者

  • 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入门到实战》
  • 🔥🔥热门专栏推荐:《Python全栈系列教程》、《爬虫从入门到精通系列教程》、《爬虫进阶+实战系列教程》、《Scrapy框架从入门到实战》、《Flask框架从入门到实战》、《Django框架从入门到实战》、《Tornado框架从入门到实战》、《前端系列教程》。
  • 📝​📝本专栏面向广大程序猿,为的是大家都做到Python全栈技术从入门到精通,穿插有很多实战优化点。
  • 🎉🎉订阅专栏后可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
  • 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!

在这里插入图片描述

MTV&MVC

先来讲一下两种常见的软件架构模式——MTV和MVC~

它俩是用于组织和管理应用程序的不同组件和逻辑。通常用于开发Web应用程序和其他软件项目。

  1. MTV(Model-Template-View):
    • Model(模型):表示应用程序的数据和业务逻辑。它负责管理数据的存储、检索和处理,以及处理与数据相关的操作。
    • Template(模板):定义了应用程序用户界面的外观和结构,通常使用模板语言编写,将动态数据插入静态页面中。
    • View(视图):表示用户界面的逻辑部分,它从模型中获取数据并将其呈现到模板中,然后将结果发送给用户的浏览器。视图还可以处理用户的输入和用户界面的交互。

MTV模式是Django Web框架的一部分(但是这个模式也非常适合Flask),其中Model对应于数据模型,Template对应于模板文件,View对应于视图函数,这些组合在一起用于构建Web应用程序。

  1. MVC(Model-View-Controller):
    • Model(模型):与MTV中的模型类似,负责应用程序的数据和业务逻辑。它处理数据的存储、检索和处理。
    • View(视图):与MTV中的视图有些不同,它表示应用程序的用户界面,但不直接与模板相关。视图接收用户输入,处理它并与模型进行通信以更新数据。
    • Controller(控制器):控制器是MVC的核心,它负责接收用户输入并根据输入调度视图和模型的操作。它决定如何响应用户的请求,并确保模型和视图之间的协同工作。

MVC模式通常在框架如Spring、Ruby on Rails等中使用,它的核心思想是分离数据处理、用户界面和控制流,以提高代码的可维护性和可扩展性。控制器充当用户输入的处理中心,调度模型和视图以完成所需的操作。

总的来说,MTV和MVC都是用于组织和管理应用程序代码的模式,它们有不同的实现方式,但目标都是分离关注点,以提高代码的可读性和可维护性。

一一对应:

在这里插入图片描述

Flask如果采用MVC架构的话,项目结构demo:

在这里插入图片描述

但是推荐在Flask中使用MTV架构模式,而且Flask中主流也是用这个:

在这里插入图片描述

构建一个基于MTV模式的Demo项目:

在这里插入图片描述

  • login.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title>
    </head>
    <body>
    <form action="" method="post">
        <input type="text" name="user">
        <input type="text" name="pwd">
        <input type="submit" value="提交">{{msg}}
    </form>
    </body>
    </html>
    
  • account.py:

    from flask import Blueprint, render_template, request, session, redirect
    from uuid import uuid4
    
    account = Blueprint('account', __name__)
    
    
    @account.route('/login', methods=['GET', 'POST'])
    def login():
        if request.method == 'GET':
            return render_template('login.html')
        user = request.form.get('user')
        pwd = request.form.get('pwd')
        if user == 'GuHanZhe' and pwd == '123':
            uid = str(uuid4())
            session['user_info'] = {'id': uid, 'name': user}
            return redirect('/index')
        else:
            return render_template('login.html', msg='用户名获或密码错误')
    
    
  • home.py:

    from flask import Blueprint, session
    
    home = Blueprint('home', __name__)
    
    
    @home.route('/index')
    def index():
        user_info = session.get('user_info')
        print(user_info)
    
        return 'Index'
    
    
    @home.route('/test')
    def test():
        return 'Test'
    
    
  • __init__.py:

    from flask import Flask
    from .views import account
    from .views import home
    
    
    def create_app():
        app = Flask(__name__)
        app.config.from_object('settings.DevelopmentConfig')
    
        app.register_blueprint(account.account)
        app.register_blueprint(home.home)
    
        return app
    
    
  • manage.py:

    from flask_stru import create_app
    app = create_app()
    
    
    if __name__ == '__main__':
        app.run()
    
    
  • settings.py:

    class Config(object):
        DEBUG = True
        SECRET_KEY = 'GuHanZheIsCool'
    
    
    class ProductionConfig(Config):
        pass
    
    
    class DevelopmentConfig(Config):
        pass
    
    
    class TestingConfig(Config):
        pass
    
    

运行manage.py文件,访问login登录(登录成功的话):

在这里插入图片描述

来看下源码,看看默认cookie过期时间是多久:

from flask.sessions import SecureCookieSessionInterface

在这里插入图片描述
在这里插入图片描述

可以看到注释中表示这个值默认是31天~而且我们可以设置这个值:

在这里插入图片描述

而这个参数生效的前提是session.permanent为True(默认就是为True);

如果设置为False,则关闭浏览器cookie就失效。

在这里插入图片描述

再看看源码设置cookie的(save_session)上面这一部分:

如果if成立就直接返回,客户端就不会存cookie了!
在这里插入图片描述

蹦出一个问题:

在这里插入图片描述

访问index接口是正常的,name修改成功:

在这里插入图片描述

但是如果访问test接口的话,就不正常了:
在这里插入图片描述

很容易想到,这个问题的原因是因为cookie修改后没有保存!

抛出答案,这是因为修改cookie的话,默认只有当第一层修改才会保存,而第二层、第三层等…都不会保存。

{
	user_info: {k1: 1, k2: 2}
}

如果是第一层被修改会保存:
{
	user_info: {k1: 1, k2: 2},
	xxx :{'A': 5}
}
但是如果是第二层,第三层...修改不会保存:
{
	user_info: {k1: 1, k2: 2, k3: 3}
}

看源码分析这种问题的点源于何处:

在这里插入图片描述
在这里插入图片描述

斗胆翻译一下第一个箭头所指变量对应的注释部分:

“当数据发生变化时,将此标志设置为True。仅跟踪会话字典本身;如果会话包含可变数据(例如嵌套的字典),则在修改该数据时必须手动将此标志设置为True。仅当此标志为True时,会话cookie才会写入响应中。”

进第一个父类:

在这里插入图片描述
在这里插入图片描述

调用on_update函数了就会给modified设为True。

所以:

session['user_info'] = 'abc'     # session.__setitem__
session['user_info'][('name')]

第一行会修改,但是第二行是调用的__getitem__,而源码(上图)没有相关处理,所以不会保存。

解决方法:
在这里插入图片描述

再来看下源码(上面没有看完的部分):
在这里插入图片描述
在这里插入图片描述

进去看,因为设置了modified为True,所以这个should_set_cookie就为True,所以这个if就不成立,就继续往下执行。

不过这部分源码给了我们另一个方法,如果设置SESSION_REFRESH_EACH_REQUEST这个参数为True,每次请求session也都会修改(用这个方法解决):
在这里插入图片描述

而且推荐使用这个方法,推荐用这个的原因:

想象一个使用场景,如果用户登录一个网站,cookie设置的二十分钟失效,如果这个过程中用户一直没有做cookie相关的操作,那么20分钟后登录就失效了,但是如果这二十分钟用户一直在访问这个网站,是不应该让用户失效的。

如果设置了上述这个参数为True,就不会出现这种问题,

SESSION_REFRESH_EACH_REQUEST 的行为是在用户请求时将会话标记为“新的”(fresh),以确保它在每个请求之后都会被刷新。这意味着,无论用户是否刷新浏览器或进行其他操作,都会重置会话的过期时间。这是为了确保用户在与应用交互期间会话不会过期(过期时间会从用户刷新的时间重新往后计算)

Flask中使用的话,要在登录成功后设置一下permanent也为True(但是如果用flask-session就不用了,因为这个默认是为True):

在这里插入图片描述

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

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

相关文章

VScode 关闭鼠标悬停提示

设置-文本编辑&#xff0c;然后搜索&#xff1a;Hover:Enanbled,出现如下图&#xff0c;取消勾选即可&#xff1b;

2024常见性能测试工具!

一&#xff1a;如何选择性能工具 选择性能测试工具时&#xff0c;可以从以下几个方面进行考虑&#xff1a; 1. 需求匹配&#xff1a;首先要明确项目的具体需求&#xff0c;比如需要测试的应用类型、协议、负载规模等。确保所选工具能够满足这些需求。 2. 技术兼容性&#xf…

Vue3--数据和方法

data 组件的 data 选项是一个函数。Vue 在创建新组件实例的过程中会自动调用此函数。   data选项通常返回一个对象&#xff0c;然后 Vue 会通过响应性系统将其包裹起来&#xff0c;并以 $data 的形式存储在组件实例中。 <!DOCTYPE html> <html lang"en"&g…

已解决:android SDK安装时点击SDK Manager出现闪退

1、首先确保电脑里边安装了JDK&#xff0c;并且要把安装路径配置在环境变量里边&#xff0c;避免使用绝对路径 推荐%JAVA_HOME%\bin 2、在C:\Users\huanhuan\Desktop\android-sdk-windows\tools路径下找到android.bat文件打开&#xff0c;把set java_exe后改为jdk中java.exe的路…

孪生网络(Siamese Network)和数字孪生的区别?

1. 孪生网络 孪生网络是一种特殊的网络框架&#xff0c;基于两个人工神经网络建立的耦合构架&#xff0c;通过比较两个样本在高维度空间的表征来判断它们的相似程度。它包含两个相同结构的神经网络&#xff0c;一个用于学习&#xff0c;一个用于验证学习效果。在训练过程中&am…

【火猫TV】欧联:8强无弱队,意甲英超球队扎堆,利物浦和药厂优势很大!

2023-2024欧联杯八强正式出炉&#xff0c;马赛、本菲卡、勒沃库森、利物浦、西汉姆联、罗马、亚特兰大和AC米兰成功拿到了晋级名额&#xff0c;于是球迷们即将看到近20年竞争最激烈的欧联杯八强对决。虽然这些队伍实力有强有弱&#xff0c;但是能够拼到现在的球队没有弱旅&…

20240304 json可以包含复杂数组(数组里面套数组)

欣赏一下我的思维&#xff0c;它会以漫画&#xff0c;表格&#xff0c;文字。。。各种各样的形式呈现 对于问题1问题2 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON本质上是一种文本…

鸿蒙实战开发:【分布式软总线组件】

简介 现实中多设备间通信方式多种多样(WIFI、蓝牙等)&#xff0c;不同的通信方式使用差异大&#xff0c;导致通信问题多&#xff1b;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。分布式软总线实现近场设备间统一的分布式通信管理能力&#xff0c;提供不区分链路…

鸿蒙开发面试真题分享~

1. 在鸿蒙应用开发中&#xff0c;有哪些常用的性能优化策略和技术手段&#xff0c;如启动速度优化、内存管理优化、功耗控制等&#xff1f; 参考答案&#xff1a; 2. 鸿蒙系统强调跨平台特性&#xff0c;你会如何利用这一特性来优化多端部署和适配&#xff1f; 参考答案&…

Android 音频系统

导入 早期Linux版本采用的是OSS框架&#xff0c;它也是Unix及类Unix系统中广泛使用的一种音频体系。 ALSA是Linux社区为了取代OSS而提出的一种框架&#xff0c;是一个源代码完全开放的系统(遵循GNU GPL和GNU LGPL)。ALSA在Kernel 2.5版本中被正式引入后&#xff0c;OSS就逐步…

力扣111---二叉树的最小深度(简单题,Java,递归+非递归)

目录 题目描述&#xff1a; &#xff08;递归&#xff09;代码&#xff1a; &#xff08;非递归、层次遍历&#xff09;代码&#xff1a; 题目描述&#xff1a; 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Panel)

可滑动面板&#xff0c;提供一种轻量的内容展示窗口&#xff0c;方便在不同尺寸中切换。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 说明&#xff1a; 子组件类型&a…

phpcms上传漏洞

原始漏洞 漏洞原理&#xff1a;我们上传一个zip的压缩包&#xff0c;它会解压然后删除其中不是.jpg .gig .png的文件 function check_dir($dir)&#xff1a;这是一个PHP函数的定义&#xff0c;它接受一个参数 $dir&#xff0c;代表要检查的目录路径。 $handle opendir($dir)…

抖音电商新店品牌孵化运营打造规划方案

【干货资料持续更新&#xff0c;以防走丢】 抖音电商新店品牌孵化运营打造规划方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 PDF共130页&#xff08;完整资料包含以下内容&#xff09; 目录 抖音电商运营计划 1. 筹备期 货-人-场匹配 - 确定优质货品…

ANOMALY: meaningless REX prefix used汇总

原因1 未使用指定的python环境 解决方案 使用activate激活指定的python环境 原因2 系统更新然后命令行爆出的错误/电脑中的杀毒软件和系统兼容有问题。 解决方案2 1.将杀毒软件卸载。 2.使用360、电脑管家等对系统进行修复。 原因3 某些软件使用的开源库&#xff0c;比…

苹果Find My App用处多多,产品认准伦茨科技ST17H6x芯片

苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、AirPods、Apple Watch&#xff0c;如今的Find My已经不单单可以查找苹果的设备&#xff0c;随着第三方设备的加入&#xff0c;将丰富Find My Network的版图。产…

Linux中GPU相关命令

Linux查看显卡信息&#xff1a; lspci | grep -i vga 使用nvidia GPU可以&#xff1a; lspci | grep -i nvidia1 前边的序号 "00:0f.0"是显卡的代号(这里是用的虚拟机); 查看指定显卡的详细信息用以下指令&#xff1a; lspci -v -s 00:0f.01 Linux查看Nvidia显…

电源ATE自动测试系统为您提供一站式自动化测试解决方案

ATECLOUD-POWER电源ATE自动测试系统已为许多客户提供专业的测试解决方案&#xff0c;并且都成功交付。那么电源模块ATE自动测试系统是如何提供测试方案&#xff0c;完成电源测试呢? 在工程师明确用户测试需求、掌握测试方法与步骤之后&#xff0c;从仪器选型到系统开发、再到机…

ACM记忆化DFS与基于优先队列的BFS

基本概念--记忆化DFS 使用数组保存已经算出来的值&#xff0c;在后续的计算中减少大量的重复计算&#xff0c;提高效率。&#xff08;用于dp不方便&#xff0c;但是搜索方便的情况&#xff0c;可以提升效率。&#xff09; eg. 记忆化dfs求解斐波那契数列 int dfs(int n) {if…

鱼哥赠书活动第13期:看完这本书教你成为逆向 汇编大佬!!《ARM汇编与逆向工程 蓝狐卷 基础知识》

鱼哥赠书活动第13期&#xff1a;看完这本书教你成为逆向 汇编大佬&#xff01;&#xff01; 内容简介&#xff1a;作者简介&#xff1a;译者简介&#xff1a;书本目录&#xff1a;了解更多&#xff1a;赠书抽奖规则:往期赠书福利&#xff1a; 与传统的CISC&#xff08;Complex …