之前我們定義了幾個角色使用者,它們分別具有不同的許可權,其中一個許可權是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參數,重新導向後會返回之前的頁面