Python 后端 编程 ·

「Flask笔记」jinja2模板练习

``

flask -- jinja2模板练习


豆瓣微信小程序

GitHub传送门
(可以拿这里的content.py这样不用自己构造数据了),有建议和不足的地方拜托师傅们指出!!!

写出大致框架

from flask import Flask,render_template,url_for

app = Flask(__name__)

@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>ding</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
        list-style:none;
        text-decoration: none;
    }
    .container {
        background: #fff;
    }
    .search-group{
        padding: 34px 20px;
        background: #41be57;
    }
    .search-group .search-input{
        background: #fff;
        display: block;
        width: 100%;
        height: 80px;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        outline: none;
        border: 0;
        text-align: center;
        font-size: 30px;
    }
    /* 内容 */
    .item-list-group .item-list-top{
        overflow: hidden;
        padding: 34px;
    }
    .item-list-top .module-title{
        float: left;
        font-size: 30px;
    }
    .item-list-top .more-btn{
        float: right;
        font-size: 30px;
    }
    .list-group{
        overflow: hidden;
        padding: 0 34px;
    }
   .item-group{
        float: left;
        margin-right: 30px;
    }
    .item-group{
        width: 30%;
    }
    .item-group .thumbanail{
        display: block;
        width: 100%;
    }
    .item-group .item-title{
        text-align: center;
        font-size: 30px;
    }
    .item-group .item-rating{
        text-align: center;
        font-size: 30px;
    }
</style>
<body>
    <div class="container">
        <div class="search-group">
            <input type="text" class="search-input" placeholder="搜索">
        </div>
        <div class="item-list-group">
            <div class="item-list-top">
                <span class="module-title">电影</span>
                <a href="#" class="more-btn">更多</a>
            </div>
            <div class="list-group">
                <div class="item-group">
                    <img src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545479945.webp" alt="" class="thumbanail">
                    <p class="item-title">死侍2</p>
                    <p class="item-rating">7.4</p>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

set实现星星评分

