flask库

flask库

文章目录

flask库

flask是python编写的轻量级框架,提供Werkzeug(WSGI工具集)和jinjia2(渲染模板)两个依赖库。

flask返回的html一定要放在python项目的templates文件夹里。

1. 基本使用

pip install flask

./templates/register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>
    <h1>Register</h1>
    <form action="/register" method="post">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <input type="submit" value="Submit">
        </div>
    </form>
</body>
</html>

./main.py

from flask import Flask,url_for,request,render_template,make_response,redirect,jsonify,json

app = Flask(__name__)  # 用本脚本名实例化Flask对象

@app.route('/',methods=['GET','POST'])#url配置
def index():#视图函数
    #return 'hello world' 响应给浏览器的内容
    return redirect('/register')#重定向

@app.route('/register',methods=['GET','POST'])
def register():
    if request.method=='POST':
        print(request.form.get('username'),request.form.get('password'))
    return render_template('register.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9901, debug=1)

2. 路由路径和路由参数

from werkzeug.routing import BaseConverter

@app.route('/') #localhost:port/
def index():
    return 'hello world'

@app.route('/index1/') #localhost:port/index1/
def index1():
    return 'index1'

#命名路径也可以声明类型,比如<string:name>
#支持类型 string,int,float,path,uuid,any,default
@app.route('/index2/<name>') #命名路径 #localhost:port/index2/Tom
def index2(name):
    return name #Tom

class RegexConverter(BaseConverter):
    #1. 自定义正则转换器类
    def __init__(self,map,*args): #args=转换器的参数
        self.map=map
        self.regex=args[0]  # BaseConberter中的属性regex

# 2.注册转换器(字典添加键值)
app.url_map.converters['regex']=RegexConverter

@app.route("/index3/<regex('\d{2}'):age>/")
def index3(age):
    return age

@app.route() 用于装饰一个视图函数,函数返回需要在用户浏览器中显示的信息(默认html)。

返回值为字符类型或者是字典
路由参数如下
1. 位置参数
/index 
/index/<name> #动态路由参数,可接受字符串和数字类型
/index/<int:id> #指定变量类型
    
2. methods=['GET','POST']
	#当前视图函数支持的请求方式(默认GET)

3. endpoint=''
	# 路由映射函数,给url起名,依然绑定正下方函数。
	# 不指定默认起名为视图函数名(view_func.__name__)
    # 存储视图函数的view_funcs是以{endpoint:view_func}形式存储,因此视图函数不能同名

3. defaults={key:value}
	#默认参数设置,必须再视图函数中定义一个形参来接收。

4. redirect_to=''
	#永久重定向(301或308)

5. strict_slashes=True/False
	# 设置路由路径匹配是否为严格模式,默认不设置为严格路由匹配模式。
    # 严格模式,路由后面原本没/,加上就会报错

3. 请求跳转和请求参数

./templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form action="{{url_for('index5')}}" method="get">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <input type="submit" value="Submit">
        </div>
    </form>
</body>
</html>

main.py

@app.route('/') #localhost:port/
def index():
    return render_template('index.html')
# 转发模板,渲染模板文件

@app.route('/index4')
def index4():
    url=url_for('index')# '/' 
    #url_for('视图函数名'),返回视图函数对应url
    return redirect(url) #重定向

@app.route('/index5')
def index5():
    u=request.args.get('username')
    p=request.args.get('password')
    # request是全局对象
    # get请求用args.get()
    # post请求用form.get()
    print(u,p)
    return '请求成功'
www.zeeklog.com  - flask库

4. 模板渲染

​ 模板是一个包含响应文本的文件,其中用占位符(模板变量{{name}})表示动态部分内容,告诉模板引擎具体的值要从具体的数据中获取,用真实值替换变量,再返回最终得到的字符串,这个过程称为‘渲染’。flask使用jinjia2模板引擎渲染模板。

1. 模板变量

在视图(view)中,模板变量向模板中传递数据,动态生成页面内容。

@app.route('/index6')
def index6():
    return render_template('test.html',a=123,b=[4,5,6])

./templates/test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
    <p>{{a}}</p>
    <p>{{b}}</p>
    {{ config.__class__.__init__.__globals__['os'].listdir('.') }}
</body>
</html>
2. 过滤器
{{ name|upper }}
{{ name|lower }}
{{ name|length }}
{{ name|trim }}
{{ name|default('name不存在') }}
{{ name|default('name为None,0,false,""',true) }}
3. 测试器

if…elif…else…endif

for…endfor

{% if m is defined %}
	{{m}}
{% else %}
    999
{% endif %}

{% for i in range(10) %}
	{{i}}
{% endfor %}

5. 钩子函数与响应对象

Hook(钩子),是一种过滤(或叫挂钩)消息的技术。Hook的目的是过滤一些关键函数调用,在函数执行前,先执行自己的挂钩函数,达到监控函数调用,改变函数功能的目的。

Hook技术按照实现原理来分的话可以分为两种:

API HOOK:拦截Windows API;

消息HOOK:拦截Windows消息。

Flask装饰器注册钩子函数说明
@app.before_request在每一次请求前调用,先绑定先执行,先flask app后blueprint
@app.before_first_request只在第一次请求之前调用(似乎没有这个)
@app.after_request每一次请求之后都会调用,接收response对象,执行完后记得归还,先绑定的后执行
@app.teardown_request每次请求之后都会调用,先绑定的后执行
www.zeeklog.com  - flask库
@app.before_request
def first():
    print("Nice to meet you!")

@app.route('/') #localhost:port/
def index():
    data = {
        'name': '张三'
    }
    # json.dumps 将一个python数据结构转化为json
    # json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
    # 生成一个response响应对象,而不是直接return来返回响应对象,便于执行更多的后续操作
    response = make_response(json.dumps(data, ensure_ascii=False))
    # 修改响应数据的MIME标准类型为json(在发送数据前会先发送该类型)
    response.mimetype = 'application/json'
    response.status = '200'  # 状态码
    response.headers['name'] = 'success!'
    return response

@app.errorhandler(404)
def page_not_found(e):
    return '页面没找到'

if __name__ == '__main__':
    print(app.url_map)# 查看所有的路由信息
    app.run(host='0.0.0.0', port=9901, debug=1)

一些测试脚本

目录遍历,文件读取

import os
import chardet
from flask import Flask,url_for,request,render_template,make_response,redirect,jsonify,json,render_template_string
app = Flask(__name__)  # 用本脚本名实例化Flask对象

@app.route('/',methods=['GET','POST'])#url配置
def index():#视图函数
    path=request.args.get('path')
    content=""
    if (path!=None and os.path.exists(path)):
        if (os.path.isdir(path)):
            content=os.listdir(path)
        elif (os.path.isfile(path)):
            with open(path, 'rb') as fp:
                raw_data = fp.read()
                result = chardet.detect(raw_data)# 获取文件编码,可能是错的
                encoding = result['encoding']
                content=raw_data.decode('utf-8')
    else:
        content="path not exists"
    template="""
    <!DOCTYPE html>
    <html>
    <head><meta charset='UTF-8'></head>
    <body>
    <h3>what can i say</h3></br>
    <p>%s</p>
    </body>
    </html>
    """%(content)
    return render_template_string(template,title='flask-test')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9901, debug=1)

