美文网首页Flask微电影网站开发
【Flask微电影】14.电影标签管理:增删查改

【Flask微电影】14.电影标签管理:增删查改

作者: 吾星喵 | 来源:发表于2018-11-11 20:06 被阅读22次

    个人博客,欢迎查看:https://blog.starmeow.cn/

    Github地址:https://github.com/xyliurui/FlaskMovie

    标签管理

    标签添加

    创建标签添加表单

    app/admin/forms.py中增加

    class TagForm(FlaskForm):
        name = StringField(
            label='名称',
            validators=[
                DataRequired('标签名称不能为空!')
            ],
            description='标签',
            render_kw={
                'class': "form-control",
                'id': "input_name",
                'placeholder': "请输入标签名称!"
            }
        )
        submit = SubmitField(
            label='添加',
            render_kw={
                'class': "btn btn-primary"
            }
        )
    

    消息分类闪现,过滤闪现消息

    参考文档: http://docs.jinkan.org/docs/flask/patterns/flashing.html

    提交表单,查询Tag数据库,这儿用到了flash的分类闪现,过滤闪现消息

    • 如果查询结果数量为1,则表明标签名称存在,并使用flash进行提示,返回添加标签页面
    {% with msgs = get_flashed_messages(category_filter=['ok']) %}
        {% if msgs %}
            <div class="alert alert-success alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                <h4><i class="icon fa fa-check"></i> 成功!</h4>
                {% for msg in msgs %}
                    <p>{{ msg }}</p>
                {% endfor %}
            </div>
        {% endif %}
    {% endwith %}
    
    • 如果标签不存在,就能添加到数据库,添加成功后也返回一条成功的消息,并跳转为添加标签页面
    {% with msgs = get_flashed_messages(category_filter=['err']) %}
        {% if msgs %}
            <div class="alert alert-danger alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                <h4><i class="icon fa fa-ban"></i> 失败!</h4>
                {% for msg in msgs %}
                    <p>{{ msg }}</p>
                {% endfor %}
            </div>
        {% endif %}
    {% endwith %}
    

    修改tag_add视图中逻辑处理

    视图逻辑如下

    from app.admin.forms import LoginFrom, TagForm
    from app.models import Admin, Tag
    from app import db
    
    
    @admin.route("/tag/add/", methods=['GET', 'POST'])
    @admin_login_require
    def tag_add():
        form = TagForm()
        if form.validate_on_submit():
            data = form.data
            tag_num = Tag.query.filter_by(name=data['name']).count()
            if tag_num == 1:
                flash('标签名称已存在!', category='err')
                return redirect(url_for('admin.tag_add'))
            # 如果标签不存在,就添加到数据库
            tag = Tag(
                name=data['name']
            )
            db.session.add(tag)
            db.session.commit()
            # 提交完成后也返回一条成功的消息
            flash('标签添加成功!', category='ok')
            return redirect(url_for('admin.tag_add'))
        return render_template('admin/tag_add.html', form=form)
    

    修改tag_add.html页面的表单

    <div class="box box-primary">
        <div class="box-header with-border">
            <h3 class="box-title">添加标签</h3>
        </div>
        <form role="form" method="post">
            <div class="box-body">
                {% with msgs = get_flashed_messages(category_filter=['ok']) %}
                    {% if msgs %}
                        <div class="alert alert-success alert-dismissible">
                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                            <h4><i class="icon fa fa-check"></i> 成功!</h4>
                            {% for msg in msgs %}
                                <p>{{ msg }}</p>
                            {% endfor %}
                        </div>
                    {% endif %}
                {% endwith %}
    
                {% with msgs = get_flashed_messages(category_filter=['err']) %}
                    {% if msgs %}
                        <div class="alert alert-danger alert-dismissible">
                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                            <h4><i class="icon fa fa-ban"></i> 失败!</h4>
                            {% for msg in msgs %}
                                <p>{{ msg }}</p>
                            {% endfor %}
                        </div>
                    {% endif %}
                {% endwith %}
    
                <div class="form-group">
                    {#<label for="input_name">标签名称</label>#}
                    {#<input type="text" class="form-control" id="input_name" placeholder="请输入标签名称!">#}
                    <label for="input_name">{{ form.name.label }}</label>
                    {{ form.name }}
                    {% for err in form.name.errors %}
                        <div class="col-md-12" style="color: red">{{ err }}</div>
                    {% endfor %}
                </div>
            </div>
            {{ form.csrf_token }}
            <div class="box-footer">
                {#<button type="submit" class="btn btn-primary">添加</button>#}
                {{ form.submit }}
            </div>
        </form>
    </div>
    

    标签添加成功页面提示如下:

    image.png

    标签已存在页面提示如下

    image.png

    查询数据库结果如下

    mysql> select * from tag;
    +----+--------+---------------------+
    | id | name   | add_time            |
    +----+--------+---------------------+
    |  1 | 科幻   | 2018-10-18 13:30:14 |
    +----+--------+---------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from tag;
    +----+--------+---------------------+
    | id | name   | add_time            |
    +----+--------+---------------------+
    |  1 | 科幻   | 2018-10-18 13:30:14 |
    |  2 | 动作   | 2018-10-18 21:40:31 |
    +----+--------+---------------------+
    2 rows in set (0.00 sec)
    

    第一条,他的add_time总是和实际添加时间相差8小时,是因为,在models.py模型中使用了datetime.datetime.utcnow,需要修改为datetime.datetime.now,这样存入数据库就是本地时间了

    标签列表

    修改tag_list增加标签显示和分页

    per_page=1每一页显示一条数据,因为测试数据较少,后面再做修改。

    @admin.route("/tag/list/<int:page>/", methods=['GET'])
    @admin_login_require
    def tag_list(page=None):
        if page is None:
            page = 1
        # 设置per_page每页显示多少个数据
        page_tags = Tag.query.order_by(Tag.add_time.desc()).paginate(page=page, per_page=1)
        return render_template('admin/tag_list.html', page_tags=page_tags)
    

    修改tag_list.html遍历显示标签列表

    <table class="table table-hover">
        <tbody>
        <tr>
            <th>编号</th>
            <th>名称</th>
            <th>添加时间</th>
            <th>操作事项</th>
        </tr>
        {% for tag in page_tags.items %}
            <tr>
                <td>{{ tag.id }}</td>
                <td>{{ tag.name }}</td>
                <td>{{ tag.add_time }}</td>
                <td>
                    <a class="label label-success">编辑</a>
                    &nbsp;
                    <a class="label label-danger">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    

    访问 http://127.0.0.1:5000/admin/tag/list/1/ 报错

    image.png

    需要修改base.html中的标签列表增加分页页码

    <li id="g-2-2">
        <a href="{{ url_for('admin.tag_list') }}">
            <i class="fa fa-circle-o"></i> 标签列表
        </a>
    </li>
    
    <!--修改为下面的-->
    
    <li id="g-2-2">
        <a href="{{ url_for('admin.tag_list', page=1) }}">
            <i class="fa fa-circle-o"></i> 标签列表
        </a>
    </li>
    
    image.png

    创建pagination.html显示分页模块

    app/templates/admin/目录下创建pagination.html文件

    将tag_list.html中的分页模块复制到pagination.html中,因为后台所有内容的分页都是相同的,单独取出来用于多个页面的调用。

    {% macro render_pagination(pagination, url_route) %}
        <!--pagination为分页数据,url为指定分页的路由,需要给路由带上page参数,指定页数-->
        <ul class="pagination pagination-sm no-margin pull-right">
            <li><a href="{{ url_for(url_route, page=1) }}">首页</a></li>
    
            {% if pagination.has_prev %}
                <li><a href="{{ url_for(url_route, page=pagination.prev_num) }}">上一页</a></li>
            {% endif %}
    
            {%- for page in pagination.iter_pages() %}
                {% if page %}
                    {% if page != pagination.page %}
                        <li><a href="{{ url_for(url_route, page=page) }}">{{ page }}</a></li>
                    {% else %}
                        <li class="active"><a>{{ page }}</a></li>
                    {% endif %}
                {% endif %}
            {%- endfor %}
    
            {% if pagination.has_next %}
                <li><a href="{{ url_for(url_route, page=pagination.next_num) }}">下一页</a></li>
            {% endif %}
    
            <li><a href="{{ url_for(url_route, page=pagination.pages) }}">尾页</a></li>
        </ul>
    {% endmacro %}
    

    修改tag_list.html导入分页模块

    <div class="box-footer clearfix">
        <!--页码模块-->
        {% import 'admin/pagination.html' as pg %}
        {{ pg.render_pagination(page_tags, 'admin.tag_list') }}
    </div>
    
    image.png

    测试完成后将tag_list视图中的per_page分页都改为10条。

    image.png

    标签删除

    参考链接: http://www.pythondoc.com/flask-sqlalchemy/queries.html#id2

    创建tag_delete标签删除视图

    app/admin/views.py中添加标签删除视图

    @admin.route("/tag/delete/<int:delete_id>/", methods=['GET'])
    @admin_login_require
    def tag_delete(delete_id=None):
        if delete_id:
            tag = Tag.query.filter_by(id=delete_id).first_or_404()
            db.session.delete(tag)
            db.session.commit()
            # 删除后闪现消息
            flash('删除标签成功!', category='ok')
        return redirect(url_for('admin.tag_list', page=1))
    

    修改tag_list.html删除标签链接和提示

    在表格顶部添加消息闪现提示框,修改删除按钮的链接,以标签的id为参数

    {% with msgs = get_flashed_messages(category_filter=['ok']) %}
        {% if msgs %}
            <div class="alert alert-success alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                <h4><i class="icon fa fa-check"></i> 成功!</h4>
                {% for msg in msgs %}
                    <p>{{ msg }}</p>
                {% endfor %}
            </div>
        {% endif %}
    {% endwith %}
    
    
    <a class="label label-danger" href="{{ url_for('admin.tag_delete', delete_id=tag.id) }}">删除</a>
    

    新建一个标签,然后点击删除,就会弹出删除成功提示信息。

    image.png image.png

    编辑标签

    类似于添加标签,只是在修改之前需要将该数据查询出来,我们可以直接复制tag_add的内容做修改。

    创建tag_update视图编辑标签

    复制tag_add的内容做修改

    @admin.route("/tag/update/<int:update_id>/", methods=['GET', 'POST'])
    @admin_login_require
    def tag_update(update_id=None):
        form = TagForm()
        tag = Tag.query.get_or_404(update_id)  # 首先查询到该标签,用主键查询,如果不存在,则返回404
        if form.validate_on_submit():
            data = form.data
            tag_num = Tag.query.filter_by(name=data['name']).count()
            if tag_num == 1:
                flash('标签名称已存在!', category='err')
                return redirect(url_for('admin.tag_update', update_id=update_id))
            # 如果标签不存在,就进行修改
            tag.name = data['name']
            db.session.commit()
            # 提交完成后也返回一条成功的消息
            flash('标签修改成功!', category='ok')
            return redirect(url_for('admin.tag_update', update_id=update_id))
        return render_template('admin/tag_update.html', form=form, tag=tag)
    

    为了编辑和删除可以使用相同的标签,统一将submit按钮名称修改为提交

    创建tag_update.html编辑标签模板

    直接复制tag_add.html做一些修改,增加name表单的初始值{{ form.name(value=tag.name) }},意思就是在name表单中设置value为以前的标签名称。

    模板代码为

    {% extends 'admin/base.html' %}
    
    {% block content %}
        <section class="content-header">
            <h1>微电影管理系统</h1>
            <ol class="breadcrumb">
                <li><a href="#"><i class="fa fa-dashboard"></i> 标签管理</a></li>
                <li class="active">修改标签</li>
            </ol>
        </section>
        <section class="content" id="showcontent">
            <div class="row">
                <div class="col-md-12">
                    <div class="box box-primary">
                        <div class="box-header with-border">
                            <h3 class="box-title">修改标签</h3>
                        </div>
                        <form role="form" method="post">
                            <div class="box-body">
                                {% with msgs = get_flashed_messages(category_filter=['ok']) %}
                                    {% if msgs %}
                                        <div class="alert alert-success alert-dismissible">
                                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                                            <h4><i class="icon fa fa-check"></i> 成功!</h4>
                                            {% for msg in msgs %}
                                                <p>{{ msg }}</p>
                                            {% endfor %}
                                        </div>
                                    {% endif %}
                                {% endwith %}
    
                                {% with msgs = get_flashed_messages(category_filter=['err']) %}
                                    {% if msgs %}
                                        <div class="alert alert-danger alert-dismissible">
                                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                                            <h4><i class="icon fa fa-ban"></i> 失败!</h4>
                                            {% for msg in msgs %}
                                                <p>{{ msg }}</p>
                                            {% endfor %}
                                        </div>
                                    {% endif %}
                                {% endwith %}
    
                                <div class="form-group">
                                    {#<label for="input_name">标签名称</label>#}
                                    {#<input type="text" class="form-control" id="input_name" placeholder="请输入标签名称!">#}
                                    <label for="input_name">{{ form.name.label }}</label>
                                    {{ form.name(value=tag.name) }}
                                    {% for err in form.name.errors %}
                                        <div class="col-md-12" style="color: red">{{ err }}</div>
                                    {% endfor %}
                                </div>
                            </div>
                            {{ form.csrf_token }}
                            <div class="box-footer">
                                {#<button type="submit" class="btn btn-primary">添加</button>#}
                                {{ form.submit }}
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </section>
    {% endblock %}
    
    {% block js %}
        <script>
            // 激活菜单栏
            $(document).ready(function () {
                $("#g-2").addClass('active');
                $("#g-2-1").addClass('active');
            })
        </script>
    {% endblock %}
    

    创建一个ABC的测试标签,然后点击编辑

    image.png

    修改为数据库中已存在的标签,比如科幻

    image.png

    修改为不存在的标签

    image.png

    查看标签列表

    image.png

    相关文章

      网友评论

        本文标题:【Flask微电影】14.电影标签管理:增删查改

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