栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

3天速成flask学习笔记

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

3天速成flask学习笔记

目录

 一、web框架:

最核心的事情

​编辑安装

二、创建flask项目

1.最小原型

2.flask断点调试之URL传参

3.URL路由映射

4. POSTMAN 收发数据

POST

5.响应

1)定义响应格式

json

html

TXT

2)定义响应码

 3)定义响应头参数

三、app()源码解析

四、模板渲染

1.前后端分离与不分离

2.模板渲染示例

render_template()函数解析

3.如何传递数据

准备一组数据

定义路由,传入数据变量

 使用变量p及逻辑代码编写html

​编辑

渲染效果

4.过滤器

特性

字符串过滤

数字过滤

 列表过滤

json过滤

自定义过滤

 参考文档

5.测试test

6.全局函数global

特性

7.继承extend

特性

父类(基模板)

子模版

 include

 宏


 一、web框架:

最核心的事情

请求分派

制造响应

安装

直接安装    pip install flask 

虚拟安装   python -m venv venv

 


二、创建flask项目

1.最小原型

from wsgiref.simple_server import make_server


def app(env,response):
    # "flask/django application"
    print("正在监听")
    response('200 OK',[("content-type",'text/html')]) #定义响应头
    return  ['cuteboy']

# 初始化一个服务器
server = make_server('',5100,app)
server.serve_forever(0.2)

2.flask断点调试之URL传参

1)在地址栏运行  http://localhost:5100/login/?usr=lyr

 2)在print()语句添加断点,点击小虫子调试按钮:

 3)刷新浏览器界面

 4)进入pycharm调试器界面,点开env环境变量列表,观察如下关键变量

3.URL路由映射
from flask import Flask
app = Flask(__name__)#得到APP对象
#路由
@app.route('/login/')
def index():
    """视图函数"""
    return "login ok"


@app.route('/projects/')
def projects():
    """视图函数"""
    return "projects ok"
app.run()#启动web服务,也可以用uwsgi,flask自带的测试服务器

127.0.0.1:5000/projects/

# def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):

:param host:要侦听的主机名。将其设置为`0.0.0.0``to
让服务器在外部也可用。默认为“127.0.0.1”或“SERVERu NAME”配置变量中的主机
:param port:Web服务器的端口。默认为“5000”或在“SERVERu NAME”配置变量中定义的端口
:param debug:如果给定,则启用或禁用调试模式。看见
:attr:'debug'。
:param loadu dotenv:加载最近的:文件:`。

