视图函数的两种实现方式
1,前后端不分离,一个url对应一个视图函数
2,前后端分离,一个试图函数对应多个url路径请求
定义试图类 试图类必须集成falsk.views下的view
主要适用于前后端分离项目,前后端不分离推荐使用函数式实现
class ProjectView(View):
# methods=['GET','POST'] 给请求方式添加限制或支持的方案2,
# 方案1,集中注册的时候添加
# decorators = (log_time,) # 是个元祖格式
def get(self):
return "get"
def post(self):
return "post"
# 重写dispatcher_request方法 分配请求
def dispatch_request(self):
dispatch_pattern = {'GET': self.get, 'POST': self.post}
method = request.method
return dispatch_pattern.get(method)() # 映射获取到对应方法,最后的()表示调用执行
# post方法是需要添加支持的,不添加的话是无法发送post进行访问,默认支持get
# 两种方式,在注册的时候进行添加,或者在类下起一个类下字典
视图类中使用装饰器的情况
# 视图函数类中
class ProjectView(View):
methods=['GET','POST'] 给请求方式添加限制或支持的方案2,方案1,集中注册的时候添加
decorators = (log_time,) # 是个元祖格式
# 集中注册时采用
# 如果想要对视图方法进行装饰器装饰
f = ProjectView.as_view('project')
log_time(f)
# 这样显式的进行调用一下装饰器完成装饰,
#之后集中注册的时候view_func直接传f即可
# 类中定义一个decorators view原码中定义好了的,定义属性吧装饰器的名传入即可
更为便利的实现方式—methodView
使用这种方式编写视图函数需要继承flask.methodView类
# methodview 继承methodview
class ProjectmethodView(MethodView):
# 装饰器,请求限制,与前面相同
def get(self):
return 'get'
def post(self):
return 'post'
# 继承了View之后的视图类,有一个as_view的静态方法,可以给视图起名
app.add_url_rule('/project',
view_func=ProjectView.as_view('project'),
methods=['POST', 'GET'])
# 此种写法将不用在自行书写分发方法dispatcher,
# 会自动根据请求调用执行不同的视图函数方法
flask.request 请求
# 通过config 配置类进行参数配置限制上传文件大小
app.config['MAX_CONTENT_LENGTH'] = 10*1024*1024
@app.route('/', methods=['POST', 'GET'])
def index():
if request.method == "GET":
return render_template("index.html")
# ajax json 请求头 xhr如果有的话就是ajax请求
elif request.method == "POST":
# 可以从原码中查看request包含的各种属性值
a = request # 通常使用request对象,打断点看request中的属性
print(request.json) # 发送如果是json就通过json获取
# json属性实际上是调用get_json的方法的,并且在其中可以设置参数
# 强制获取返回的json数据,而不管设置是否冲突
print(request.form)
print(request.content_type) # 判断contentType是否为application/json
# print(request.environ) # 可以
print(request.values)
# print(request.headers)
print(request.is_json)
# if request.is_xhr ==True: # 通过is_xhr 可以简单判断是否为 ajax请求
# print("是通过ajax发送过来的请求") 但是后面可能被移除
return "发送ajax成功"
在构建视图函数的时候,如果想要取到前端页面传送过来的数据,在request.args进行拿取
从request的原码中可以看到request请求中包含的各种属性值
request.json 如果发送的是json数据就通过json获取,json属性实际上是调用get_json方法获取的,强制获取返回的json数据,不管设置是否冲突
request.conten_type 得到request的content type
request.environ 得到请求的环境变量
request.headers 请求的头信息
request.is_json 判断是否为json请求
构建视图函数的响应数据
有多种方式可以进行构建。
使用json.dumps直接在视图函数设定返回值
# return json.dumps({"usernmae": "addicated"}),
201, {"content-type": "application/json"}
第二种方式, 使用flask.make_response(json.dumps({})) 用一个对象接受并返回这个对象
r = make_response(json.dumps({"usernmae": "addicated"}), 201, {"content-type": "application/json"})
r.status = '201'
# flask 里面封装了一个jsonify方法
# 将响应内容转换成json 相应内容类型设置成json
return r
第三种方式,使用jsonify 同样是flask内封装的
# flask 里面封装了一个jsonify方法 将响应内容转换成json 相应内容类型设置成json
r = jsonify({"usernmae": "addicated"})
r.status = '201'
# 响应内容要返回中文的时候 app.config['JSON_AS_ASCII'] = False
return r
# jsonify会默认将返回内容设置成json格式,如果需要添加状态码等设定直接在对象中赋值
响应对象
如果不进行任何设置,返回字符串浏览器会自动将它变成hml
# 1 ,主要响应的类型 content-type
# 文本 text/plain
# HTML text/html
# xml application/xml
# json application/json
细碎知识点
上传文件时的时候前端页面中要设定enctype
<form action="/upload" method="post" enctype="multipart/form-data">
<!-- // enctype 这个属性不能忘设置,不然会影响图片没有真正的上传-->
<input type="file" name="pic">
<input type="submit" >
</form>
视图函数编写上传方法的时候
要注意设置保存文件的文件名不可按照原名,因为如果有空格的话会导致访问不到上传的文件,这里使用
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload():
# TODO 限制被上传文件类型
# TODO 限制被上传文件大小
file = request.files.get('pic') # 获取发送请求过来的名为pic的文件
if file is None:
return render_template("index.html")
if allowed_format(file.filename):
# 在文件保存的时候直接保存原文件名的话会出现bug
# 因为文件名中一旦出现空格,url在访问的时候会进行解析
# 导致文件访问不到 所以使用secure_filename
file.save(secure_filename(file.filename))
return "success"
# 上传成功之后让文件可以被访问到
# 下面是访问上传文件的视图函数
@app.route("/upload/<filename>")
def get_upload(filename):
return send_from_directory(os.getcwd(),filename)