美文网首页利用Flask搭建微电影视频网站
利用Flask搭建微电影视频网站(十四):前台后续开发

利用Flask搭建微电影视频网站(十四):前台后续开发

作者: 啃饼小白 | 来源:发表于2018-09-17 07:56 被阅读23次

    关于博主

    努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

                      微信公众号:  啃饼思录
    
                       QQ: 2810706745(啃饼小白)
    

    写在前面

    本篇笔记,我们将完成前台的后续开发,需要实现上映预告,标签筛选,电影搜索,电影播放,评论显示和收藏电影等功能。

    本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第十四篇。

    上映预告

    使用到的内容

    我们将使用到的内容有:
    模型:Preview
    表单: 无
    请求方法: GET
    访问控制: 无

    1、修改动画视图

    打开views.py文件,我们修改一下动画视图:

    from app.models import  Preview
    
    
    # 动画
    @home.route('/animation/')
    def animation():
        data = Preview.query.all()
        return render_template("home/animation.html", data=data)
    

    2、配置animation页面

    我们修改一下我们的animation.html页面:

    标签筛选和电影分页

    标签就是这里:

    使用到的内容

    我们将使用到的内容有:
    模型:Tag ,Movie
    表单: 无
    请求方法: GET
    访问控制: 无

    1、编写视图函数

    打开views.py文件,我们修改index函数:

    from app.models import Tag
    
    # 首页
    @home.route('/')
    def index():
        tags = Tag.query.all()
        movtag = request.args.get("movtag", 0)    # 获取电影标签
        star = request.args.get("star", 0)  # 获取电影星级
        ontime = request.args.get("ontime", 0)  # 获取上映时间
        playnum = request.args.get("playnum", 0)  # 获取播放数量
        commnum = request.args.get("commnum", 0)  # 获取评论数量
        return render_template("home/index.html", tags=tags)
    

    2、进行标签和星级遍历

    {% for v in tags %}
    <a  class="label label-info"><span
    class="glyphicon glyphicon-tag"></span>&nbsp;{{ v.name }}</a>
     {% endfor %}
    
    
    {% for v in range(1,6) %}
    <a class="label label-warning"><span class="glyphicon glyphicon-star"></span>&nbsp;{{ v }}</a>
     {% endfor %}
    

    3、构建参数字典

     p = dict(
            movtag=movtag,
            star=star,
            ontime=ontime,
            playnum=playnum,
            commnum=commnum
        )
    

    这是为了后面的筛选用,记得把p传进去!

    4、配置筛选

    我们对电影标签进行筛选,采用这种方式进行:

    <a href="{{ url_for('home.index') }}?movtag={{ v.id }}&star={{ p['star'] }}&ontime={{ p['ontime'] }}&playnum={{ p['playnum'] }}&commnum={{ p['commnum'] }}"...</a>
    

    也就是说除了当前所选之外,其余的我们都是采用获取字典属性的方法来获得相关属性。

    电影星级:

    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ v }}&ontime={{ p['ontime'] }}&playnum={{ p['playnum'] }}&commnum={{ p['commnum'] }}" ......</a>
    

    上映时间:

    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime=1&playnum={{ p['playnum'] }}&commnum={{ p['commnum'] }}"  .......最近</span></a>
                              
    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime=2&playnum={{ p['playnum'] }}&commnum={{ p['commnum'] }}"  ......更早</span></a>            
    

    我们这里用ontime的值1-2分别代表最近,更早。

    播放数量:

    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime={{ p['ontime'] }}&playnum=1&commnum={{ p['commnum'] }}" ......从高到低</span></a>
    
    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime={{ p['ontime'] }}&playnum=2&commnum={{ p['commnum'] }}" ......从低到高</span></a>
    
    

    我们这里用playnum的值1-2分别代表从高到低,从低到高。

    评论数量:

    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime={{ p['ontime'] }}&playnum={{ p['playnum'] }}&commnum=1"......从高到低</span></a>
    
    <a href="{{ url_for('home.index') }}?movtag={{ p['movtag'] }}&star={{ p['star'] }}&ontime={{ p['ontime'] }}&playnum={{ p['playnum'] }}&commnum=2" ......从低到高</span></a>
    
    

    我们这里用commnum的值1-2分别代表从高到低,从低到高。

    5、修改视图函数

    我们打开views.py文件,继续完善我们的index视图:

    from app.models import Movie
    
    # 首页
    @home.route("/<int:page>/", methods=["GET"])
    @home.route("/", methods=["GET"])
    def index(page=None):
        tags = Tag.query.all()
        page_data = Movie.query
    
        movtag = request.args.get("movtag", 0)    # 获取电影标签
        if int(movtag) != 0:
            page_data = page_data.filter_by(tag_id=int(movtag))
    
        star = request.args.get("star", 0)  # 获取电影星级
        if int(star) != 0:
            page_data = page_data.filter_by(star=int(star))
    
        ontime = request.args.get("ontime", 0)  # 获取上映时间
        if int(ontime) != 0:
            if int(ontime) == 1:
                page_data = page_data.order_by(
                    Movie.addtime.desc()
                )
            else:
                page_data = page_data.order_by(
                    Movie.addtime.asc()
                )
    
        playnum = request.args.get("playnum", 0)  # 获取播放数量
        if int(playnum) != 0:
            if int(playnum) == 1:
                page_data = page_data.order_by(
                    Movie.playnum.desc()
                )
            else:
                page_data = page_data.order_by(
                    Movie.playnum.asc()
                )
    
        commnum = request.args.get("commnum", 0)  # 获取评论数量
        if int(commnum) != 0:
            if int(commnum) == 1:
                page_data = page_data.order_by(
                    Movie.commentnum.desc()
                )
            else:
                page_data = page_data.order_by(
                    Movie.commentnum.asc()
                )
        if page is None:
            page = 1
        page_data = page_data.paginate(page=page, per_page=12)
    
        p = dict(
            movtag=movtag,
            star=star,
            ontime=ontime,
            playnum=playnum,
            commnum=commnum
        )
        return render_template("home/index.html", tags=tags, p=p, page_data=page_data)
    

    6、进行列表显示和分页配置

    打开搜索框,输入home.index,我们在这些后面添加page=1,一共5个地方:

    如果少了运行就会报下面的错误:

    werkzeug.routing.BuildError: Could not build url for endpoint 'home.index'. Did you forget to specify values ['page']?
    

    分页的配置就2步:首先复制这个置于文件开头:

    {% import "ui/home_page.html" as pg %}
    

    接着复制下面的替换静态分页效果:

    {{ pg.page(page_data, "home.index") }}
    

    别放错位置哈:

    电影搜索和电影分页

    使用到的内容

    我们将使用到的内容有:
    模型:Movie
    表单: 无
    请求方法: GET
    访问控制: 无

    1、书写搜索视图函数

    # 搜索页面
    @home.route('/search/<int:page>/')
    def search(page=None):
        if page is None:
            page = 1
        key = request.args.get('key', '')
        movie_count = Movie.query.filter(
            Movie.title.ilike('%' + key + '%')   # ilike可以进行模糊查询
        ).count()
        page_data = Movie.query.filter(
            Movie.title.ilike('%' + key + '%')
        ).order_by(
            Movie.addtime.desc()
        ).paginate(page=page, per_page=10)
        return render_template("home/search.html", key=key, movie_count=movie_count, page_data=page_data)
    

    2、修改home和layout页面

    为搜索电影加id="key_movie",与此同时为搜索添加id="do_search",还要删除搜索的链接href:

    然后采用Jquery来控制搜索按钮,在JavaScript里面添加这段Jquery代码:

    $("#do_search").click(function () {
                var key = $("#key_movie").val();
                location.href = "{{ url_for('home.search', page=1) }}?key=" + key;
            });
    

    这段Jquery代码的意思是说,当点击class="do_search"的搜索框时,就会去查询电影里面含有key的电影,并返回到search搜索结果列表页面。

    注意这些操作都需要在home和layout页面进行,2个都要进行配置!!!

    然后就是分页了,就2步:首先复制这个置于文件开头:

    {% import "ui/home_page.html" as pg %}
    

    接着复制下面的替换静态分页效果:

    {{ pg.page(page_data, "home.search") }}
    

    别放错位置哈!!!

    电影详情和电影播放

    使用到的内容

    我们将使用到的内容有:
    模型: Movie
    表单: 无
    请求方法: GET
    访问控制: 无

    1、编写播放视图

    # 详情页面
    @home.route('/play/<int:id>/')
    def play(id=None):
        movie = Movie.query.join(Tag).filter(
            Tag.id == Movie.tag_id,
            Movie.id == int(id)
        ).first_or_404()
        return render_template("home/play.html", movie=movie)
    

    2、添加电影id

    打开搜索框,输入home.play,我们在这些后面添加id=v.id,一共3个地方:

    3、修改播放页面显示


    注意一下星级:

    {% for val in range(1,movie.star+1) %}
     <span class="glyphicon glyphicon-star" style="color:#FFD119"></span>
     {% endfor %}
    
    {% for val in range(1,5-movie.star) %}
     <span class="glyphicon glyphicon-star-empty" style="color:#FFD119"></span>
    {% endfor %}
    

    还有底下的配置:

    电影评论和电影统计

    使用到的内容

    我们将使用到的内容有:
    模型:Movie User Comment
    表单: CommentForm
    请求方法: GET ,POST
    访问控制: 需要登入

    1、添加表单验证字段

    # 添加评论
    class CommentForm(FlaskForm):
        content = TextAreaField(
            label="内容",
            validators=[
                DataRequired("请输入内容!"),
            ],
            description="内容",
            render_kw={
                "id": "input_content"
            }
        )
        submit = SubmitField(
            '提交评论',
            render_kw={
                "class": "btn btn-success",
                "id": "btn-sub"
            }
        )
    
    

    2、判断登入和是否显示评论框

    打开play.html页面,我们修改成这样:

    注意,是"user",不是user,这个一定要注意哈!!!

    3、准备页面渲染字段

    打开home/views.py文件,我们修改play函数:

    from app.home.forms import CommentForm
    
    # 详情页面
    @home.route('/play/<int:id>/', methods=["GET", "POST"])
    def play(id=None):
        movie = Movie.query.join(Tag).filter(
            Tag.id == Movie.tag_id,
            Movie.id == int(id)
        ).first_or_404()
        form = CommentForm()
        if "user" in session and form.validate_on_submit():
            data = form.data
    
        return render_template("home/play.html", movie=movie, form=form)
    

    4、前台页面传值显示以及操作信息提示

    可以仿照后台的那些页面的配置来修改play.html:

    5、继续完善我们的播放视图

    from app.models import Comment
    
    # 详情页面
    @home.route('/play/<int:id>/', methods=["GET", "POST"])
    def play(id=None):
        movie = Movie.query.join(Tag).filter(
            Tag.id == Movie.tag_id,
            Movie.id == int(id)
        ).first_or_404()
        movie.playnum = movie.playnum + 1
        form = CommentForm()
        if "user" in session and form.validate_on_submit():
            data = form.data
            comment = Comment(
                content=data["content"],    # 左侧字段与数据库Comment字段保持一致
                movie_id=movie.id,
                user_id=session["user_id"]
            )
            db.session.add(comment)
            db.session.commit()
            flash("添加评论成功!", "ok")
            return redirect(url_for("home.play", id=movie.id))
            movie.commentnum = movie.commentnum+1
        db.session.add(movie)
        db.session.commit()
        return render_template("home/play.html", movie=movie, form=form)
    

    然后你就可以去play.html页面添加我们的评论了!

    评论分页及显示

    我们继续修改我们的播放视图:

    # 详情页面
    @home.route('/play/<int:id>/<int:page>/', methods=["GET", "POST"])
    def play(id=None, page=None):
        movie = Movie.query.join(Tag).filter(
            Tag.id == Movie.tag_id,
            Movie.id == int(id)
        ).first_or_404()
    
        if page is None:
            page = 1
            # 查询的时候关联标签,采用join来加进去,多表关联用filter,过滤用filter_by
        page_data = Comment.query.join(
            Movie
        ).join(
            User
        ).filter(
            Movie.id == movie.id,
            User.id == Comment.user_id
        ).order_by(
            Comment.addtime.desc()
        ).paginate(page=page, per_page=10)
    
        movie.playnum = movie.playnum + 1
        form = CommentForm()
        if "user" in session and form.validate_on_submit():
            data = form.data
            comment = Comment(
                content=data["content"],    # 左侧字段与数据库Comment字段保持一致
                movie_id=movie.id,
                user_id=session["user_id"]
            )
            db.session.add(comment)
            db.session.commit()
            movie.commentnum = movie.commentnum + 1
            db.session.add(movie)
            db.session.commit()
            flash("添加评论成功!", "ok")
            return redirect(url_for("home.play", id=movie.id, page=1))
            movie.commentnum = movie.commentnum+1
        db.session.add(movie)
        db.session.commit()
        return render_template("home/play.html", movie=movie, form=form, page_data=page_data)
    
    

    然后就是在index.html 和search.html页面添加page=1:

    接下来就是评论的遍历了,打开play.html页面,我们做如下修改:

    别忘记了评论数量的统计显示:

    然后运行一下我们的项目,发现评论出现了,但是有些却是html片段:



    那是因为为了保证页面的安全,都默认不允许直接显示html页面,我们可以和Django一样,管道符号加safe:

    <p>{{ v.content|safe }}</p>
    

    然后就是分页了:就2步:首先复制这个置于文件开头:

    {% import "ui/home_page.html" as pg %}
    

    接着复制下面的替换静态分页效果:

    {{ pg.page(page_data, "home.play") }}
    

    然后运行发现报了下面的错误:

    werkzeug.routing.BuildError: Could not build url for endpoint 'home.play' with values ['page']. Did you forget to specify values ['id']?
    

    因为这个页面是比较特殊的,我们需要做一下配置:在ui文件夹下面新建comment_page.html,把home_page.html的页面信息全部拷贝进去,然后添加id参数,以及在第几页添加id=id:

    现在修改我们play.html的分页配置:开头变成

    {% import "ui/comment_page.html" as pg %}
    

    下面也需要修改:

    {{ pg.page(page_data, "home.play", movie.id) }}
    

    就是这样:

    然后刷新一下,看一下分页功能是否已经实现了呢!!!还记得我们之前在个人中心没有对个人评论进行配置吗,现在我们就可以配置了!

    个人中心评论配置

    首先需要修改我们的评论视图:

    # 评论记录
    @home.route('/comments/<int:page>', methods=["GET"])
    @user_login_req
    def comments(page=None):
        if page is None:
            page = 1
            # 查询的时候关联标签,采用join来加进去,多表关联用filter,过滤用filter_by
        page_data = Comment.query.join(
            Movie
        ).join(
            User
        ).filter(
            Movie.id == Comment.movie_id,
            User.id == session["user_id"]
        ).order_by(
            Comment.addtime.desc()
        ).paginate(page=page, per_page=10)
    
        return render_template("home/comments.html", page_data=page_data)
    

    然后就是打开comments.html页面,我们直接复制paly.html页面那里面关于评论的那部分:

    然后就是分页了,还是2步:首先复制这个置于文件开头:

    {% import "ui/comment_page.html" as pg %}
    

    接着复制下面的替换静态分页效果:

    {{ pg.page(page_data, "home.comments") }}
    

    然后刷新一下,看看个人中心的评论记录是否都已经显示了呢!!!

    电影收藏

    使用到的内容

    我们将使用到的内容有:
    模型:Movie User Moviecol
    表单: 无
    请求方法: GET
    访问控制: 需要登录

    1、新定义一个添加收藏函数:

    
    # 添加收藏电影
    @home.route('/moviecol/add/', methods=["GET"])
    @user_login_req
    def moviecol_add():
        mid = request.args.get("mid", "")
        uid = request.args.get("uid", "")
        moviecol = MovieCol.query.filter_by(
            user_id=int(uid),
            movie_id=int(mid),
        ).count()
        if moviecol == 1:
            data = dict(ok=0)
        if moviecol == 0:
            moviecol = MovieCol(
                user_id=int(uid),
                movie_id=int(mid),
            )
            db.session.add(moviecol)
            db.session.commit()
            data = dict(ok=1)
        import json
        return json.dumps(data)
    

    2、采用ajax进行收藏的提示

    打开play.html页面,我们新定义一个Script,编写我们的ajax代码:

    <script>
            $(document).ready(function () {
                $("#btn-col").click(function () {
                    var mid = {{ movie.id }};
                    var uid = {{ session['user_id'] }};
                    $.ajax({
                        url: "{{ url_for('home.moviecol_add') }}",
                        type: "GET",
                        data: "mid=" + mid + "&uid=" + uid,
                        dataType: "json",
                        success: function (res) {
                            if (res.ok == 1) {
                                $("#show_col_msg").empty();
                                $("#show_col_msg").append("收藏成功!");
                            } else {
                                $("#show_col_msg").empty();
                                $("#show_col_msg").append("已经收藏!");
                            }
                        }
                    })
                });
            });
    </script>
    

    3、添加页面收藏提示

    继续在我们的play.html页面配置:

    然后就可以去测试我们的电影收藏功能是否已经实现了呢,接下来就是会员中心收藏电影的一个显示了,这个和我们的评论记录的显示几乎一样,所以我快点配置。

    个人中心电影收藏显示

    首先我们需要在menu.html页面配置收藏电影的page=1:

    接着去完善我们的收藏电影moviecol,我们可以借鉴之前的会员登入日志的配置:

    # 收藏电影
    @home.route('/moviecol/<int:page>/', methods=["GET"])
    @user_login_req
    def moviecol(page=None):
        if page is None:
            page = 1
            # 查询的时候关联标签,采用join来加进去,多表关联用filter,过滤用filter_by
        page_data = MovieCol.query.join(
            Movie
        ).join(
            User
        ).filter(
            User.id == session["user_id"],
            Movie.id == MovieCol.movie_id
        ).order_by(
            MovieCol.addtime.desc()
        ).paginate(page=page, per_page=10)
        return render_template("home/moviecol.html", page_data=page_data)
    
    

    然后打开moviecol.html页面,我们进行收藏电影的显示:

    可能会遗漏page=1id=v.movie_id,但是页面运行时会提示你的,这个按照提示进行即可。

    然后就是分页了:还是2步:首先复制这个置于文件开头(可以借鉴我们loginlog.html的配置):

    {% import "ui/home_page.html" as pg %}
    

    接着复制下面的替换静态分页效果:

    {{ pg.page(page_data, "home.moviecol") }}
    

    然后刷新一下,看看个人中心收藏的电影是否都已经显示了呢!!!

    至此,本篇关于上映预告,标签筛选,电影搜索,电影播放,评论显示和收藏电影等功能的介绍就到此为止了。也就是说我们整个项目的开发就全部完成了,后面就是代码的优化和电影弹幕的实现了,我们下一篇介绍了,感谢你的赏阅!!!

    本篇笔记对应上传的仓库为:https://github.com/licheetools/movie对应第十四篇。

    相关文章

      网友评论

        本文标题:利用Flask搭建微电影视频网站(十四):前台后续开发

        本文链接:https://www.haomeiwen.com/subject/jmwggftx.html