Python-Flask开发微电影网站(四)

it2026-04-03  6

会员中心页面,如下图所示

用户登录后,修改密码页面,如下图所示

用户查看自己的评论页面,如下图所示

用户查看自己的登录日志页面,如下图所示

用户查看自己收藏的电影的页面,如下图所示

1. 定义用户主页面左侧部分

在上面的图片里,可以看到,整个页面的顶部和左侧都是一样的

在之前,已经把顶部部分单独定义在templates目录的home目录下

这里可以把用户主页的左侧也单独定义一个文件menu.html,然后让包含左侧部分的页面引入menu.html页面

menu.html页面的内容:

<div class="col-md-3"> <div class="list-group"> <a id='m-1' href="{{ url_for('home.user') }}" class="list-group-item"> <span class="glyphicon glyphicon-user"></span>&nbsp;会员中心 </a> <a id='m-2' href="{{ url_for('home.pwd') }}" class="list-group-item"> <span class="glyphicon glyphicon-lock"></span>&nbsp;修改密码 </a> <a id='m-3' href="{{ url_for('home.comments',page=1) }}" class="list-group-item"> <span class="glyphicon glyphicon-comment"></span>&nbsp;评论记录 </a> <a id='m-4' href="{{ url_for('home.loginlog',page=1) }}" class="list-group-item"> <span class="glyphicon glyphicon-calendar"></span>&nbsp;登录日志 </a> <a id='m-5' href="{{ url_for('home.moviecol',page=1) }}" class="list-group-item"> <span class="glyphicon glyphicon-heart"></span>&nbsp;收藏电影 </a> </div> </div>

2. 定义用户登录后的主页面代码

2.1 在home目录下的forms.py文件中,定义用户主页显示用户详细信息的表单类UserdetailForm

可以通过调用UserdetailForm表单类直接在前端页面上渲染生成用户详细信息的字段标签

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 UserdetailForm(FlaskForm): name = StringField( label="呢称", validators=[ DataRequired("请输入呢称!") ], description="呢称", render_kw={ "class": "form-control", "placeholder": "请输入呢称!" } ) email = StringField( label="邮箱", validators=[ DataRequired("请输入邮箱!"), Email("邮箱的格式不正确,请重新输入!") ], description="邮箱", render_kw={ "class": "form-control", "placeholder": "请输入邮箱!" } ) phone = StringField( label="手机号", validators=[ DataRequired("请输入手机号!"), Regexp("1[34578]\\d{9}", message="输入的手机号格式不正确!"), ], description="手机号", render_kw={ "class": "form-control", "placeholder": "请输入手机号!" } ) face = FileField( label="头像", validators=[ DataRequired("请上传头像!") ], description="头像" ) info = TextAreaField( label="简介", validators=[ DataRequired("请输入简介!") ], description="简介", render_kw={ "class": "form-control", "rows": "10" } ) submit = SubmitField( "保存修改", render_kw={ "class": "btn btn-success", } )

2.2 定义用户主页面的视图函数user

@home.route("/user/", methods=['GET', 'POST']) def user(): form = UserdetailForm() user = User.query.get(int(session.get("user_id"))) form.face.validators = [] if request.method == 'GET': form.name.data = user.name form.email.data = user.email form.phone.data = user.phone form.info.data = user.info if form.validate_on_submit(): data = form.data file_face = secure_filename(form.face.data.filename) if not os.path.exists(app.config['FC_DIR']): os.makedirs(app.config['FC_DIR']) os.chmod(app.config['FC_DIR']) user.face = change_filename(file_face) form.face.data.save(app.config['FC_DIR'] + user.face) name_count = User.query.filter_by(name=data.get("name")).count() if data.get("name") != user.name and name_count == 1: flash("用户名已经存在,请重新输入!", "err") return redirect(url_for("home.user")) email_count = User.query.filter_by(email=data.get("email")).count() if data.get("email") != user.email and email_count == 1: flash("邮箱已经存在,请重新输入!", "err") return redirect(url_for("home.user")) phone_count = User.query.filter_by(phone=data.get('phone')).count() if data.get("phone") != user.phone and phone_count == 1: flash("手机号已经存在,请重新输入!", "err") return redirect(url_for("home.user")) user.name = data.get("name") user.email = data.get("email") user.phone = data.get("phone") user.info = data.get("info") db.session.add(user) db.session.commit() flash("修改已经保存!", "ok") return redirect(url_for("home.user")) return render_template("home/user.html", form=form, user=user)

2.3 定义用户主页的前端页面

