__name__
__name__ 表示当前模块的名称
如果__name__ 在运行模块中,显示为__main__
如果作为模块被导入,则为模块名称
执行文件时输出__main__
被当做模块引入输出模块名称
Flask实例化
# __name__ 当前模块的名字,flask以模块所在的目录为总目录
app = Flask(__name__,
# 静态文件存放目录,默认static
static_folder="dome",
# 静态文件访问url, 默认static
static_url_path="/python",
# 模板存放目录,默认templates
template_folder="dome_temp")
config
读取参数配置
# 获取配置文件中的变量
print(app.config.get("name"))
# 通过current_app获取参数
print(current_app.config.get("name"))
url_map
# 通过url_map可以查看整个flask中的路由信息
print(app.url_map)
methods
# 视图函数,可以接收GET,POST请求
@app.route("/", methods=["GET", "POST"])
def dome():
return "post or get"
url_for
@app.route("/login")
def login():
# 使用url_for的函数,通过视图函数名称解析为其url
# redirect重定向
return redirect(url_for("index"))
# 传递参数
return redirect(url_for("index"),name="lisi")
获取请求参数
flask中表示当前请求的request对象,request中保存了一次HTTP请求的一切信息。
data 记录请求的数据,并转换为字符串 ,类型 *
form 记录请求中的表单数据 ,类型 MultiDict
args 记录请求中的查询参数 ,类型 MultiDict
files 记录请求上传的文件 ,类型 *
示例:
from flask import Flask, request
app = Flask(__name__)
@app.route("/data", methods=["GET", "POST"])
def dataView():
# json 等body提交的非表单数据,读取请求体中数据
rest = request.data
# 表单提交的数据,如果表单中由相同key,默认返回第一个key的参数,
# 如果想要都获得请使用getlist,读取请求体中数据
rest1 = request.form.get("lisi")
# 获取url后传的参数
rest2 = request.args.get("lisi")
# 获取上传的文件对象
pic = request.files.get(("pic"))
# 保存图片
pic.save("./1.png")
print("url传参%s" % rest2)
print("表单提交%s" % rest1)
print("data提交%s" % rest)
return "ok"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5678)
cookies 记录请求中的cookies值 ,类型 Dict
headers 记录请求中的报文头 ,类型 EnvironHeaders
method 记录请求使用的HTTO方法 ,类型 GET/POST
url 记录请求的URL地址 ,类型 string
响应信息
from flask import Flask, request, render_template, url_for, redirect, abort, make_response
@app.route("/xy")
def index():
# 响应体 状态码 响应头
# 返回顺序不能错
# return "hello", 200, {"he": "side"}
# 响应体
rest = make_response("hello")
# 状态码
rest.status = 208
# 响应头
rest.headers["HE!"] = "sude"
return rest
render_template
# 返回渲染后的html页面,默认静态页存放在根目录的templates下
return render_template("index.html")
# 模板变量
{{ name }}
# 列表
{{list[3]}}
# 字典
{{mydic["key"]}}
# 对象
{{obj.methed()}}
# 过滤器
# 值的首字母大写
<h1>Hello, {{ name|capitalize }}</h1>
# 控制结构
{% if name %}
<h1>Hello, {{ name|capitalize }}</h1>
{% else %}
<h1>Hello, Flask </h1>
{% endif %}
# 循环
<ul>
{% for num in nums %}
<li>{{ num }}</li>
{% endfor %}
</ul>
# 宏,类似于函数
# 创建一个宏
{% macro render_comment(comment) %}
<li>{{ comment }}</li>
{% endmacro %}
# 引入
{% import 'macros.html' as macros %}
{% block page_content %}
<div class="page-header">
# 使用
<ul>
{% for num in nums %}
{{macros.render_comment(num)}}
{% endfor %}
</ul>
</div>
{% endblock %}
# 模板继承
{% extends "base.html" %}
# 继承父模板的js
{% block scripts %}
{{super()}}
# 增加自己的js
{{ moment.include_moment() }}
{% endblock %}
abort
@app.route("/link/<name>")
def link_url(name):
if name == "lisi":
# 抛出异常
abort(404)
return name
自定义错误页
# 自定义404异常
@app.errorhandler(404)
# 试图函数需要有参数来接收异常信息
def page_not_found(e):
print(e)
# 返回异常模板信息和状态码
return render_template('404.html'), 404
flsak-Bootstrap
# 安装
pip install flask-bootstrap
# 初始化
from flask_bootstrap import Bootstrap
bootstrap = Bootstrap(app)
# 初始化完成后,bootstrap提供一个包含所有Bootsrtap文件的基模板我们利用jinja2的模板继承机制,可以衍生出自己的基模板
----------------------
base.html
# 引入bootstrap基模板
{% extends "bootstrap/base.html" %}
# title 块 -- 标题
{% block title %}Flasky{% endblock %}
# navbar 块 --- 导航
{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
# content 块 ---主体内容
{% block content %}
{% block mycontent %}
{% endblock %}
<div class="container">
<div class="page-header">
{% block page_content %}{% endblock %}
</div>
</div>
{% endblock %}
# scripts 块 --底部的js
{% block scripts %}
# 继承父级js
{{super()}}
# 添加自己的js文件
<scripts type="text/javascripts" src="my.js"></scripts>
{% endblock %}
自定义基模板示例:
{% extends "bootstrap/base.html" %}
{% block title %}Flasky{% endblock %}
{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{% block content %}
{% block mycontent %}
{% endblock %}
<div class="container">
<div class="page-header">
{% block page_content %}{% endblock %}
</div>
</div>
{% endblock %}
{% block scripts %}
{{super()}}
{{ moment.include_moment() }}
{% endblock %}
自定义错误页
# 自定义404异常
@app.errorhandler(404)
# 试图函数需要有参数来接收异常信息
def page_not_found(e):
print(e)
# 返回异常模板信息和状态码
return render_template('404.html'), 404
--------
404.html
# 继承自己编写的基模板
{% extends "base.html" %}
# 修改模板标题
{% block title %} Flasky - Page Not Found {% endblock %}
# 修改模板中内容
{% block page_content %}
<div class="page-header">
<h1>404 Not Found</h1>
</div>
{% endblock %}
flask_moment
# 安装
pip install flask_moment
# 初始化
from flask_moment import Moment
moment = Moment(app)
# flask_moment还是依赖jquery.js,bootstrap已经引入jquery.js,因此我们在基模板只需引入moment.js即可
----
base.html
#…………
{% block scripts %}
{{super()}}
{{ moment.include_moment() }}
{% endblock %}
# 使用示例
index.html
-----
{% extends "base.html" %}
{% block title %} Flasky {% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, flask</h1>
<!-- format参数决定了渲染方式 L 到 LLL 复杂度不同 -->
<p> The local data time is {{moment(current_time).format('LLL')}}</p>
<!-- fromNow 渲染相对时间,而且回随着时间的推移自动刷新refresh 设置为True会自动更新 -->
<p> That was {{moment(current_time).fromNow(refresh=True)}}</p>
</div>
{% endblock %}
methods
-----
from datetime import datetime
@app.route("/times")
def index():
return render_template("index.html", current_time=datetime.utcnow())
表单
# 安装
pip install flask-wtf
# 引入
from wtforms import Form, SubmitField, StringField, PasswordField, BooleanField
from wtforms.validators import DataRequired, Length
# 为了实现csrf保护,需要设置csrf密钥,来生成加密令牌
app.config["SECRET_KEY"] = "key string"
# 创建一个表单
form
----------
class DomeForm(Form):
# 通过字段创建标点,通过验证器验证提交信息的合法性,通过传参自定义错误信息
name = StringField("Name", validators=[DataRequired(message='not null')])
passwd = PasswordField("passwd", validators=[DataRequired(), Length(8, 12)])
remember = BooleanField('Remember me')
# 定义提交按钮
submit = SubmitField("submit")
# 创建一个视图函数
methods
------------
@app.route("/basic", methods=["GET", "POST"])
def basic():
form = DomeForm()
# if form.validate_on_submit():
# if request.method == 'POST' and form.validate():
if request.method == 'POST':
name = request.form.get('name')
print(name)
flash("Hello,%s" % name)
return redirect(url_for('basic'))
return render_template('form.html', form=form)
# 编写一个html页面
form.html
-------------
{% extends "base.html" %}
{% block title %} Forms {% endblock %}
{% block page_content %}
<form method="post">
{{form.csrf_token}}
<!-- bootstrap 表单渲染 -->
<div class="form-group">
{{form.name.label}}
{{form.name(class_='form-control')}}<br>
# 获取flash中数据
{% for message in get_flashed_messages() %}
<small class="error"> {{message}}</small><br>
{% endfor %}
</div>
{{form.passwd.label}}{{form.passwd}}<br>
{{form.remember}}{{form.remember.label}}<br>
{{form.submit}}
</form>
{% endblock %}
表单常用字段
表单实例化参数
表单常用验证器
蓝本
# 创建一个蓝图
from flask import Blueprint
admin = Blueprint('admin', __name__)
@admin.route("/")
def index():
return "admin"
# 注册蓝图,url_prefix指定蓝图前缀
app.register_blueprint(admin, url_prefix='/admin')
工厂函数
# 借助工厂函数可是使部署和测试更加方便
import os
from flask import Flask
from bluelog.setting import config
from bluelog.blueprints.admin import admin
from bluelog.blueprints.blog import blog
from bluelog.blueprints.auth import auth
# 创建工厂函数,flask run时会自动从环境变量FLASK_APP值定义的模块中找create_app或make_app的工厂函数,自动调用运行,
def create_app(config_name=None):
# 设置配置
if config_name is None:
config_name = os.getenv('FLASK_CONFIG', 'development')
app = Flask("bluelog")
app.config.from_object(config[config_name])
app.register_blueprint(admin, url_prefix='/admin')
app.register_blueprint(blog, url_prefix='/blog')
app.register_blueprint(auth, url_prefix='/auth')
print(app.url_map)
return app
python-dotenv
# 安装
pipenv install python-dotenv
# 我们可以把所有用到的环境变量写到.env文件里,然后以k,v的方式读取作为环境变量。
# 最简单和最常见的用法是当前目录或其父目录中的.env文件或.flaskenv加载环境变量,然后你可以调用os.getenv提供的与环境相关的方法。
.flaskenv
---------
FLASK_APP=bluelog
FLASK_ENV=development
FLASK_CONFIG=development
__init__.py
---------
config_name = os.getenv('FLASK_CONFIG', 'development')
jsonify
# 引入
from flask import jsonify
import json
# 使用
@app.route("/tojson")
def test_json():
rest = {
"name": "python",
"age": 24
}
# 将python字典转为json字符串
json_str = json.dumps(rest)
# 将json 转为字典
rest = json.loads(json_str)
# flask提供的函数用于字符串转json
return jsonify(rest)
cookie
# 引入
from flask import make_response, request
# 使用
@app.route('/set_cookie')
def set_cookie():
resp = make_response("hello")
resp.set_cookie("dome", "python")
# 设置有效期,max_age单位秒
resp.set_cookie("dome2", "python2", max_age=60)
return resp
@app.route("/get_cookie")
def get_cookie():
rest = request.cookies.get("dome")
return rest
@app.route("/del_cookie")
def del_cookie():
resp = make_response("del")
resp.delete_cookie("dome")
return resp
session
# 引入
from flask import session
# 使用
# 配置密钥
app.config["SECRET_KEY"] = "key string"
# 设置session
@app.route("/set_session")
def set_session():
session["name"] = "python"
return "success"
# 获取session
@app.route("/get_session")
def get_session():
print(session.get("name"))
return "index"
# cookie 是加密的session
# cookie 存放在客户端
# session 存放在服务器
click
Python 内置了一个标准库用于创建命令行
# 引入
import click
# 创建一个命令
# 添加装饰器,创建一个命令
@app.cli.command()
# 配置命令参数,
# 指定命令行参数,多参数配置多条选择,is_flag设置第一个参数的类型为布尔类型,default设置参数的默认值,help 设置参数的帮助信息。
@click.option('--drop', is_flag=True, help='Create After Drop')
def initdb(drop):
if drop:
db.drop_all()
click.echo("Dorp tables")
db.create_all()
click.echo("Create tables")
# 使用
# 不带参数
flask initdb
# 带参数
flask initdb --drop