这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
from flask import request
request对象中包含很多可以利用的属性,可以帮助在视图编写时获取有关用户请求部分的数据
request.method # 请求方式,如GET、POST大写字符串
request.args # get请求提交的数据
request.from # post请求提交的数据
request.files # 请求提交的文件
request.values
'''
是一个列表,包含query及post的全部数据
列表[0]上的是query数据,列表[-1]是post数据
获取其中数据时直接通过key即可,不需要选访问对应索引的字典
如果get与post参数key值相同,可以通过getlist批量获取到全部的,再通过索引区分
'''
假设当前get传递?id=1&name=2,post传递的也是{id:1},那么通过getlist获取,返回结果为一个类似列表的数据结构
其中索引为0的位置上是get传递的数据,索引为1的位置上是post/put提交的数据
request.values.getlist("id")
# CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('name', '2')]), ImmutableMultiDict([('id', '1')])])
# 返回结果: ['1', '1']
request.cookies # 客户端所带的cookie
request.headers # 请求头
request.path # 不带域名,请求路径
request.full_path 不带域名,带参数的请求路径
request.url 带域名带参数的请求路径
request.base_url 带域名请求路径
http://127.0.0.1:5000/?id=1
from flask import Flask, request
@app.route('/')
def index():
# url中?后面所有的值,最为一个字符串
print(request.query_string)
# 返回ImmutableMultiDict,类似字典,连接查询参数中的?key=value组成的字典{key:value}
print(request.args)
...
返回结果如下所示
b'id=1'
ImmutableMultiDict([('id', '1')])
如果是form表单提交,form-data
格式数据,比如
id : 1
request.form # 获取form表单类型提交的数据
ImmutableMultiDict([('id', '1')])
如果是json格式提交,那么可以通过request.json
获取
{
"id": 1,
}
request.json # 获取application/json格式提交的数据,处理为一个字典数据
{
'id': '1'}
记得上传文件的表单要加着属性
enctype="multipart/form-data"
request.files["upload_file"] # 获取文件上传
如果希望将这个文件快速保存至本地,那么flask也提供了save方法,可以使上传文件快速保存
from flask import request
from werkzeug.utils import secure_filename
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 项目根目录
STATIC_DIR = os.path.join(BASE_DIR, 'static') # 静态文件夹位置
@app.route('/upload', methods=['POST'])
def upload_file():
if request.method == 'POST':
f = request.files['upload']
f.save(os.path.join(STATIC_DIR, secure_filename(f.filename))) # 存储
flask默认的头部信息获取通过headers属性即可拿到,如果是拿取定义的Authorization认证信息,最基本的做法如下
request.headers.get("Authorization")
那么初次之外,flask还支持一套Basic Auth的认证机制,当客户端发送具有Basic前缀,且是base64编码的头部字段时,将会自动对其进行解析
使用默认头部认证方式,客户端的auth值发起要具备如下格式
比如组成一个账号为
root
,密码为123456
的头部
base64.b64encode("root:123456".encode())
# cm9vdDoxMjM0NTY=
那么发起的请求头部将是这样
Authorization: Basic cm9vdDoxMjM0NTY=
flask在检测到头部中含有Authorization
属性时,并且此时Authorization
属性对应的value是具备Basic
前缀,那么会自动将其进行解析,并将解析到的username和password存入request.authorization属性中
最后如果Authorization
属性合法传递,那么可以通过request.authorization对象轻松获取到username及password
request.authorization
request.authorization.username # root
request.authorization.password # 123456
默认的认证解析部分源码如下
...
if auth_type == b"basic":
try:
username, password = base64.b64decode(auth_info).split(b":", 1)
# 通过冒号进行base64解码后字符串的切分,对应上方组成token的规则
...
return Authorization(
"basic",
{
"username": to_unicode(username, _basic_auth_charset),
"password": to_unicode(password, _basic_auth_charset),
},
)
如果视图返回的是一个响应对象,那么就直接返回它
如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的响应对象
如果返回的是一个字典,那么调用 jsonify 创建一个响应对象,也就是application/json
如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少包含一个项目,且项目应当由 (response, status) 、 (response, headers) 或者 (response, status, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表或字典
如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把它转换为一个响应对象
(html字符串, 状态码, 头部信息)
(body, status, headers), (body, status), or (body, headers)
@app.route('/', methods=["GET", "POST"])
def index():
return ("ABC", 404, {
"Content-Type": "application/json"})
redirect用作重定向使用,常见的在登陆后的跳转或者权限判断后的跳转工作
@app.route('/')
def index():
return redirect(url_for("home")) # 重定向至home视图
@app.route('/home', endpoint="home")
def home():
return 'home'
返回一个模版,第一个参数是模板的名字,之后的参数是模版传递的上下文,只要你愿意,可以传递无数个
还可以传函数,在模板中调用函数
@app.route("/")
def index():
return render_template("index.html", double=lambda x : x * 2)
index.html的内容
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
{
{ double(2) }}
body>
html>
make_response函数生成Response对象,可以对响应进行一些设置后再返回,比如设置cookie
可以传入一个字符串对象,它将被编码为UTF-8并被显示在body中
也可以传入一个字典类型的对象,它将被先变成json格式再返回
也可以传入一个元组,包含两个或者三个元素,分别是body内容,status状态码,headers响应头(字典类型)
from flask import make_response
@app.route("/response")
def response():
response = make_response("This response
")
response.set_cookie("id","1") # 设置cookie
response.headers["Header"] = "header" # 响应头上放东西
return response
还可以对返回的响应体进行包裹,获得响应对象,并对该对象进行修改,然后再返回
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404) # 加工响应体
resp.headers['X-Something'] = 'A value' # 设置头部
return resp
abort()函数用于提前退出一个请求,并用指定的错误码返回
参数可以是一个状态码,比如,404;也可以是一个WSGI应用
abort(404)
abort(Response('Hello World'))
JSON 格式的响应是常见的,用 Flask 写这样的 API 是很容易上手的,如果从视图返回一个 dict 将会自动转换为一个 JSON 响应
@app.route("/user")
def user():
return {
"username": "zhangsan",
"image": url_for("static", image_path),
}
还可以使用flask自带的json处理类jsonify进行json数据处理,并返回,支持Python中可以被json处理的数据类型
通过jsonify返回的数据头部的Content-Type为
application/json
app.config['JSON_AS_ASCII'] = False
@app.route('/')
def index():
return jsonify({
"name": "张三"})
如果使用json模块封装json处理,那么Content-Type为
text/html; charset=utf-8
@app.route('/')
def index():
return json.dumps({
"name": "张三"}, ensure_ascii=False)
注意:如果想正确展示中文,而非通过编码显示,那么要用到如下配置
app.config['JSON_AS_ASCII'] = False # jsonify配置
json.dumps(ensure_ascii=False) # jsom模块
errorhandle
可以捕获错误,并且对错误做出响应,返回给用户,必须要在装饰器参数明确捕获的错误码
@app.errorhandler(500)
def error_500(e):
return "Something Wrong % s" % e
FBV简单, 小巧, 当不涉及到复杂的逻辑时可以使用FBV
CBV灵活, 为什么说灵活呢?因为, 类的封装, 继承, 多态, 你说灵活不灵活
views.View是最基本的视图基类,在dispatch_request
方法中进行逻辑处理
def login(f): # 测试装饰器
def wapper(*args, **kwargs):
print("login wapper")
return f(*args, **kwargs)
return wapper
class Index(views.View):
methods = ["GET"] # 请求方式
decorators = [login] # 请求到达会执行的装饰器方法
def dispatch_request(self):
return "index"
注册路由
app.add_url_rule("/", view_func=Index.as_view(name="index"))
# as_view的参数name代表当前路由映射视图的路由命名
# 该命名必须提供,否则所有的视图都会叫View这就不对了
该基类提供了真正对于请求反射的实现方法,可以类似django的视图进行get、post等请求的映射编写视图
class Index(views.MethodView):
methods = ["GET"]
decorators = [login]
def get(self):
return "Index"
路由映射是一样的
app.add_url_rule("/", view_func=Index.as_view(name="index"))