之前我們定義了幾個角色用戶,它們分別具有不同的權限,其中一個權限是Permission.MODERATE_COMMENTS,擁有此權限的用戶可以管理其他用戶的評論
爲了方便管理評論,我們要在導航條中添加一個鏈接,具有權限的用戶才能看到,這個鏈接在base.html模板中使用條件語句添加,如下:
# app/templates/base.html
#...
{if current_user.can(Permission.MODERATE_COMMENTS) %}
<li><a href="{{ url_for('main.moderate') }}">Moderate Comments</a></li>
{% endif %}
管理頁面在同一個列表中顯示全部文章的評論,最新發布的評論會顯示在前面,每篇評論的下方都會顯示一個按鈕,用來切換disabled
屬性的值,/moderate
路由的定義如下:
# app/main/views.py
#...
@main.route('/moderate')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate():
page = request.args.get('page', 1, type=int)
pagination = Comment.query.order_by(Comment.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'],
error_out=False)
comments = pagination.items
return render_template('moderate.html', comments=comments,
pagination=pagination, page=page)
這個函數很簡單,它從數據庫中讀取一頁評論,將其傳入模板進行渲染,除了評論列表之外,還能把分頁對象和當前頁數傳入了模板
moderate.html
模板也不難,因爲它依靠之前創建的子模板_comments.html
渲染評論
# app/templates/moderate.html
{% extends "base.html" %}
{% import "_macros.html" as macros %}
{% block title %}Flasky - Comment Moderation{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Comment Moderation</h1>
</div>
{% set moderate = True %}
{% include '_comments.html' %}
{% if pagination %}
<div class="pagination">
{{ macros.pagination_widget(pagination, '.moderate') }}
</div>
{% endif %}
{% endblock %}
這個模板將渲染評論的工作交給_comments.html
模板完成,但把控制權交給從屬模板之前,會使用Jinja2提供的set
指令定義一個模板變量moderate
,並將其設值爲True
,這個變量用在_comments.html
,決定是否渲染評論管理功能
_comments.html
模板中顯示評論正文的部分要做兩方面修改,對於普通用戶,(沒設定moderate變量),不顯示標記爲有問題的評論,對於協管員(moderate設爲True),不管評論是否被標記爲有問題,都要顯示,而且在正文下方還要顯示一個用來切換狀態的按鈕,具體代碼如下:
# app/templates/_comments.html
#...
<div class="comment-body">
{% if comment.disabled %}
<p><i>This comment has been disabled by a moderator</i></p>
{% endif %}
{% if moderate or not comment.disbled %}
{% if comment.body_html %}
{{ comment.body_html | safe }}
{% else %}
{{ comment.body }}
{% endif %}
{% endif %}
</div>
{% if moderate %}
<br>
{% if comment.disabled %}
<a class="btn btn-default btn-xs" href="{{url_for('.moderate_enable', id=comment.id, page=page) }}">Enable</a>
{% else %}
<a class="btn btn-danger btn-xs" href="{{url_for('.moderate_disbled', id=comment.id, page=page) }}">
Disable</a>
{% endif %}
{% endif %}
</div>
做了上述改動之後,用戶將看到一個關於有問題評論的簡短提示,協管員既能看到這個提示,也能看到評論的正文,在每篇評論的下方,協管員還能看到一個按鈕,用來切換評論的狀態,點擊按鈕後會觸發兩個新路由中的一個,但具體觸發哪一個取決於協管員要把評論設爲什麼狀態,兩個新路由如下:
# app/main/views.py
@main.route('/moderate/enable/<int:id>')
@login_required
@permission_required(Psermission.MODERATE_COMMENTS)
def moderate_enable(id):
comment = Comment.query.get_or_404(id)
comment.disabled = False
db.session.add(comment)
return redirect(url_for('.moderate', poage=request.args.get('page', 1, type=int)))
@main.route('/moderate/disable/<int:id>')
@login_required
@permission_required(Permission.MODERATE_COMMENTS)
def moderate_disabled(id):
comment = Comment.query.get_or_404(id)
comment.disabled = True
db.session.add(comment)
return redirect(url_for('.moderate', page=request.args.get('page', 1, type=int)))
上述啓用路由和禁用路由先加載評論對象,把disabled字段設爲正確的值,再把評論對象寫入數據庫,最後,重定向到評論管理頁面,如果查詢字符串中指定了page參數,會將其傳入重定向操作,_comments.html
模板中的按鈕指定了page參數,重定向後會返回之前的頁面