1+1=10

记记笔记,放松一下...

Python flask入门笔记(三)

Flask是一款轻量级的用python实现的web微框架,它基于Werkzeug WSGI工具包和Jinja2模板引擎。

在简单了解Werkzeug和Jinja之后,可以回头看看HTTP相关的东西了...

请求类型

HTTP有不同的请求类型。

Request 用途 备注
GET 最常用的方式(method)。客户端发送GET请求,服务端返回数据。
POST 用于发送表单(form)数据到服务端。服务端不缓存POST的数据。
HEAD 同GET一样,只是不需要响应的body数据
PUT 使用PUT的内容替换掉服务端的对应的资源
PATCH 部分更新
DELETE 删除服务端对应的资源

Flask有不同的装饰器来处理HTTP请求。所有的请求数据都封装进flask.Request类。这个类是werkzeug.wrappers.Request派生而来。

Request

Flask 的 Request 类有很多成员属性,部分可能常用的如下:

属性 用途 备注
data 请求的数据
form 请求中的表单数据 不包含上传文件
args 请求中的查询参数(the part in the URL after the question mark)
json data类型是JSON(application/json)
cookies 请求中的cookie信息
headers 请求中的报文头信息
method HTTP方法
url 请求的URL地址(全路径)
files 请求上传的文件(对应 input type="file" name="">)。 对应Wekzeug中的FileStorage

获取GET参数

程序:

1
2
3
4
5
6
7
8
from flask import Flask, request

app = Flask(__name__)

@app.route('/login')
def login():
    user = request.args.get('user')
    return f'Hello {user}'

通过浏览器直接访问:

1
http://127.0.0.1:8000/login?user=debao

通过GET方式获取表单信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
    return '''
      <form action = "/login" method = "get">
         <p>Enter Name:</p>
         <p><input type = "text" name = "user" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>   
'''

@app.route('/login')
def login():
    user = request.args.get('user')
    return f'Hello {user}'

获取POST参数

通过POST方式获取表单信息

代码上和GET方式基本一致

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
    return '''
      <form action = "/login" method = "post">
         <p>Enter Name:</p>
         <p><input type = "text" name = "user" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>   
'''

@app.route('/login', methods = ['POST'])
def login():
    user = request.form['user']
    return f'Hello {user}'

直接使用一个URL地址login也可以

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/login', methods = ['POST', 'GET'])
def login():
    if request.method == 'POST':
        user = request.form['user']
        return f'Hello {user}'
    else:
        return '''
          <form action = "/login" method = "post">
             <p>Enter Name:</p>
             <p><input type = "text" name = "user" /></p>
             <p><input type = "submit" value = "submit" /></p>
          </form>
        '''

Content-Type

使用POST时,enctype属性可以设置:

  • application/x-www-form-urlencoded :默认。所有字符发送前进行编解码
  • multipart/form-data:如要上传文件,需使用
  • text/plain:不建议

另外还有个application/json

文件上传

表单使用multipart/form-data,控件用file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from flask import Flask, request

app = Flask(__name__)

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file1']
        f.save('uploaded_file.txt')
        return f'file uploaded successfully'
    else:
        return '''
          <form action = "/upload" method = "post" enctype='multipart/form-data' >
             <p>Enter File Name:</p>
             <p><input type = "file" name = "file1" /></p>
             <p><input type = "submit" value = "submit" /></p>
          </form>
        '''

Cookies

  • 获取cookies通过 Request的 cookies属性
  • 设置cookies通过Reponse的 set_cookie方法
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, request, render_template_string, make_response

app = Flask(__name__)

@app.route('/login', methods = ['POST', 'GET'])
def login():
    if request.method == 'POST':
        user = request.form['user']
        resp = make_response(f'Hello {user}')
        resp.set_cookie('userID', user)
        return resp
    else:
        user = request.cookies.get('userID')
        return render_template_string(f'''
          <form action = "http://localhost:8000/login" method = "post">
             <p>Enter Name:</p>
             <p><input type = "text" name = "user" value="{user}"/></p>
             <p><input type = "submit" value = "submit" /></p>
          </form>
        ''', user=user)
  • 注意,为了设置cookie,此处使用make_reponse()创建Response对象,而后进行设置。不能像先前一样,直接返回字符串。

Sessions

尽管和获取request数据不相关,既然遇到cookies了,还是看一下Sessions。

先实现丐版的登录登出程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from flask import Flask, request, session, redirect, url_for

app = Flask(__name__)
app.secret_key = b'_5#y2L"F4QF@\n\xf4]/'

@app.route('/')
def index():
    if 'username' in session:
        return f'Logged in as {session["username"]}, <a href="/logout">Logout Now</a>'
    return 'You are not logged in, <a href="/login">Login Now</a>'

@app.route('/login', methods = ['POST', 'GET'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['user']
        return redirect(url_for('index'))
    return f'''
          <form action = "http://localhost:8000/login" method = "post">
             <p>Enter Name:</p>
             <p><input type = "text" name = "user""/></p>
             <p><input type = "submit" value = "submit" /></p>
          </form>
        '''

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))
  • 必须要设置一个 app.secret_key

Session时在 Cookies 的基础上实现的,flask需要在cookies中存储通过secret_key加密后的信息。

参考

  • https://flask.palletsprojects.com
  • https://pythonbasics.org/flask-http-methods/
  • https://www.digitalocean.com/community/tutorials/processing-incoming-request-data-in-flask
  • https://zhuanlan.zhihu.com/p/623755314
  • https://blog.csdn.net/ling620/article/details/107562294