{% extends "home/home.html" %} {% block css %} <style> .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { padding-right: 3px; padding-left: 3px; } </style> {% endblock %} {% block content %} {% include "home/menu.html" %} <div class="col-md-9"> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-map-marker"></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" enctype="multipart/form-data"> <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_face"><span class="glyphicon glyphicon-picture"></span>&nbsp;{{ form.face.label }}</label> {{ form.face }} {% if user.face %} <img src="{{ url_for('static',filename='uploads/users/'+user.face) }}" class="img-responsive img-rounded" style="width: 100px;"> {% else %} <img data-src="holder.js/100x100" class="img-responsive img-rounded"> {% endif %} </div> <!--错误提示--> {% for err in form.face.errors %} <div class="col-md-12"> <font style="color:red">{{ err }}</font> </div> {% endfor %} <div class="form-group"> <label for="input_info"><span class="glyphicon glyphicon-edit"></span>&nbsp;{{ form.info.label }}</label> {{ form.info }} </div> <!--错误提示--> {% for err in form.info.errors %} <div class="col-md-12"> <font style="color:red">{{ err }}</font> </div> {% endfor %} {{ form.csrf_token }} {{ form.submit }} </fieldset> </form> </div> </div> </div> {% endblock %} {% block js %} <script> $(document).ready(function () { $("#m-1").addClass("active"); }); </script> {% endblock %}

3. 定义用户修改密码的页面代码

3.1 在home目录下的forms.py文件中,定义用户修改密码的表单类PwdForm

可以通过调用PwdForm表单类直接在前端页面上渲染生成用户修改密码需要的字段标签

from flask_wtf import FlaskForm from wtforms.fields import StringField, PasswordField, SubmitField, FileField, TextAreaField from wtforms.validators import DataRequired, EqualTo, Email, Regexp, ValidationError class PwdForm(FlaskForm): old_pwd = PasswordField( label="旧密码", validators=[ DataRequired("请输入旧密码!") ], description="旧密码", render_kw={ "class": "form-control", "placeholder": "请输入旧密码!" } ), new_pwd = PasswordField( label="新密码", validators=[ DataRequired("请输入新密码!") ], description="新密码", render_kw={ "class": "form-control", "placeholder": "请输入新密码!" } ) submit = SubmitField( "修改密码", render_kw={ "class": "btn btn-success" } )

3.2 定义用户修改密码的视图函数pwd

@home.route("/pwd/", methods=['GET', 'POST']) def pwd(): form = PwdForm() if form.validate_on_submit(): data = form.data user = User.query.filter_by(name=session.get("user")).first() if not user.check_pwd(data.get("pwd")): flash("旧密码输入错误,请重新输入!", "err") return redirect(url_for("home.pwd")) from werkzeug.security import generate_password_hash user.pwd = generate_password_hash(data.get("new_pwd")) db.session.add(user) db.session.commit() flash("修改密码成功,请重新登录!", "ok") return redirect(url_for("home.logout")) return render_template("home/pwd.html", form=form)

3.3 定义用户修改密码的前端页面的代码

{% extends "home/home.html" %} {% block content %} {% block css %} <style> .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9{ padding-right: 3px; padding-left: 3px; } </style> {% endblock%} {% include "home/menu.html" %} <div class="col-md-9"> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-map-marker"></span>&nbsp;会员中心</h3> </div> <div class="panel-body"> <form role="form"> <fieldset> <div class="form-group"> <label for="input_oldpwd"><span class="glyphicon glyphicon-lock"></span>&nbsp;旧密码</label> <input id="input_oldpwd" class="form-control" placeholder="旧密码" name="oldpwd" type="password" autofocus> </div> <div class="col-md-12" id="error_oldpwd"></div> <div class="form-group"> <label for="input_newpwd"><span class="glyphicon glyphicon-lock"></span>&nbsp;新密码</label> <input id="input_newpwd" class="form-control" placeholder="新密码" name="newpwd" type="password" autofocus> </div> <div class="col-md-12" id="error_newpwd"></div> <a href="login.html" class="btn btn-success"><span class="glyphicon glyphicon-edit"></span>&nbsp;修改密码</a> </fieldset> </form> </div> </div> </div> {% endblock %} {% block js %} <script> $(document).ready(function(){ $('#m-2').addClass('active') }); </script> {% endblock %}

4. 定义用户查看自己评论的页面代码

4.1 定义用户查看自己评论的视图函数

由于每个用户的电影评论数可能有很多,这许多的评论不可能在一个页面上全部显示完成,所以要进行分页,默认显示第一页的评论内容

@home.route("/comments/<int:page>/") def comments(page=None): if page is None: page = 1 page_data = Comment.query.join(Movie).join(User).filter( Movie.id == Comment.movie_id, User.id == session["user_id"] ).order_by(Comment.id).paginate(page=page, per_page=10) return render_template("home/comments.html", page_data=page_data)

4.2 定义用户查看自己的评论的前端页面代码

