目标效果:
修改blog\_detail.html的提交评论和评论列表样式以及相关区域
因为表单提交需要id和content\_type,所以我们再html中也要把这些写表单中
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<div class="comment-area">
<h3 class="comment-area-title">提交评论</h3>
{% if user.is_authenticated %}
<form action="{% url 'update_comment' %}" method="POST" style="overflow:hidden">
{% csrf_token %}
<div class="form-group">
<label for="comment_text">{{ user.username }},欢迎评论~</label>
<textarea id="comment_text" class="form-control" name="text" rows="4"></textarea>
{#使用input无法多行输入,换成textarea来写多行内容,使用bootstrap中的form-control对编辑区域和提交功能的性能优化#}
</div>
<input type="hidden" name="object_id" value="{{ blog.pk }}">
<input type="hidden" name="content_type" value="blog">
<input type="submit" value="评论" class="btn btn-primary" style="float:right">
</form>
{% else %}
未登录,登录之后方可评论
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
<span>用户名:</span>
<input type="text" name="username">
<span>密码:</span>
<input type="password" name="password">
<input type="submit" value="登录">
</form>
{% endif %}
</div>
<div class="comment-area">
<h3 class="comment-area-title">评论列表</h3>
{% for comment in comments %}
<div>
{{ comment.user.username }}
({{ comment.comment_time|date:"Y-m-d H:n:s" }}):
{{ comment.text }}
</div>
{% empty %}
暂无评论
{% endfor %}
</div>
</div>
</div>
修改blog.css
div.comment-area {
margin-top: 2em;
}
h3.comment-area-title {
border-bottom: 1px solid #ccc;
padding-bottom: 0.4em;
}
登录后会跳到主页这个操作不太好,修改mysite/views.py中的redirect('原所在页面');元所在页面通过referer = request.META.get('HTTP_REFERER','/'),然后导入reverse,使用reverse将home解析成原网页
from django.urls import reverse
...
def login(request):
...
referer = request.META.get('HTTP_REFERER', reverse('home'))
if user is not None:
auth.login(request, user)
return redirect(referer)
else:
...
comment/views.py中新增视图函数,用于处理前端提交的表单:def update_comment(request):
from django.shortcuts import render, redirect
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from .models import Comment
def update_comment(request):
"""
用于处理blog_detail.html中提交的评论表单
"""
# 因为提交的有三个内容,所以用三个对象来接受
referer = request.META.get('HTTP_REFERER', reverse('home'))
# 数据检查
if not request.user.is_authenticated:
return render(request, 'error.html', {'message': '用户未登录', 'redirect_to': referer})
text = request.POST.get('text', '').strip()
if text == '':
return render(request, 'error.html', {'message': '评论内容为空', 'redirect_to': referer})
try:
content_type = request.POST.get('content_type', '')
object_id = int(request.POST.get('object_id', ''))
model_class = ContentType.objects.get(model=content_type).model_class()
model_obj = model_class.objects.get(pk=object_id)
except Exception as e:
return render(request, 'error.html', {'message': '评论对象不存在', 'redirect_to': referer})
# 检查通过,保存数据
comment = Comment()
comment.user = request.user
comment.text = text
comment.content_object = model_obj
comment.save()
return redirect(referer)
然后写comment中新增urls.py文件,写对应的路由处理:update_comment
from django.urls import path
from . import views
urlpatterns = [
path('update_comment', views.update_comment, name='update_comment')
]
再总的路由中增加path:mysite/urls.py
path('comment/', include('comment.urls')),
运行:
但是我们发现运行以后只是后台提交了该评论,没有在网页上展示
修改blog/views.py中的blog_detail函数以及所用方法导入
from django.contrib.contenttypes.models import ContentType
from comment.models import Comment
...
def blog_detail(request, blog_pk):
...
blog_content_type = ContentType.objects.get_for_model(blog)
comments = Comment.objects.filter(content_type=blog_content_type, object_id=blog.pk)
...
context['comments'] = comments
...
效果如下:
修改评论模型:comment/models.py
但如果评论内容则不能提交,给一个错误提示:在comment的views.py中:strip()用于将前后空格去掉;另外如果object\_id不存在,要返回一个错误信息;在error.html中新增一个返回链接
{{ message }},<a href="{{ redirect_to }}">返回</a>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。