Python Flask框架笔记(更新中~)

一、URL与视图

1、Flask简介

flask是一款非常流行的Python Web框架,出生于2010年,作者是Armin Ronacher,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个正式的项目。

flask自2010年发布第一个版本以来,大受欢迎,深得开发者的喜爱,目前在Github上的Star数已经超过55.5k了,有超Django之趋势。flask能如此流行的原因,可以分为以下几点:

  • 微框架、简洁、只做他需要做的,给开发者提供了很大的扩展性。
  • Flask和相应的插件写得很好,用起来很爽。
  • 开发效率非常高,比如使用SQLAlchemy的ORM操作数据库可以节省开发者大量书写sql的时间。

Flask的灵活度非常之高,他不会帮你做太多的决策,一些你都可以按照自己的意愿进行更改。比如:

  • 使用Flask开发数据库的时候,具体是使用SQLAlchemy还是MongoEngine,选择权完全掌握在你自己的手中。区别于Django,Django内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。
  • 把默认的Jinija2模板引擎替换成其他模板引擎都是非常容易的。

2、安装Flask

在终端输入命令 pip install flask 即可安装。
Python Flask框架笔记(更新中~)_第1张图片

3、新建第一个flask程序

新建项目中框架选择需pycharm专业版才有这功能

Python Flask框架笔记(更新中~)_第2张图片

4、运行flask项目

Python Flask框架笔记(更新中~)_第3张图片
Python Flask框架笔记(更新中~)_第4张图片

在浏览器中输入http://127.0.0.1:5000就能看到hello world了。需要说明一点的是,app.run这种方式只适合于开发,如果在生产环境中,应该使用Gunicorn或者uWSGI来启动。如果是在终端运行的,可以按ctrl+c来让服务停止。
Python Flask框架笔记(更新中~)_第5张图片

5、设置为DEBUG模式

默认情况下flask不会开启DEBUG模式,开启DEBUG模式后,flask会在每次保存代码的时候自动的重新载入代码,此时网页直接刷新就能看到效果,并且如果代码有错误,会在终端进行提示。
Python Flask框架笔记(更新中~)_第6张图片
Python Flask框架笔记(更新中~)_第7张图片
需要注意的是,只能在开发环境下开启DEBUG模式,因为DEBUG模式会带来非常大的安全隐患。

6、配置文件

Flask项目的配置,都是通过app.config对象来进行配置的。比如要配置一个项目的SECRET_KEY,那么可以使用app.config[‘SECRET_KEY’] = "xxx"来进行设置

常用有这几种方法:

1、在py文件中直接硬编码:

缺点:需要一个个写,涉及文件多的话显得很累赘
Python Flask框架笔记(更新中~)_第8张图片

2、将所有配置项写成一个配置文件,然后使用者进行模块导入

Python Flask框架笔记(更新中~)_第9张图片
Python Flask框架笔记(更新中~)_第10张图片
Python Flask框架笔记(更新中~)_第11张图片
Flask项目内置了许多的配置项,所有的内置配置项,可以点这查看~

7、URL与视图函数的映射

Python Flask框架笔记(更新中~)_第12张图片
在这里插入图片描述
@app.route()是什么?

  • 在Python中,只要是带着@的,基本上就是装饰器,装饰器的本质是扩展原本函数功能的一种函数
  • 而这里的app.route(‘URL’)就是在Flask框架中非常重要的一个装饰器,它的作用是在程序运行时,装饰一个视图函数,用给定的URL规则和选项注册它,这里不理解也无所谓,能用即可。

从之前的helloworld.py文件中,我们已经看到,一个URL要与执行函数进行映射,使用的是@app.route装饰器。@app.route装饰器中,可以指定URL的规则来进行更加详细的映射,比如现在要映射一个文章详情的URL,文章详情的URL是/article/id/,id有可能为1、2、3…,那么可以通过以下方式:

@app.route('/article//')
def article(id):
   return '%s article detail' % id

其中,尖括号是固定写法,语法为,variable默认的数据类型是字符串。如果需要指定类型,则要写成converter:variable,其中converter就是类型名称,可以有以下几种:

  • string: 默认的数据类型,接受没有任何斜杠/的字符串。
  • int: 整形
  • float: 浮点型。
  • path: 和string类似,但是可以传递斜杠/。
  • uuid: uuid类型的字符串。
  • any:可以指定多种路径,这个通过一个例子来进行说明:
@app.route('//')
def item(url_path):
  return url_path

以上例子中,item这个函数可以接受两个URL,一个是/article/,另一个是/blog/。并且,一定要传url_path参数,当然这个url_path的名称可以随便。

如果不想定制子路径来传递参数,也可以通过传统的?=的形式来传递参数,例如:/article?id=xxx,这种情况下,可以通过request.args.get(‘id’)来获取id的值。如果是post方法,则可以通过request.form.get(‘id’)来进行获取

8、视图转URL(url_for)

