视图函数的两种实现方式

1,前后端不分离,一个url对应一个视图函数
2,前后端分离,一个试图函数对应多个url路径请求
定义试图类 试图类必须集成falsk.views下的view
主要适用于前后端分离项目,前后端不分离推荐使用函数式实现

  1. class ProjectView(View):
  2. # methods=['GET','POST'] 给请求方式添加限制或支持的方案2,
  3. # 方案1,集中注册的时候添加
  4. # decorators = (log_time,) # 是个元祖格式
  5. def get(self):
  6. return "get"
  7. def post(self):
  8. return "post"
  9. # 重写dispatcher_request方法 分配请求
  10. def dispatch_request(self):
  11. dispatch_pattern = {'GET': self.get, 'POST': self.post}
  12. method = request.method
  13. return dispatch_pattern.get(method)() # 映射获取到对应方法,最后的()表示调用执行
  14. # post方法是需要添加支持的,不添加的话是无法发送post进行访问,默认支持get
  15. # 两种方式,在注册的时候进行添加,或者在类下起一个类下字典

视图类中使用装饰器的情况

  1. # 视图函数类中
  2. class ProjectView(View):
  3. methods=['GET','POST'] 给请求方式添加限制或支持的方案2,方案1,集中注册的时候添加
  4. decorators = (log_time,) # 是个元祖格式
  5. # 集中注册时采用
  6. # 如果想要对视图方法进行装饰器装饰
  7. f = ProjectView.as_view('project')
  8. log_time(f)
  9. # 这样显式的进行调用一下装饰器完成装饰,
  10. #之后集中注册的时候view_func直接传f即可
  11. # 类中定义一个decorators view原码中定义好了的,定义属性吧装饰器的名传入即可

更为便利的实现方式—methodView

使用这种方式编写视图函数需要继承flask.methodView类

  1. # methodview 继承methodview
  2. class ProjectmethodView(MethodView):
  3. # 装饰器,请求限制,与前面相同
  4. def get(self):
  5. return 'get'
  6. def post(self):
  7. return 'post'
  8. # 继承了View之后的视图类,有一个as_view的静态方法,可以给视图起名
  9. app.add_url_rule('/project',
  10. view_func=ProjectView.as_view('project'),
  11. methods=['POST', 'GET'])
  12. # 此种写法将不用在自行书写分发方法dispatcher,
  13. # 会自动根据请求调用执行不同的视图函数方法

flask.request 请求

  1. # 通过config 配置类进行参数配置限制上传文件大小
  2. app.config['MAX_CONTENT_LENGTH'] = 10*1024*1024
  3. @app.route('/', methods=['POST', 'GET'])
  4. def index():
  5. if request.method == "GET":
  6. return render_template("index.html")
  7. # ajax json 请求头 xhr如果有的话就是ajax请求
  8. elif request.method == "POST":
  9. # 可以从原码中查看request包含的各种属性值
  10. a = request # 通常使用request对象,打断点看request中的属性
  11. print(request.json) # 发送如果是json就通过json获取
  12. # json属性实际上是调用get_json的方法的,并且在其中可以设置参数
  13. # 强制获取返回的json数据,而不管设置是否冲突
  14. print(request.form)
  15. print(request.content_type) # 判断contentType是否为application/json
  16. # print(request.environ) # 可以
  17. print(request.values)
  18. # print(request.headers)
  19. print(request.is_json)
  20. # if request.is_xhr ==True: # 通过is_xhr 可以简单判断是否为 ajax请求
  21. # print("是通过ajax发送过来的请求") 但是后面可能被移除
  22. 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直接在视图函数设定返回值

  1. # return json.dumps({"usernmae": "addicated"}),
  2. 201, {"content-type": "application/json"}

第二种方式, 使用flask.make_response(json.dumps({})) 用一个对象接受并返回这个对象

  1. r = make_response(json.dumps({"usernmae": "addicated"}), 201, {"content-type": "application/json"})
  2. r.status = '201'
  3. # flask 里面封装了一个jsonify方法
  4. # 将响应内容转换成json 相应内容类型设置成json
  5. return r

第三种方式,使用jsonify 同样是flask内封装的

  1. # flask 里面封装了一个jsonify方法 将响应内容转换成json 相应内容类型设置成json
  2. r = jsonify({"usernmae": "addicated"})
  3. r.status = '201'
  4. # 响应内容要返回中文的时候 app.config['JSON_AS_ASCII'] = False
  5. return r
  6. # jsonify会默认将返回内容设置成json格式,如果需要添加状态码等设定直接在对象中赋值

响应对象

如果不进行任何设置,返回字符串浏览器会自动将它变成hml
# 1 ,主要响应的类型 content-type
# 文本 text/plain
# HTML text/html
# xml application/xml
# json application/json

细碎知识点

上传文件时的时候前端页面中要设定enctype

  1. <form action="/upload" method="post" enctype="multipart/form-data">
  2. <!-- // enctype 这个属性不能忘设置,不然会影响图片没有真正的上传-->
  3. <input type="file" name="pic">
  4. <input type="submit" >
  5. </form>

视图函数编写上传方法的时候
要注意设置保存文件的文件名不可按照原名,因为如果有空格的话会导致访问不到上传的文件,这里使用

  1. from werkzeug.utils import secure_filename
  2. @app.route('/upload', methods=['GET', 'POST'])
  3. def upload():
  4. # TODO 限制被上传文件类型
  5. # TODO 限制被上传文件大小
  6. file = request.files.get('pic') # 获取发送请求过来的名为pic的文件
  7. if file is None:
  8. return render_template("index.html")
  9. if allowed_format(file.filename):
  10. # 在文件保存的时候直接保存原文件名的话会出现bug
  11. # 因为文件名中一旦出现空格,url在访问的时候会进行解析
  12. # 导致文件访问不到 所以使用secure_filename
  13. file.save(secure_filename(file.filename))
  14. return "success"
  15. # 上传成功之后让文件可以被访问到
  16. # 下面是访问上传文件的视图函数
  17. @app.route("/upload/<filename>")
  18. def get_upload(filename):
  19. return send_from_directory(os.getcwd(),filename)