Read more

Java虚拟机学习总结(3)——JDK内置工具(jps、jstack、jmap、jstat)使用详解

Java虚拟机学习总结(3)——JDK内置工具(jps、jstack、jmap、jstat)使用详解

一、JDK内置工具 - javap 1、 介绍 java 反编译工具,主要用于根据Java字节码文件反汇编为Java源代码文件。 2、命令 javap <options> <classes> 3、命令集 -help --help -? 输出此用法消息 -version 版本信息,其实是当前javap所在jdk的版本信息,不是class在哪个jdk下生成的。 -v -verbose 输出附加信息(包括行号、本地变量表,反汇编等详细信息) -l 输出行号和本地变量表 -public 仅显示公共类和成员 -protected 显示受保护的/公共类和成员 -package 显示程序包/受保护的/公共类 和成员 (默认) -p -private 显示所有类和成员

By Ne0inhk
Spring学习总结(29)——Spring异步处理@Async的使用以及原理、源码分析(@EnableAsync)

Spring学习总结(29)——Spring异步处理@Async的使用以及原理、源码分析(@EnableAsync)

在开发过程中,我们会遇到很多使用线程池的业务场景,例如异步短信通知、异步记录操作日志。大多数使用线程池的场景,就是会将一些可以进行异步操作的业务放在线程池中去完成。例如在生成订单的时候给用户发送短信,生成订单的结果不应该被发送短信的成功与否所左右,也就是说生成订单这个主操作是不依赖于发送短信这个操作,所以我们就可以把发送短信这个操作置为异步操作。那么本文就是来看看Spring中提供的优雅的异步处理方案:在Spring3中,Spring中引入了一个新的注解@Async,这个注解让我们在使用Spring完成异步操作变得非常方便。需要注意的是这些功能都是Spring Framework提供的,而非SpringBoot。因此下文的讲解都是基于Spring Framework的工程。Spring中用@Async注解标记的方法,称为异步方法,它会在调用方的当前线程之外的独立的线程中执行,其实就相当于我们自己new Thread(()-> System.out.println("hello world !"))这样在另一个线程中去执行相应的业务逻辑。 Demo // @Async 若把注解放在类

