《Flask Web开发》 请教如何重定向到当前页面???

学习《Flask Web开发》一书,自己想增加删除博客文章的功能。修改了相应代码。
views.py:

@main.route('/post/delete/<int:id>')
@login_required
@permission_required(Permission.ADMINISTER)
def delete_post(id):
    post = Post.query.get_or_404(id)
    db.session.delete(post)
    db.session.commit()
    return redirect(url_for('._posts',
                             page=request.args.get('page', 1, type=int)))

_posts.html:

          <a class="btn btn-danger btn-xs" href="{{ url_for('.delete_post', id=post.id, page=page) }}">Delete</a>

_posts.html

<ul class="posts">
    {% for post in posts %}
    <li class="post">
        <div class="post-thumbnail">
            <a href="{{ url_for('.user', username=post.author.username) }}">
                <img class="img-rounded profile-thumbnail" src="{{ post.author.gravatar(size=40) }}">
            </a>
        </div>
        <div class="post-content">
            <div class="post-date">{{ moment(post.timestamp).fromNow() }}</div>
            <div class="post-author"><a href="{{ url_for('.user', username=post.author.username) }}">{{ post.author.username }}</a></div>
            <div class="post-bdoy">
                {% if post.body_html %}
                    {{ post.body_html | safe }}
                {% else %}
                    {{ post.body }}
                {% endif %}
            </div>
            <div class="post-footer">
                {% if current_user == post.author %}
                <a href="{{ url_for('.edit', id=post.id) }}">
                    <span class="label label-primary">Edit</span>
                </a>
                {% elif current_user.is_administrator %}
                <a href="{{ url_for('.edit', id=post.id) }}">
                    <span class="label label-danger">Edit [Admin]</span>
                </a>
                {% endif %}
                <a href="{{ url_for('.post', id=post.id) }}">
                    <span class="label label-default">Permalink</span>
                </a>
                <a href="{{ url_for('.post', id=post.id) }}#comments">
                    <span class="label label-primary">{{ post.comments.count() }}Comments</span>
                </a>
                <a class="btn btn-danger btn-xs" href="{{ url_for('.delete_post', id=post.id, page=page) }}">Delete</a>

            </div>
       </div> 
    </li>
    {% endfor %}
</ul>

views.py:

@main.route('/post/<int:id>', methods=['GET','POST'])
def post(id):
    post = Post.query.get_or_404(id)
    form = CommentForm()
    if form.validate_on_submit():
        comment = Comment(body=form.body.data,
                            post=post,
                            author=current_user._get_current_object())
        db.session.add(comment)
        flash('Your comment has been published.')
        return redirect(url_for('.post', id=post.id, page=-1))
    page = request.args.get('page', 1, type=int)
    if page == -1:
        page = (post.comments.count() - 1) // \
            current_app.config['FLASKY_COMMENTS_PER_PAGE'] + 1
    pagination = post.comments.order_by(Comment.timestamp.asc()).paginate(
        page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
        error_out=False)
    comments = pagination.items
    return render_template('post.html', posts=[post], form=form,
                            comments=comments, pagination=pagination)

post.html:

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "_macros.html" as macros %}

{% block title %}Flasky - Post{% endblock %}

{% block page_content %}
{% include '_posts.html' %}
<h4 id="comments">Comments</h4>
{% if current_user.can(Permission.COMMENT) %}
<div class="comment-form">
    {{ wtf.quick_form(form) }}
</div>
{% endif %}
{% include '_comments.html' %}
{% if pagination %}
<div class="pagination">
    {{ macros.pagination_widget(pagination, '.post', fragment='#comments', id=posts[0].id) }}
</div>
{% endif %}
{% endblock %}

运行之后发现,点击删除按钮,重定向会失败,估计是因为_posts.html是作为局部模板的,url上并不是这个地址。虽然可以将重定向地址改为index。但是文章显示在index和user两个页面。这样无论在哪里删除博客文章只能重定向到index页面。

请教,这种情况下。在页面操作后,怎样重定向到当前页面???

阅读 5.3k
2 个回答
return redirect(url_for('._posts',
                             page=request.args.get('page', 1, type=int)))

希望你能把._posts的视图函数写出来。


以下才是正经的回答

在此,我理解你的意图是想实现博客内容的增减改查功能,也就是常用的 CRUD 功能。但是,在实现博客内容的删除——这项功能的时候,你的思路出现了问题

首先,你的思路是利用 url 来定位资源,并进行删除操作,这样的思想很 restful(至于如何实现 restful,请继续阅读该书),但是在这个前后端一体的 flask 架构中,你在实际项目中使用了 jinja2,更使用了 bootstrap,同时也没有放过 flask-wtf。那么,你的 restful 思想就无从谈起了。

为了更好的能够解决你的问题,我先沿着你的错误思路来捋一捋到底是那里出了问题。

你想使用删除功能的 URL —— /post/delete/<int:id>,试图用一个按钮<a class="btn btn-danger btn-xs" href="{{ url_for('.delete_post', id=post.id, page=page) }}">Delete</a> Delete 来跳转到带有删除功能的 URL(这个页面根本就不会显示),并且待删除博客内容的实际动作完成之后,再跳转回来原来的博客文章的页面。但是你的跳转回原有页面的重定向却是这样的内容——return redirect(url_for('._posts', page=request.args.get('page', 1, type=int))),你的 ._post的使视图函数在那里,明显是思路到此,就无法补救了,不知道该如何跳转回原有页面了。

至于这种“重定向到一个带有操作(比如增减改查) URL,无需显示,等操作完成后,再返回原有页面”的功能,http 协议不支持,至于为什么?我也不知道,请大侠多多补课。如果你要使用这样的功能,javascript 还是能够满足你的,用 flask 专做 restful api,javascript 来处理前端。


那么在 flask 这种前后端一体化的框架中,如何实现文章的 增减改查 功能呢?

答案就是在一个页面中使用多个 form。

你可以参阅我的 pyblog项目 里的 admin 蓝图里的视图函数 https://github.com/eastossifrage/pyblog/blob/master/app/admin/views.py

图片描述

这两天我正在写一篇关于基于 flask 框架,利用 flask-wtf 来实现增减改查功能的文章,今天,已把实现代码都写好了,正在编写文字内容,随后我会发表在我创建的技术圈 —— flask讨论小组 或我的博客里——藕丝空间里,敬请期待。

redirect 是重定向到视图函数,而不是网页模板。
问题出在 _posts 函数,检查这个函数是不是存在,或者贴出来

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题