Flask笔记

什么是Flask

在讲什么是Flask之前,我们先了解一下什么是Web Application Framework,Web Application Framework(Web应用程序框架)表示一个库和模块的集合,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。

而Flask是一个用Python编写的Web应用程序框架。 Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。

安装Flask
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Flask
一个简单的demo

在这个简单的demo中,我们在浏览器访问http://localhost:5000 ,将在页面显示“Hello World”消息。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello world'

if __name__ == '__main__':
    app.run('127.0.0.1',5000,debug = True)

Flask类的构造函数使用当前模块的名称(name)作为参数,创建一个app对象。app对象的route()函数是一个装饰器(而关于python中装饰器的详解,可以参见 python中装饰器详解),它告诉应用程序用户请求哪个URL时应该调用哪个函数启动相应的服务(路由),在这里,URL '/ ’ 将绑定到hello_world()函数,因此,如果用户访问http:127.0.0.1:5000,hello_world()函数的输出将在浏览器中呈现。app对象的add_url_rule()函数也可用于将URL与函数绑定,如以上的demo可进行如下改写:

from flask import Flask
app = Flask(__name__)

def hello_world():
    return 'hello world1!'

app.add_url_rule(rule='/', view_func=hello_world)

if __name__ == '__main__':
    app.run('127.0.0.1', 5000, debug = True)

再来讲讲Flask中的调试模式,当应用程序正在开发中时,应该为代码中的每个更改手动重新启动它。为避免这种不便,可以启用调试模式。如果代码更改,服务器将自行重新加载。

启动调试模式的方式:

#第一种方式
app.debug = True
app.run()

# 另一种方式
app.run(debug = True)
Flask之动态构建URL

有时我们需要将同一类URL映射到同一个视图函数处理,而在Flask中,可以将URL中的可变部分使用一对小括号<>声明为变量, 并为视图函数传入同名的形参。

from flask import Flask
app = Flask(__name__)

@app.route('/hello/<name>')
def hello_world(name):
    return 'Hello %s!' % name


if __name__ == '__main__':
    app.run('0.0.0.0', 5000, True)

在上面的示例中,URL规则中的这部分是可变的,Flask将提取用户请求的 URL中这部分的内容,作为视图函数hello_world()的name参数传入。

除了默认字符串作为URL的变量部分之外,还可以使用以下数据类型来构建URL的变量部分:

序号转换器和描述
1int 接受整数
2float 浮点数

如下面代码示例:

from flask import Flask
app = Flask(__name__)

@app.route('/blog/<int:postID>')
def blog(postID):
    return 'Blog Number %s!' % postID


@app.route('/price/<float:priceNum>')
def price(priceNum):
    return 'Price is %s!' % priceNum


if __name__ == '__main__':
    app.run('127.0.0.1', 5000, debug = True)
Flask url_for()

URL反转:根据视图函数名称得到当前所指向的url(视图函数的名称作为第一个参数传入,后续可跟一个或多个关键字参数,每个参数对应于URL的变量部分)

url_for() 函数的用法

  • 该函数接受视图函数的名称作为参数,返回对应的url
from flask import Flask, redirect, url_for
app = Flask(__name__)

@app.route('/admin')
def hello_admin():
   return 'Hello Admin'

@app.route('/guest/<guest>')

def hello_guest(guest):
   return 'Hello %s as Guest' % guest

@app.route('/user/<name>')
def hello_user(name):
   if name =='admin':
      return redirect(url_for('hello_admin'))
   else:
      return redirect(url_for('hello_guest',guest = name))

if __name__ == '__main__':
   app.run(debug = True)
  • 还可以用作加载静态文件,例如
//该条语句就是在模版中加载css静态文件. 
<link rel="stylesheet" href="{{url_for('static',filename='css/index.css')}}">
Flask HTTP方法

Http协议是万维网中数据通信的基础。在该协议中定义了从指定URL获取数据的不同方法。 下表总结了不同的http方法:

序号方法与描述
1GET 请求指定的页面信息,当需要向服务器传输数据时,是以未加密的形式将数据传输的,最常见的方法。
2HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3POST 向指定网址提交数据进行处理请求(例如提交表单或者上传文件,数据被包含在请求体中),并返回相应响应内容。
4PUT 向服务器传送数据,并保存到请求URL指定的位置。
5DELETE 请求服务器删除指定的页面。

默认情况下,Flask路由响应GET请求。但是可以通过为route()装饰器提供方法参数来更改此默认选项(@app.route(’/login’,methods = [‘POST’, ‘GET’]))。