{% extends "home/home.html" %} {% import "ui/home_page.html" as pg %} {% block css %} <style> .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { padding-right: 3px; padding-left: 3px; } </style> {% endblock %} {% block content %} {% include "home/menu.html" %} <div class="col-md-9"> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-map-marker"></span>&nbsp;评论记录</h3> </div> <div class="panel-body"> <ul class="commentList"> {% for v in page_data.items %} <li class="item cl"> <a href="user.html"> <i class="avatar size-L radius"> <img alt="50x50" src="{{ url_for('static',filename='uploads/users' + v.user.face) }}" class="img-circle" style="border:1px solid #abcdef;"> </i> </a> <div class="comment-main"> <header class="comment-header"> <div class="comment-meta"> <a class="comment-author" href="user.html">{{ v.user.name }}</a> 评论于 <time title="2016-12-07 09:12:51" datetime="2016-12-07 09:12:51">{{ v.addtime }}</time> </div> </header> <div class="comment-body"> <p>{{ v.content | safe }}</p> </div> </div> </li> {% endfor %} </ul> <div class="col-md-12 text-center"> {{ pg.page(page_data,'home.comments') }} </div> </div> </div> </div> {% endblock %} {% block js %} <script> $(document).ready(function () { $("#m-3").addClass("active"); }); </script> {% endblock %}

5. 定义用户登录日志部分代码

5.1 定义用户查看自己的登录日志的视图函数

每个用户登录的次数可以有很多,所以要进行分页,默认显示第一页的登录日志

@home.route("/loginlog/<int:page>/", methods=['GET']) def loginlog(page=None): if page is None: page = 1 page_data = Userlog.query.filter_by(user_id=int(session.get("user_id"))).order_by( Userlog.id ).paginate(page=page, per_page=10) return render_template("home/loginlog.html", page_data=page_data)

5.2 定义用户查看自己的登录日志的前端页面代码

{% extends "home/home.html" %} {% import "ui/home_page.html" as pg %} {% block css %} <style> .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { padding-right: 3px; padding-left: 3px; } </style> {% endblock %} {% block content %} {% include "home/menu.html" %} <div class="col-md-9"> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-map-marker"></span>&nbsp;登录日志</h3> </div> <div class="panel-body"> <table class="table table-bordered"> <tr> <td style="width:10%">编号</td> <td style="width:30%">登录时间</td> <td style="width:30%">登录IP</td> </tr> {% for v in page_data.items %} <tr> <td>{{ v.id }}</td> <td>{{ v.addtime }}</td> <td>{{ v.ip }}</td> </tr> {% endfor %} </table> <div class="col-md-12 text-center" style="margin-top:6px"> {{ pg.page(page_data,'home.loginlog') }} </div> </div> </div> </div> {% endblock %} {% block js %} <script> $(document).ready(function () { $("#m-4").addClass("active"); }); </script> {% endblock %}

6. 定义用户查看自己的电影收藏的部分的代码

6.1 定义用户查看自己收藏的电影的视图函数

当用户收藏的电影可能有很多,所以需要进行分页,默认显示第一页的内容

@home.route("/moviecol/<int:page>/") def moviecol(page=None): if page is None: page = 1 page_data = Moviecol.query.join(Movie).join(User).filter( Movie.id == Moviecol.movie_id, User.id == session.get("user_id") ).order_by(Moviecol.id).paginate(page=page, per_page=10) return render_template("home/moviecol.html", page_data=page_data)

6.2 定义用户查看自己收藏的电影的前端页面代码

{% extends "home/home.html" %} {% import "ui/home_page.html" as pg %} {% block css %} <style> .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { padding-right: 3px; padding-left: 3px; } </style> {% endblock %} {% block content %} {% include "home/menu.html" %} <div class="col-md-9"> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-map-marker"></span>&nbsp;收藏电影</h3> </div> <div class="panel-body"> <div class="col-md-12"> {% for v in page_data.items %} <div class="media"> <div class="media-left"> <a href="{{ url_for('home.play',id=movie.id,page=1) }}"> <img class="media-object" style='width:131px;height:83px;' src="{{ url_for('static',filename='uploads/'+v.movie.logo) }}" alt="{{ v.movie.title }}"> </a> </div> <div class="media-body"> <h4 class="media-heading">{{ v.movie.title }}<a href="{{ url_for('home.play',id=v.movie_id,page=1) }}" class="label label-primary pull-right"><span class="glyphicon glyphicon-play"></span>播放影片</a></h4> {{ v.movie.info }} </div> </div> {% endfor %} </div> <div class="col-md-12 text-center" style="margin-top:6px;"> {{ pg.page(page_data,'home.moviecol') }} </div> </div> </div> </div> {% endblock %} {% block js %} <script> $(document).ready(function () { $("#m-5").addClass("active"); }); </script> {% endblock %}

到这里,用户登录后显示的主页面就已经开发完成了。

注:本文转载于:https://www.cnblogs.com/renpingsheng/p/9108441.html

最新回复(0)