Flask入门教程

一、Flask基础

  • 安装flask模块
pip install flask
  • 一个简单的flask小案例
编辑manager.py
# 导入Flask类库
from flask import Flask
# 创建应用实例
app = Flask(__name__)
# 创建视图函数(路由)
@app.route("/")
def index():
    return "<h1>Hello Flask!</h1>"
if __name__ == "__main__":
    # 启动实例
    # app.run(threaded=True)
    app.run(debug=True, threaded=True, host="127.0.0.1", port=8000)
    
默认访问:127.0.0.1:5000
  • 参数设置
参数描述
dubug是否开启调试模式(代码更新可以自动重启),默认为False
threaded是否开启多线程,默认False
port指定端口号,默认为5000
host指定主机地址,默认127.0.0.1,设置为0.0.0.0则全局监听,可以通过ip访问
  • 请求与响应
变量上下文描述
current_app程序上下文当前激活的程序实例
g程序上下文处理请求时的临时变量,每次会重置
request请求上下文请求对象,存放客户端发来的HTTP信息
session请求上下文用户会话,记录需要"记住"的信息
  • 钩子函数和蓝本

什么是钩子函数
在Flask中钩子函数是使用特定的装饰器装饰的函数,为什么叫钩子函数呢,因为钩子函数可以在正常执行的代码中,插入一段自己想要执行的代码,这种函数就是钩子函数。

什么是蓝本
蓝本官方叫Blueprint,如果你将所有代码都放在单个程序文件中,是非常不合适的,这不仅会让代码阅读变得困难,而且会给后期维护带来麻烦。所以蓝本应运而生,在Flask中,使用蓝本可以帮助我们实现模块化应用的功能。简单来说,蓝本就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。

  • 请求钩子函数
函数描述
before_first_request项目部署之后,第一次请求之前
before_request每次请求之前
after_request没有异常,每次请求结束之后
teardown_request每次请求之后执行,即使有异常
说明:以上钩子函数若写在蓝本中,只能针对本蓝本的请求;
若想在蓝本中设置全局有效的钩子函数,需要使用带'app'的相关钩子函数,例如:
before_first_request => before_app_first_request
before_request => before_app_request
after_request => after_app_request
teardown_request => teardown_app_request
  • 视图模型
1、MVC,其他语言开发框架,例如:java
M: Model,模型,即数据模型
V: View,视图,负责显示内容
C: Controller,控制器,负责处理业务逻辑

2、MVT  Python开发框架
M: Model,模型,即数据模型
V: View,视图函数,负责处理业务逻辑
T: Template,模板,负责数据的表现逻辑(展示)

二、视图函数

  • 视图函数可以不带参数

案例1:视图函数不带参数

以下视图函数统一编辑在views.py文件中

@app.route("/")
def index():
    return "<h1>Hello Flask!</h1>"
  • 视图函数也可以带参数
    案例2:带参数的视图函数
@app.route("/user/<username>")
def welcome(username):
    return "<h1>Welcome, %s!</h1>" % username

测试访问URL:http://127.0.0.1:8000/user/Alice

说明:

1. 参数要写在<>中
2. 视图函数的参数需要和路由中的一致
3. 也可以执行参数类型(int/float/path),默认是字符串
4. 路由中最后的'/'最好带上,否则访问时可能会报错

案例3:带类型限定的参数的视图函数,path也是字符串类型,只是不再将/作为分隔符

@app.route("/test/<path:info>")
def test(info):
    return info

测试访问URL:http://127.0.0.1:8000/test/a/b/c/
  • request请求
form flask import request
@app.route('/request/<path:info>')
def url(info):
    # return request.url
    # 去掉get参数,只有路由
    # return request.base_url
    # 只有主机和端口号
    # return request.host_url
    # 装饰器中写的路由地址
    # return request.path
    # 返回请求的方法
    # return request.method
    # 返回客户端访问地址
    # return request.remote_addr
    # 返回所有的GET参数,request.args返回一个参数字典,里面存放所有传递的参数
    # return str(request.args)
    # 返回浏览器信息,所有的请求头信息都在headers中
    return request.headers.get("User-Agent")
    
测试访问URL:http://127.0.0.1:8000/request/a/b/c?username=xiaoming&password=123456
  • response响应
