Flask快速入门(路由、CBV、请求和响应、session)

Flask快速入门(路由、CBV、请求和响应、session)

目录

  • Flask快速入门(路由、CBV、请求和响应、session)
    • 安装
    • 创建页面
    • Debug模式
    • 快速使用
    • Werkzeug介绍
    • watchdog介绍
      • 快速体验
    • 路由系统
      • 源码分析
      • 手动配置路由
      • 动态路由-转换器
    • Flask的CBV
      • 快速使用
      • cbv源码分析
    • 请求和响应
      • 请求对象(request)
      • 响应对象
    • Session
      • 基本使用
      • 原理解析

安装

pip install flask

创建页面

from flask import Flask

# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)

# 配置路由和视图函数的对应关系(基于装饰器)
@app.route("/")
def index():
    return "Hello World!"

# 启动一个本地开发服务器,激活该网页
app.run()
# 或者:
# if __name__ == '__main__':
#     app.run()

Debug模式

终端执行

if __name__ == '__main__':
	app.debug = True
    app.run()

debug模式下:

  • 自动重载 - 根据代码内容变化自动重启项目
  • 终端展示错误提示
  • 日志记录

快速使用

用route接受请求方式

@app.route("/", methods=['GET', 'POST'])
def index():
    return '你好'

直接调用请求方法

@app.get("/")
def index():
    return '你好'

Werkzeug介绍

Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库,它并没有和flask有直接联系,但是flask可以借助它执行各种Web操作,例如Request,Response

from werkzeug.wrappers import Request, Response

@app.route("/")
def index():
    return Response('你好')

watchdog介绍

快速体验

当前目录下修改文件会被监控,并打印日志

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    # 初始化监控类(文件的创建 删除...)
    event_handler = LoggingEventHandler()
    # 初始化监控类
    observer = Observer()
    # 配置 observer 以使用 event_handler 来处理 path 路径下的事件,并递归地监控该路径下的所有子目录(由于 recursive=True)
    observer.schedule(event_handler, path, recursive=True)
    # 启动监控
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

路由系统

源码分析

@app.route('/',methods=['GET'])

直接Ctrl左键进入route

