flask简单了解
Flask简介:
Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务,在介绍Flask之前首先来聊下它和Django的联系以及区别,django个大而全的web框架,它内置许多模块,flask是一个小而精的轻量级框架,Django功能大而全,Flask只包含基本的配置 Django的一站式解决的思路,能让开发者不用在开发之前就在选择应用的基础设施上花费大量时间。Django有模板,表单,路由,认证,基本的数据库管理等等内建功能。与之相反,Flask只是一个内核,默认依赖于两个外部库: Jinja2 模板引擎和 Werkzeug WSGI 工具集,其他很多功能都是以扩展的形式进行嵌入使用,相比于其他Web框架例如Django,更加灵活也更加简洁,如下几行代码就可以写出一个小程序:

from flask import Flask
app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello Flask!' if __name__ == '__main__':
app.run()

接下来我们按照执行顺序来了解下Flask
配置文件
app.config.from_object("settings.DevelopmentConfig")
路由
路由通过使用Flask的app.route装饰器来设置
动态路由(url传参)

@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id

如果希望获取/article/1这样的路径参数,就需要使用路径变量。路径变量的语法是/path/<converter:varname>。在路径变量前还可以使用可选的转换器,有以下几种转换器。
| 转换器 | 作用 |
|---|---|
| string | 默认选项,接受除了斜杠之外的字符串 |
| int | 接受整数 |
| float | 接受浮点数 |
| path | 和string类似,不过可以接受带斜杠的字符串 |
| any | 匹配任何一种转换器 |
| uuid | 接受UUID字符串 |
HTTP方法
如果需要处理具体的HTTP方法,在Flask中也很容易,使用route装饰器的methods参数设置即可。
- GET 将未经加密的信息发送的服务器. 是最通用的方法.
- HEAD 该方法除了服务端不返回响应内容只返回头信息之外, 同GET是一样的.
- POST 用于向服务器发送HTML表单数据. POST请求不会被缓存.
- PUT 将URL所指示的资源用上传的内容替换.
- DELETE 将URL所指示的资源删除.

from flask import request,render_template
@app.route('/login', methods=['GET', 'POST']) #如果不加methods,Flask路由默认处理的是GET请求
def login():
if request.method == 'POST':
do_the_login()
else:
return render_template('xxx.html')

url_for 和 endpoint

from flask import Flask,url_for
app=Flask(__name__)
@app.route('/<path:url>',endpoint='XXX') #endpoint默认为函数名
def demo(url):
print(url_for('XXX',url=url)) #如果设置了url参数,url_for(别名,加参数)
return 'Hello World' if __name__ == '__main__':
app.run()

处理请求
Request 对象
Request 对象是一个全局对象,利用它的属性和方法,我们可以方便的获取从页面传递过来的参数。
| request.method | 获取请求方法 |
| request.form | 获取POST类型的表单提交的数据和ajax请求的数据 |
| request.args | 获取get请求参数 |
| request.values | 获取GET和POST请求携带的所有参数(GET/POST通用) |
| request.cookies | 获取cookies信息 |
| request.headers | 获取请求头信息 |
| request.path | 获取cookies信息 |
| request.full_path | 获取获取用户访问的完整url地址+参数 例如(/index/?page=1) |
| request.url | 获取完整路径 |
| request.base_url | 获取访问url地址(不获取参数),例如 http://127.0.0.1:5000/; |
| request.files | 获取用户上传的文件 |
响应处理
- 返回字符串 ----return “asdf”
- 返回模板 ----return render_template('xxx.html')
- 返回重定向 ----return redirect(' /')
- 返回字典 ----jsonify({'k1':'v1'})
默认的错误页面是一个空页面,如果需要自定义错误页面,可以使用errorhandler装饰器。
from flask import render_template @app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
我们也可以自己决定如何设置响应对象,方法也很简单,使用make_response函数即可。
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
session
我们可以使用全局对象session来管理用户会话。Sesison 是建立在 Cookie 技术上的,不过在 Flask 中,我们还可以为 Session 指定密钥,这样存储在 Cookie 中的信息就会被加密,从而更加安全。

