flask(一)之路由和视图

01-介绍

Flask 是一个 Python 实现的 Web 开发微框架,同时具有很强的扩展能力。

02-第一个flask程序

# 初始化

from flask import Flask, url_for, views
app = Flask(__name__)

Flask类的构造函数只有一个必须指定的参数,即应用主模块或包的名称。在大多数应用中,Python的__name__变量就是所需的值。

from flask import Flask

# 创建flask对象,传递__name__参数进去
app = Flask(__name__) # url与视图映射
@app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run() # 也可以更改端口号 run(port=5500)

flask(一)之路由和视图

03-设置debug模式

from flask import Flask
import config
#创建一个Flask对象,传递__name__参数进去
app = Flask(__name__)
# app.debug = True #第二种
# app.config.update(DEBUG=True) #第三种
app.config.from_object(config) #第四种 #url与视图映射
@app.route('/')
def hello_world():
print('helloworkl')
return 'Hello World!' if __name__ == '__main__':
# app.run(debug=True) #第一种
app.run()

04-配置文件

新建config.py

DEBUG =True

主程序中的两种引用方式:

# 第一种:推荐使用
import config
app.config.from_object(config) # 第二种:
app.config.from_pyfile('config.py')

05-url传参方式

from flask import Flask, request

# 创建flask对象,传递__name__参数进去
app = Flask(__name__) # 普通的传参方式 127.0.0.1:5000/p/1
@app.route('/p/<id>/')
def article_detail(id):
return '你访问的文章第%s篇' % id """
指定参数类型
有以下几种类型:
string:默认的数据类型
int:接受整形
float:浮点型
path:和string的类似,但是接受斜杠
any:可以指定多个路径
uuid:只接受uuid字符串
""" # any: 127.0.0.1:5000/blog/id 127.0.0.1:5000/user/id
@app.route('/<any(blog,user):url_path>/<id>')
def detail(url_path, id):
if url_path == 'blog':
return '博客详情%s' % id
else:
return '用户详情%s' % id # path: 127.0.0.1:5000/article/python/1/
@app.route('/article/<path:test>/')
def test_article(test):
return 'test_article:{}'.format(test) # 获取参数 127.0.0.1:5000/tieba/?wd=python
@app.route('/tieba/')
def tieba():
wd = request.args.get('wd')
return '获取的参数的是%s' % wd if __name__ == '__main__':
app.run()

06-url_for:实现创建url,只是生成一个url

如果要生成一个css样式的静态文件的url需要使用url_for('static',filename='style.css')来创建相应的url。

视图中的url_for:

# 1. 通过视图函数解析出url

from flask import Flask, url_for

@app.route('/')
def hello_world():
# url_for里面:第一个是视图函数,第二个是url需要的参数
return url_for('my_list',page=2) @app.route('/list/<page>/')
def my_list(page):
return 'my_list' 访问 127.0.0.1:5000/,结果:/list/2/ # 2. url_for里面多的参数会当做搜索字符 @app.route('/')
def hello_world():
return url_for('my_list',page=2,count=2) @app.route('/list/<page>/')
def my_list(page):
return 'my_list' 访问 127.0.0.1:5000/,结果:/list/2/?count=2

模板中的url_for:

模板中的url_for和视图函数中的url_for是类似的,也是传递视图函数的名字,也可以传递参数。使用的时候,需要在url_for两边加上一个{{ url_for('func_name'),ref='/',id='1'}}

07-Response

视图函数中可以返回的类型:
1. 可以返回字符串,返回的字符串其实底层将这个字符串包装成了一个‘Response’对象
2. 可以返回元组,形式(响应体,状态码,头部信息),返回的元组其实底层将这个字符串包装成了一个‘Response’对象
3. 可以返回Response及其子类 实现一个自定义的Response对象:
1.继承自、‘Response’类
2. 实现方法‘force_type’
3. 指定‘app.response_class’为你自定义的‘Response’对象
4. 如果视图函数返回的数据,不是字符串,也不是元组,也不是Response对象,那么就会将返回值传给‘force_type’,然后将‘force_type’的返回值返回给前端
from flask import Flask,url_for,Response,jsonify

app = Flask(__name__)

class JsonResponse(Response):

    @classmethod
def force_type(cls, response, environ=None):
'''
这个方法只有视图函数返回非字符、非元祖、非Response对象才会调用
:param response:
:param environ:
:return:
'''
# 把字典转换成json
if isinstance(response,dict):
# jsonify将字典转换成json对象,还将该对象包装成了一个Response对象
response = jsonify(response)
return super(JsonResponse, cls).force_type(response,environ) app.response_class = JsonResponse @app.route('/')
def hello_world():
return 'Hello world' @app.route('/list1/')
def list1():
return Response('list1') # 合法对象,直接返回 @app.route('/list3/')
def list3():
return {'username':'derek','age':18} # 返回的是非字符、非元祖、非Response对象,所以执行force_type方法 if __name__ == '__main__': app.run(debug=True)

08-add_url_rule:

from flask import Flask, render_template, url_for