@setupmethod
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:

    # 将视图函数作为参数执行了add_url_rule
    def decorator(f: T_route) -> T_route:
        endpoint = options.pop("endpoint", None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f

    return decorator

image-20240612154416089

该注释的意思是,当有给定的url规则来注册该视图函数时,将会触发该装饰器,且装饰器会执行add_url_rule方法,因此我们只需要搞明白add_url_rule做了什么

@setupmethod
def add_url_rule(
    self,
    rule: str,
    endpoint: str | None = None,
    view_func: ft.RouteCallable | None = None,
    provide_automatic_options: bool | None = None,
    **options: t.Any,
) -> None:
  • rule:定义路由的字符串,例如'/''/login'
  • endpoint:当URL中无参数,函数需要参数时,使用defaults = {‘k’: ‘v’}-为函数提供参数,django中也有,叫kwargs,默认为None
  • view_func:视图函数的名称,也就是源码中的f
  • provide_automatic_options: 一个布尔值,用于控制是否应该自动为路由添加一个 OPTIONS 方法的处理器。如果为 None,则使用应用配置的 ADD_AUTOMATIC_OPTIONS
  • options: 一个可变参数,用于传递额外的选项给路由。这些选项可以包括用于路由的各种配置,如 HTTP 方法的集合(methods

手动配置路由

知晓了路由原理后我们就可以不用装饰器自定义路由

def login():
    return '我是login'

app.add_url_rule('/login', endpoint=None, view_func=login, methods=['GET', 'POST'])

image-20240612161318162

动态路由-转换器

大致与Django同理

# 转换器
app.add_url_rule('/index/<int:pk>')

pk值是一个int类型的任意参数,除此之外还有其他类型参数:

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}

Flask的CBV

CBV(Class-Based Views)指的是基于类的视图编写方式

快速使用

from flask import Flask, url_for
from flask.views import MethodView

app = Flask(__name__)
app.debug = True

class IndexView(MethodView):
    def get(self):
        return 'get请求'

    def post(self):
        return 'post请求'
    
# name可以理解为别名
app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

if __name__ == '__main__':
    app.run()

# CBV也可以使用路由装饰器:
# @route('/index')  
# class IndexView(MethodView):  

即传了endpoint,又传了name,以谁为准?

  • 如果传了endpoint,以endpoint 为准
    如果没传,以函数名为准,函数名是view,但是被name改了,所以以name为准

cbv源码分析

class View:
    methods: t.ClassVar[t.Collection[str] | None] = None
    provide_automatic_options: t.ClassVar[bool | None] = None
    decorators: t.ClassVar[list[t.Callable[[F], F]]] = []
    init_every_request: t.ClassVar[bool] = True

    def dispatch_request(self) -> ft.ResponseReturnValue:
        raise NotImplementedError()

    @classmethod
    def as_view(
        cls, name: str, *class_args: t.Any, **class_kwargs: t.Any
    ) -> ft.RouteCallable:
        if cls.init_every_request:

            def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
                self = view.view_class(  # type: ignore[attr-defined]
                    *class_args, **class_kwargs
                )
                # 这里其实就是return self.dispatch_request(**kwargs)
                return current_app.ensure_sync(self.dispatch_request)(**kwargs)  # type: ignore[no-any-return]

        else:
            self = cls(*class_args, **class_kwargs)

            def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
                return current_app.ensure_sync(self.dispatch_request)(**kwargs)  # type: ignore[no-any-return]

        if cls.decorators:
            # 将view的名字改为传入的name 否则一直叫view
            view.__name__ = name
            view.__module__ = cls.__module__
            for decorator in cls.decorators:
                view = decorator(view)

        view.view_class = cls  # type: ignore
        view.__name__ = name
        view.__doc__ = cls.__doc__
        view.__module__ = cls.__module__
        view.methods = cls.methods  # type: ignore
        view.provide_automatic_options = cls.provide_automatic_options  # type: ignore
        return view
  • 每当有请求过来时执行view(),执行view的本质就是执行dispatch_request(),self就是我们定义的视图类对象

请求和响应

请求对象(request)

from flask import Flask, request

响应对象

make_response生成的响应对象可以存放字符串、模板、重定向、json

from flask import Flask, render_template, make_response

class ContactView(MethodView):
    def get(self):
        res = make_response('get请求')
        res.set_cookie('name', '<NAME>', path='/contact')
        return res
  • 可以对响应对象添加cookie,path的意思是只有path指定的路径会存储cookie,浏览其他页面不会携带cookie

Session

基本使用

# 配置secret_key 自定义的字符串
app.secret_key = 'abcdefg'
  • session['name'] = '张三'
  • session.pop('name')
  • session.clear()
  • name = session.get('name')

原理解析

  • 存储或修改session时
    • 对session进行加密(三段式)
    • 存储到cookie(obj.set_cookie)
  • 校验session时
    • 根据session取出cookie
    • 将第二段反解放入session中

源码:

# open_session
def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None:
    s = self.get_signing_serializer(app)
    if s is None:
        return None
    val = request.cookies.get(self.get_cookie_name(app))
    if not val:
        return self.session_class()
    max_age = int(app.permanent_session_lifetime.total_seconds())
    try:
        data = s.loads(val, max_age=max_age)
        return self.session_class(data)
    except BadSignature:
        return self.session_class()

# save_session
def save_session(
	self, app: Flask, session: SessionMixin, response: Response
    ) -> None:
    name = self.get_cookie_name(app)
    domain = self.get_cookie_domain(app)
    path = self.get_cookie_path(app)
    secure = self.get_cookie_secure(app)
    samesite = self.get_cookie_samesite(app)
    httponly = self.get_cookie_httponly(app)

    # Add a "Vary: Cookie" header if the session was accessed at all.
    if session.accessed:
        response.vary.add("Cookie")

        # If the session is modified to be empty, remove the cookie.
        # If the session is empty, return without setting the cookie.
        if not session:
            if session.modified:
                response.delete_cookie(
                    name,
                    domain=domain,
                    path=path,
                    secure=secure,
                    samesite=samesite,
                    httponly=httponly,
                )
                response.vary.add("Cookie")

                return

            if not self.should_set_cookie(app, session):
                return

            expires = self.get_expiration_time(app, session)
            val = self.get_signing_serializer(app).dumps(dict(session))  # type: ignore
            response.set_cookie(
                name,
                val,  # type: ignore
                expires=expires,
                httponly=httponly,
                domain=domain,
                path=path,
                secure=secure,
                samesite=samesite,
            )
            response.vary.add("Cookie")

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

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

相关文章

青书学堂 看视频 耍课时

1. 获取课程节点id ( /nynzy/Student/Course/GetStudyRecordAndScore ) 接口地址 2. 把所有的nodeId 保存下来 保存到 old.txt 格式 课程id 与 nodeId 用 | 隔开 3. 然后创建 test.php 注意把 cookie 换成自己的 <?php$oldFilename ./old.txt; $newFilename ./new.…

使用MySQL全文索引实现高效搜索功能

MySQL全文索引是MySQL提供的一种高效的搜索功能&#xff0c;可以快速地搜索文本内容。全文索引可以用于搜索大量文本数据&#xff0c;通常应用在文章、博客、论坛等需要搜索的场景中。 什么是MySQL全文索引 MySQL全文索引是一种用于快速搜索文本内容的索引技术。它可以在存储和…

vue+elementplus模拟“山野愚人居”简单实现个人博客

目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客&#xff1a;山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…

联邦学习权重聚合,联邦学习权重更新

目录 联邦学习权重聚合 model.state_dict() 保存模型参数 加载模型参数 注意事项 联邦学习权重更新 联邦学习权重聚合 model.state_dict() 在PyTorch框架中,model.state_dict() 是一个非常重要的方法,它用于获取模型的参数(即权重和偏置)作为一个有序字典(Order…

最流行的后端框架:如何选择适合自己的框架

最流行的后端框架&#xff1a;如何选择适合自己的框架 在当今快节奏的数字环境中&#xff0c;软件开发需要高效、可扩展且可靠的解决方案。最流行的后端框架&#xff0c;这就是后端框架的用武之地。这些软件框架提供了构建 Web 应用程序的骨干&#xff0c;处理了从数据库交互到…

Spring系统学习 - Bean的作用域

bean作用域介绍 Spring框架提供了不同的作用域来管理Bean的生命周期和可见性&#xff0c;这对于控制不同类型的组件和处理并发请求尤其重要。 singleton&#xff08;默认&#xff09;&#xff1a; 每个Spring IoC容器只有一个bean实例。当容器创建bean后&#xff0c;它会被缓存…

CP AUTOSAR标准中文文档链接索引(更新中)

AUTOSAR标准的核心组件包括通信、诊断、安全等&#xff0c;这些组件通过模块化结构进行组织。系统被划分为多个模块&#xff0c;每个模块负责特定的功能。模块之间通过接口进行通信&#xff0c;接口定义了模块之间的交互规则。AUTOSAR标准支持模块的配置&#xff0c;可以根据不…

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…

Web端在线/离线Stomp服务测试与WebSocket服务测试

Stomp服务测试 支持连接、发送、订阅、接收&#xff0c;可设置请求头、自动重连 低配置云服务器&#xff0c;首次加载速度较慢&#xff0c;请耐心等候 预览页面&#xff1a;http://www.daelui.com/#/tigerlair/saas/preview/lxbho9lkzvgc 演练页面&#xff1a;http://www.da…

「OC」UI练习(二)——照片墙

「OC」UI练习——照片墙 文章目录 「OC」UI练习——照片墙UITapGestureRecognizer介绍照片墙实现 UITapGestureRecognizer介绍 UITapGestureRecognizer是UIKit框架中的一个手势识别器类&#xff0c;用于检测用户在视图上的轻击手势。它是UIGestureRecognizer的一个子类&#x…

基于51单片机的智能恒温箱设计--数码管显示

一.硬件方案 根据恒温箱控制器的功能要求&#xff0c;并结合对51系列单片机软件编程自由度大&#xff0c;可用编程实现各种控制算法和逻辑控制。所以采用AT89C52作为电路系统的控制核心。按键将设置好的温度值传给单片机&#xff0c;通过温度显示模块显示出来。初始温度设置好…

Java I/O模型

引言 根据冯.诺依曼结构&#xff0c;计算机结构分为5个部分&#xff1a;运算器、控制器、存储器、输入设备、输出设备。 输入设备和输出设备都属于外部设备。网卡、硬盘这种既可以属于输入设备&#xff0c;也可以属于输出设备。 从计算机结构的视角来看&#xff0c;I/O描述了…

龙迅LT6911GX HDMI 2.1转四 PORT MIPI或者LVDS,支持图像处理以及旋转,内置MCU以及LPDDR4

龙迅LT6911GX描述&#xff1a; LT6911GX是一款高性能的HDMI2.1到MIPI或LVDS芯片&#xff0c;用于VR/显示器应用。HDCP RX作为HDCP中继器的上游端&#xff0c;可以与其他芯片的HDCP TX协同工作&#xff0c;实现中继器的功能。对于HDMI2.1输入&#xff0c;LT6911GX可配置为3/4车…

Elasticsearch集群运维,重平衡、分片、宕节点、扩容

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 参考 探索集群 Elasticsearch 中文文档 https://www.elastic.co/guide/en/elasticsearch/reference…

linux系统——wget命令

wget命令可以用于下载指定的url地址文件&#xff0c;支持断点续传&#xff0c;支持ftp&#xff0c;http协议下载&#xff0c;在下载普通文件时&#xff0c;即使网络出现故障&#xff0c;依然会不断尝试下载 wget命令直接加url地址 使用-o参数可以将下载文件改名&#xff0c;-c…

windows11 建立批处理bat文件来删除指定目录下的所有隐藏的文件。

今天在导入项目的时候发现之前项目中的文件夹中有很多隐藏的临时文件&#xff0c;这个文件应该是版本控制产生的&#xff0c;导致导入后文件夹上有X&#xff0c;然后里面文件是一个没有错。 我们来建立一个bat来&#xff0c;进行批量删除隐藏文件就可以了&#xff1a; echo o…

【Go】用 DBeaver、db browser 和 SqlCipher 读取 SqlCipher 数据库

本文档主要描述如何用 DBeaver、db browser 和 SqlCipher 上打开加密的 SQLite3 数据库(用 SqlCipher v3 加密) 软件版本 DBeaver&#xff1a;v24.1.0 SQLite-driver: sqlite-jdbc-3.46.0.0.jar dbbrowser-for-sqlite-cipher&#xff1a;3.12.2 SqlCipher cli(ubuntun)&am…

探索未来通信的新边界:AQChat一款融合AI的在线匿名聊天

探索未来通信的新边界&#xff1a;AQChat一款融合AI的在线匿名聊天 在数字时代&#xff0c;即时通讯变得无处不在&#xff0c;但隐私和性能仍旧是许多用户和开发者关注的焦点。今天&#xff0c;我要介绍一个开创性的开源项目 —— AQChat&#xff0c;它不仅重定义了在线匿名聊…

noVNC 小记

1. 怎么查看Ubuntu版本

Vue.js结合ASP.NET Core构建用户登录与权限验证系统

1. 环境准备2. 创建项目3. Vue配置步骤一: 安装包步骤二: 配置文件步骤三: 页面文件 4. 后台配置 在本教程中&#xff0c;我将利用Visual Studio 2022的强大集成开发环境&#xff0c;结合Vue.js前端框架和ASP.NET Core后端框架&#xff0c;从头开始创建一个具备用户登录与权限验…