• Flask开发微电影网站(四)


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

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

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

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

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

    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=" 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="10%">编号</td>
                            <td style="30%">登录时间</td>
                            <td style="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='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 %}
    

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

  • 相关阅读:
    (OK) Android graphic (12)—display上层相关概念、关系
    (OK) Android系统启动-SystemServer下篇
    (OK) Android系统启动-SystemServer上篇
    (OK) Android 5 SystemServer 各个系统Manager-startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
    Android 6.0 源码分析
    (OK) android6.0源码分析之Runtime的初始化
    (OK) Android的JNI_OnLoad简介与应用
    (OK) Android架构实例分析之注册hello HAL的JNI方法表
    (OK) Android的NDK开发(1)————Android JNI简介与调用流程
    (OK) android-5.0 sensor工作原理—sensorservice的启动(二)
  • 原文地址:https://www.cnblogs.com/renpingsheng/p/9108441.html
Copyright © 2020-2023  润新知