博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask基础快速上手
阅读量:2020 次
发布时间:2019-04-28

本文共 14542 字,大约阅读时间需要 48 分钟。

Flask基础快速上手

0. URL传参

0.1 URL传参有什么用?

可以使用相同的URL指定不同的参数,来访问不同的内容。

0.2 URL传参的语法是什么?

传递参数的语法是:'/<参数名>/'

注意2点:
参数需要放在一对<>(尖括号)内;
视图函数中需要设置同URL中相同的参数名。

0.3 URL传参的2个案例

例1:

### 从Flask框架中导入Flask类from flask import Flask### 传入__name__初始化一个Flask实例app = Flask(__name__)### 这个路由将根URL映射到hello_world函数上@app.route('/')def hello_world():			### 定义视图函数    return '这是url传参演示!'   ### 返回响应对象### 定义路由,传递的参数名是name,因此函数的形参也是name。视图函数的名字不做要求,随意 = 不重名 + 见名知意@app.route("/user/
")### 定义试图函数fun01,形参是namedef fun01(name): return f"接收到的名称是:{name}"### 如果该模块直接被执行,那么__name__ == '__main__'条件为真,开始执行下面代码。当该模块被导入时,无法执行代码。if __name__ == '__main__':### 指定默认主机是127.0.0.1,port是5000 app.run(debug=True)

在这里插入图片描述

将上述代码中的【@app.route("/user/")】改为【@app.route("/")】试试:
在这里插入图片描述
例2:

### 从Flask框架中导入Flask类from flask import Flask### 传入__name__初始化一个Flask实例app = Flask(__name__)### 这个路由将根URL映射到hello_world函数上@app.route('/')def hello_world():			### 定义视图函数    return '这是url传参演示!'   ### 返回响应对象### 定义路由,传递的参数名是name,因此函数的形参也是name。视图函数的名字不做要求,随意 = 不重名 + 见名知意,比如fun01@app.route("/user/
")### 定义试图函数fun01,形参是namedef fun01(name): return f"接收到的名称是:{name}"### 定义路由,传递的参数名是【整型】的id,因此函数的形参也是id,视图函数的名字不做要求,随意 = 不重名 + 见名知意,比如fun02@app.route("/news/
")def fun02(id): return f"接收到的id是:{id}"### 如果该模块直接被执行,那么__name__ == '__main__'条件为真,开始执行下面代码。当该模块被导入时,无法执行代码。if __name__ == '__main__':### 指定默认主机是127.0.0.1,port是5000 app.run(debug=True)

在这里插入图片描述

在这里插入图片描述

1. URL反转

1.1 URL反转是什么?

有时候,在作网页重定向或是模板文件时需要使用在视图函数中定义的URL,我们必须根据视图函数名称得到当前所指向的URL,这就是URL反转。

正转:通过url查看视图函数中的内容,比如输入:http://127.0.0.1:5000/,看到hello world。
反转:通过视图函数名字得到视图函数指向的url。
用途:页面跳转和重定向

1.2 URL反转的语法

语法:导入url_for,url_for(‘视图函数名字’,参数)

1.3 URL反转的使用

### 导入Flask及url_for模块from flask import Flask,url_for### Flask初始化app = Flask(__name__)### 定义根路由@app.route("/")def index():    ### fun01是视图函数的名字。 id的类型要相同。    ### 哪里有url_for,哪里就有URL反转    url1 = (url_for("fun01",id = 12580))    return f"URL反转的内容是:{url1}"###只是定义路由。id的类型要相同。@app.route("/news/
")###函数名fun01与url_for的第一个参数必须同名。def fun01(id): return f"你的请求参数是:{id}"### 如果该模块直接被执行,那么执行代码块,如果该模块被导入,那么不执行代码块if __name__ == "__main__": app.run(debug = True)

在这里插入图片描述

2. 页面跳转和重定向

用户在访问某个页面的时候,我们希望他登录后才能访问该页面,如果此时他没有登录,系统就让浏览器由当前页面跳转到登录页面,这里就涉及页面重定向问题。所谓页面重定向,就是用户在打开某个页面的时候,我们期望页面跳转到另一个指定的页面,让用户完成某种操作或执行某个动作。

Flask中提供了重定向函数redirect(),该函数的功能就是跳转到指定的URL。

### 导入Flask和url_for和redirect模块from flask import Flask,url_for,redirect### Flask初始化app = Flask(__name__)### 根路由@app.route("/")### 定义试图函数def index():    ### 打印输出    print("首先访问了index()这个函数")    ### URL反转    url1 = url_for("user_login")    ### 网页重定位    return redirect(url1)### 定义路由@app.route("/user_login")### 定义试图函数def user_login():    ### 返回值    return "这是用户登录的页面,请你登录才能访问首页"### 当直接执行该模块时,条件为真,执行代码块;当被当做模块导入时,代码不执行if __name__ == '__main__':    app.run()

