不得不说这一张给了我很大的帮助和启发,所以这一篇的总结我会好好的写,不单单是书上的内容,更多是我的个人思路和理解
首先给出全部的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标签,留意标签属性和文件选择