这里为了巩固知识点用的set开发的时候可以使用插件或者雪碧图之类的

  <div class="item-group">
                    <img src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545479945.webp" alt="" class="thumbanail">
                    <p class="item-title">死侍2</p>
                    <p class="item-rating">
                        {% set rating = 7.4 %}  {# 暂时使用设置的值 #}
                        {% set lights = ((rating|int)/2)|int %}
                        {% set halfs = (rating|int)%2 %}
                        {% set grays = 5 - lights - halfs %}
                        {% for light in range(lights) %}
                            <img class="score" src="{{ url_for('static',filename='img/pic1.png') }}" alt="">
                        {% endfor %}
                        {% for half in range(halfs) %}
                            <img class="score" src="{{ url_for('static',filename='img/pic2.png') }}" alt="">
                        {% endfor %}
                        {% for gray in range(grays) %}
                            <img class="score" src="{{ url_for('static',filename='img/pic3.png') }}" alt="">
                        {% endfor %}
                        7.4
                    </p>
                </div>

重构代码,将item-group抽取做为宏

{% macro itemGroup(thumbnail,title,rating) %}
      <div class="item-group">
            <img src={{ thumbnail }} alt="" class="thumbanail">
            <p class="item-title">{{ title }}</p>
            <p class="item-rating">
                {% set lights = ((rating|int)/2)|int %}
                {% set halfs = (rating|int)%2 %}
                {% set grays = 5 - lights - halfs %}
                {% for light in range(lights) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic1.png') }}" alt="">
                {% endfor %}
                {% for half in range(halfs) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic2.png') }}" alt="">
                {% endfor %}
                {% for gray in range(grays) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic3.png') }}" alt="">
                {% endfor %}
                7.4
            </p>
      </div>
{% endmacro %}
....
<div class="list-group">
     {{ itemGroup('https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545479945.webp','死侍2',8.5) }}
</div>

使用循环,并且模拟后台传值

由于这里还没学到数据库,所以模拟后台传数据
先创建一个content.py,传数据到主函数

def content():
    context = [
        {
            'thumbnail':'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2545479945.webp',
            'title':'死侍2',
            'rating':8.5,
        },
        {
            'thumbnail':'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2543972440.webp',
            'title':'掠食城市',
            'rating':6.7,
        },
        {
            'thumbnail':'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2542268337.webp',
            'title':'家和万事惊',
            'rating':7.5,
        },
        {
            'thumbnail':'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2543631842.webp',
            'title':'密室逃生',
            'rating':7.3,
        },
        {
            'thumbnail':'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2544313786.webp',
            'title':'白蛇:缘起',
            'rating':8.0,
        },
        {
            'thumbnail':'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2541662397.webp',
            'title':'大黄蜂',
            'rating':7.1,
        },
    ]
    return context

主函数导入模块,接收数据

from flask import Flask,render_template,url_for
import content

movies = content.content()
app = Flask(__name__)

@app.route('/')
def index(): 
    context ={   # **context只接收dict
        'movies':movies
    }
    return render_template('index.html',**context)

if __name__ == '__main__':
    app.run(debug=True)

将抽取的宏用for循环输出item

 <div class="list-group">
     {% for movie in movies[0:3] %}
     #因为首页只需要遍历三个所以用切片遍历前三个
        {{ itemGroup(movie.thumbnail,movie.title,movie.rating) }}
     {% endfor %}
</div>

用同样的方法加入tv

重构代码,将list-group抽取做为宏

{% macro listGroup(module_title,items) %}
    <div class="item-list-top">
        <span class="module-title">{{ module_title }}</span>
        <a href="#" class="more-btn">更多</a>
    </div>
    <div class="list-group">
         {% for item in items[0:3] %}
            {{ itemGroup(item.thumbnail,item.title,item.rating) }}
         {% endfor %}
    </div>
{% endmacro %}
<div class="item-list-group">
    {{ listGroup('电影',movies) }}
    {{ listGroup('电视剧',tvs) }}
</div>

宏的继承和导入

再做列表页之前,观察页面,列表页的搜索框和其他标签,都和首页一样,所以抽取相同的地方做宏
创建一个叫base.html的模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{{ url_for('static',filename='css/base.css') }}"> 
    {# 这里把搜索框的css抽出来做一个css文件,下面的是列表的css #}
    <link rel="stylesheet" href="{{ url_for('static',filename='css/style.css') }}">
</head>
<body>
    <div class="container">
        <div class="search-group">
            <input type="text" class="search-input" placeholder="搜索">
        </div>
        {% block body %}{% endblock %}
    </div>
</body>
</html>

然后再把之间做了listGroupitemGroup两个宏放到一个宏模板中叫做macrros.html

{# itemGroup的宏 #}

{% macro itemGroup(thumbnail,title,rating) %}
      <div class="item-group">
            <img src={{ thumbnail }} alt="" class="thumbanail">
            <p class="item-title">{{ title }}</p>
            <p class="item-rating">
                {% set lights = ((rating|int)/2)|int %}
                {% set halfs = (rating|int)%2 %}
                {% set grays = 5 - lights - halfs %}
                {% for light in range(lights) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic1.png') }}" alt="">
                {% endfor %}
                {% for half in range(halfs) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic2.png') }}" alt="">
                {% endfor %}
                {% for gray in range(grays) %}
                    <img class="score" src="{{ url_for('static',filename='img/pic3.png') }}" alt="">
                {% endfor %}
                7.4
            </p>
      </div>
{% endmacro %}

{# listGroup的宏 #}

{% macro listGroup(module_title,items,category) %} 
{# 这里的category参数用来判断是tv还是movies #}
    <div class="item-list-top">
        <span class="module-title">{{ module_title }}</span>
        <a href="{{ url_for('item_list',category=category) }}" class="more-btn">更多</a>
        {# 通过url_for,请求一个参数,如果是1,就返回电影,如果是2就返回tv #}
    </div>
    <div class="list-group">
         {% for item in items[0:3] %}
            {{ itemGroup(item.thumbnail,item.title,item.rating) }}
         {% endfor %}
    </div>
{% endmacro %}

根据上面的分析重构index.html

{% extends 'base.html' %}
{% from "macrros.html" import listGroup,itemGroup %}
{% block body %}
    <div class="item-list-group">
        {{ listGroup('电影',movies,1) }}
        {{ listGroup('电视剧',tvs,2) }}
    </div>
{% endblock %}

制作list页面

这里可以使用宏模板和继承,快速完成list

{% extends 'base.html' %}
{% from 'macrros.html' import itemGroup %}

{% block body %}
    {% for item in items %}
         {{ itemGroup(item.thumbnail,item.title,item.rating) }}
    {% endfor %}
{% endblock %}

大致就这样,第一个flask的jinja2练习,可能有遗漏的地方,建议看源码。。。

参与评论