学习《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页面。
请教,这种情况下。在页面操作后,怎样重定向到当前页面???
希望你能把
._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