构造url
一般我们通过一个url就可以执行到某一个函数。如果反过来,我们知道一个函数,怎么去获得这个url呢?url_for函数就可以实现这个功能。url_for()函数接受两个及以上的参数,它接受函数名作为第一个参数,接受对应的url规则的命名参数。如果还出现其他的参数。则会添加到url的后面作为查询参数。
通过构建url的方式而选择直接在代码中拼url的原因有两点
- 将来如果修改了url,但没有修改该url对应的函数名,就不用到处去替换url了。
- url_for()函数会转义一些特殊字符和unicode字符串,这些事情url_for会自动地帮我们搞定。
@app.route('/')
def index():
# article_list/3/ 只传一个aid
#m
# 根据函数地名字,进行反转 得到函数对应地路由 重定向
# print(url_for("article_list", aid=3))
# article_list / 3 /?page=4
print(url_for("article_list", aid=3, page=4, t=123))
return "hello world"
@app.route('/article/<aid>/')
def article_list(aid):
return "article list {}".format(aid)
指定url末尾地斜杠
有些url地末尾是有斜杠地,有些url末尾没有斜杠的。这是两个不同地url地址:
@app.route('/article/')
def article():
return "文章列表"
上述例子中,当一个结尾不带斜杠地url: /article,会被重定向到带斜线的url: /article/上去,但是当我们定义article的url的时候,如果末尾没有加上斜杠,但是在访问的时候加上了斜杠,这时候会抛出一个404错误页面
@app.route('/article')
def article():
return "文章列表"
以上没有在末尾加上斜杠,因此在访问/article/的时候,就会抛出一个404错误。
指定HTTP方法
在@()中可以传入一个关键字参数methods来指定本方法支持的HTTP方法。默认情况下为GET请求
# @('/login/')
#http://127.0.0.1:5000/login/?username=happy
@app.route('/login/', methods=['GET','POST'])
def login():
# GET : 参数直接在url中
# post 参数没有直接体现在url地址中
# print(type()) #字典类型
# GET请求接受参数
# print(('username'))
# POST请求接受参数
print(request.form.get("name"))
return "login"
以上装饰器将让login的url既能支持GET又能支持POST。
页面跳转和重定向
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面,比如用户访问需要权限的页面,但是该用户当前并没有登录,因此我们需要给他重定向到登录页面。
- 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问。
- 暂时性重定向:http的状态码是302,表示页面的暂时性跳转,比如访问一个需要权限的网址,如果该用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
在flask中,重定向就是通过(location,code=302)这个函数来实现的,location表示需要重定向到的url,应该配合之前讲的url_for()函数来实现,code表示采用哪个重定向,默认是302也暂时性重定向,可以修改成301来实现永久性重定向。
@app.route('/login/')
def login():
return "login"
@app.route('/profile/')
def profile():
name = request.args.get("name")
if name:
return name
else: # http://127.0.0.1:5000/profile/?name=happy
# 重定向到登录页面
return redirect(url_for('login'), code=301)
关于响应(Response)
视图函数中可以返回一下类型的值:
- Response对象
- 字符串。其实flask是根据返回的字符串类型,重新创建一个对象,Response将该字符串作为主体,状态码为200,MIMI类型为text/html,然后返回该Response对象。
- 元组。元组中格式是(response,status,headers)。response为一个字符串,status值是状态码,headers是一些响应头
- 如果不是以上三种类型。那么flask会通过Response.force_type(rv,)转化为一个请求对象。
@app.route('/about/')
def about():
# return 'happy'
# return {"name":"happy"}
# return ('name','python')
# return Response("关于我们", status=200,mimetype="text/html")
# return "关于我们",200
return make_response("关于我们")
模板
模板是一个web开发必备的模块。因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个有富文本标签的页面。这时候我们就需要使用模板了。在flask中,配套的模板是Jinja2,Jinja2的作者也是flask的作者,这个模板非常强大,并且执行效率高。
flask渲染Jinja模板
要渲染一个模板,通过render_template方法即可。
from flask import Flask, render_template
app = Flask(__name__) # 在括号里添加template_folder=r"路径"即可转变模板路径
@app.route('/')
def index():
return render_template("")
当访问/about/的时候。about()函数会在当前目录下的templates文件夹下寻找模板文件。如果想更改模板文件地址,应该在创建app的时候,给flask传递一个关键字参数template_folder,指定具体路径
@app.route('/profile')
def profile():
return render_template("profile/")
传参
@app.route('/')
def index():
# 默认会从templates目录下找模板文件
# return render_template("", username="喜欢!", age= 18)
# 传参过于麻烦,我们定义一个模板
context = {
"username": "凋落",
"age": 18,
"books": {
"python": 22,
"java": 33,
"php" : 44
},
"book": ["python", "php", "java"]
}
return render_template("", **context)
@app.route('/profile')
def profile():
return render_template("profile/")