完整版模板项目实战【实战演练】

今天给你们带来的是模板项目实战,先给你们看一下效果图javascript

说明:css

  • 点击图片后会跳转到对应的详情页面html

  • 数据:前端

movies = [
    {
        'id': '34532', 'title': u'胖子行动队', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2526215398.webp', 'rating': u'7.6', 'comment_count': 39450, 'authors': u'宝贝儿 / 李成敏 Clara Lee / 文章 Zhang Wen' }, { 'id': '394558', 'title': u'李茶的姑妈', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2533384240.webp', 'rating': u'6.3', 'comment_count': 38409, 'authors': u'钱晨光 / 吴瑾蓉 / 黄才伦' }, { 'id': '26921827', 'title': u'找到你', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2534471408.webp', 'rating': u'4.3', 'comment_count': 682, 'authors': u'姚晨 / 马伊琍 / 袁文康' }, { 'id': '26287884', 'title': u'悲伤逆流成河', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2529701498.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'赵英博 / 任敏 / 辛云来' }, { 'id': '26287884', 'title': u'嗝嗝老师', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2535365481.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'拉妮·玛克赫吉 / 内拉吉·卡比 / 萨钦' } ] # 电视剧 tvs = [ { 'id': '235434', 'title': u'如懿传', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2460165077.jpg', 'rating': u'7.4', 'comment_count': 49328, 'authors': u'拉妮·玛克赫吉 / 内拉吉·卡比 / 萨钦' }, { 'id': '48373095', 'title': u'奇葩说第五季', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2534020405.jpg', 'rating': u'8.4', 'comment_count': 2483, 'authors': u'伊藤沙莉 / 中川大志 / 上原实矩 / 森绘梨佳 / 樱田通 /' }, { 'id': '27005982', 'title': u'最亲爱的你', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508399162.jpg', 'rating': u'7.6', 'comment_count': 25532, 'authors': u'杰西·普莱蒙 / 莫莉·香侬 / 布莱德利·惠特福德 / Maude Apatow / 麦迪逊·贝蒂 /' }, { 'id': '30290917', 'title': u'咱们没法成为野兽', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2537556934.jpg', 'rating': u'3.7', 'comment_count': 8493, 'authors': u'钟汉良 / 杨颖 / 甘婷婷 / 孙艺洲 / 亓航 /' }, { 'id': '292843', 'title': u'奇遇人生', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2533929218.jpg', 'rating': u'8.2', 'comment_count': 23456, 'authors': u'托马斯·哈登·丘奇 / 泰伦斯·霍华德 / 波伊德·霍布鲁克 / 瑞斯·维克菲尔德 / 马尔洛·托马斯 /' } ] 
  • 说明
  1. 页面只显示三个java

  2. 下面浅蓝色为背景色。python

咱们先来完成首页的功能web

你们能够先本身试着作一下,而后再看船长的代码:面试

先新建一个项目microProflask

app.py数组

# coding: utf-8 from flask import Flask import flask app = Flask(__name__) # type: Flask app.debug = True # 电影 movies = [ { 'id': '34532', 'title': u'胖子行动队', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2526215398.webp', 'rating': u'7.6', 'comment_count': 39450, 'authors': u'宝贝儿 / 李成敏 Clara Lee / 文章 Zhang Wen' }, { 'id': '394558', 'title': u'李茶的姑妈', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2533384240.webp', 'rating': u'6.3', 'comment_count': 38409, 'authors': u'钱晨光 / 吴瑾蓉 / 黄才伦' }, { 'id': '26921827', 'title': u'找到你', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2534471408.webp', 'rating': u'4.3', 'comment_count': 682, 'authors': u'姚晨 / 马伊琍 / 袁文康' }, { 'id': '26287884', 'title': u'悲伤逆流成河', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2529701498.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'赵英博 / 任敏 / 辛云来' }, { 'id': '26287884', 'title': u'嗝嗝老师', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2535365481.webp', 'rating': u'7.5', 'comment_count': 33060, 'authors': u'拉妮·玛克赫吉 / 内拉吉·卡比 / 萨钦' } ] # 电视剧 tvs = [ { 'id': '235434', 'title': u'如懿传', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2460165077.jpg', 'rating': u'7.4', 'comment_count': 49328, 'authors': u'拉妮·玛克赫吉 / 内拉吉·卡比 / 萨钦' }, { 'id': '48373095', 'title': u'奇葩说第五季', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2534020405.jpg', 'rating': u'8.4', 'comment_count': 2483, 'authors': u'伊藤沙莉 / 中川大志 / 上原实矩 / 森绘梨佳 / 樱田通 /' }, { 'id': '27005982', 'title': u'最亲爱的你', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508399162.jpg', 'rating': u'7.6', 'comment_count': 25532, 'authors': u'杰西·普莱蒙 / 莫莉·香侬 / 布莱德利·惠特福德 / Maude Apatow / 麦迪逊·贝蒂 /' }, { 'id': '30290917', 'title': u'咱们没法成为野兽', 'thumbnail': u'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2537556934.jpg', 'rating': u'3.7', 'comment_count': 8493, 'authors': u'钟汉良 / 杨颖 / 甘婷婷 / 孙艺洲 / 亓航 /' }, { 'id': '292843', 'title': u'奇遇人生', 'thumbnail': u'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2533929218.jpg', 'rating': u'8.2', 'comment_count': 23456, 'authors': u'托马斯·哈登·丘奇 / 泰伦斯·霍华德 / 波伊德·霍布鲁克 / 瑞斯·维克菲尔德 / 马尔洛·托马斯 /' } ] @app.route('/') def hello_world(): context = { "movies": movies, "tvs": tvs } return flask.render_template('index.html', **context) if __name__ == '__main__': app.run() 

