一、页面跳转和重定向
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。
- 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成了jd.com,所以这种情况下应该用永久性重定向。
- 暂时性重定向:http的状态码是302,表示页面的暂时性跳转,比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面,这种情况下应该用暂时性重定向
在flask中,重定向是通过flask.redirect(location,code=302)这个函数实现的,location表示的是需要重定向到URL,应该配合之前的url_for()函数来使用,code表示采用哪个重定向,默认是302也即是、暂时性重定向,可以修改为301来实现永久性重定向。
#导入Flask扩展
from flask import Flask,jsonify,url_for,request,redirect
import config
#创建Flask应用程序实例
#需要传入__name__,作用是为了确定资源所在的路径
app=Flask(__name__)
#以后所有的配置项都是放在config.py中
app.config.from_object(config)
books=[{"id":1,"name":"三国演义"},{"id":2,"name":"水浒传"},{"id":3,"name":"红楼梦"},{"id":4,"name":"西游记"}]
@app.route("/book/<int:book_id>",methods=['GET'])
def book_detail(book_id):
for book in books:
if book_id==book['id']:
return book
return f"{book_id}的图书没有找到"
@app.route("/book/list")
def book_list():
for book in books:
book['url']=url_for("book_detail",book_id=book['id'])
return jsonify(books)
@app.route("/profile")
def profile():
#参数传递的两种形式:
#1,作为url的组成成分:/book/1
#2,查询字符串:/book?id=1
user_id=request.args.get("id")
if user_id:
return "用户个人中心"
else:
return redirect(url_for("index"))
@app.route('/')
def index():
return "Hellow world"
#启动程序
if __name__=='__main__':
#执行了app.run。就会将Flask程序运行在一个简易的服务器(Flask提供的,用于测试的)
app.run(debug=True)
结果:
?二、模板
模板:模板是一个web开发必备的模块,因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个有富文本标签的页面。这时候我们就需要使用模板了,在Flask中,配套的模板是Jinja2,Jinja2的作者也是Flask的作者,这个模板非常的强大,而且执行效率很高。
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/about1")
def about():
context={
"username":"arise"
}
return render_template("about.html",**context)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__=='__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>关于我</title>
</head>
<body>
<h1>我是{{username}}</h1>
</body>
</html>
?
结果:
?三、模板过滤器
过滤器是通过管道符号(|)进行使用的,例如:{{name|length}},将返回name的长度。过滤器相当于是一个函数,把当前变量传入到过滤器中,然后过滤器根据自己的功能,在返回相应的值,之后再将结果渲染到页面中,Jinja2中内置了很多过滤器,
join过滤器的使用:
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/about1")
def about():
context={
"username":"arise",
'books':['红楼梦','三国演义']
}
return render_template("about.html",**context)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__=='__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>关于我</title>
</head>
<body>
<h1>我是{{username}}</h1>
<div>{{books}}</div>
<div>{{books|join(",")}}</div>
<div>{{books|join("//")}}</div>
</body>
</html>
?
结果:
?四、Jinja2中的控制语句
1,if:if语句和python中的类似,可以使用>,<,<=,>=,==,!=来进行判断,也可以通过and,or,not,()来进行逻辑合并操作。
实例:
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/control")
def control():
context={
"age":18
}
return render_template("control.html",**context)
@app.route("/about1")
def about():
context={
"username":"arise",
'books':['红楼梦','三国演义']
}
return render_template("about.html",**context)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__=='__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>控制语句</title>
</head>
<body>
{% if age >18 %}
<div>您已成年!</div>
{% elif age < 18 %}
<div>您未成年</div>
{% else %}
<div>您刚成年</div>
{% endif %}
</body>
</html>
?结果:
?
2,for.....in....:for循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/control")
def control():
context={
"age":18,
'books': ['红楼梦', '三国演义', '水浒传', '西游记'], #列表
"person":{"name":"arise","age":19} #字典
}
return render_template("control.html",**context)
@app.route("/about1")
def about():
context={
"username":"arise",
'books':['红楼梦','三国演义']
}
return render_template("about.html",**context)
@app.route('/')
def hello_world():
return 'Hello world!'
if __name__=='__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>控制语句</title>
</head>
<body>
{% if age >18 %}
<div>您已成年!</div>
{% elif age < 18 %}
<div>您未成年</div>
{% else %}
<div>您刚成年</div>
{% endif %}
<ul>
{% for book in books %}
<li>{{ book }}</li>
{% endfor %}
</ul>
{% for key,value in person.items() %}
<div>{{ key }}:{{ value}}</div>
{% endfor %}
</body>
</html>
结果:
?
?五、模板继承
Flask中的模板可以继承,通过继承可以把模板中重复出现的元素抽取出来,放在父类模板中,并且父模板通过定义block给子模版开一个口,子模版根据需要,再实现这个block。
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/control")
def control():
context={
"age":18,
'books': ['红楼梦', '三国演义', '水浒传', '西游记'], #列表
"person":{"name":"arise","age":19} #字典
}
return render_template("control.html",**context)
@app.route("/about")
def about():
context={
"username":"arise",
'books':['红楼梦','三国演义']
}
return render_template("about.html",**context)
@app.route('/')
def index():
return render_template("index.html")
if __name__=='__main__':
app.run(debug=True)
#父模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<ul>
<li>
<a href="/">首页</a>
</li>
<li>
<a href="/control">控制</a>
</li>
<li>
<a href="/about">关于我</a>
</li>
</ul>
{% block body %}{% endblock %}
<footer style="backgroud-color: #ccc">我是底部的</footer>
</body>
</html>
#子模版1
{% extends "base.html" %}
{% block title %}
这是首页
{% endblock %}
{% block body %}
<h1>我是首页</h1>
{% endblock %}
#子模版2
{% extends "base.html" %}
{% block title %}
关于我
{% endblock %}
{% block body %}
<h1>我是{{username|length}}</h1>
<div>{{books}}</div>
<div>{{books|join(",")}}</div>
<div>{{books|join("//")}}</div>
{% endblock %}
#子模版3
{% extends "base.html" %}
{% block title %}
控制
{% endblock %}
{% block body %}
{% if age >18 %}
<div>您已成年!</div>
{% elif age < 18 %}
<div>您未成年</div>
{% else %}
<div>您刚成年</div>
{% endif %}
<ul>
{% for book in books %}
<li>{{ book }}</li>
{% endfor %}
</ul>
{% for key,value in person.items() %}
<div>{{ key }}:{{ value}}</div>
{% endfor %}
{% endblock %}
结果:
?
|