一般我们通过一个URL就可以执行到某一个函数。如果反过来,我们知道一个函数,怎么去获得这个URL呢?url_for函数就可以帮我们实现这个功能。url_for()函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到URL的后面作为查询参数。

Python Flask框架笔记(更新中~)_第13张图片

Python Flask框架笔记(更新中~)_第14张图片
Python Flask框架笔记(更新中~)_第15张图片

9、指定指定(methods)HTTP方法:

在@app.route()中可以传入一个关键字参数methods来指定本方法支持的HTTP方法,默认情况下,只能使用GET请求,看以下例子:
Python Flask框架笔记(更新中~)_第16张图片
以上装饰器将让login的URL既能支持GET又能支持POST。

10、页面跳转和重定向(redirect):

重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。

  • 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。
  • 暂时性重定向:http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。

在flask中,重定向是通过flask.redirect(location,code=302)这个函数来实现的,location表示需要重定向到的URL,应该配合之前讲的url_for()函数来使用,code表示采用哪个重定向,默认是302也即暂时性重定向,可以修改成301来实现永久性重定向。
Python Flask框架笔记(更新中~)_第17张图片
两个例子都为如果没有登录或者找不到该用户,即给你重定向到首页或者登录页面!
Python Flask框架笔记(更新中~)_第18张图片

Python Flask框架笔记(更新中~)_第19张图片

二、Jinja模板

1、模板简介

模板是一个web开发必备的模块。因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个有富文本标签的页面。这时候我们就需要使用模板了。在Flask中,配套的模板是Jinja2,Jinja2的作者也是Flask的作者。这个模板非常的强大,并且执行效率高。以下对Jinja2做一个简单介绍!

2、Flask渲染Jinja模板(render_template)

要渲染一个模板,通过render_template方法即可,以下将用一个简单的例子进行讲解:

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/about/')
def about():
    return render_template('about.html')

当访问/about/的时候,about()函数会在当前目录下的templates(默认不建议修改)文件夹下寻找about.html模板文件。如果想更改模板文件地址,应该在创建app的时候,给Flask传递一个关键字参数template_folder,指定具体的路径,再看以下例子:

from flask import Flask,render_template
app = Flask(__name__,template_folder=r'C:\templates')

@app.route('/about/')
def about():
    return render_template('about.html')

以上例子将会在C盘的templates文件夹中寻找模板文件。还有最后一点是,如果模板文件中有参数需要传递,应该怎么传呢,我们再来看一个例子:

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/about/')
def about():
    # return render_template('about.html',user='zhiliao')
    return render_template('about.html',**{'user':'zhiliao'})

以上例子介绍了两种传递参数的方式,因为render_template需要传递的是一个关键字参数,所以第一种方式是顺其自然的。但是当你的模板中要传递的参数过多的时候,把所有参数放在一个函数中显然不是一个好的选择,因此我们使用字典进行包装,并且加两个*号,来转换成关键字参数。

渲染模板例子:
Python Flask框架笔记(更新中~)_第20张图片

3、Jinja2模版概述

​ 视图函数的主要作用是,处理业务逻辑,返回响应内容

​ flask是使用jinja2这个模板引擎来渲染模板

使用模板的好处

  • 视图函数只负责业务逻辑和数据处理
  • 模板取到视图函数的数据结果进行展示
  • 代码结构清晰,耦合度低

模板传参

  1. 再使用render_template渲染模板的时候,可以传递关键字参数,以后直接在模板中使用即可
  2. 如果参数过多,可以将所有的参数放到一个字典或列表中。将字典打散成关键字参数可以在参数前面加**
from flask import Flask,render_template

app = Flask(__name__)

student = {
    'name': 'zhangsan',
    'age':8,
    'gender':'男'
}
student_list = [
    {'name': 'zhangsan','age':18,'gender':'男'},
    {'name': 'lisi','age':68,'gender':'女'},
    {'name': 'wangwu','age':16,'gender':'男'}
]

student_dict = {
    'a':{'name': 'zhangsan','age':18,'gender':'男'},
    'b':{'name': 'lisi','age':28,'gender':'女'},
    'c':{'name': 'wangwu','age':19,'gender':'男'}
}
@app.route('/test1')
def test1():
    return render_template('01.html', **student) # 为了方便在模板中使用,可以把字典打散

@app.route('/test2')
def test2():
    return render_template('02.html', stu_list = student_list)

@app.route('/test3')
def test3():
    return render_template('03.html', stu_dict = student_dict)

if __name__ == '__main__':
    app.run()


01.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第一个模板</title>
</head>
<body>
    学生姓名:{{ name }}
    学生年龄:{% if age >= 18 %}
                    已经成年
            {% else %}
                    未成年
            {% endif %}
    学生性别:{{ gender }}
</body>
</html>