这里只须要渲染数据便可,即将**context传给模板。

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</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{ {# 块级元素 #} display: block; height: 30px; width: 100%; background: #fff; {# 与盒子总体匹配 #} box-sizing: border-box; {# 搜索框不显示 #} border: none; {# 鼠标点击搜索框后不显示边框 #} outline: none; {# 边框圆角 #} border-radius: 5px; } .list-group{ background: #fff; padding: 17px 18px; } .list-group .group-top{ font-size: 18px; {# 获取浮动元素 #} 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"> {# 搜索框 #} <div class="searich-group"> <input class="search-input" type="text" placeholder="请输入查询条件"> </div> {# 电影 #} <div class="list-group"> <div class="group-top"> <span class="group-title">电影</span> <a href="#" class="more-btn">更多</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"> {# 肯定整星个数 #} {% set lights = ((movie.rating|int)/2)|int %} {# 肯定半个星个数 #} {% set halfs = ((movie.rating|int)%2) %} {# 灰色星星个数 #} {% set grays = 5 - lights - halfs %} {# 渲染高亮星星 #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# 渲染半高亮星星 #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# 渲染灰色星星 #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ movie.rating }} </p> </div> {% endfor %} </div> </div> {# 电视剧 #} <div class="list-group"> <div class="group-top"> <span class="group-title">电视剧</span> <a href="#" class="more-btn">更多</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"> {# 肯定整星个数 #} {% set lights = ((tv.rating|int)/2)|int %} {# 肯定半个星个数 #} {% set halfs = ((tv.rating|int)%2) %} {# 灰色星星个数 #} {% set grays = 5 - lights - halfs %} {# 渲染高亮星星 #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# 渲染半高亮星星 #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# 渲染灰色星星 #} {% 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> 

上面代码综合了以前学过的知识,包括:flask for 循环set模板赋值其他都是前端的内容,这里不作过多的阐述。

  • 分析优化

观察index.html中设置星星显示数量代码,咱们发如今电影和电视剧两部分的代码是大致一致的,遇到重复代码就要想到优化,这里就能够用到咱们学过的来简化上面的代码:

<div class="list-group"> <div class="group-top"> <span class="group-title">电影</span> <a href="#" class="more-btn">更多</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"> {# 肯定整星个数 #} {% set lights = ((movie.rating|int)/2)|int %} {# 肯定半个星个数 #} {% set halfs = ((movie.rating|int)%2) %} {# 灰色星星个数 #} {% set grays = 5 - lights - halfs %} {# 渲染高亮星星 #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# 渲染半高亮星星 #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# 渲染灰色星星 #} {% for light in range(0, grays) %} <img src="{{ url_for('static', filename='img/rate_gray.png') }}"> {% endfor %} {{ movie.rating }} </p> </div> {% endfor %}</div> 

将以上代码提取出来做为宏,咱们发现变化的只有两个——电影/电视剧movies/tvs,其他都同样,因此咱们能够将这两个做为变量传入:

  • 第一次优化——宏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</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{ {# 块级元素 #} display: block; height: 30px; width: 100%; background: #fff; {# 与盒子总体匹配 #} box-sizing: border-box; {# 搜索框不显示 #} border: none; {# 鼠标点击搜索框后不显示边框 #} outline: none; {# 边框圆角 #} border-radius: 5px; } .list-group{ background: #fff; padding: 17px 18px; } .list-group .group-top{ font-size: 18px; {# 获取浮动元素 #} 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">更多</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"> {# 肯定整星个数 #} {% set lights = ((item.rating|int)/2)|int %} {# 肯定半个星个数 #} {% set halfs = ((item.rating|int)%2) %} {# 灰色星星个数 #} {% set grays = 5 - lights - halfs %} {# 渲染高亮星星 #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# 渲染半高亮星星 #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# 渲染灰色星星 #} {% 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"> {# 搜索框 #} <div class="searich-group"> <input class="search-input" type="text" placeholder="请输入查询条件"> </div> {# 电影 #} {{ listGroup('电影', movies) }} {# 电视剧 #} {{ listGroup('电视剧', tvs) }} </div> </body> </html> 

上面咱们利用将首页代码进行了第一次优化。若是咱们如今还有其余页面,试想一下,首页上面的搜索框

以及页面背景

是否能够提取为公用的,其余页面在应用到的时候经过继承来实现呢?答案是确定的。

因此咱们如今新建base.html文件,而且将页面布局代码,提出,再想一下,既然名为公用也就意味着其余代码也能够继承这个base.html,那么页面内容:

这部分代码是否是就不能够再在base.html里了【答:是】,可是咱们又要往base.html这里面插入上图部分代码,那要用什么呀?block对吧。此外,按照习惯,咱们一样将样式style以文件的形式提取出来,此时头部搜索样式与内容部分样式确定是不能提取在一个文件里的,由于在一个文件里每次都会加载全部的代码,这样在head中就不必加载内容的样式,因此咱们把样式分别提取成css文件,一个是搜索栏和页面背景,命名为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{ /* {# 块级元素 #} */ display: block; height: 30px; width: 100%; background: #fff; /* {# 与盒子总体匹配 #} */ box-sizing: border-box; /* {# 搜索框不显示 #} */ border: none; /* {# 鼠标点击搜索框后不显示边框 #} */ outline: none; /* {# 边框圆角 #} */ border-radius: 5px;} 

另外一个是页面样式,命名为index_page.css

.list-group{ background: #fff; padding: 17px 18px;}.list-group .group-top{ font-size: 18px; /* {# 获取浮动元素 #} */ 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;} 

static文件夹下新建css文件夹,而后分别新建以上两个文件:

综上,咱们最后base.html文件代码应该以下:

base.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}"> {% block head %}{% endblock %} </head> <body> <div class="page"> {# 搜索框 #} <div class="searich-group"> <input class="search-input" type="text" placeholder="请输入查询条件"> </div> {% block content %}{% endblock %} </div> </body> </html> 

其中block head填充的是内容部分的样式代码。
如今公用部分已经提取好,回到index.html,咱们发现要作的工做只须要

1.继承`base.html` 2\. 填充`block` 

便可。

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">更多</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"> {# 肯定整星个数 #} {% set lights = ((item.rating|int)/2)|int %} {# 肯定半个星个数 #} {% set halfs = ((item.rating|int)%2) %} {# 灰色星星个数 #} {% set grays = 5 - lights - halfs %} {# 渲染高亮星星 #} {% for light in range(0, lights) %} <img src="{{ url_for('static', filename='img/rate_light.png') }}"> {% endfor %} {# 渲染半高亮星星 #} {% for light in range(0, halfs) %} <img src="{{ url_for('static', filename='img/rate_half.jpg') }}"> {% endfor %} {# 渲染灰色星星 #} {% 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 %} {# 电影 #} {{ listGroup('电影', movies) }} {# 电视剧 #} {{ listGroup('电视剧', tvs) }} {% endblock %} 

执行文件,页面显示不变。

 

接着咱们来完成更多的模块,点击更多后页面显示效果如上图。

咱们先来分析上面这个页面,咱们发现除了搜索栏下面的图片区域有些变化之外,其他都是base.html的布局,因此咱们首先想到能够继承base.html,而图片显示规则则和咱们前面定义过的彻底一致,咱们就能够导入写好的
因此咱们先在templates文件夹下新建moreList.html文件:

咱们已经在base.html中保留了block,因此页面新的布局只须要经过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 %} 

若是对软件测试、接口测试、自动化测试、面试经验交流。感兴趣能够加软件测试交流:1085991341,还会有同行一块儿技术交流。
固然,咱们还要将更多加上连接,咱们先定义函数:

@app.route('/list/<int:category>/')def itemList(category): # 若是category等于1:返回电影 # 若是category等于2:返回电视剧 # 不然返回空数组 items = [] if category == 1: items = movies elif category == 2: items = tvs else: items = [] return flask.render_template('moreList.html', items=items) 

这里咱们新加了一个整型的category参数,方便咱们对进入的页面究竟是电影仍是电视剧进行分辨,在macros.html文件中须要加上更多的连接:

<a href="{{ url_for('itemList', category=category) }}" class="more-btn">更多</a> 

这样就会完成点击更多后的页面跳转和跳转后的页面布局了。以上就是一个完整的一个项目实战实操,以上内容但愿对你有帮助,有被帮助到的朋友欢迎点赞,评论。

相关文章
相关标签/搜索