Flask 模板

Web模板的诞生是为了将显示与数据分离,让前端工作人员专注表现设计,后台人员注重业务逻辑。模板技术多种多样,但其本质是将模板文件和数据通过模板引擎生成最终的HTML代码。

Flask使用jinga2模板引擎,jinja2是Python的一个流行的模板引擎,它将模板与特定数据源组合以呈现动态网页。

关于Flask中模板的使用,可见这篇博客,写得很详细:Flask入门很轻松(三)—— 模板

Flask静态资源

Web应用程序通常需要静态文件,例如javascript文件或支持网页显示的CSS文件,它将在应用程序的/static中提供。

在Flask中使用静态资源可见:Flask之静态文件处理

Flask Request对象

来自客户端的数据作为全局请求对象发送到服务器。为了处理这些请求数据,应该从Flask模块导入request:from flask import request。

Request对象的重要属性如下所列:

  • form` - 它是一个字典对象,包含表单参数及其值的键和值对。

  • args` - 解析查询字符串的内容,它是问号(?)之后的URL的一部分。

  • Cookies` - 保存Cookie名称和值的字典对象。

  • files` - 与上传文件有关的数据。

  • method` - 当前请求方法。

其详细可见:Flask request 属性详解

下面来讲讲Request对象里的Cookies

Flask Request对象之Cookies

Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。

Request对象包含Cookie的属性。它是所有cookie变量及其对应值的字典对象,除此之外,cookie还存储其网站的到期时间,路径和域名。

cookie默认只能在主域名下使用,如果我们想要在子域名下使用cookie需要另外设置。

如何在Flask中构造Cookie?在Flask中,服务器对响应对象设置cookie,使用make_response()函数从视图函数的返回值获取响应对象,之后,使用响应对象的set_cookie()函数来存储cookie。

如何在Flask中获取Cookie?读回cookie很容易,request.cookies属性的get()`方法用于读取cookie。

下面来看一个简单的demo

cookie.py

from flask import Flask, redirect, url_for, request, render_template, make_response

app = Flask(__name__)

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

@app.route('/setcookie', methods = ['POST', 'GET'])
def setcookie():
    if request.method == 'POST':
        user = request.form['nm']
        response = make_response(render_template('readcookie.html'))
        response.set_cookie('userID', user)
        return response

@app.route('/getcookie')
def getcookie():
    name = request.cookies.get('userID')
    return '<h1>welcome '+ name + '</h1>'

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

cookie_index.html

<html>
   <body>

      <form action = "/setcookie" method = "POST">
         <p><h3>Enter userID</h3></p>
         <p><input type = 'text' name = 'nm'/></p>
         <p><input type = 'submit' value = 'Login'/></p>
      </form>

   </body>
</html>

readcookie.html

Cookie is set<br/>
<a href='/getcookie'>click to check</a>
Flask Session

与Cookie不同,Session(会话)数据存储在服务器上,需要在该会话中保存的数据会存储在服务器上的临时目录中,Session对象也是一个字典对象,包含会话变量和关联值的键值对。

服务端会为每个客户端的会话分配会话ID。会话数据存储在cookie的顶部,服务器以加密方式对其进行签名,对于此加密,Flask应用程序需要定义一个SECRET_KEY。

有关Flask中Session的操作,可见:Flask操作session

Flask 重定向和错误

重定向

Flask中的redirect()函数调用时,它将用户重定向到具有指定状态代码的另一个目标位置,并返回响应对象,即为重定向。

重定向也分为暂时性重定向(状态码为302)和永久性重定向(状态码为301)

错误

Flask中的abort(code)函数用于提前退出一个请求,并用指定的错误码返回。

errorhandler(code_or_exception):用来监听捕捉异常,然后返回自定义的页面处理,参数code_or_exception –为HTTP的错误状态码或指定异常。

一个小demo

from flask import Flask,abort

app = Flask(__name__)

@app.route('/game/<int:age>')
def play_game(age):
    #异常抛出
    abort(404)

    return "helloworld"

#异常捕获
@app.errorhandler(404)
def page_not_found(e):
    print(e)
    return "找不到服务器资源,服务器搬家了"

if __name__ == '__main__':
    app.run()
Flask 消息闪现

Flask中包含flash()方法,在视图函数调用flash()函数,传入消息内容,flash()会把消息存储在session中,我们需要在模板中使用全局函数get_flashed_messages()获取消息并将它显示出来。

通过flash()函数发送的消息会存储在session对象中,如果需要把消息加密存储,可以通过设置app.secret_key属性。

Flask 文件上传

