Today, I'm going to bring you the actual battle of template project. Let's have a look at the renderings
explain:
-
Click the picture to jump to the corresponding details page
- Data:
movies = [ { 'id': '34532', 'title': u'Fat action team', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2526215398.webp', 'rating': u'7.6', 'comment_count': 39450, 'authors': u'heart / Li Chengmin Clara Lee / article Zhang Wen' }, { 'id': '394558', 'title': u'Li Cha's aunt', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2533384240.webp', 'rating': u'6.3', 'comment_count': 38409, 'authors': u'Qian Chenguang / Wu Jinrong / Huang Cailun' }, { 'id': '26921827', 'title': u'Find you', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2534471408.webp', 'rating': u'4.3', 'comment_count': 682, 'authors': u'Yao Chen / Mayi / Yuan Wenkang' }, { 'id': '26287884', 'title': u'Sorrow flows back into a river', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2529701498.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'Zhao Yingbo / Ren Min / Xin Yunlai' }, { 'id': '26287884', 'title': u'Burp teacher', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2535365481.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'rani ·Makkherjee / Neiraji·Cabi / Sachin ' } ] # TV play tvs = [ { 'id': '235434', 'title': u'Biography of Ruyi', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2460165077.jpg', 'rating': u'7.4', 'comment_count': 49328, 'authors': u'rani ·Makkherjee / Neiraji·Cabi / Sachin ' }, { 'id': '48373095', 'title': u'Season 5', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2534020405.jpg', 'rating': u'8.4', 'comment_count': 2483, 'authors': u'Ito Sally / Great annals of Zhongchuan / Upper primitive real moment / Picturesque and beautiful / Sakura Tiantong /' }, { 'id': '27005982', 'title': u'Dearest of you', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508399162.jpg', 'rating': u'7.6', 'comment_count': 25532, 'authors': u'Jesse·Premon / Molly·Shannon / Bradley·Whitford / Maude Apatow / Madison·Betty /' }, { 'id': '30290917', 'title': u'We can't be beasts', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2537556934.jpg', 'rating': u'3.7', 'comment_count': 8493, 'authors': u'Zhong Hanliang / Yang Ying / Gan Tingting / Sun Yizhou / Qihang /' }, { 'id': '292843', 'title': u'Adventure life', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2533929218.jpg', 'rating': u'8.2', 'comment_count': 23456, 'authors': u'Thomas·Hadden·Qiu Qi / Terence·Howard / Boyd ·Holbrooke / Reyes·Wickfield / Marlow ·Thomas /' } ]
- explain
-
The page displays only three
- The light blue below is the background color.
Let's finish the function of the home page first
You can try to do it yourself first, and then look at the captain's code:
First, create a new project microPro:
app.py
# coding: utf-8 from flask import Flask import flask app = Flask(__name__) # type: Flask app.debug = True # film movies = [ { 'id': '34532', 'title': u'Fat action team', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2526215398.webp', 'rating': u'7.6', 'comment_count': 39450, 'authors': u'heart / Li Chengmin Clara Lee / article Zhang Wen' }, { 'id': '394558', 'title': u'Li Cha's aunt', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2533384240.webp', 'rating': u'6.3', 'comment_count': 38409, 'authors': u'Qian Chenguang / Wu Jinrong / Huang Cailun' }, { 'id': '26921827', 'title': u'Find you', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2534471408.webp', 'rating': u'4.3', 'comment_count': 682, 'authors': u'Yao Chen / Mayi / Yuan Wenkang' }, { 'id': '26287884', 'title': u'Sorrow flows back into a river', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2529701498.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'Zhao Yingbo / Ren Min / Xin Yunlai' }, { 'id': '26287884', 'title': u'Burp teacher', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2535365481.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'rani ·Makkherjee / Neiraji·Cabi / Sachin ' } ] # TV play tvs = [ { 'id': '235434', 'title': u'Biography of Ruyi', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2460165077.jpg', 'rating': u'7.4', 'comment_count': 49328, 'authors': u'rani ·Makkherjee / Neiraji·Cabi / Sachin ' }, { 'id': '48373095', 'title': u'Season 5', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2534020405.jpg', 'rating': u'8.4', 'comment_count': 2483, 'authors': u'Ito Sally / Great annals of Zhongchuan / Upper primitive real moment / Picturesque and beautiful / Sakura Tiantong /' }, { 'id': '27005982', 'title': u'Dearest of you', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508399162.jpg', 'rating': u'7.6', 'comment_count': 25532, 'authors': u'Jesse·Premon / Molly·Shannon / Bradley·Whitford / Maude Apatow / Madison·Betty /' }, { 'id': '30290917', 'title': u'We can't be beasts', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2537556934.jpg', 'rating': u'3.7', 'comment_count': 8493, 'authors': u'Zhong Hanliang / Yang Ying / Gan Tingting / Sun Yizhou / Qihang /' }, { 'id': '292843', 'title': u'Adventure life', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2533929218.jpg', 'rating': u'8.2', 'comment_count': 23456, 'authors': u'Thomas·Hadden·Qiu Qi / Terence·Howard / Boyd ·Holbrooke / Reyes·Wickfield / Marlow ·Thomas /' } ] @app.route('/') def hello_world(): context = { "movies": movies, "tvs": tvs } return flask.render_template('index.html', **context) if __name__ == '__main__': app.run()
Here, you only need to render the data, that is, to pass * * context to the template.
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home page</title> <style> *{ padding: 0; margin: 0; list-style: none; text-decoration: none; font-family: "Microsoft Ya Hei"; } .page{ width: 375px; height: 667px; background: #d1fcff; } .page .searich-group{ padding: 14px 8px; background: #41b357; } .page .searich-group .search-input{ {# Block level elements #} display: block; height: 30px; width: 100%; background: #fff; {# Match the box as a whole #} box-sizing: border-box; {# Search box does not display #} border: none; {# Do not display the frame after clicking the search box #} outline: none; {# Border fillet #} border-radius: 5px; } .list-group{ background: #fff; padding: 17px 18px; } .list-group .group-top{ font-size: 18px; {# Get floating element #} overflow: hidden; } .group-top .group-title{ float: left; color: #000; } .group-top .more-btn{ float: right; } .any-group{ margin-top: 20px; overflow: hidden; } .any-group .item-group{ width: 100px; float: left; margin-right: 8px; } .item-group .thumbnail{ width: 100%; height: 140px; } .item-group .item-title{ text-align: center; margin-top: 12px; } .item-group .item-rating{ color: #acacac; text-align: center; font-size: 12px; } .item-rating img{ width: 10px; height: 10px; } </style> </head> <body> <div class="page"> {# Search box #} <div class="searich-group"> <input class="search-input" type="text" placeholder="Please enter query criteria"> </div> {# film #} <div class="list-group"> <div class="group-top"> <span class="group-title">film</span> <a href="#" class="more-btn">more</a> </div> <div class="any-group"> {% for movie in movies[0:3] %} <div class="item-group"> <img src="{{ movie.thumbnail }}" class="thumbnail" alt=""> <p class="item-title">{{ movie.title }}</p> <p class="item-rating"> {# Determine the number of whole stars #} {% set lights = ((movie.rating|int)/2)|int %} {# Determine the number of half stars #} {% set halfs = ((movie.rating|int)%2) %} {# Number of grey stars #} {% set grays = 5 - lights - halfs %} {# Rendering highlighted stars #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# Render semi bright stars #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# Rendering gray stars #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ movie.rating }} </p> </div> {% endfor %} </div> </div> {# TV play #} <div class="list-group"> <div class="group-top"> <span class="group-title">TV play</span> <a href="#" class="more-btn">more</a> </div> <div class="any-group"> {% for tv in tvs[0:3] %} <div class="item-group"> <img src="{{ tv.thumbnail }}" class="thumbnail" alt=""> <p class="item-title">{{ tv.title }}</p> <p class="item-rating"> {# Determine the number of whole stars #} {% set lights = ((tv.rating|int)/2)|int %} {# Determine the number of half stars #} {% set halfs = ((tv.rating|int)%2) %} {# Number of grey stars #} {% set grays = 5 - lights - halfs %} {# Rendering highlighted stars #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# Render semi bright stars #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# Rendering gray stars #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ tv.rating }} </p> </div> {% endfor %} </div> </div> </div> </body> </html>
The above code synthesizes the knowledge learned before, including: flash for loop, set template assignment and the rest are front-end content, which will not be described here too much.
- Analysis optimization
observation index.html Set the star display quantity code in. We found that the codes in the movie and TV series are basically the same. When encountering repeated codes, we need to think about optimization. Here we can use the macros we have learned to simplify the above Codes:
<div class="list-group"> <div class="group-top"> <span class="group-title">film</span> <a href="#" class="more-btn">more</a></div><div class="any-group"> {% for movie in movies[0:3] %} <div class="item-group"> <img src="{{ movie.thumbnail }}" class="thumbnail" alt=""> <p class="item-title">{{ movie.title }}</p> <p class="item-rating"> {# Determine the number of whole stars #} {% set lights = ((movie.rating|int)/2)|int %} {# Determine the number of half stars #} {% set halfs = ((movie.rating|int)%2) %} {# Number of grey stars #} {% set grays = 5 - lights - halfs %} {# Rendering highlighted stars #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# Render semi bright stars #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# Rendering gray stars #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ movie.rating }} </p> </div> {% endfor %}</div>
Extract the above code as a macro, and we find that there are only two changes - movies / TV series, movies/tvs, and the rest are the same, so we can pass these two as variables:
- First optimization - macro
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home page</title> <style> *{ padding: 0; margin: 0; list-style: none; text-decoration: none; font-family: "Microsoft Ya Hei"; } .page{ width: 375px; height: 667px; background: #d1fcff; } .page .searich-group{ padding: 14px 8px; background: #41b357; } .page .searich-group .search-input{ {# Block level elements #} display: block; height: 30px; width: 100%; background: #fff; {# Match the box as a whole #} box-sizing: border-box; {# Search box does not display #} border: none; {# Do not display the frame after clicking the search box #} outline: none; {# Border fillet #} border-radius: 5px; } .list-group{ background: #fff; padding: 17px 18px; } .list-group .group-top{ font-size: 18px; {# Get floating element #} overflow: hidden; } .group-top .group-title{ float: left; color: #000; } .group-top .more-btn{ float: right; } .any-group{ margin-top: 20px; overflow: hidden; } .any-group .item-group{ width: 100px; float: left; margin-right: 8px; } .item-group .thumbnail{ width: 100%; height: 140px; } .item-group .item-title{ text-align: center; margin-top: 12px; } .item-group .item-rating{ color: #acacac; text-align: center; font-size: 12px; } .item-rating img{ width: 10px; height: 10px; } </style> </head> <body> {% macro listGroup(category, items) %} <div class="list-group"> <div class="group-top"> <span class="group-title">{{ category }}</span> <a href="#"Class =" more BTN "> more</a> </div> <div class="any-group"> {% for item in items[0:3] %} <div class="item-group"> <img src="{{ item.thumbnail }}" class="thumbnail" alt=""> <p class="item-title">{{ item.title }}</p> <p class="item-rating"> {# Determine the number of whole stars #} {% set lights = ((item.rating|int)/2)|int %} {# Determine the number of half stars #} {% set halfs = ((item.rating|int)%2) %} {# Number of grey stars #} {% set grays = 5 - lights - halfs %} {# Rendering highlighted stars #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# Render semi bright stars #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# Rendering gray stars #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ item.rating }} </p> </div> {% endfor %} </div> </div> {% endmacro %} <div class="page"> {# Search box #} <div class="searich-group"> <input class="search-input" type="text" placeholder="Please enter query criteria"> </div> {# film #} {{ listGroup('film', movies) }} {# TV play #} {{ listGroup('TV play', tvs) }} </div> </body> </html>
Above we used the macro to optimize the home code for the first time. If we have other pages now, imagine the search box on the front page
And page background
Can other pages be extracted for public use and implemented by inheritance when they are applied? The answer is yes.
So we're building a new one base.html File, and the page layout code, put forward, and think again, since the name is public, it means that other code can also inherit this base.html , then the page content:
Is this part of the code no longer available base.html Yes, but we are going again base.html Insert part of the code in the figure above. What do you want to use? block, right. In addition, according to the habit, we also extract the style in the form of a file. At this time, the header search style and the content part style cannot be extracted in one file. Because all the codes will be loaded in one file every time, so there is no need to load the content style in the head, so we extract the styles into CSS files respectively. One is to search Column and page background, named base.css :
*{ padding: 0; margin: 0; list-style: none; text-decoration: none; font-family: "Microsoft Ya Hei";}.page{ width: 375px; height: 667px; background: #d1fcff;}.page .searich-group{ padding: 14px 8px; background: #41b357;}.page .searich-group .search-input{ /* {# Block level element */ display: block; height: 30px; width: 100%; background: #fff; /* {# Match the box as a whole */ box-sizing: border-box; /* {# Search box does not show ×} */ border: none; /* {# Do not display the border after clicking the search box */ outline: none; /* {# Border fillet */ border-radius: 5px;}
The other is page style, named index_page.css :
.list-group{ background: #fff; padding: 17px 18px;}.list-group .group-top{ font-size: 18px; /* {# Get floating element ×} */ overflow: hidden;}.group-top .group-title{ float: left; color: #000;}.group-top .more-btn{ float: right;}.any-group{ margin-top: 20px; overflow: hidden;}.any-group .item-group{ width: 100px; float: left; margin-right: 8px;}.item-group .thumbnail{ width: 100%; height: 140px;}.item-group .item-title{ text-align: center; margin-top: 12px;}.item-group .item-rating{ color: #acacac; text-align: center; font-size: 12px;}.item-rating img{ width: 10px; height: 10px;}
Create a new css folder under the static folder, and then create the above two files respectively:
To sum up, we finally base.html The file code should be as follows:
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>home page</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}"> {% block head %}{% endblock %} </head> <body> <div class="page"> {# Search box #} <div class="searich-group"> <input class="search-input" type="text" placeholder="Please enter query criteria"> </div> {% block content %}{% endblock %} </div> </body> </html>
The block head is filled with the style code of the content part.
Now that the public part has been extracted, go back to index.html , we found that all we had to do was
1. Inheritance base.html
2. Fill block
Just.
index.html
{% extends 'base.html' %} {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='css/index_page.css') }}"> {% endblock %} {% block content %} {% macro listGroup(category, items) %} <div class="list-group"> <div class="group-top"> <span class="group-title">{{ category }}</span> <a href="#"Class =" more BTN "> more</a> </div> <div class="any-group"> {% for item in items[0:3] %} <div class="item-group"> <img src="{{ item.thumbnail }}" class="thumbnail" alt=""> <p class="item-title">{{ item.title }}</p> <p class="item-rating"> {# Determine the number of whole stars #} {% set lights = ((item.rating|int)/2)|int %} {# Determine the number of half stars #} {% set halfs = ((item.rating|int)%2) %} {# Number of grey stars #} {% set grays = 5 - lights - halfs %} {# Rendering highlighted stars #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# Render semi bright stars #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# Rendering gray stars #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ item.rating }} </p> </div> {% endfor %} </div> </div> {% endmacro %} {# film #} {{ listGroup('film', movies) }} {# TV play #} {{ listGroup('TV play', tvs) }} {% endblock %}
Execute the file, and the page display will not change.
Then we will complete more modules. Click more and the page will display as shown above.
Let's analyze the above page first. We found that except for some changes in the image area below the search bar, the rest are base.html So we first thought that we could inherit base.html , and the image display rule is exactly the same as the macro we defined earlier, so we can import the written macro.
So we first create a new one under the templates folder moreList.html File:
We have base.html The block is reserved in, so the new layout of the page only needs to be inserted through the block:
moreList.html
{% extends 'base.html' %} {% from 'macros/macros.html' import itemGroup %} {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='css/item.css') }}"> <style> .content{ padding: 25px 10px; } </style> {% endblock %} {% block content %} <div class="content"> {% for item in items %} {{ itemGroup(item) }} {% endfor %} </div> {% endblock %}
If for software testing, interface testing, automation testing, interview experience exchange. If you are interested, you can add software test exchange: 1085991341, and there will be technical exchanges with peers.
Of course, we need to add more links. Let's define the function first:
@app.route('/list/<int:category>/')def itemList(category): # If category equals 1: return to movie # If category equals 2: return to the show # Otherwise, an empty array is returned items = [] if category == 1: items = movies elif category == 2: items = tvs else: items = [] return flask.render_template('moreList.html', items=items)
Here we add an integer category parameter, which is convenient for us to distinguish whether the entered page is a movie or a TV play macros.html More links need to be added to the file:
<a href="{{ url_for('itemList', category=category) }}" class="more-btn">more</a>
This will complete the page Jump after clicking more and the page layout after jump.
The above is a complete practical operation of a project. I hope the above content can help you. If you have any friends who have been helped, please comment.