不得不说这一张给了我很大的帮助和启发,所以这一篇的总结我会好好的写,不单单是书上的内容,更多是我的个人思路和理解
首先给出全部的app.py的代码顺着代码代入思路和知识点
import os
from flask import Flask, render_template, flash, redirect, url_for, Markup
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY', 'secret string')
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
user = {
'username': 'Grey Li',
'bio': 'A boy who loves movies and music.',
}
movies = [
{'name': 'My Neighbor Totoro', 'year': '1988'},
{'name': 'Three Colours trilogy', 'year': '1993'},
{'name': 'Forrest Gump', 'year': '1994'},
{'name': 'Perfect Blue', 'year': '1997'},
{'name': 'The Matrix', 'year': '1999'},
{'name': 'Memento', 'year': '2000'},
{'name': 'The Bucket list', 'year': '2007'},
{'name': 'Black Swan', 'year': '2010'},
{'name': 'Gone Girl', 'year': '2014'},
{'name': 'CoCo', 'year': '2017'},
]
@app.route('/watchlist')
def watchlist():
return render_template('watchlist.html', user=user, movies=movies)
@app.route('/')
def index():
return render_template('index.html')
# register template context handler
#自定义上下文变量,返回值必须为字典
@app.context_processor
def inject_info():
foo = 'I am foo.'
return dict(foo=foo) # equal to: return {'foo': foo}
# register template global function
#自定义全局函数
@app.template_global()
def bar():
return 'I am bar.'
# register template filter
@app.template_filter()
def musical(s):
return s + Markup(' ♫')
# register template test
@app.template_test()
def baz(n):
if n == 'baz':
return True
return False
@app.route('/watchlist2')
def watchlist_with_static():
return render_template('watchlist_with_static.html', user=user, movies=movies)
# message flashing
@app.route('/flash')
def just_flash():
flash('I am flash, who is looking for me?')
return redirect(url_for('index'))
# 404 error handler
@app.errorhandler(404)
def page_not_found(e):
return render_template('errors/404.html'), 404
# 500 error handler
@app.errorhandler(500)
def internal_server_error(e):
return render_template('errors/500.html'), 500
app.run(debug=True)
首先创建一个实例
将用户列表和电影的信息全部传到一个新的url中,在新的url中去返回一个html页面,来输出这些信息
所以这里就新建了一个watchlist.html,这个html的目的就是为了返回url对应视图函数传入的内容
watchlist.html的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{user.username}}'s Watchlist</title>
</head>
<body>
<a href="{{ url_for('index') }}">← Return</a>
<h2>{{user.username}}</h2>
{% if user.bio %}
<i>{{user.boio}}</i>
{% else %}
<i>This user has not provided a bio.</i>
{% endif %}
<h5>{{ user.username }}'s Watchlist ({{movies | length}}):</h5>
<ul>
{% for movie in movies %}
<li>{{movie.name}} - {{movie.year}}</li>
{% endfor%}
</ul>
</body>
</html>
主要有俩个知识点,也就Jinja2模板中常用的语法,for循环和if判断
唯一值得注意的就是要对应开始就要对应结束
{% if xxx %} -----{% endif %}
{% for xxx %} ----{% endfor %}
模板中的变量,需要视图函数导入
然后在根据代码流程分析:
1.上下文变量:
上下文变量是在模块中可以直接使用的,相当于模块中的全局变量。
自定义上下文变量是利用装饰器@app.context_processor
(1)@app.context_processor
def xxx():
pass
(2)当然还有先定义函数,然后将函数以方法的方式去返回
def xxx():
pass
app.context_processor(xxx)
2.全局函数:全局函数就相当于是所有模块都可以使用的.
自定义全局函数是利用装饰器:@app.template_global:
3.过滤器:模板中的工具,操作对象|过滤方法(例如在watchlist.html{{movies|length}})计算这个movies有多长
4.测试器:测试器从字面理解就是用来判断和对比测试
关键装饰器@app.templat_text(),像下面这个例子的意思就是给baz函数传入参数,进行对比,再根据对比来返回结果
5.基模板:来到Jinja2的灵魂之处了
基模板的意思,通俗去理解就是共享块
而块的概念就是将一个模板分成若干个块
<!DOCTYPE html>
<html>
<head>
{% block head %}
<meta charset="utf-8">
<title>{% block title %}Template - HelloFlask{% endblock %}</title>
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
{% block styles %}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css' ) }}">
{% endblock %}
{% endblock %}
</head>
<body>
<nav>
<ul><li><a href="{{ url_for('index') }}">Home</a></li></ul>
</nav>
<main>
{% for message in get_flashed_messages() %}
<div class="alert">{{ message }}</div>
{% endfor %}
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}
<small> © 2018 <a href="http://greyli.com" title="Written by Grey Li">Grey Li</a> /
<a href="https://github.com/greyli/helloflask" title="Fork me on GitHub">GitHub</a> /
<a href="http://helloflask.com" title="A HelloFlask project">HelloFlask</a>
</small>
{% endblock %}
</footer>
{% block scripts %}{% endblock %}
</body>
</html>
从上述代码分析
{%block head%} 中有俩个块
一个是{%block title%}放置标题,
另外一个是{%block style%}用来存放读取css链接的块,每个块结束,都要对应的使用{%endblcok%}这个关键字来结束块。
在<body>这个标签中首先有一个Home跳转小按钮,跳转到主页,
紧接着在<main>的标签中读取消息闪现中的消息,并存放了{%block content%}的信息,方便子模块继承
在<footer>标签中创建{%block footer%}这个块,用来存放页脚信息。
最后一个块就是{%block script%}用来放置js脚本链接的块
6.子模版的继承问题
子模版的只要是继承了基模块,那么在模板就开始要使用extend '基模板名',
并且在写入内容或者修改内容的时候,必须是在主模块的已经定义了块中进行操作,
如{%block content%} xxx {%endblock%},中间的内容就是子模块新增的。
7.加载静态文件(js.css.img)
使用<link>标签来加载静态文件,在{%block style%}中加载css文件,在{%block scripts%}中加载js文件,如下所示
8.宏
9.宏加载静态文件
10.加载Favion:网页有一个小图标
在模块中直接使用link标签,留意标签属性和文件选择