Flask 文件上传 在Flask中处理文件上传非常简单。它需要一个HTML表单,其enctype属性设置为“multipart / form-data”,将文件发布到URL。URL处理程序从request.files[]对象中提取文件,并将其保存到所需的位置。

Flask文件上传中的一些设置

配置描述
app.config[‘MAX_CONTENT_PATH’]指定要上传的文件的最大大小(以字节为单位)
app.config[‘UPLOAD_FOLDER’]定义上传文件夹的路径
ALLOWED_EXTENSIONS = set([‘txt’, ‘pdf’, ‘png’, ‘jpg’, ‘jpeg’, ‘gif’])允许的文件扩展名
app.config[‘MAX_CONTENT_LENGTH’] = 16 * 1024 * 1024限制文件大小

关于文件上传的一个小demo

# -*- coding: utf-8 -*-
import os
from flask import Flask, request, url_for, send_from_directory
from werkzeug import secure_filename

ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)
#设置文件的上传路径目录
app.config['UPLOAD_FOLDER'] = os.getcwd()
#限制文件大小
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024


html = '''
    <!DOCTYPE html>
    <title>Upload File</title>
    <h1>图片上传</h1>
    <form method=post enctype=multipart/form-data>
         <input type=file name=file>
         <input type=submit value=上传>
    </form>
    '''


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS


@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],
                               filename)


@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            file_url = url_for('uploaded_file', filename=filename)
            return html + '<br><img src=' + file_url + '>'
    return html


if __name__ == '__main__':
    app.run()
Flask 扩展

Flask通常被称为微框架,Flask扩展为Flask框架提供了可扩展性。

Flask有大量的Flask扩展可用。Flask扩展是一个Python模块,它向Flask应用程序添加了特定类型的支持,可以通过pip下载所需的扩展。

pip install Flask-Mail

有以下一些常用的扩展

  • Flask Mail - 为Flask应用程序提供SMTP接口
  • Flask WTF - 添加WTForms的渲染和验证
  • Flask SQLAlchemy - 为Flask应用程序添加SQLAlchemy支持
  • Flask Sijax - Sijax的接口 - Python/jQuery库,使AJAX易于在Web应用程序中使用

每种类型的扩展通常提供有关其用法的大量文档。由于扩展是一个Python模块,因此需要导入它才能使用它。

Flask 邮件

基于web的应用程序通常需要具有向用户发送邮件的功能。Flask-Mail扩展使得与任何电子邮件服务器建立简单的接口变得非常容易。

首先,应该在pip下安装Flask-Mail扩展。

pip install Flask-Mail

其使用可以分为以下几步

  • 配置Flask-Mail的配置项

  • 创建邮递系统对象

  • 创建邮件对象

  • 使用邮递系统对象发送消息

Flask-Mail的配置项

序号参数与描述
1MAIL_SERVER 电子邮件服务器的名称/IP地址
2MAIL_PORT 使用的服务器的端口号
3MAIL_USE_TLS 启用/禁用传输安全层加密
4MAIL_USE_SSL 启用/禁用安全套接字层加密
5MAIL_DEBUG 调试支持。默认值是Flask应用程序的调试状态
6MAIL_USERNAME 发件人的用户名
7MAIL_PASSWORD 发件人的密码
8MAIL_DEFAULT_SENDER 设置默认发件人

Mail类

用于构建邮递系统对象的类,它管理电子邮件消息传递需求,构造函数将Flask应用程序(app)对象作为参数。

flask-mail.Mail(app = None)

Mail类的方法

序号方法与描述
1send()发送消息对象
2connect()打开与邮件主机的连接
3send_message()发送消息对象

Message类

用于构建邮件对象的类,它封装了一封电子邮件的内容。Message类构造函数有几个参数:

flask-mail.Message(subject, recipients, body, html, sender, cc, bcc, 
   reply-to, date, charset, extra_headers, mail_options, rcpt_options)

Message类方法

attach() - 为邮件添加附件。此方法一般采用以下参数:

  • filename - 要附加的文件的名称
  • content_type - MIME类型的文件
  • data - 原始文件数据

add_recipient() - 向邮件添加另一个收件人

关于使用Flask发送邮件的demo,可以参见 flask_mail发送邮件(附源码),里面有发送普通文本邮件、发送一个html模板的邮件、发送一个附带附件的邮件的代码示例,私以为写得还是挺全的。

Flask WTF

HTML提供了一个****标签,可以适当地使用Form(表单)元素,例如文本输入,单选按钮,选择等。