在这里插入图片描述

2.1 问题

(1)什么是Flask?(2)URL如何传递参数?(3)网页如何重定向?

3.Jinja 2 模板引擎

3.1 模板引擎是什么及使用

在Flask中通常使用Jinja 2模板引擎来实现复杂的页面渲染。

templates文件夹下的index.html配置如下:

    
这是首页

这是首页文字

templates文件夹下的user.html配置如下:

    
这是用户中心

这是用户中心!

app.py配置如下:

# 导入flask模块from flask import Flask# 导入render_template模块from flask import render_template# Flask初始化app = Flask(__name__)# 定义根路由@app.route("/")# 定义视图函数def index():    # 使用render_template()方法渲染模板    return render_template("index.html")#定义路由,实践时比如/user/yjg,比如/user/yj@app.route("/user/
")#定义视图函数def user(username): # 使用render_template()方法渲染模板 return render_template("user.html")# 当直接执行该模块时,条件为真,执行代码块;当该模块被其他模块调用时,不执行代码块if __name__ == '__main__': app.run(debug = True)

运行结果如下:

在这里插入图片描述
Flask通过render_template()函数来实现模板的渲染。要使用Jinja 2模板引擎,需要使用fromflask import render_template命令导入render_template函数。在视图函数的return方法中,render_template()函数的首个参数声明使用哪一个模板文件。

注意:在render_template()函数中,有一个参数是用来声明使用哪个静态文件,除此参数之外,还可以有多个参数。

3.2 向模板中传递参数

Flask提供Jinja 2模板引擎来渲染模板的同时,还可以将程序中的参数或变量值传递给指定的模板进行渲染。

templates文件夹下的index.html配置如下:

    
这是首页

这是首页文字

templates文件夹下的user.html配置如下:

    
这是用户中心

欢迎您:{
{
name }}

app.py配置如下:

# 导入flask模块from flask import Flask# 导入render_template模块from flask import render_template# Flask初始化app = Flask(__name__)# 定义根路由@app.route("/")# 定义视图函数def index():    # 使用render_template()方法渲染模板    return render_template("index.html")#定义路由,实践时比如/user/yjg@app.route("/user/
")#定义视图函数def user(username): # 使用render_template()方法渲染模板并向模板传递参数 return render_template("user.html",name = username)# 当直接执行该模块时,条件为真,执行代码块;当该模块被其他模块调用时,不执行代码块if __name__ == '__main__': app.run(debug = True)

运行程序,得到如图所示结果。

在这里插入图片描述
render_template()函数第一个参数是指定模板文件的名称,比如这里的index.html和user.html。render_template()函数的第二个参数为可选项,可以为空。比如index()视图函数中的render_template(‘index.html’),这里第二个参数为空。第二个参数不为空的话,一般用于向模板中传递变量。这里传递变量,一般是以键值对方式进行的。

def index():    title = "python的键值对"    author = "CSDN_Keegan"    # 使用render_template()方法渲染模板    return render_template("index.html",var1 = title,var2 = author)

用上述代码替换index()视图函数代码,在index.html的和区域增加下面的代码:

传过来的标题是:{

{
var1 }}

