页面完成后的最终布局

电影视频网站首页面

会员登录页面

会员注册页面

点击退出和会员按钮,直接进入会员登录页面

视频播放页面

可以看到,页面共同的部分是顶部导航和底部导航

所以我们可以把页面顶部导航和底部导航部分单独定义一个文件home.html,然后让需要使用顶部导航和底部导航的页面都继承home.html页面

1.创建父模板home.html

在templates目录的home目录下创建home.html页面,用来定义页面顶部导航和底部导航部分

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1 , user-scalable=no">
<title>微电影</title>
<link rel="shortcut icon" href="{{ url_for('static',filename='base/images/logo.png') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/bootstrap-movie.css') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/animate.css') }}">
<style>
.navbar-brand > img {
display: inline;
} .media {
padding: 3px;
border: 1px solid #ccc
}
</style>
</head> {% block css %} {% endblock %} <body>
<!--导航-->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<!--小屏幕导航按钮和logo-->
<div class="navbar-header">
<button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="{{ url_for('home.index',page=1) }}" class="navbar-brand" style="width:250px;">
<img src="{{ url_for('static',filename='base/images/logo.png') }}" style="height:30px;">&nbsp;微电影
</a>
</div>
<!--小屏幕导航按钮和logo-->
<!--导航-->
<div class="navbar-collapse collapse">
<form class="navbar-form navbar-left" role="search" style="margin-top:18px;">
<div class="form-group input-group">
<input type="text" class="form-control" placeholder="请输入电影名!">
<span class="input-group-btn">
<a class="btn btn-default" id='do-search'><span
class="glyphicon glyphicon-search"></span>&nbsp;搜索</a>
</span>
</div>
</form>
<ul class="nav navbar-nav navbar-right">
<li>
<a class="curlink" href="{{ url_for('home.index',page=1) }}"><span
class="glyphicon glyphicon-film"></span>&nbsp;电影</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.login') }}"><span
class="glyphicon glyphicon-log-in"></span>&nbsp;登录</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.register') }}"><span
class="glyphicon glyphicon-plus"></span>&nbsp;注册</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.logout') }}"><span
class="glyphicon glyphicon-log-out"></span>&nbsp;退出</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.user') }}"><span class="glyphicon glyphicon-user"></span>&nbsp;会员</a>
</li>
</ul>
</div>
<!--导航-->
</div>
</nav>
<!--导航-->
<!--内容-->
<div class="container" style="margin-top:76px">
{% block content %} {% endblock %}
</div>
<!--内容-->
<!--底部-->
<footer>
<div class="container">
<div class="row">
<div class="col-md-12">
<p>
©&nbsp;2017&nbsp;flaskmovie.com&nbsp;京ICP备 123456789号
</p>
</div>
</div>
</div>
</footer>
<!--底部-->
<script src="{{ url_for('static',filename='base/js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/jquery.singlePageNav.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/wow.min.js') }}"></script>
<script src="{{ url_for('static',filename='lazyload/jquery.lazyload.min.js') }}"></script>
<script src="//cdn.bootcss.com/holder/2.9.4/holder.min.js"></script>
<script>
$(function () {
new WOW().init();
})
</script>
<script>
$(document).ready(function () {
$("img.lazy").lazyload({
effect: "fadeIn"
});
$("#do_search").click(function () {
var key = $("#key_movie").val();
location.href = "{{ url_for('home.search',page=1) }}?key=" + key;
});
});
</script>
{% block js %} {% endblock %}
</body>
</html>

2. 完成登录页面

2.1 定义登录视图函数login

在home目录下创建forms.py文件,用来定义登录的表单LoginForm

可以通过调用LoginForm表单类直接在前端页面上渲染生成登录需要的字段标签