用户输入的数据以Http请求消息的形式通过GET或POST方法提交给服务器端脚本。

而使用HTML表单的一个缺点是很难动态呈现表单元素。HTML本身无法验证用户的输入。

而在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms(WTForms的作用,就是提供一个灵活的表单,能够方便使用。Flask-WTF扩展为这个WTForms库提供了一个简单的接口),使用Flask-WTF表单扩展,可以帮助进行CSRF验证,帮助我们快速定义表单字段并使用HTML模板进行渲染,而且可以将验证应用于WTF字段。

WTforms包中包含各种表单字段的定义。下面列出了一些标准表单字段。

序号标准表单字段与描述
1TextField 表示 HTML表单元素
2BooleanField 表示 HTML表单元素
3DecimalField 用于显示带小数的数字的文本字段
4IntegerField 用于显示整数的文本字段
5RadioField 表示 HTML表单元素
6SelectField 表示选择表单元素
7TextAreaField 表示 HTML表单元素
8PasswordField 表示 HTML表单元素
9SubmitField 表示表单元素

下面列出一些WTForms常用验证函数

序号验证器类与描述
1DataRequired 检查输入字段是否为空
2Email 检查字段中的文本是否遵循电子邮件ID约定
3IPAddress 在输入字段中验证IP地址
4Length 验证输入字段中的字符串的长度是否在给定范围内
5NumberRange 验证给定范围内输入字段中的数字
6URL验证在输入字段中输入的URL

对于在Flask中使用WTF扩展创建表单类、使用模板渲染表单、获取表单数据,并对表单的数据进行校验,Flask:Flask-WTF扩展 一文在1.1—1.4中做了使用示例。

Flask SQLAlchemy

关于ORM

ORM全称Object Relation Mapping(对象关系映射),主要实现模型对象到关系数据库数据的映射,比如:把数据库表中每条记录映射为一个模型对象。

关于SQLAlchemy

SQLAlchemy是一个基于Python的ORM框架。该框架是建立在DB-API之上(DB-API是Python的数据库接口规范),使用对象关系映射进行数据库操作。

DB API的作用如下

在这里插入图片描述

关于SQLAlchemy的基本认识和使用,可戳 使用SQLAlchemy | 廖雪峰

进入正题:Flask SQLAlchemy

Flask-SQLAlchemy是Flask扩展,它将对SQLAlchemy的支持添加到Flask应用程序中。

我们一步步来简单列举Flask SQLAlchemy的用法

步骤2 - 安装Flask-SQLAlchemy扩展。

pip install flask-sqlalchemy

步骤2 - 您需要从此模块导入SQLAlchemy类。

from flask_sqlalchemy import SQLAlchemy

步骤3 - 现在创建一个Flask应用程序对象并为要使用的数据库设置URI。

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root@127.0.0.1/flask_books'

步骤4 - 然后使用app对象作为参数创建SQLAlchemy类的对象。该对象包含用于ORM操作的辅助函数。它还提供了一个父Model类,要使用它来声明用户定义的数据模型。在下面的代码段中,创建了books模型。

db = SQLAlchemy(app)
class Books(db.Model):
    # 表名
    __tablename__ = "books"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16), unique=True)
    author_id = db.Column(db.Integer,db.ForeignKey("authors.id"))

    def __repr__(self):
        return "books:%s %s" % {self.name,self.author_id}

步骤5 - 要在数据库中创建所有定义好的数据表(上面定义好的books数据模型),请运行create_all()方法。

db.create_all()

SQLAlchemy的session对象管理ORM对象的所有持久性操作。

以下session方法执行CRUD操作(CRUD操作要db.session.commit()之后才开始真正执行):

  • db.session.add (模型对象) - 将记录插入到映射表中

  • db.session.delete (模型对象) - 从表中删除记录

  • model.query.all() - 从表中检索所有记录(对应于SELECT查询)。

还可以使用filter属性用于过滤返回检索得到的记录集。例如要在books表中检索name='东野圭吾’的记录:

Author.query.filter_by(name = "东野圭吾").first()

一个结合使用了Flask WTF和Flask SQLAlchemy的图书管理的demo,可以见我之前写的博客:小坨的Flask之图书管理小案例

一个Flask的综合案例:问答论坛

此小demo是基于Flask和MySQL搭建起来的问答平台,是我在学习过程中按b站:Python Flask零基础到项目实战系列-项目实战 手敲起来的一个小demo,它综合涵盖了上面讲到的Flask知识点。
代码在我的GitHub上:https://github.com/atuo-200/flask_questions-and-answers_demo
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值