接上一节,带来了 flask
的demo
flask 示例
from flask import Flask
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
下面带来一些其他的基础知识:
1. 如何开启debug
模式
当我们在编写flask
应用的时候,免不了对各种 路由 、各种 视图函数 的编写,每一次都重新运行程序,显然是个比较费时的操作,当然 flask
这个框架的底层 服务器 werkzeug
(非生产环境)为我们提供了比较方便的 debug
模式
- 在app.run()中传递一个参数:
app.run(debug=True)
- 通过设置参数:
app.debug = True
- 通过 配置参数的形式:
app.config.append(DEBUG=True)
- 通过 配置文件 :
app.config.from_object()
,示例如下:
# config.py
DEBUG=True
# app.py
from flask import Flask
import config # 导入配置文件
app = Flask(__name__)
app.config.from_object(config) # 添加配置文件
2. Pin码的使用
pin
码是 在 debug
模式下,如果代码出现 bug ,在网页中,可以通过执行一些代码来查看部分的参数,而在执行代码之前,需要输入 pin
码,开启 debug
模式之后,终端可以看见 pin
码
3. 路由和 函数映射
路由:浏览器输入的url路径部分,比如:
/user/
函数映射:即在 demo 代码中,使用app.route()
装饰器装饰的函数,它决定了 当浏览器防问该路由时,由什么函数带处理这个请求。
路由变量
/<参数名>/
: 在路由中使用变量,默认是字符串类型
如果指定类型需要使用/<conventer:variable_name>
,其中:
string:默认字符串类型,接收没有任何“/\”的字符
int:整型
float:浮点型
path:和string类似,可以接受“/\”
uuid:只接受uuid类型的字符串,例如
# uuid例子
@app.route('/u/<uuid:user_id>/')
def user_detail(user_id):
return '用户个人中心页面:{}'.format(user_id)
any:可以指定多种路径,例如:
@app.route('/<any(user,blog):url_path>/')
def func(url_path):
if url_path == 'blog':
return '访问的是博客页面'
if url_path == 'user':
return '访问的是用户页面'
接收用户传递的参数
- 通过
path
的方式 - 查询字符串的方式,就是
?key=value
的形式,例如:
# 获取?后的参数
@app.route('/q/')
def get_query_words():
wd = request.args.get('wd') # 获取请求参数'wd'的值
return '通过字符串查询的参数是:{}'.format(wd)
如果这个页面需要做SEO
优化,就是被搜索引擎搜索到,那么推荐使用第一种形式(path的形式),如果不在乎被搜索引擎优化,那么就可以使用第二种(查询字符串的形式)。
url_for()
url_for(endpoint,**values)
:param endpoint: the endpoint of the URL (name of the function)
:param values: the variable arguments of the URL rule
value
如果不在路由中,那么不在路由中的参数以?key=value
的形式出现
自定义 url转换器
实现方式
- 实现一个类,继承自
BaseConverter
- 在自定义类中,重写
regex
,也就是这个变量的正则表达式 - 将自定义的类映射到
app.url_map.converters
中,比如:
app.url_map.converters['tel'] = TelephoneConverter
- 使用
案例:一个url中,含有手机号码的变量,必须限定这个变量的字符串格式满足手机号码的格式
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
class TelephoneConverter(BaseConverter):
"""自定义手机号码匹配转换器"""
regex = r'1[345789]\d{9}'
# 将转换器添加到 url_map.converters中
app.url_map.converters['tel'] = TelephoneConverter
# 使用
@app.route('/telephone/<tel:number>/')
def get_phone(number):
return '输入的手机号码是:{}'.format(number)
if __name__ == '__main__':
app.run(debug=True)
BaseConverter中的方法
to_python()
返回值会传递到view函数中作为参数
class ListConverter(BaseConverter):
def to_python(self, value):
return value.split('+')
app.url_map.converters['list'] = ListConverter
# 实现 /post/a+b/ 返回 a 和 b 下面的所有板块内容
@app.route('/posts/<list:boards>/')
def posts(boards):
return '您提交的板块是:{}'.format(boards)
to_url()
这个方法的返回值会在调用url_for
函数时,生成符合要求的 URL 形式
URl部分的小细节
在局域网中让其他电脑访问我的网站
`host='0.0.0.0'`
指定端口号
默认5000端口, `port=9999`
url唯一
推荐在url中添加尾部‘/’,利与SEO优化和用户体验
GET
请求 与 POST
请求
通过在视图函数中指定`methods=['GET','POST']`这种形式限制访问路由的方法
URL 页面跳转 与 重定向
重定向 分为 永久重定向(状态码: 301) 和 临时重定向(状态码为: 302)
在flask
中,重定向使用flask.redirect(location,code=302)
来实现的, 例如 :
from flask import Flask, redirect, request, url_for
app = Flask(__name__)
@app.route('/login/')
def login():
return 'login'
@app.route('/profile/')
def profile():
# 通过k-v形式,如果传递name,模拟登陆过
name = request.args.get('name')
if not name:
return redirect(url_for('login'))
return 'profile page'
if __name__ == '__main__':
app.run()
响应(Response)
视图函数的返回值会被自动转换为一个响应对象,Flask
的转换逻辑如下:
-
如果返回的是一个合法的响应对象,则直接返回
-
如果返回的是一个字符串,那么
Flask
会创建一个werkzeug.wrappers.Response
对象
Response 将该字符串作为主体,状态码为200
,MIME类型为:text/html
然后返回 Response 对象 -
如果返回的是一个元祖,元祖数据的类型是
(response,status,headers)
。
status
会覆盖200
状态码,headers
可以是一个列表或者字典,作为额外的消息头 -
如果以上条件都不满足,
flask
会假设返回一个合法的WSGI
应用程序,并通过Response.force_type(rv,request,environ)
转换一个请求对象。
以下将用例子来说明:
- 直接使用
Response
创建
@app.route('/')
def index():
return Response(response='index', status=200, mimetype='text/html')
- 可以使用
make_response
函数创建Response
对象,这个方法可以设置额外的数据,比如设置 cookie, header 信息等
from flask import make_response
@app.route('/about/')
def about():
return make_response('about page')
- 使用元组的方式返回响应
@app.route('/list/')
def list():
# 元组方式返回响应 (response,status,headers) # headers 可以使用 列表 或者 字典
return ('list page', 200, {'A': 'AAA'})
-
自定义响应。自定义响应必须满足3个条件
- 必须继承自
Response
类 - 必须实现类方法
force_type(cls, response, environ=None)
- 必须指定
app.response_class
为你自定义的 响应类
示例:Restful API 都是通过 JSON 来传递的,如果后台跟前台通信需要使用 JSON 数据那么可以自定义一个叫做 JSONResponse 的类 来代替 Flask 中自带的 Response 类
class JsonResponse(Response): @staticmethod def force_type(cls, response, environ=None): """ 这个方法只有视图函数返回 非字符串 非元组 非Response对象 才能调用 :param cls: :param response: 视图函数的返回值 :param environ: :return: """ if isinstance(response, dict): response = jsonify(response) return super(JsonResponse, cls).force_type(response, environ) # 指定响应类 app.response_class = JsonResponse @app.route('/list2/') def list2(): return {'name': 'CK', 'age': 18}
- 必须继承自
网友评论