env`和:文件:`。弗拉斯肯夫`
用于设置环境变量的文件。也会改变工作方式
目录到包含找到的第一个文件的目录。
:param options:转发到底层Werkzeug的选项
服务器见:func:` werkzeug。服务run_simple`了解更多信息
信息

4. POSTMAN 收发数据

POST
from flask import Flask,request

app = Flask(__name__)#得到APP对象
#路由
@app.route('/',methods=['POST'])
def hello():
    """视图函数"""
    #获取请求当中的post
    bodydata = request.form
    print (bodydata)
    return "hello world"
(base) PS D:TELEARNINGKDTLearningwebflask快速开始> flask run

D:TELEARNINGKDTLearningwebflask快速开始app.py:38: Warning: Silently ignoring app.run() because the application is run from the flask command line ex
ecutable.  Consider putting app.run() behind an if __name__ == "__main__" guard to silence this warning.
  app.run(debug=True)
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [20/Jul/2022 00:52:49] "?[31m?[1mGET / HTTP/1.1?[0m" 405 -
ImmutableMultiDict([('"username', 'lyr')])
127.0.0.1 - - [20/Jul/2022 00:53:05] "?[37mPOST / HTTP/1.1?[0m" 200 -

5.响应

1)定义响应格式
  • json

  • html

  • TXT

2)定义响应码

 3)定义响应头参数

三、app()源码解析

四、模板渲染

1.前后端分离与不分离


2.模板渲染示例

  • render_template()函数解析

def render_template(template_name_or_list, **context):
    #**context是上下文
    """Renders a template from the template folder with the given
    context.

    :param template_name_or_list: the name of the template to be
                                  rendered, or an iterable with template names
                                  the first one existing will be rendered
    :param context: the variables that should be available in the
                    context of the template.
    """
    ctx = _app_ctx_stack.top
    ctx.app.update_template_context(context)
    return _render(
        ctx.app.jinja_env.get_or_select_template(template_name_or_list),
        context,
        ctx.app,
    )

3.如何传递数据
  • 准备一组数据

#测试数据
projects_data =[
    {"name": "CUPID","tester": "luoyiran","createtime":2022.01},
    {"name": "DDH", "tester": "yangshuokai", "createtime": 2022.02},
    {"name": "Pair", "tester": "liuwenxing", "createtime": 2022.03},
    {"name": "Pevic", "tester": "liran", "createtime": 2022.04},
    {"name": "AutoEF", "tester": "gaorui", "createtime": 2022.05},
    {"name": "3Dbaby", "tester": "yuhao", "createtime": 2022.06},
]
  • 定义路由,传入数据变量

@app.route('/test3/')
def test3():
    """如何传递数据"""
    return render_template('test3.html',p=projects_data)
  •  使用变量p及逻辑代码编写html




    
    
    
    展示测试状态信息



获取全局变量config
{{ config }}

打印全局变量config的键值
 MAX_COOKIE_SIZE:  {{ config ['MAX_COOKIE_SIZE'] }}

获取全局变量request
{{ request }}


展示测试状态信息
{% for project in p%}


{%set name = project['name']%}
{%set tester = project['tester']%}
{%set createtime = project['createtime']%}
    {% if tester=="luoyiran" %}
        

测试项目:{{name}} 测试人员:{{tester}} 创建时间:{{createtime}}

{% elif tester!="luoyiran" %} 测试项目:{{name}} 测试人员:{{tester}} 创建时间:{{createtime}}
{% endif %} {% endfor %}
  • 渲染效果

 


4.过滤器filter

特性

| [过滤器名字]

字符串过滤

数字过滤

 列表过滤

json过滤

自定义过滤
@app.template_filter("dt_to_string")
def dt_to_string(dt):
    return dt.strftime("%Y-%m-%d")



    
    
    
    展示测试状态信息


首页  联系我们
获取全局变量config
{{ config }}

打印全局变量config的键值
 MAX_COOKIE_SIZE:  {{ config ['MAX_COOKIE_SIZE'] }}

获取全局变量request
{{ request }}


展示测试状态信息
{% for project in p%}


{%set name = project['name']%}
{%set tester = project['tester']%}
{%set createtime = project['createtime']%}
    {% if tester=="luoyiran" %}
        

测试项目:{{name}} 测试人员:{{tester}} 创建时间:{{createtime |dt_to_string }}

{% elif tester!="luoyiran" %} 测试项目:{{name}} 测试人员:{{tester}} 创建时间:{{createtime|dt_to_string}}
{% endif %} {% endfor %}

过滤效果:

 参考文档

jinjia2(内置过滤器清单)

5.测试器 test

6.全局函数 global 特性

7.继承extend 特性

如随意跳转,网易顶部导航页/页脚一般不会变      “ 首页 | 联系我们”

父类(基模板)

所有子页面继承这个页面(basepage),可以理解为组件

子模版

 

 include

 宏

python flask路由post无法解析:A request was sent to this

https://zhuanlan.zhihu.com/p/107383595

我们的声明:

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

例如:post请求 http://127.0.0.1:5000/ 访问没问题。

post请求 http://127.0.0.1:5000 解析出错

正确的声明方法是:
@app.route('/', methods=['get', 'post'], strict_slashes=False)


这样不会再 严格的要求 斜杠

post请求 http://127.0.0.1:5000 访问正确

五、FLASK路由原理和可插拔视图 特性

1.添加路由的方式很简单

2.路由就是把URL和需要执行的程序绑定在一起

3.输入URL,调用对应的函数

wsgi程序如何处理路由  自制路由装饰器@route()
# 路由地图
url_map = {}

# 添加路由函数
def add_url_rule(url,view_func):
    """添加路由"""
    url_map[url] = view_func


app.add_url_rule('/login',view_func = login)
app.add_url_rule('/',view_func = index)

def route(url):
    # 路由装饰器
    def decorator(f):
        add_url_rule(url, f)
        return f
    return decorator
@route('/case')
def case():
    return "case ok"

print("url.map:",url_map) #map是对象

def app(env,response):
    url = env.get('PATH_INFO') # 接口地址
    # para = env.get('QUERY_STRING')
    print("url:",url)
    # print("para:",para)
    if url is None or (url not in url_map.keys() ):
        response('404 ok',[('content-type','text/plain'),])
        res = "页面不存在"
        return [res.encode()]
    else:
        response('200 ok', [('content-type', 'text/plain'), ])
        res = url_map.get(url)
        print (res)
        return [res().encode()]
自定义时间打印装饰器

# 路由函数的装饰器必须放在route装饰器下

def printtime(f):
    """打印时间"""
    def decorator():
        print (datetime.datetime.now())
        return "time ok"
    return decorator
@route('/case')
@printtime
# 路由函数的装饰器必须放在route装饰器下
def case():
    return "case ok"
URL和视图函数的数量关系
# 问题1 一个URL=====》route装饰器将同个url赋值给多个视图函数,可行?
# 问题2 一个视图函数====>赋值给多个URL,可行?
# 添加路由规则,关联url和视图函数
def add_url_rule(url,view_func):
    """添加路由
      key:url
      value:视图函数
      # 使用此种方法:字典里的key不能重复,后绑定的视图函数会覆盖前面绑定了同个路由的视图函数返回结果
        url_map[url] = view_func
     # 使用此种方法:字典里的key不能重复,后面绑定同个key(url)的视图函数时,会先判断前面是否绑定相同key,若绑定,无法写入字典
      # url_map.setdefault(url,view_func)
    """
    # url_map[url] = view_func
    url_map.setdefault(url,view_func)
@route('/case')
def case():
    return "case ok"

@route('/case')
def case2():
    """问题1"""
    return "case2 ok"

url_map[url] = view_func    返回结果:调用了case2()

url_map.setdefault(url,view_func)   返回结果:调用了case()

五、类视图 1.类视图有什么好处?

1)类是可以继承的

2)代码可以复用

3)可以定义多种行为 类:方法/行为/属性/特征

4)类:不同的请求方式 get/post/delete

2.类视图demo View

特性     |     View类衍生出来的现成写法

1.在app.py编写如下代码

from flask import Flask, request
from flask import render_template,redirect
from flask.views import View

from wsgiref.simple_server import make_server

app = Flask(__name__,
            template_folder ='pages',
            static_folder ='static'
            )  # 得到APP对象

# 修改配置
app.config['JSON_AS_ASCII'] = False  # 返回字符设置

# 测试数据
projects_data = [
    {"name": "CUPID", "tester": "luoyiran"},
    {"name": "DDH", "tester": "yangshuokai"},
]


# 类视图
class ProjectView(View):
    # View视图一定要记得定义methods
    methods = ['GET', 'POST', 'PUT']

    def get(self):
        return "get ok",200

    def post(self):
        return "post ok",211

    def dispatch_request(self):
        """一定要实现,这是一个规范,第二次请求的分派
        """
        #获取请求方法,根据请求方法,调用不同的实例方法
        method = request.method.lower()
        if method == 'get' :
            return self.get()
        elif method == 'post':
            return self.post()
        else:
            return "Method not allowed",405


# 注册视图
# 基于类的视图,不要用装饰器,采取集中注册的形式,add_url_rule
# view_func 是一个类 ,需要添加as_view("XXX")
app.add_url_rule('/project1',view_func = ProjectView.as_view('PV'))

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

2.打开postman,访问路由视图'/project1’

1)发送post请求 

 2)发送get请求

 3)发送其他请求

MethodView

特性     |     是flask针对现在的RESTful风格的接口设计出来的

1.在app.py编写如下代码 

from flask import Flask, request
from flask import render_template,redirect
from flask.views import View,MethodView

from wsgiref.simple_server import make_server
# get : 获取资源
# post :创建资源
# put :更新资源
# delete :删除资源
app = Flask(__name__,
            template_folder ='pages',
            static_folder ='static'
            )  # 得到APP对象

# 修改配置
app.config['JSON_AS_ASCII'] = False  # 返回字符设置


# 类视图
class ProjectView(MethodView):

    def get(self):
        return "MethodView get ok",200

    def post(self):
        return "MethodView post ok",211




# 注册视图
# 基于类的视图,不要用装饰器,采取集中注册的形式,add_url_rule
# view_func 是一个类 ,需要添加as_view("XXX")
app.add_url_rule('/project1',view_func = ProjectView.as_view('PV'))

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

 2.postman测试

 

 3.实现指定的methods类属性,照样可以控制请求方法

就算类当中实现了实例方法get(),post(),put()等等,也是不支持对应的请求方法的

class ProjectView(MethodView):
    # 实现指定的methods类属性,照样可以控制请求的方法
    methods = ['GET']  #相当于:禁用ProjectView类试图里的除了get()以外的所有请求函数
    def get(self):
        return "MethodView get ok",200

    def post(self):
        return "MethodView post ok",211

 

postman测试

类视图为何能够生效? 

【原因】因为类实现了as_view( )这个方法

  • 视图函数 : /project  ==> def project()
  • 类视图: /project  ==> def view( )  ==> 调用dispatch_request( )

view.py

class View(object):
    """使用视图函数的替代方法。一个子类必须实现:meth:`dispatch_request`,
    它使用来自 URL 路由系统的视图参数调用。
    如果提供了 :attr:`methods`,
    则方法不必显式传递给 :meth:`~flask.Flask.add_url_rule` 方法
    

        class MyView(View):
            methods = ['GET']

            def dispatch_request(self, name):
                return 'Hello %s!' % name

        app.add_url_rule('/hello/', view_func=MyView.as_view('myview'))

    # 当你想装饰一个可插入的视图时,你必须在创建视图函数时这样做:
    # 通过包装:meth:`as_view`的返回值,或者你可以使用:attr:`decorators`属性::

        class SecretView(View):
            methods = ['GET']
            decorators = [superuser_required]

            def dispatch_request(self):
                ...

    # 储在装饰器列表中的装饰器在创建视图函数时一个接一个地应用。请注意,您不能使用基于类
    # 的装饰器,因为它们会装饰视图类而不是生成的视图函数
    """

    #此视图可以处理的方法列表
    methods = None

    # 设置此项禁用或强制启用自动选项处理
    provide_automatic_options = None

    """
    # 装饰基于类的视图的规范方法是装饰 as_view() 的 : 返回值。
    # 然而,由于这将部分 : 逻辑从类声明移动到它被钩住的地方 : 进入路由系统。
    # 你可以在这个列表中放置一个或多个装饰器,每当创建视图函数时,结果就会自动被装饰。
    # 0.8
    """
    decorators = ()

    def dispatch_request(self):
        """
       子类必须重写此方法才能实现 实际查看功能代码。这个方法被全部调用 URL 规则中的参数。 

        """
        raise NotImplementedError()

    @classmethod
    def as_view(cls, name, *class_args, **class_kwargs):
        """将类转换为可以使用的实际视图函数 与路由系统。在内部,这会在 fly 
        它将在每个请求上实例化 View 并调用 :meth:`dispatch_request` 方法。  
        传递给 as_view 的参数被转发到类的构造函数。
        """

        def view(*args, **kwargs):
            self = view.view_class(*class_args, **class_kwargs)
            return self.dispatch_request(*args, **kwargs)

        if cls.decorators:
            view.__name__ = name
            view.__module__ = cls.__module__
            for decorator in cls.decorators:
                view = decorator(view)
       """

       # 我们将视图类附加到视图函数有两个原因:首先,它可以让我们轻松找出这个东西
       # 来自哪个基于类的视图,其次,它还用于实例化视图类,因此您实际上可以用某些
       # 东西替换它否则用于测试目的和调试。
       """

        view.view_class = cls
        view.__name__ = name
        view.__doc__ = cls.__doc__
        view.__module__ = cls.__module__
        view.methods = cls.methods
        view.provide_automatic_options = cls.provide_automatic_options
        return view

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023083.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号