from flask import Flask, session, redirect, url_for, escape, request app = Flask(__name__)
app.secret_key = 'qwertyuiop'
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in' @app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))

Blueprint
- 目录结构划分
- 前缀
- 特殊装饰
- 某一类url添加前缀url_prefix
@h.route('',methods=[],url_prefix='')
- 给一类url添加before_request
特殊装饰器
app.before_request 修饰器在开发中用处非常大,比如判断某个ip是否有恶意访问行为,从而进行拦截等操作。
app.after_request 修饰器是在用户请求得到函数响应后被执行,不过需要注意的是这个执行是在函数返回数据前被调用,即请求已经被app.route修饰的函数响应过了,已经形成了response,但还未返回给用户的时候,调用的。

from flask import Flask, Request, render_template
app = Flask(__name__, template_folder='templates')
app.debug = True @app.before_first_request #第1个请求到来执行
def before_first_request():
print('before_first_request') @app.before_request #在进入视图前执行
def before_request():
if request.path=='/login':
return None
if session['user']:
return None
return redirect('/login')
@app.errorhandler(404)
def page_not_found(error):
return 'This page does not exist', 404 @app.route('/index')
def index():
return "Hello World" @app.after_request #视图之后执行
def after_request1(response):
print('after_request1', response)
return response @app.after_request #先执行 after_request2
def after_request2(response):
print('after_request2', response)
return response if __name__ == '__main__':
app.run()

模板
使用方式和Django的模板渲染类似:{{ }} 和 {% %}。
基本方法不太一样,函数需要加括号执行,类似于python的语法:
- {{ dict.get() }} 或 {{ dict["key"] }}
- {{ list[0] }}
- {% for 循环 %} {% endfor %}
- {% if 判断 %} {% endif %}
还可以自定义全局函数,在模板中使用:

@app.template_global()
def sum(a1, a2):
return a1 + a2
# 模板中使用{{ sum(2, 3) }} # 类似的
@app.template_filter()
def sum(a1, a2, a3):
return a1 + a2 + a3
# 调用方式不同{{ 1|sum(2,3) }}

模板继承:

{% extends "base.html"%}
{% block content %}
自定义内容
{% endblock %}
{% include "组件.html" %}

定义宏:

{% macro input(name, type='text', value=' ') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
# 使用
<form>
{{ input('username') }}
{{ input('password', type="password") }}
{{ input(' ', type="submit", value="提交") }}
</form>

安全:

# 前端
{{ data|safe }} # 后端
from flask import Markup
data = Markup(data)

Flash
flask中暂时储存数据的一个方式

from flask import flash, get_flashed_messages # 储存数据
flash("临时数据", "name") # 获取数据, 通过pop获取并移除
msg = get_flashed_messages(category_filter=["name"])

wtforms
安装:pip3 install wtforms
用户登录注册示例
1. 用户登录
当用户登录时候,需要对用户提交的用户名和密码进行多种格式校验。如:
密码不能为空;密码长度必须大于12;密码必须包含 字母、数字、特殊字符等(自定义正则);
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets app = Flask(__name__, template_folder='templates')
app.debug = True class LoginForm(Form):
name = simple.StringField(
label='用户名',
validators=[
validators.DataRequired(message='用户名不能为空.'),
validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
],
widget=widgets.TextInput(),
render_kw={'class': 'form-control'} )
pwd = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空.'),
validators.Length(min=8, message='用户名长度必须大于%(min)d'),
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符') ],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
) @app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
form = LoginForm()
return render_template('login.html', form=form)
else:
form = LoginForm(formdata=request.form)
if form.validate():
print('用户提交数据通过格式验证,提交的值为:', form.data)
else:
print(form.errors)
return render_template('login.html', form=form) if __name__ == '__main__':
app.run()
app
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets app = Flask(__name__, template_folder='templates')
app.debug = True class LoginForm(Form):
name = simple.StringField(
label='用户名',
validators=[
validators.DataRequired(message='用户名不能为空.'),
validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
],
widget=widgets.TextInput(),
render_kw={'class': 'form-control'} )
pwd = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空.'),
validators.Length(min=8, message='用户名长度必须大于%(min)d'),
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符') ],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
) @app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
form = LoginForm()
return render_template('login.html', form=form)
else:
form = LoginForm(formdata=request.form)
if form.validate():
print('用户提交数据通过格式验证,提交的值为:', form.data)
else:
print(form.errors)
return render_template('login.html', form=form) if __name__ == '__main__':
app.run()
login.html
2.注册
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets app = Flask(__name__, template_folder='templates')
app.debug = True class RegisterForm(Form):
name = simple.StringField(
label='用户名',
validators=[
validators.DataRequired()
],
widget=widgets.TextInput(),
render_kw={'class': 'form-control'},
default='alex'
) pwd = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空.')
],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
) pwd_confirm = simple.PasswordField(
label='重复密码',
validators=[
validators.DataRequired(message='重复密码不能为空.'),
validators.EqualTo('pwd', message="两次密码输入不一致")
],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
) email = html5.EmailField(
label='邮箱',
validators=[
validators.DataRequired(message='邮箱不能为空.'),
validators.Email(message='邮箱格式错误')
],
widget=widgets.TextInput(input_type='email'),
render_kw={'class': 'form-control'}
) gender = core.RadioField(
label='性别',
choices=(
(1, '男'),
(2, '女'),
),
coerce=int
)
city = core.SelectField(
label='城市',
choices=(
('bj', '北京'),
('sh', '上海'),
)
) hobby = core.SelectMultipleField(
label='爱好',
choices=(
(1, '篮球'),
(2, '足球'),
),
coerce=int
) favor = core.SelectMultipleField(
label='喜好',
choices=(
(1, '篮球'),
(2, '足球'),
),
widget=widgets.ListWidget(prefix_label=False),
option_widget=widgets.CheckboxInput(),
coerce=int,
default=[1, 2]
) def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
self.favor.choices = ((1, '篮球'), (2, '足球'), (3, '羽毛球')) def validate_pwd_confirm(self, field): #局部钩子,全局钩子为 def validate()
"""
自定义pwd_confirm字段规则,例:与pwd字段是否一致
:param field:
:return:
"""
# 最开始初始化时,self.data中已经有所有的值 if field.data != self.data['pwd']:
# raise validators.ValidationError("密码不一致") # 继续后续验证
raise validators.StopValidation("密码不一致") # 不再继续后续验证 @app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
form = RegisterForm(data={'gender': 1})
return render_template('register.html', form=form)
else:
form = RegisterForm(formdata=request.form)
if form.validate():
print('用户提交数据通过格式验证,提交的值为:', form.data)
else:
print(form.errors)
return render_template('register.html', form=form) if __name__ == '__main__':
app.run()
register app
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户注册</h1>
<form method="post" novalidate style="padding:0 50px">
{% for item in form %}
<p>{{item.label}}: {{item}} {{item.errors[0] }}</p>
{% endfor %}
<input type="submit" value="提交">
</form>
</body>
</html>
register.html
flask-session组件
在app的__init__中

from flask import Flask
from flask_session import Session # 第一步:导入并实例化SQLAlchemy
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() from .views.account import ac
from .views.user import us from .models import * def create_app():
app = Flask(__name__)
app.config.from_object('settings.Config') app.register_blueprint(ac)
app.register_blueprint(us) # Flask-Session: 第一步示例Session
# Session(app) # 第三步:依赖app中的配置文件
db.init_app(app) return app