结果
Python Flask框架笔记(更新中~)_第21张图片
02.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第二个模板</title>
</head>
<body>
   {{ stu_list }}

    <table border="1px">
        <tr>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </tr>

        {% for stu in stu_list %}
            <tr>
                <td>{{ loop.index }}</td>
                <td>{{ stu.name }}</td> <!-- 由于stu是字典,有三种写法得到key的value-->
                {% if stu.age >= 60 %}
                    <td>已退休</td>
                {% elif stu.age >= 18 %}
                    <td>已成年</td>
                {% else %}
                    <td>未成年</td>
                {% endif %}
{#                {{ stu.get('age') }}#}
                <td>{{ stu['gender'] }}</td>
            </tr>
        {% endfor %}
        
    </table>
</body>
</html>

结果
Python Flask框架笔记(更新中~)_第22张图片
03.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第三个模板</title>
</head>
<body>
   {{ stu_dict }}

    <table border="1px">
        <tr>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
        </tr>

        {% for stu_key,stu in stu_dict.items() %}
            <tr>
                <td>{{ loop.index }},key:{{ stu_key }}</td>
                <td>{{ stu.name }}</td> <!-- 由于stu是字典,有三种写法得到key的value-->
                {% if stu.age >= 60 %}
                    <td>已退休</td>
                {% elif stu.age >= 18 %}
                    <td>已成年</td>
                {% else %}
                    <td>未成年</td>
                {% endif %}
{#                {{ stu.get('age') }}#}
                <td>{{ stu['gender'] }}</td>
            </tr>
        {% endfor %}
        
    </table>
</body>
</html>

结果
Python Flask框架笔记(更新中~)_第23张图片
语法

  1. 控制结构(逻辑代码){%%}
  2. 变量取值{{}}
  3. 注释{##}

更多参考原文章

4、模板过滤器

过滤器是通过管道符号(|)进行使用的,例如:{{ name|length }},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器,在这里可以看到所有的过滤器,现对一些常用的过滤器进行讲解:

  1. abs(value):返回一个数值的绝对值。 例如:-1|abs。

  2. default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。

  3. escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。例如:content|escape或content|e。

  4. first(value):返回一个序列的第一个元素。names|first。

  5. format(value,*arags,**kwargs):格式化字符串。例如以下代码:

{{ "%s" - "%s"|format('Hello?',"Foo!") }}

将输出:Helloo? - Foo!

  1. last(value):返回一个序列的最后一个元素。示例:names|last。

  2. length(value):返回一个序列或者字典的长度。示例:names|length。

  3. join(value,d=u’'):将一个序列用d这个参数的值拼接成字符串。

下边做实验
Python Flask框架笔记(更新中~)_第24张图片
Python Flask框架笔记(更新中~)_第25张图片

Python Flask框架笔记(更新中~)_第26张图片

  1. safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。

  2. int(value):将值转换为int类型。

  3. float(value):将值转换为float类型。

  4. lower(value):将字符串转换为小写。

  5. upper(value):将字符串转换为小写。

  6. replace(value,old,new): 替换将old替换为new的字符串。

  7. truncate(value,length=255,killwords=False):截取length长度的字符串。

  8. striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。

  9. trim:截取字符串前面和后面的空白字符。

  10. string(value):将变量转换成字符串。

  11. wordcount(s):计算一个长字符串中单词的个数。

也可以自定义过滤器,但是用的不多~

5、控制语句

所有的控制语句都是放在{% … %}中,并且有一个语句{% endxxx %}来进行结束,Jinja中常用的控制语句有if/for…in…,现对他们进行讲解:

  1. if:if语句和python中的类似,可以使用>,<,<=,>=,==,!=来进行判断,也可以通过and,or,not,()来进行逻辑合并操作,以下看例子:
    Python Flask框架笔记(更新中~)_第27张图片
    Python Flask框架笔记(更新中~)_第28张图片

Python Flask框架笔记(更新中~)_第29张图片

  1. for…in…:for循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历,以下将用几个例子进行解释:
  • 普通的遍历:

Python Flask框架笔记(更新中~)_第30张图片
Python Flask框架笔记(更新中~)_第31张图片

Python Flask框架笔记(更新中~)_第32张图片

  • 遍历字典:
    Python Flask框架笔记(更新中~)_第33张图片

Python Flask框架笔记(更新中~)_第34张图片
Python Flask框架笔记(更新中~)_第35张图片

  • 如果序列中没有值的时候,进入else:
<ul>
{% for user in users %}
	<li>{{ user.username|e }}</li>
{% else %}
	<li><em>no users found</em></li>
{% endfor %}
</ul>

并且Jinja中的for循环还包含以下变量,可以用来获取当前的遍历状态:
Python Flask框架笔记(更新中~)_第36张图片

6、测试器

测试器主要用来判断一个值是否满足某种类型,并且这种类型一般通过普通的if判断是有很大的挑战的。语法是:if…is…,先来简单的看个例子:

{% if variable is escaped%}
    value of variable: {{ escaped }}
{% else %}
    variable is not escaped
{% endif %}

以上判断variable这个变量是否已经被转义了,Jinja中内置了许多的测试器,看以下列表:
Python Flask框架笔记(更新中~)_第37张图片

你可能感兴趣的:(关于Python,python,flask,web)