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. CSS 伪类与伪元素

    CSS的元素选择器除了根据id(#).class(.).属性([ ])选取元素以外,还有很重要的一类,就是根据元素的特殊状态来选取元素.它们就是伪类和伪元素.跟id选择器.类选择器.属性选择器以及派生 ...

  2. PhoneGap 3.4 开发配置及问题

    PhoneGap这个坑爹货,开发确实迅速,又无需学习新知识,但又有N多深不见底坑,最大的坑无疑是性能,滑动时卡顿明显,iPhone5上性能比较好,大部分安卓上就坑爹了,神马动画效果最好少用:其次是不同 ...

  3. C#连接Mysql数据库 MysqlHelper.cs文件

    mysql.data.dll下载_c#连接mysql必要插件mysql.data.dll是C#操作MYSQL的驱动文件,是c#连接mysql必要插件,使c#语言更简洁的操作mysql数据库.当你的电脑 ...

  4. linux下方便的录屏命令

    linux下方便的录屏命令   ffmpeg -f x11grab -s 1024*768 -r 20 -i :0.0 -sameq ~/recode.mpg -r后是刷新屏率,   推出直接Ctrl ...

  5. Linux tmux

    一.简介 Tmux是一个用于终端复用的软件,它允许一个用户在一个终端窗口或远程终端会话中使用多个不同的终端会话.在同一个命令行接口处理多个程序,以及将程序从已经开始运行另外的程序的Unix shell ...

  6. 19、SOAP安装,运用与比对结果解释

    转载:http://www.dengfeilong.com/post/Soap2.html https://blog.csdn.net/zhu_si_tao/article/details/71108 ...

  7. python 将字符串转化为可执行代码

    场景: 在一个遍历的的程序中,有一步需要调用函数,调用的方式是根据输入参数,从3个可供被调用的函数中,选择其中一个.所以写了一个dict={1:"function_a_name", ...

  8. 5.WHERE 子句

    WHERE 子句用于规定选择的标准. WHERE 子句 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句. 语法 SELECT 列名称 FROM 表名称 WHERE 列 运 ...

  9. 专题2-通过按键玩中断\第1课-中断处理流程深度剖析-lesson1

    中断概念 1.中断生命周期 串口先产生一个事件,该事件传送到中断控制器里面,中断控制器会进行相应过滤,能通过过滤,那么就交给CPU去处理. 2.中断源 2440芯片手册 6410芯片手册 3.中断过滤 ...

  10. URAL 1104 Don’t Ask Woman about Her Age(数论)

    题目链接 题意 : 给你一个数,未知进制,然后让你从2到36进制中找出一个最小的进制K,满足给你的这个数作为k进制时能够整除k-1. 思路 : 有一个公式,(a*b^n)mod(b-1)=a: 给定你 ...