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. 用户登录

当用户登录时候,需要对用户提交的用户名和密码进行多种格式校验。如:

用户不能为空;用户长度必须大于6;

密码不能为空;密码长度必须大于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简单了解的更多相关文章

  1. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

  2. flask简单的路由分发

    flask简单的路由分发 from flask import Flask, request app = Flask(__name__) @app.route('/hello') def index() ...

  3. FLASK简单入门

    假定你已经安装好了 Flask.如果没有,请跳转到 安装 章节. 一个最小的应用¶ 一个最小的 Flask 应用看起来会是这样: from flask import Flask app = Flask ...

  4. docker打包flask简单程序

    简单代码: from flask import Flask app=Flask(__name__) @app.route('/') def hello(): return 'hello world' ...

  5. 编写一个简单的flask的前后端交互的网页(flask简单知识的讲解)

    实验原理: 1.什么是flask Flask是一个使用Python编写的轻量级Web应用框架,其WSGI工具采用Werkzeng,模板引擎使用Jinja2.Flask与 Django之间的区别就是Dj ...

  6. flask简单web应用

    推荐一个学习python的网站,个人觉得在这里面收获挺大的,希望对后来学习flask的小伙伴们有帮助.http://www.pythondoc.com/ 用flask框架实现第一个web应用 首先需要 ...

  7. ajax的get和post请求 -- 基于flask 简单示例

    需求:在浏览器端输入姓名,将数据发送给后端,后端将内容追加到 user.json 中,并将该文件中的数据,返回到浏览器打印 1.浏览器端(html文件) index.html文件 <!DOCTY ...

  8. Flask简单学习

    一:安装 直接 pip install Flask,就可以安装好了 二:hello world 编写一个hello.py # coding: utf- from flask import Flask ...

  9. flask 简单的语音识别

    from aip import AipSpeech,AipNlp #AipNlp 为自然语言处理 """ 你的 APPID AK SK """ ...

随机推荐

  1. 使用composer安装laravel5.4

    composer create-project --prefer-dist laravel/laravel blog 后面的是文件目录

  2. MyGeneration代码生成工具

    使用MyGeneration 生成代码:转自http://www.cnblogs.com/jack-liang/archive/2011/08/18/2144066.html 我们经常用数据访问层和业 ...

  3. vim 的移动

    越来也喜欢用linux的vim 来编程了,简单.高效.专业,最近拿着一本<vim的中文使用手册>在慢慢的看,看到现在就没有勇气继续看下去,我想先放一下,运用前面自己学的东西实际的去操作一下 ...

  4. ROS naviagtion analysis: move_base

    博客转载自:https://blog.csdn.net/u013158492/article/details/50483123 这是navigation的第一篇文章,主要通过分析ROS代码级实现,了解 ...

  5. Vue.js组件调用用及其组件通信

    1.需要import,然后components注册.然后如下代码调用. <template> <header></header> //注册后才能这样使用 <b ...

  6. IntelliJ IDEA——maven环境下整合SSM

    SSM整合目录结构 开发环境:JDK1.8:apache-tomcat-7.0.52 : MySql5.7 开发工具:IntelliJ IDEA pom.xml <?xml version=&q ...

  7. js选择文件夹路径

    该方法只支持IE. 语法:strDir=Shell.BrowseForFolder(Hwnd,Title,Options,[RootFolder])参数:Hwnd:包含对话框的窗体句柄(handle) ...

  8. SNMP协议学习笔记

    什么是SNMP协议? SNMP协议是以UDP为基础的应用层协议,全称为 简单网络管理协议,用于网络管理系统与被管设备(路由器,交换机,服务器等设备)进行通信. 应用场景 随着网络设备的增多,需要单独的 ...

  9. Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别与使用

    1.首先看下最简单的SSE: 只用支持SSE的浏览器(大部分)即可,浏览器内置EventSource对象,该对象默认隔三秒刷新一下response的数据. HTML代码(取自w3cschool): & ...

  10. mysql5.6数据库双机热备、主从备份

    主题:mysql5.6数据库双机热备.主从备份 缘由: 在Web应用系统中,数据库性能是导致系统性能瓶颈最主要的原因之一.尤其是在大规模系统中,数据库集群已经成为必备的配置之一.集群的好处主要有:查询 ...