在settings中
class Config(object):
#配置
SESSION_TYPE = 'redis'
SESSION_REDIS = Redis(host='192.168.0.94', port='6379')
SECRET_KEY='QWERT' #使用session,必须配置secret_key 否则会报错
flask简单了解的更多相关文章
- 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。
基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...
- flask简单的路由分发
flask简单的路由分发 from flask import Flask, request app = Flask(__name__) @app.route('/hello') def index() ...
- FLASK简单入门
假定你已经安装好了 Flask.如果没有,请跳转到 安装 章节. 一个最小的应用¶ 一个最小的 Flask 应用看起来会是这样: from flask import Flask app = Flask ...
- docker打包flask简单程序
简单代码: from flask import Flask app=Flask(__name__) @app.route('/') def hello(): return 'hello world' ...
- 编写一个简单的flask的前后端交互的网页(flask简单知识的讲解)
实验原理: 1.什么是flask Flask是一个使用Python编写的轻量级Web应用框架,其WSGI工具采用Werkzeng,模板引擎使用Jinja2.Flask与 Django之间的区别就是Dj ...
- flask简单web应用
推荐一个学习python的网站,个人觉得在这里面收获挺大的,希望对后来学习flask的小伙伴们有帮助.http://www.pythondoc.com/ 用flask框架实现第一个web应用 首先需要 ...
- ajax的get和post请求 -- 基于flask 简单示例
需求:在浏览器端输入姓名,将数据发送给后端,后端将内容追加到 user.json 中,并将该文件中的数据,返回到浏览器打印 1.浏览器端(html文件) index.html文件 <!DOCTY ...
- Flask简单学习
一:安装 直接 pip install Flask,就可以安装好了 二:hello world 编写一个hello.py # coding: utf- from flask import Flask ...
- flask 简单的语音识别
from aip import AipSpeech,AipNlp #AipNlp 为自然语言处理 """ 你的 APPID AK SK """ ...
随机推荐
- subprocess模块和logging模块
主要内容: 一.subprocess模块 二.logging模块 1️⃣ subprocess模块 三种执行命令的方法 subprocess.run(*popenargs, input=None, ...
- SpringBoot26 利用 Ribbon + RestTemplate 调用远程服务资源
1 RestTemplate扫盲 借助 RestTemplate,Spring应用能够方便地使用REST资源 2 准备 创建三个springCloud项目 >Eureaka : 服务注册中心 ...
- jQuery基础,选择器
jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是“write Less, ...
- AlphaPose ubuntu16 python2安装
#https://www.tensorflow.org/install/install_linux#ValidateYourInstallation #https://github.com/MVIG- ...
- 一次shell中seq的处理
一次shell中seq的处理 背景:用要shell 提取 文件中内容,文件名是用序列号如下生成,文件差不多有将近400多w个 如下: www.ahlinux.com 原始脚本#! /bin/sh# ...
- 487C Prefix Product Sequence
传送门 题目大意 分析 因为n为质数所以i-1的逆元唯一 因此ai唯一 代码 #include<iostream> #include<cstdio> #include<c ...
- laravel实现多对多的分析
在实际开发中多对多的开发还是比较常见的 1.1首先由migrate来创建表(文章表) 1.2同理创建标签表 1.3这是 我会的到如下结果: 2.1在数据迁移表contents中添加几个字段 publi ...
- Django ——Timezone 处理
Django ——Timezone 处理 https://blog.csdn.net/qq_37049781/article/details/79347278 2018年02月22日 14:50:24 ...
- 再谈JavaScript的closure--JavaScript 闭包
关于JavaScript的闭包,在我的博客上之前有一篇文章 https://www.cnblogs.com/wphl-27/p/8491327.html 今天看了几篇文章,感觉又有了一些更深的理解,特 ...
- c#事务的使用、示例及注意事项
什么是数据库事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作. 设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作: · 更新客户所购商品的库存信息 · 保存客户付款信息--可能 ...