{
#br表示网页中的回车#}

传过来的作者是:{

{
var2 }}

在这里插入图片描述

模板中接收变量值,需要把变量放在{
{}},比如{
{var1}}等。模板中如果要写注释,格式为{##},比如这里的{#br表示网页中的回车#}。

如果视图函数中有多个变量值都需要传递给模板该怎么办呢?

可以使用**locals()方法,例如:

def index():    title = "python的键值对"    author = "CSDN_Keegan"    # 使用render_template()方法渲染模板    return render_template("index.html",**locals())

实际上是将 return render_template(‘index.html’,var1=title,var2=author)这行代码替换为

return render_template(‘index.html’,**locals())。
将模板文件index.html中的{
{var1}}
{
{var2}}替换为{
{title}}
{
{author}}即可。

传过来的标题是:{

{
title }}

{
#br表示网页中的回车#}

传过来的作者是:{

{
author }}

在这里插入图片描述

**注意:在render_template()函数中,如果要给模板传递【全部】的本地变量,可以使用【locals()】方法,此时,在模块中可以直接使用{
{title}}和{
{author}}来直接使用变量。

3.3 模板中控制语句之if语句

在Jinja 2模板引擎中也可以使用if和for循环控制语句,控制模板渲染的方向。模板引擎中,if和for语句中应该放到{%%}中。

index.html

Title
{
% if name %}

产生的随机数有效!

{
% else %}

产生的随机数无效

{
% endif %}

app.py

# 导入Flask及render_template模块from flask import Flask,render_template# 导入random模块import random# Flask初始化app = Flask(__name__)# 定义路由@app.route('/')# 定义视图函数def hello_world():    # 产生0-1之间的整数    rand1 = random.randint(0,1)    return render_template("index.html",name = rand1)if __name__ == '__main__':    app.run(debug=True)

在这里插入图片描述

index.html

    
Title{
% if name == 1 %}

恭喜,你获得了一等奖

{
% elif name == 2 %}

恭喜,你获得了二等奖

{
% else %}

恭喜,抽到了三等奖

{
% endif %}{
{
name }}

app.py

from flask import Flask,render_templateimport randomapp = Flask(__name__)@app.route('/')def hello_world():    rand1 = random.randint(1,3)    return render_template("index.html",name = rand1)if __name__ == '__main__':    app.run(debug=True)

在这里插入图片描述

在模板中,尽量少使用多层嵌套的if…else…语句,往往会因为缩进出现这样或那样的问题。尽量多用if…elif…else…的结构(即多个elif),这一系列条件判断会从上到下依次判断,如果某个判断为True,执行完对应的代码块,后面的条件判断就会直接忽略,不再执行。

注意:模板的表达式都是包含在分隔符”{

{}}”内的;控制语句都是包含在分隔符”{%%}”内的;模板中的注释是放在包含在分隔符”{##}”内,支持块注释。

3.4 模板中控制语句之for语句

for循环语句是Python中的一个循环控制语句,任何有序的序列对象内的元素都可以遍历,比如字符串、列表、元组等可迭代对像。for循环的语法格式如下:

在这里插入图片描述
shop.html

    
Title
{
% for goods in goods %}
{
% endfor %}
商品名称 商品价格
{
{
goods.name }}
{
{
goods.price }}

app.py

from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    goods = [{
"name":"阳光男孩外套春秋韩版宽松2020新款上市","price":149.00}, {
"name":"黑色时尚外套女春秋版2020新款韩版休闲","price":100.00}, {
"name":"复古牛仔外套男2020新款","price":136.00}, {
"name":"新百伦耐穿2020新款","price":265.00}] return render_template("shop.html",**locals())if __name__ == '__main__': app.run(debug=True)

在这里插入图片描述

注意:在模板中,使用if条件判断语句或者是for循环语句可以帮助开发者更好地渲染模板。通过{%逻辑表达式%}可以实现代码的嵌套,其语法与Python语法基本一致,但是必须要包含在{%%}内部。

3.5 Flask的过滤器

过滤器本质上是一个转换函数,有时候我们不仅需要输出变量的值,还需要把某个变量的值修改后再显示出来,而在模板中不能直接调用Python中的某些方法,这么这就用到了过滤器。

3.5.1 常见的过滤器

1.与字符串操作相关的过滤器

2.对列表进行操作相关的过滤器
3.对数值进行操作相关的过滤器
index.html

    
过滤器

{

{
age|abs }}

{

{
"hello"|capitalize }}

{

{
"hello"|replace("h","x") }}

{

{
[01,80,42,44,77]|first }}

{

{
[01,80,42,44,77]|last }}

{

{
[01,80,42,44,77]|count }}

{

{
[01,80,42,44,77]|sort }}

{

{
[01,80,42,44,77]|join(",")}}

{

{
18.888|round(2,"floor")}}

{

{
18.888|round }}

{

{
-2|abs }}

app.py

from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    student = {
"name":"keegan", "age":-18 } return render_template("index.html",**student)if __name__ == '__main__': app.run()

在这里插入图片描述

3.5.2 自定义过滤器

过滤器的实质就是一个转换函数,我们其实完全可以写出属于自己的自定义过滤器。通过调用应用程序实例的add_template_filter方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称。

index.html

    
Title
{
% for goods in goods %}{
#对列表进行遍历#}
  • {
    {
    goods.name }}
  • {
    % endfor %}

    上面的代码对传递过来的列表进行遍历,每3行输出一条分割线,分割线的样式见style里的代码。

    app.py

    from flask import Flask,render_templateimport sysapp = Flask(__name__)@app.route('/')def hello_world():    ### 定义商品列表goods    goods = [{
    "name":"三国痣"}, {
    "name":"y语言核心编程"}, {
    "name":"阿里巴巴和四十大盗"}, {
    "name":"荣耀25 pro"}] return render_template("index.html",**locals())def do_index_class(index): ### 每个三行输出输出line if index % 3 == 0: return "line"### 使用自定义过滤器添加CSSapp.add_template_filter(do_index_class,"index_class")if __name__ == '__main__': app.run()

    在这里插入图片描述

    3.6 宏是什么及使用

    Jinja 2中的宏功能有些类似于传统程序语言中的函数,它跟Python中的函数类似,可以传递参数,但是【不能】有返回值,可以将一些经【常用】到的代码片段放到【宏】中,然后把一些【不固定】的值抽取出来作为一个【变量】。

    3.6.1 宏是什么?

    index.html

        
    宏的定义和使用{
    #宏的定义#}{
    % macro input(name,type="text",value = "") -%}{
    %- endmacro %}{
    #宏的使用#}

    用户名:{

    {
    input("username") }}

    密码:{

    {
    input("password",type = "password") }}

    登录:{

    {
    input("submit",type = "submit",value = "登录") }}

    app.py

    from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    return render_template("index.html")if __name__ == '__main__':    app.run(debug=True)

    在这里插入图片描述

    注意:上面将input标签定义成了一个宏,根据实际情况,还可以在宏的定义中加入size和placeholder等属性,如{
    %macro input(name,type='text',value='',size=20,placeholder="请在这里输入用户名")-%}。<input type="{
    {type}}"name="{
    {name}}"value="{
    {value}}"size="{
    {size}}",placeholder="{
    {placeholder}}">

    3.6.2 宏的导入

    一个宏可以被不同的模板使用,所以我们建议将其声明在一个单独的模板文件中。需要使用时导入即可,而导入的方法类似于Python中的import。

    form.html

    {
    % macro input(name,type = "text",value = "") -%} {
    %- endmacro %}

    index.html

        
    宏的导入{
    % import "form.html" as form %}{
    #导入宏#}
    {
    #使用宏定义用户名输入框#}

    用户名:{

    {
    form.input("username") }}

    {
    #使用宏定义输入密码输入框#}

    密码:{

    {
    form.input("password",type = "password" )}}

    登录:{

    {
    form.input("submit",type = "submit",value = "登录") }}

    app.py

    from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    return render_template("index.html")if __name__ == '__main__':    app.run()

    在这里插入图片描述

    注意:{%import’form.html’as form%}这种导入方法也可以使用{%from’form.html’importinput%}实现导入。

    用户名:{

    {form.input(‘username’)}}

    中的form需要去掉了,直接写成

    用户名:{

    {input(‘username’)}}

    3.6.3 include的使用

    宏文件中引用其他宏,可以使用include语句。include语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码复制到另外一个模板的指定位置。

    index.html

        
    Title {
    % include "header.html" %}
    这是网页内容
    {
    % include "footer.html" %}

    header.html

        
    Title
    这是网页头部

    footer.html

        
    Title

    在这里插入图片描述

    include把一个模板的代码复制到另外一个模板的指定位置,这里的{%include''header.html''%}和{%include''footer.html''%}把头文件和尾部文件引入到index.html文件中。

    注意:使用include标签时是在templates目录中寻找相应的文件,不要使用相对路径。

    3.7 set和with语句的使用

    set与with语句都可以在Jinja 2中定义变量并赋予值。set定义的变量在整个模板范围内都有效,with关键字在定义变量并赋值的同时,限制了with定义变量的作用范围。

    index.py

        
    Title
    {
    #给变量赋值#}{
    % set telephone = "1388888888" %}{
    #给列表或数组赋值#}{
    % set nav = [("index.html","index"),("product.html","product")] %}{
    {
    telephone }}
    {
    {
    nav }}
    {
    #with定义的变量的作用范围在{%with%}和{%endwith%}代码块内,在模板的其他地方,引用此变量值无效。#}{
    % with pass = 60 %}{
    {
    pass }}{
    % endwith %}

    app.py

    from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    return render_template("index.html")if __name__ == '__main__':    app.run(debug=True)

    在这里插入图片描述

    3.8 静态文件的加载

    静态文件的加载一般需要先新建文件夹static,在文件夹下再新建css、js和images文件夹,在这些文件夹中存放css、js、images,同时要需要使用url_for函数。

    项目目录结构:

    在这里插入图片描述
    在templates目录下新建一个名为index.html的文件,在app.py的视图函数中使用returnrender_template(‘index.html’)方法来渲染模板。下面分别给出加载JS、图片和CSS的方法。
    (1)加载JS文件在静态文件index.html中,在之前引入jquery-3.4.1.js文件,具体代码如下:

        
    Title {
    # 加载JS文件#}

    (2)加载图片文件。

    (3)加载CSS文件。加载外部CSS文件,可以使用下述代码实现:

    {
    # 加载CSS文件#}

    a.css

    .img{
    BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px; BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid}

    总代码:

    a.css

    .img{
    BORDER-RIGHT: #000 1px solid;BORDER-TOP: #000 1px solid; MARGIN: 10px 0px; BORDER-LEFT: #000 1px solid;BORDER-BOTTOM: #000 1px solid}

    index.html

        
    Title{
    # 加载JS文件#} {
    # 加载CSS文件#}
    {
    #测试jQuery是否加载#}
    加载图片

    app.py

    from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def hello_world():    return render_template("index.html")if __name__ == '__main__':    app.run(debug=True)

    运行结果:

    在这里插入图片描述

    3.9 模板的继承

    一个系统网站往往需要统一的结构,这样看起来比较“整洁”。比如,一个页面中都有标题、内容显示、底部等几个部分。如果在每一个网页中都进行这几部分的编写,那么整个网站将会有很多冗余部分,而且编写的网页程序也不美观。这时可以采用模板继承,即将相同的部分提取出来,形成一个base.html,具有这些相同部分的网页通过继承base.html来得到对应的模块。

    1.模板的继承语法模板的继承语法如下:
    在这里插入图片描述

    在templates目录中创建index.html、base.html和product.html 3个静态文件。base.html文件作为基类,index.html和product.html文件作为子类,子类去继承基类的基本内容。

    目录结构:

    在这里插入图片描述

    base.html文件内容如下:

        
    {<div></div> % block title %}{<div></div> % endblock %} -我的网站{
    % block body %}这是基类里的内容{
    % endblock %}

    index.html文件内容如下:

    {
    % extends "base.html" %}{
    % block title %}网站首页{
    % endblock %}{
    % block body %} {
    {
    super() }}

    这是网站首页的内容

    {
    % endblock %}

    product.html文件的内容:

    {
    % extends "base.html" %}{
    % block title %} 产品列表页{
    % endblock %}{
    % block body %}

    这是产品列表页的内容

    取得网页标题的内容:

    {
    {
    self.title() }}

    {
    % endblock %}

    app.py文件内容如下:

    from flask import Flask,render_templateapp = Flask(__name__)@app.route('/')def index():    return render_template("index.html")@app.route("/product")def product():    return render_template("product.html")if __name__ == '__main__':    app.run(debug = True)

    默认情况下,子模板如果实现了父模板定义的block,那么子模板block中的代码就会覆盖父模板中的代码。如果想要在子模板中仍然保持父摸板中的代码,那么可以使用{

    {super()}}来实现,如index.html中{%block body%}{%endblock%}代码块中使用了{
    {super()}}方法,运行结果如图所示:
    在这里插入图片描述
    如果想要在一个block中调用其他block中的代码,可以通过{
    {self.其他block名称()}}实现。比如product.html文件中的

    {
    {self.title()}}

    方法。运行此代码,结果如图所示。
    在这里插入图片描述
    注意:模板的继承可以这么理解:就是在一个html文档中已经写好了框架,然后要往里面放东西时,先用<%block blockname%><%endblock%>放一个空的块在里面作为基础模块,接下来被别的子模块导入的时候,用子模块里相同名称的模块替代。
    例如:
    在这里插入图片描述

    转载地址:http://kaqxf.baihongyu.com/

    你可能感兴趣的文章
    DotNetty 学习
    查看>>
    DotNetty的通道处理细节
    查看>>
    Protocol Buffer Basics: C#
    查看>>
    Protobuf3 语法指南
    查看>>
    Netty Pipeline、channel、Context之间的数据流向
    查看>>
    code
    查看>>
    remove all event handlers from a control
    查看>>
    C# using Sendkey function to send a key to another application
    查看>>
    Async callback to awaitable Task<> z
    查看>>
    NESPER的大体结构 z
    查看>>
    VMware Tools 的安装无法手动启动,自动安装正在进行中。
    查看>>
    C# Socket简单例子(服务器与客户端通信)【转】
    查看>>
    135行实现CRUD功能(PHP)
    查看>>
    Hibernate事务与并发问题处理(乐观锁与悲观锁)【转】
    查看>>
    Spring事务配置的五种方式【转】
    查看>>
    ant 入门
    查看>>
    maven 入门
    查看>>
    bootstrap资料收集
    查看>>
    socket中pack 和 unpack 的使用
    查看>>
    CentOS 64bit 安装 lampp 后无法运行
    查看>>