from flask_wtf import FlaskForm
from wtforms.fields import StringField, PasswordField, SubmitField, FileField, TextAreaField
from wtforms.validators import DataRequired, EqualTo, Email, Regexp, ValidationError from app.models import User class LoginForm(FlaskForm):
name = StringField(
label="账号",
validators=[
DataRequired("请输入帐号!")
],
description="账号",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入帐号!"
}
)
pwd = PasswordField(
label="密码",
validators=[
DataRequired("请输入密码!")
],
description="密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入密码!",
}
)
submit = SubmitField(
"登录",
render_kw={
"class": "btn btn-lg btn-primary btn-block"
}
) def validate_name(self, field):
name = field.data
user = User.query.filter_by(name=name).count()
if user == 0:
raise ValidationError("会员账号不存在!") def validata_pwd(self, field):
from app.models import User
pwd = field.data
name = self.name.data
user = User.query.filter_by(name=name).count()
if not user.check_pwd(pwd):
raise ValidationError("密码错误!")

2.2 定义登录视图函数login

@home.route("/login/", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit(): # 如果用户输入的用户名和密码符合验证条件
data = form.data # 获取用户输入的表单数据
user = User.query.filter_by(name=data.get("name")).first() # 根据用户名查询数据库,返回第一个查询结果
if user == None: # 如果从数据库中查不到用户名
flash("会员账号不存在,请重新输入!", "err")
return redirect(url_for("home.login"))
elif not user.check_pwd(data.get("pwd")): # 如果从数据库查询到用户名但密码不匹配
flash("用户名或密码错误!", "err")
return redirect(url_for("home.login"))
session['user'] = user.name # 定义session信息
session['user_id'] = user.id
userlog = Userlog( # 定义用户登录日志
user_id=user.id,
ip=request.remote_addr
)
db.session.add(userlog) # 添加用户登录日志
db.session.commit()
return redirect(url_for("home.user"))
return render_template("home/login.html", form=form)

2.3 在home目录下创建登录前端页面login.html,继承home.html页面

{% extends "home/home.html" %}

{% block content %}
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><span class="glyphicon glyphicon-log-in"></span>&nbsp;会员登录</h3>
</div>
<div class="panel-body">
<!--消息闪现-->
{% for msg in get_flashed_messages(category_filter=["err"]) %}
<p style="color:red">{{ msg }}</p>
{% endfor %} {% for msg in get_flashed_messages(category_filter=["ok"]) %}
<p style="color:green">{{ msg }}</p>
{% endfor %} <form role="form" method="post">
<fieldset>
<div class="form-group">
<label for="input_contact"><span
class="glyphicon glyphicon-user"></span>&nbsp;{{ form.name.label }}</label>
{{ form.name }}
</div>
<!--错误提示-->
{% for err in form.name.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
<div class="form-group">
<label for="input_password"><span
class="glyphicon glyphicon-lock"></span>&nbsp;{{ form.pwd.label }}</label>
{{ form.pwd }}
</div>
<!--错误提示-->
{% for err in form.pwd.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
{{ form.csrf_token }}
{{ form.submit }}
</fieldset>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

3. 完成退出页面

3.1 定义退出视图函数logout

@home.route("/logout/")
def logout():
session.pop("user", None) # 从session中删除用户名
session.pop("user_id", None) # 从session中删除用户id
return redirect(url_for("home.login"))

3.2 在home目录下创建登录前端页面logout.html,继承home.html页面

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1 , user-scalable=no">
<title>微电影</title>
<link rel="shortcut icon" href="{{ url_for('static',filename='base/images/logo.png') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/bootstrap-movie.css') }}">
<link rel="stylesheet" href="{{ url_for('static',filename='base/css/animate.css') }}">
<style>
.navbar-brand > img {
display: inline;
} .media {
padding: 3px;
border: 1px solid #ccc
} </style>
{% block css %}{% endblock %}
</head> <body>
<!--导航-->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<!--小屏幕导航按钮和logo-->
<div class="navbar-header">
<button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="{{ url_for('home.index',page=1) }}" class="navbar-brand" style="width:250px;">
<img src="{{ url_for('static',filename='base/images/logo.png') }}" style="height:30px;">&nbsp;微电影
</a>
</div>
<!--小屏幕导航按钮和logo-->
<!--导航-->
<div class="navbar-collapse collapse">
<form class="navbar-form navbar-left" role="search" style="margin-top:18px;">
<div class="form-group input-group">
<input type="text" class="form-control" placeholder="请输入电影名!" id="key_movie">
<span class="input-group-btn">
<a class="btn btn-default" id="do_search"><span class="glyphicon glyphicon-search"></span>&nbsp;搜索</a>
</span>
</div>
</form>
<ul class="nav navbar-nav navbar-right">
<li>
<a class="curlink" href="{{ url_for('home.index',page=1) }}"><span
class="glyphicon glyphicon-film"></span>&nbsp;电影</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.login') }}"><span
class="glyphicon glyphicon-log-in"></span>&nbsp;登录</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.regist') }}"><span
class="glyphicon glyphicon-plus"></span>&nbsp;注册</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.logout') }}"><span
class="glyphicon glyphicon-log-out"></span>&nbsp;退出</a>
</li>
<li>
<a class="curlink" href="{{ url_for('home.user') }}"><span class="glyphicon glyphicon-user"></span>&nbsp;会员</a>
</li>
</ul>
</div>
<!--导航--> </div>
</nav>
<!--导航-->
<!--内容--> {% block content %}
{% endblock %} <!--内容-->
<!--底部-->
<footer>
<div class="container">
<div class="row">
<div class="col-md-12">
<p>
©&nbsp;2017&nbsp;flaskmovie.com&nbsp;京ICP备 123456789号
</p>
</div>
</div>
</div>
</footer>
<!--底部-->
<script src="{{ url_for('static',filename='base/js/jquery.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/jquery.singlePageNav.min.js') }}"></script>
<script src="{{ url_for('static',filename='base/js/wow.min.js') }}"></script>
<script src="{{ url_for('static',filename='lazyload/jquery.lazyload.min.js') }}"></script>
<script src="//cdn.bootcss.com/holder/2.9.4/holder.min.js"></script>
<script>
$(function () {
new WOW().init();
}) </script>
<script>
$(document).ready(function () {
$("img.lazy").lazyload({
effect: "fadeIn"
});
$("#do_search").click(function () {
var key = $("#key_movie").val();
location.href = "{{ url_for('home.search',page=1) }}?key=" + key;
});
}); </script> {% block js %}{% endblock %} </body>
</html>

4. 完成注册页面

4.1 在home目录下的forms.py文件中,定义注册用的表单类RegistForm

可以通过调用RegistForm类直接在前端页面渲染生成注册使用的字段标签

from flask_wtf import FlaskForm
from wtforms.fields import StringField, PasswordField, SubmitField, FileField, TextAreaField
from wtforms.validators import DataRequired, EqualTo, Email, Regexp, ValidationError from app.models import User class RegistForm(FlaskForm):
name = StringField(
label="呢称",
validators=[
DataRequired("请输入呢称!")
],
description="呢称",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入呢称!",
}
)
email = StringField(
label="邮箱",
validators=[
DataRequired("请输入邮箱!"),
Email("邮箱格式不正确!"),
],
description="邮箱",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入邮箱!"
}
)
phone = StringField(
label="手机号",
validators=[
DataRequired("请输入手机号!"),
Regexp("1[34578]\\d{9}", message="输入的手机号格式不正确!"),
],
description="手机号",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入手机号!"
}
)
pwd = PasswordField(
label="密码",
validators=[
DataRequired("请输入密码!")
],
description="密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入密码!"
}
)
repwd = PasswordField(
label="确认密码",
validators=[
DataRequired("请输入确认密码!"),
EqualTo("pwd", message="两次密码不一致!")
],
description="确认密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入确认密码!"
}
)
submit = SubmitField(
"注册",
render_kw={
"class": "btn btn-lg btn-success btn-block"
}
) def validate_name(self, field):
name = field.data
user = User.query.filter_by(name=name).count()
if user == 1:
raise ValidationError("呢称已经存在,请重新输入!") def validate_email(self, field):
email = field.data
user = User.query.filter_by(email=email).count()
if user == 1:
raise ValidationError("邮箱已经存在,请重新输入!") def validate_phone(self, field):
phone = field.data
user = User.query.filter_by(phone=phone).count()
if user == 1:
raise ValidationError("手机号已经存在,请重新输入!")