from flask import make_response
@app.route('/response/')
def response():
    # 不指定状态码,默认返回200,表示OK
    # return 'OK'
    # 可以指定状态码,以元组的形式返回
    # return 'not find', 404
    # 先构造一个响应,然后返回,构造时也可以指定状态码
    resp = make_response("我是通过函数构造的response", 404)
    return resp
  • 重定向redirect
from flask import redirect
from flask import url_for
@app.route('/old/')
def old():
    # return "这里是原始内容"
    # 重定向指定的网址
    # return redirect('https://www.baidu.com')
    # 重定向到另一路由
    # return redirect('/new/')
    # 根据视图函数找到路由,传递的参数是视图函数名
    # return redirect(url_for('new'))
    # 带参数的视图函数也可以构造一个路由
    return redirect(url_for('/welcome/', username="xiaoming"))

@app.route('/new/')
def new():
    return "这里是新的内容"
  • 终止abort
from flask import abort
@app.route('/login/')
def login():
    # return "欢迎登录"
    # 此处使用abort抛出异常,将控制权交给WEB服务器
    abort(404)
  • 会话控制cookie
@app.route('/set_cookie/')
def set_cookie():
    # 构造响应
    resp = make_response('cookie已设置')
    # 手动设置cookie
    resp.set_cookie('name', 'xiaoming')
    return resp

测试访问URL: http://127.0.0.1:8000/set_cookie/
在浏览器开发者模式中,可以看到请求的cookie信息,例如:
请求        Cookie
名称        值
namexiao    ming
# 获取cookie
@app.route('/get_cookie/')
def get_cookie():
    return request.cookies.get('name') or 'who are you'

访问URL:http://127.0.0.1:8000/set_cookie/
cookie默认过期时间是365天,可以设置cookie过期时间:
import time
@app.route('/set_cookie/')
def set_cookie():
    resp = make_response('cookie已设置')
    # 指定过期时间10秒
    expires = time.time() + 10
    resp.set_cookie('name', 'xiaoming', expires=expires)
    return resp
@app.route('/get_cookie/')
def get_cookie():
    return request.cookies.get('name') or 'who are you'
  • 会话控制session
设置session时需要配置秘钥,不然会报如下错误:
RuntimeError: The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
# 设置秘钥
app.config['SECRET_KEY'] = 'CY4/jtwTcLQx7HdyZOZEfXZCVUCvhScn'
@app.route('/set_session/')
def set_session():
    session['username'] = "孙尚香"
    return 'session已设置'
@app.route('/get_session/')
def get_session():
    return session.get('username', 'who are you')
  • 命令行控制启动

说明:默认的项目在不同的模式下不同的设置,在切换时只能通过修改代码来完成,这有风险,而且比较繁琐。通过命令行参数控制是一个比较好的选择,需要用
第三方库扩展flask_script。

安装flask_script模块

pip install flask_script

使用方式如下

manage.py
from flask_script import Manager
# 创建对象
manager = Manager(app)
@app.route("/")
def index():
    return "<h1>Hello Flask!</h1>"
# 启动程序
if __name__ == '__main__':
    manager.run()

命令行运行程序

python manage.py runserver -d -r
参数:
-d 开启debug模式
-r 重新加载配置
-h, --host 指定主机
-p, --port 指定端口
--threaded 使用多线程

三、Flask模板

1、模板简介

若想开发出结构清晰易于维护的代码,目前我们所写的代码都比较简单,但是一个很明显可以预见的问题是,当项目越来越复杂时,视图函数将变得异常庞大和烦琐,因此试图函数中存放了业务逻辑和表现逻辑。

解决此类问题的通用方式是将不同种类的逻辑分开存放。
业务逻辑:存放视图函数中,专门负责处理业务逻辑
表现逻辑:存放单独的(模板)文件中,专门负责展示效果

2、模板引擎

规定了一套特定的语法,提供了一种为表现逻辑的灵活实现的特殊替换,然后提供一种专门的替换接口负责将模板文件替换成目标文件。

说明:flask中提供了专门的模板引擎(jinja2)

3、JinJa2模板
  • 准备工作,创建项目
project/			# 项目根目录
        templates/		# 存放模板文件
        manage.py		# 启动控制文件
  • 渲染模板

