现在在首页我们已经可以看到展示的问题了,我们再设计一个问题的详情页,通过点击问题的标题进去,可以给问题添加评论或者回答。
问题的详情页都使用一个名为'details.html'
的模板,其网址我们设计成'/details/<question_id>/'
的形式,这时候我们可以用到一开始提到过的url传参,编写对应的视图函数如下:
@app.route('/details/<question_id>/')
def details(question_id):
question_obj = Questions.query.filter(Questions.id == question_id).first()
return render_template('details.html', question=question_obj)
这部分代码也很简单,将url
的参数question_id
传递给函数,函数用question_id
返回一个question
模型的对象,并将其传递给模板,在模板中处理quesiton
对象,包括解析其title/content/author
以及对应的comments
(在模型部分我们已经建立了Questions
和Comments
的关系和引用)。为首页问题的title
添加链接:
<p class="question-title"><a href="{{ url_for('details',question_id=question.id) }}">{{ question.title }}</a></p>
details.html
核心代码(其余部分继承base.html
)如下:
{% block body_part %}
<h3 class="question-title">{{ question.title }}</h3>
<p class="question-info">
<span>作者:{{ question.author.username }}</span>
<span>时间:{{ question.create_time }}</span>
</p>
<hr>
<p class="question-content">
{{ question.content }}
</p>
<hr/>
<div class="comments-list-container">
<ul>
<!-- 在模板中排序 -->
{# {% for comment in question.comments | sort(attribute='create_time',reverse=true) %} #}
<!-- 模型相互关联时排序好 -->
{% for comment in question.comments %}
<li>
<div class="comments-content">
{{ comment.content }}
</div>
<div class="comments-info" style="text-align: right">
<span>{{ comment.author.username }}</span>
<span>{{ comment.create_time }}</span>
</div>
</li>
<hr/>
{% endfor %}
</ul>
</div>
{% endblock %}
此时还没有添加评论功能,我手动往数据库写了一条评论,来查看html
的效果,如下:
我们再添加评论(或者说回答)的功能,其实就是加个POST
表单,和注册的逻辑是一样的,为html
增加下面的代码,放在问题和评论之间:
<h4>评论({{ question.comments | length }}):</h4>
<form method="POST" action="">
<div class="form-group">
<textarea class="form-control" rows="2" placeholder="评论详情" name="comment_desc"></textarea>
</div>
<div class="form-group" style="text-align: right;">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
这里用了一个length
过滤器来获取comments
的数量。修改detail
视图函数,为其增加POST
方法如下:
@app.route('/question/', methods=['GET', 'POST'])
def question():
if request.method == 'GET':
return render_template('question.html')
else:
if hasattr(g, 'user'):
question_title = request.form.get('question_title')
question_desc = request.form.get('question_desc')
author_id = g.user.id
new_question = Questions(title=question_title, content=question_desc, author_id=author_id)
db.session.add(new_question)
db.session.commit()
return redirect(url_for('home'))
else:
flash('请先登录')
return redirect(url_for('login'))
这部分与前面的文章中发布问答的视图函数也是很像的,无需重复讲解,经测试发布评论功能以及可以使用了。
最后美化界面如下:
补充:
由于在前文中我们的Comments
模型通过以下代码和Users/Questions
都建立了关系:
author = db.relationship('Users', backref=db.backref('comments'))
question = db.relationship('Questions', backref=db.backref('comments', order_by=create_time.desc()))
我们在新增comment
的时候,这条代码:
comment = Comments(content=content, question_id=question_id, author_id=g.user.id)
就可以改成:
comment = Comments(content=content)
comment.author = g.user
comment.question = Questions.query.filter(Questions.id == question_id).first()
虽然看上去长了,但可能更容易看出模型之间的关系了,anyway,两种方式都是OK的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。