app = Flask(__name__)
app.config.update({
'DEBUG':True,
   # 配置自动加载模板文件,调试模式下会自动开启
'TEMPLATES_AUTO_RELOAD':True
}) @app.route('/',endpoint='index')
def hello_world():
print(url_for("derek_list")) # 通过endpoint找到对应的url /list/
return render_template('index.html') def my_list():
return "列表页" # 三个参数
# 1.url
# 2.给url起个别名,如果没有指定endpoint,则默认使用视图函数的名字作为endpoint的值
# 3.视图函数
app.add_url_rule('/list/',endpoint='derek_list',view_func=my_list) with app.test_request_context():
print(url_for('index')) # / if __name__ == '__main__':
app.run()

09-render_template: 渲染模板文件

from flask import Flask, render_template, url_for

return render_template('index.html')

10-send_from_directory:主要用于下载文件

from flask import Flask
from flask import g
from flask import send_from_directory
from flask import url_for
import os.path app = Flask(__name__)
dirpath = os.path.join(app.root_path,'upload')
@app.route("/download/<path:filename>")
def downloader(filename):
return send_from_directory(dirpath,filename,as_attachment=True)

11-static_url_path和static_folder

static_url_path主要用于改变url的path的,静态文件放在static下面,所以正常情况url是static/filename ,但是可以通过static_url_path来改变这个url。

static_folder主要是用来改变url的目录的,默认是static,可以通过这个变量来改变静态文件目录。

from flask import Flask
from flask import g
from flask import send_from_directory
from flask import url_for
import os.path app = Flask(__name__,static_url_path="/test") @app.route("/")
def static_create():
return url_for('static',filename='style.css')

12-Request对象

Request是Flask中表示当前请求的request对象,一般称之为请求上下文变量(可以理解成全局变量,在任意一个视图中都可以访问到)。常用的属性有:

  args:url中的查询字符串。本质上是键值对,跟在"?"后面,多个键值对之间使用"&"连接;

  form:请求url中的表单数据。也是由键值对组成,一般使用post方法提交数据

  cookies:请求中的cookie信息。由服务器生成的键值对,把值发送给客户端并保存,稍后重点讲解!

  files:上传的文件

12-类视图

1. 继承views.VIew。
2. 必须实现‘dispatch_request’方法,以后请求过来后,都会执行这个方法,返回值相当于视图函数一样,必须返回'Response'或者子类的对象,或者是字符串,或者是元祖。
3. 必须通过app.add_url_role(url_rule,view_func)来做url与视图的映射。
from flask import Flask, url_for, views
# 创建一个Flask对象,传递__name__参数进去
app = Flask(__name__) app.config.update({
'DEBUG': True,
'TEMPLATES_AUTO_RELOAD': True,
}) class ListView(views.View):
def dispatch_request(self):
return "我的列表页" # 1.ListView.as_view('list')里面必须传个参数‘name’,给view_func起个别名,实际上就是dispatch_request函数
# 2.endpoint也可以不指定,则默认使用view_func的别名(name参数的值)
app.add_url_rule('/list/', endpoint='list', view_func=ListView.as_view('list')) # url与视图映射
@app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run(port=5555)

13-通过类的继承实现多个视图返回json数据

from flask import Flask,url_for,views,jsonify

app = Flask(__name__)
app.config.update({
'DEBUG':True,
'TEMPLATES_AUTO_RELOAD':True
}) # 父类,把数据转换成json格式
class JsonView(views.View):
def get_data(self):
raise NotImplementedError def dispatch_request(self):
return jsonify(self.get_data()) # 子类只需要写get_data方法
class ListView(JsonView):
def get_data(self):
return {"usernmae":'derek','age':18} app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list')) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run()

14-基于调度方法的类视图

class LoginView(views.MethodView):
def __render(self,error=None):
return render_template('login.html', error=error) def get(self,error=None):
return self.__render() def post(self):
username = request.form.get('username')
password = request.form.get('password')
if username == 'derek' and password == '':
return '登录成功'
else:
return self.__render(error='用户名或密码错误') app.add_url_rule('/login/',view_func=LoginView.as_view('login'))

15-路由

方式一:

  在Flask应用中定义路由的最简单方式,是使用应用实例提供的 app.route 装饰器。

# url与视图映射
@app.route('/')
def hello_world():
return 'Hello World!'

方式二:

  使用 add_url_rule()方法。接收3个参数:URL,端点名和视图函数。

16-Web开发服务器

Flask应用自带Web服务器,通过 flask run 命令启动。这个命令在 FLASK_APP 环境变量指定的python脚本中寻找应用的实例。

$ export FLASK_APP=hello.py

$ flask run

flask(一)之路由和视图

17-请求-响应循环

17.1 应用和请求上下文

为了避免大量可有可无的参数把视图函数弄得很乱,Flask使用 上下文 临时把一些变量变为全局可以访问。

在Flask中有两种上下文:应用上下文和请求上下文。

flask(一)之路由和视图

注意:获取应用上下文的方法是应用实例上调用 app.app_context()。

17.2 请求分派

flask(一)之路由和视图

17.3 请求对象

Falsk通过上下文变量request对外开放请求对象,包含了客户端发送的HTTP请求的全部信息。

Flask请求中最常用的属性和方法:

flask(一)之路由和视图

flask(一)之路由和视图

17.4 请求钩子

flask(一)之路由和视图

上一篇:NOIP2012 同余方程


下一篇:NOIP2012 同余方程-拓展欧几里得