步骤:

  1. 创建模板文件
templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
</head>
<body>
    <h1>模板引擎测试</h1>
</body>
</html>
  1. 渲染模板文件
views.py
from flask import render_template
@app.route('/')
def index():
    # 使用渲染模板文件
    return render_template('index.html')

注意:若渲染字符串可以使用render_template_string函数
  1. 使用变量
user.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板文件使用变量</title>
</head>
<body>
    {# 这是一个注释,解释变量要使用两个大括号 #}
    <h1>Hello {{ name }}!</h1>
</body>
</html>
manage.py
from flask import render_template
@app.route('/user/<name>')
def welcome(name):
    return render_template('user.html', name=name)
# 使用模板字符串
from flask import render_template_string
@app.route('/user/<name>')
def welcome(name):
    return render_template_string('<h1>Hello, {{ name }}</h1>', name=name)

# 使用变量g
from flask import g
@app.route('/user/<name>')
def welcome(name):
    # g变量不需要分配就可以在模板文件中使用
    g.name = name
    return render_template('user.html', name=name)
  1. 使用函数
(1)在要解析的变量后边添加一个'|'
(2)在'|'的后面添加一个需要处理的函数,代码如下:
<h1>Hello {{ name|capitalize }}!</h1>
(3)常用函数
capitalize: 首字母大写
upper: 全部大写
lower: 全部小写
title: 每个单词首字母大写
trim: 去掉两边的空白
striptags: 去掉所有的HTML标签
safe: 渲染时不转义,默认转义
说明:不要在不信任的变量上使用safe(如:用户表单数据)
  1. 控制结构
(1) if-else
前端:control.html
{% if name %}
    <h1>hello {{ name }}</h1>
{% else %}
    <h1>请登录</h1>
{% endif %}
说明:会根据是否分配name变量显示不通的内容
后端:
@app.route('/control/')
def control():
    # return render_template('control.html', name='xiaoming')
    return render_template('control.html', name='')

(2) for循环
前端:control.html
<ol>
    {% for x in range(1, 5) %}
        <li>{{ x }}</li>
    {% endfor %}
</ol>
后端:
@app.route('/control/')
def control():
    return render_template('control.html')
  1. 宏的使用

说明:模板中可以采用类似python中的函数方式定义宏,使用的地方调用即可,这样可以减少大量代码的重复书写,
提高开发效率。

实例1:
<!--定义宏-->
{% macro show(name) %}
    <h1>This is {{name}}</h1>
{% endmacro %}
<!--调用宏-->
{{show(name)}}

后端manage.py:
# 使用宏
@app.route('/macro/')
def macro():
    return render_template('macro.html', name='xiaoming')
实例2:导入宏
macro2.html
<!--定义宏-->
{% macro welcome(name) %}
    <h1>Hello {{name}}</h1>
{% endmacro %}

macro.html
<!--导入宏-->
{% from 'macro2.html' import welcome %}
<!--调用宏-->
{{welcome(name)}}
后端manage.py:
# 使用宏
@app.route('/macro/')
def macro():
    return render_template('macro.html', name='xiaoming')
  1. 文件包含

文件包含相当于直接将被包含的文件的内容粘贴到包含处,用法如下:

前端:include.html
{% include 'macro.html' %}

后端:
@app.route('/include/')
def include():
    return render_template('include.html', name="xiaohong")
  1. 模板继承
先写一个基础模板:base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
    <!--block是提供给子模板继承需要修改内容的地方-->
    {% block body %}
    默认内容
    {% endblock %}
</body>
</html>

子模板页面:children.html
<!--extends可以指定继承的模板-->
{% extends 'base.html' %}

<!--通过block可以修改需要改变的部分-->
{% block title %}
首页
{% endblock %}

{% block body %}
<!--super可以保留父级模板内容-->
{{ super() }}
<h1 align="center" style="color: blueviolet">欢迎来到我的首页!</h1>
{% endblock %}
后端测试:
@app.route('/extends/')
def extends():
    return render_template('children.html')

四、使用BootStrap

  • 安装
pip install flask_bootstrap
  • 使用
# 导入类库
from flask_bootstrap import Bootstrap
app = Flask(__name__)
# 创建类库
bootstrap = Bootstrap(app)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值