4.2 定义注册视图函数register

@home.route("/register/", methods=["GET", "POST"])
def register():
form = RegistForm() # 获取用户输入的注册信息数据
if form.validate_on_submit(): # 如果用户输入的注册数据通过form基础验证
data = form.data # 获取用户输入的表单数据
user = User(
name=data.get("name"), # 从表单中获取用户输入的用户名
email=data.get("email"), # 从表单中获取用户输入的邮箱地址
phone=data.get("phone"), # 从表单中获取用户输入的手机号
pwd=generate_password_hash(data.get("pwd")), # 从表单中获取用户输入的密码并进行加密
uuid=uuid.uuid4().hex # 生成uuid,保证唯一性
)
db.session.add(user) # 添加用户
db.session.commit() # 向数据库提交用户注册信息
flash("注册成功!", "ok")
return redirect(url_for("home.login"))
return render_template("home/register.html", form=form)

4.3 在home目录下创建登录前端页面register.html,继承home.html页面

{% extends 'home/home.html' %}

{% block content %}
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"><span class="glyphicon glyphicon-plus"></span>&nbsp;会员注册</h3>
</div>
<div class="panel-body">
<!--消息闪现-->
{% for msg in get_flashed_messages(category_filter=["err"]) %}
<p style="color:red">{{ msg }}</p>
{% endfor %} {% for msg in get_flashed_messages(category_filter=["ok"]) %}
<p style="color:green">{{ msg }}</p>
{% endfor %}
<form role="form" method="post">
<fieldset>
<div class="form-group">
<label for="input_name"><span
class="glyphicon glyphicon-user"></span>&nbsp;{{ form.name.label }}</label>
{{ form.name }}
</div>
<!--错误提示-->
{% for err in form.name.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
<div class="form-group">
<label for="input_email"><span
class="glyphicon glyphicon-envelope"></span>&nbsp;{{ form.email.label }}</label>
{{ form.email }}
</div>
<!--错误提示-->
{% for err in form.email.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
<div class="form-group">
<label for="input_phone"><span
class="glyphicon glyphicon-phone"></span>&nbsp;{{ form.phone.label }}</label>
{{ form.phone }}
</div>
<!--错误提示-->
{% for err in form.phone.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
<div class="form-group">
<label for="input_password"><span
class="glyphicon glyphicon-lock"></span>&nbsp;{{ form.pwd.label }}</label>
{{ form.pwd }}
</div>
<!--错误提示-->
{% for err in form.pwd.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
<div class="form-group">
<label for="input_repassword"><span
class="glyphicon glyphicon-lock"></span>&nbsp;{{ form.repwd.label }}</label>
{{ form.repwd }}
</div>
<!--错误提示-->
{% for err in form.repwd.errors %}
<div class="col-md-12">
<font style="color:red">{{ err }}</font>
</div>
{% endfor %}
{{ form.submit }}
{{ form.csrf_token }}
</fieldset>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

5. 完成index页面

5.1 定义主页视图函数index

@home.route("/<int:page>/", methods=['GET'])
def index(page=None):
tags = Tag.query.all() # 获取数据库中所有的电影标签
page_data = Movie.query # 从数据库中获取所有的电影信息 tid = request.args.get("tid", 0) # 获取用户请求的电影标签id
if int(tid) != 0:
page_data = page_data.filter_by(tag_id=int(tid)) # 根据用户请求的页码进行过滤 star = request.args.get("star", 0) # 获取用户请求的电影星级id
if int(star) != 0:
page_data = page_data.filter(star=int(star)) # 根据用户请求的电影星级id进行过滤 time = request.args.get("time", 0) # 获取用户请求的电影添加时间
if int(time) != 0:
page_data = page_data.order_by(Movie.addtime) # 获取用户请求的电影添加时间进行过滤 pm = request.args.get("pm", 0) # 获取用户请求的电影播放次数
if int(pm) != 0:
page_data = page_data.order_by(Movie.playnum) # 获取用户请求的电影播放次数进行过滤 cm = request.args.get("cm", 0) # 获取用户请求的电影评论次数
if int(cm) != 0:
page_data = page_data.order_by(Movie.commentnum) # 获取用户请求的电影评论次数进行过滤 if page is None: # 获取用户请求的页数
page = 1
page_data = page_data.paginate(page=page, per_page=10) # 进行分页,每页显示10条电影数据 p = dict(
tid=tid,
star=star,
time=time,
pm=pm,
cm=cm
) # 定义返回给前端页面的字典信息
return render_template("home/index.html", tags=tags, p=p, page_data=page_data)

5.2 在templates目录下创建ui目录,在ui目录下创建home_page.html,定义分页显示组件

{% macro page(data,url) -%}

    {% if data %}
<nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="{{ url_for(url,page=1) }}">首页</a></li>
{% if data.has_prev %}
<li><a href="{{ url_for(url,page=data.prev_num) }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="#">上一页</li>
{% endif %} {% for v in data.iter_pages() %}
{% if v == data.page %}
<li class="active"><a href="#">{{ v }}</a></li>
{% else %}
<li><a href="{{ url_for(url,page=v) }}">{{ v }}</a></li>
{% endif %}
{% endfor %} {% if data.has_next %}
<li><a href="{{ url_for(url,page=data.next_num) }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="#">下一页</a></li>
{% endif %} <li><a href="{{ url_for(url,page=data.pages) }}">尾页</a></li>
</ul>
</nav>
{% endif %}
{%- endmacro %}

5.3 在home目录下创建登录前端页面index.html,继承home.html页面

{% extends "home/layout.html" %}
{% import "ui/home_page.html" as pg %} {% block content %}
<!--热门电影-->
<section id="hotmovie" style="margin-top:76px">
<div class="container">
<div class="row wow fadeInRight" data-wow-delay="0.6s">
<div class="row">
<iframe class="wow fadeIn" width="100%" height="375px" frameborder=0 scrolling=no
src="{{ url_for('home.animation') }}"></iframe>
</div>
</div>
</div>
</section>
<!--热门电影-->
<!--电影列表-->
<section id="movielist">
<div class="container">
<div class="row wow fadeIn" data-wow-delay="0.6s">
<div class="col-md-12 table-responsive">
<table class="table text-left table-bordered" id="movietags">
<tr>
<td style="width:10%;">电影标签</td>
<td style="width:90%;">
{% for v in tags %}
<a href="{{ url_for('home.index',page=1) }}?tid={{ v.id }}&star={{ p['star'] }}&time={{ p['time'] }}&pm={{ p['pm'] }}&cm={{ p['cm'] }}"
class="label label-info"><span
class="glyphicon glyphicon-tag"></span>&nbsp;{{ v.name }}</a>
{% endfor %}
</tr>
<tr>
<td>电影星级</td>
<td>
{% for v in range(1,6) %}
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ v }}&time={{ p['time'] }}&pm={{ p['pm'] }}&cm={{ p['cm'] }}"
class="label label-warning"><span
class="glyphicon glyphicon-star"></span>&nbsp;{{ v }}星</a>
{% endfor %}
</td>
</tr>
<tr>
<td>上映时间</td>
<td>
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time=1&pm={{ p['pm'] }}&cm={{ p['cm'] }}"
class="label label-default"><span
class="glyphicon glyphicon-time"></span>&nbsp;最近</span></a>
&nbsp;&nbsp;
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time=2&pm={{ p['pm'] }}&cm={{ p['cm'] }}"
class="label label-default"><span
class="glyphicon glyphicon-time"></span>&nbsp;更早</span></a>
</td>
</tr>
<tr>
<td>播放数量</td>
<td>
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time={{ p['time'] }}&pm=1&cm={{ p['cm'] }}"
class="label label-success"><span class="glyphicon glyphicon-arrow-down"></span>&nbsp;从高到底</span>
</a>
&nbsp;
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time={{ p['time'] }}&pm=2&cm={{ p['cm'] }}"
class="label label-danger"><span class="glyphicon glyphicon-arrow-up"></span>&nbsp;从低到高</span>
</a>
</td>
</tr>
<tr>
<td>评论数量</td>
<td>
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time={{ p['time'] }}&pm={{ p['pm'] }}&cm=1"
class="label label-success"><span class="glyphicon glyphicon-arrow-down"></span>&nbsp;从高到底</span>
</a>
&nbsp;
<a href="{{ url_for('home.index',page=1) }}?tid={{ p['tid'] }}&star={{ p['star'] }}&time={{ p['time'] }}&pm={{ p['pm'] }}&cm=2"
class="label label-danger"><span class="glyphicon glyphicon-arrow-up"></span>&nbsp;从低到高</span>
</a>
</td>
</tr>
</table>
</div> {% for v in page_data.items %}
<div class="col-md-3">
<div class="movielist text-center"> <img src="{{ url_for('static',filename='uploads/'+v.logo) }}"
class="img-responsive center-block" alt="">
<div class="text-left" style="margin-left:auto;margin-right:auto;width:210px;">
<span style="color:#999;font-style: italic;">{{ v.title }}</span><br>
<div>
{% for val in range(1,v.star+1) %}
<span class="glyphicon glyphicon-star" style="color:#FFD119"></span>
{% endfor %}
{% for val in range(1,6-v.star) %}
<span class="glyphicon glyphicon-star-empty" style="color:#FFD119"></span>
{% endfor %}
</div>
</div>
<a href="{{ url_for('home.play',id=v.id,page=1) }}" class="btn btn-primary" target="_blank"
role="button"><span
class="glyphicon glyphicon-play"></span>&nbsp;播放</a>
</div>
</div>
{% endfor %} <div class="col-md-12">
{{ pg.page(page_data,'home.index') }}
</div>
</div>
</div>
</section>
<!--电影列表-->
{% endblock %}

至此,电影网站的首页面开发完成了

Flask开发微电影网站(三)的更多相关文章

  1. Flask开发微电影网站(一)

    1.用到的Flask知识 1.使用整形,浮点型,路径型,字符串型下正则表达式路由转化器 2.使用GET与POST请求,上传文件,cookie获取与响应,404处理 3.使用模板自动转义,定义过滤器,定 ...

  2. Flask开发微电影网站(五)

    后台管理页面是系统管理员登录后对网站进行管理的前端页面 后台登录页面,如下图所示 管理员登录后的页面,如下图所示 管理员登录后,在右上角显示的管理员信息,如下图所示 管理员登录后,在页面中间部分的左侧 ...

  3. Flask开发微电影网站(七)

    1.后台管理之电影管理 1.1 定义电影表单 在app的admin目录的forms.py文件中,定义电影表单 # 电影表单 class MovieForm(FlaskForm): title = St ...

  4. Flask开发微电影网站(六)

    1. 后台管理登录功能实现 1.1 后台管理页面登录表单LoginForm 在app的admin目录下创建forms.py文件,用来保存admin蓝图中需要使用到的表单 from flask_wtf ...

  5. Flask开发微电影网站(二)

    1.安装数据库连接依赖包 pip install flask-sqlalchemy 2.创建movie数据库 在CentOS虚拟机,进入MaridDB数据库提示符,创建movie数据库 create ...

  6. Flask开发微电影网站(十)

    1.后台管理之角色管理 1.1 角色管理之定义角色表单 在app的admin目录的forms.py文件中,定义角色表单 # 角色表单 class RoleForm(FlaskForm): name = ...

  7. Flask开发微电影网站(九)

    1.后台管理之电影管理 1.1 电影管理之所有电影收藏列表 1.1.1 电影管理之电影收藏列表视图函数 在admin目录下的views.py文件中定义电影收藏列表视图函数 电影收藏列表视图函数需要被登 ...

  8. Flask开发微电影网站(八)

    1.后台管理之电影预告管理 1.1 定义电影预告表单 在app的admin目录的forms.py文件中,定义电影预告表单 # 预告表单 class PreviewForm(FlaskForm): ti ...

  9. Flask开发微电影网站(四)

    会员中心页面,如下图所示 用户登录后,修改密码页面,如下图所示 用户查看自己的评论页面,如下图所示 用户查看自己的登录日志页面,如下图所示 用户查看自己收藏的电影的页面,如下图所示 1. 定义用户主页 ...

随机推荐

  1. Hadoop DataNode不能正常工作的原因

    在把Hadoop环境搭建成功,并且也Hadoop的各个组件都正常工作.在重启过几次Hadoop后发现DataNode不能正常工作,打开Hadoop 的后台http://localhost:50030和 ...

  2. LeetCode之旅(16)-Climbing Stairs

    题目描述: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either ...

  3. cocos2dx 跨平台编译遇到的几个问题

    首先声明一下自己用的版本 vs2010   cocos2d-x_2.2    ndk_r9 1. 安装cygwin之后,也设置好了 ndk_root, 但是 cd $NDK_ROOT 进入不了, 只好 ...

  4. 不容忽视的js面试题

    1.全局变量和局部变量(变量提升和连等赋值问题) (function() { var a = b = 5; })(); console.log(a); console.log(b); 上面代码运行结果 ...

  5. Oracle12c中性能优化&amp;功能增强新特性之临时undo

    临时表最有意思的特点之一是undo段也存储在常规undo表空间中,而它们的undo反过来被redo保护,这会导致一些问题. 1)  写undo表空间需要数据库以读写模式打开,因此,只读数据库和物理备库 ...

  6. (linux虚拟机)克隆得到的虚拟机修改网卡信息和IP地址,以及DNS

    克隆得到的虚拟机,与原先的系统是一模一样的包括MAC地址和IP地址.需要修改成信息. 克隆完事之后,首先在 点击生成一个新的MAC地址.然后启动,登陆. vim /etc/udev/rules.d/7 ...

  7. 微信公众号网页授权登录--JAVA

    网上搜资料时,网友都说官方文档太垃圾了不易看懂,如何如何的.现在个人整理了一个通俗易懂易上手的,希望可以帮助到刚接触微信接口的你. 请看流程图!看懂图,就懂了一半了: 其实整体流程大体只需三步:用户点 ...

  8. JavaScript打开新窗口被拦截问题

    新窗口打开页面,一个很常用的效果,至于代码,一般第一反应都是这么写: window.open(url); 但是主流的浏览器都会拦截这种效果(可能这些年弹窗广告太多,如果浏览器不拦截,用户受不了)   ...

  9. 基于Python的数据分析(2):字符串编码

    在上一篇文章<基于Python的数据分析(1):配置安装环境>中的第四个步骤中我们在python的启动步骤中强制要求加载sitecustomize.py文件并设置其默认编码为"u ...

  10. Apriori算法思想和其python实现

    第十一章 使用Apriori算法进行关联分析 一.导语 "啤酒和尿布"问题属于经典的关联分析.在零售业,医药业等我们经常需要是要关联分析.我们之所以要使用关联分析,其目的是为了从大 ...