By Ne0inhk
Spring Boot学习总结(19)——使用Redisson实现分布式锁

Spring Boot学习总结(19)——使用Redisson实现分布式锁

一、什么是分布式? 要想说什么是分布式,那么首先要知道分布式之前的系统是什么样的架构,之前的架构又存在什么样的问题? 单体架构 分布式之前就是单体架构,单体架构顾名思义就是将所有的业务功能打包在一个应用中,然后部署在服务器上。如果我们把单体架构比作一个汽车工厂,那么从汽车发动机到汽车上的一个螺丝钉都需要由它来负责完成,如果有一天这家工厂由于自然灾害的原因导致业务量急剧下滑,甚至停止生产,那么这个整个工厂无论是造发动机的,还是造螺丝钉的全部都得停工。落实到互联网就是单体架构开发成本高、出现故障影响的范围大,很难适应现在的互联网项目。 分布式 既然单体架构不足以解决现在存在的高并发、高性能、高可用的要求,那么分布式就来了,原来我们把一个汽车所有的零件都放在一家工厂进行生产,结果会出现上面停工的情况,那么分布式怎么解决的?所谓分布式就是把所有的零件分开生产,每个工厂根据自己的特长来生产相应的汽车配件,最后统一组装,即使因为一些其他原因,导致某个工厂停止了生产,但是依旧不影响其他工厂的生产进度,我们可以通过小的代价来寻找其他工厂来代替停工的工厂,确保我们的生产任务可以正常的运转。

By Ne0inhk
Java虚拟机学习总结(4)—— JVM 性能调优常用参数详解

Java虚拟机学习总结(4)—— JVM 性能调优常用参数详解

前言 在JVM性能调优时有三个组件: 1. 堆大小调整(内存最够大的话,尽量搞大点) 2. 垃圾收集器调整 3. JIT 编译器(比较深,需要掌握源码才能更好的优化更加底层) 大多数调优选项都与调整堆大小和为您的情况选择最合适的垃圾收集器有关。JIT编译器对性能也有很大影响,但很少需要使用较新版本的JVM进行调优。通常,在调优Java应用程序时,重要是以下两个主要目标之一: * 响应性:应用程序或系统对请求的数据进行相应的速度,对于专注于响应性的应用程序,长的暂停时间是不可接受的,重点是在短时间内做出回应。 * 吞吐量:(批处理任务,大数据量任务)侧重于在特定时间段内最大化应用程序的工作量,对于专注于吞吐量的应用程序,高暂停时间是可接受的。由于高吞吐量应用程序在较长时间内专注于基准测试,因此不需要考虑响应时间。 注意:系统瓶颈核心还是在应用代码,一般情况下无需过多调优,JVM本身在不断优化。 一、verbose:gc 表示,启动jvm的时候,输出jvm里面的gc信息。格式如下: [Full GC 178K->99K(1984K), 0.

By Ne0inhk