目标效果:
image.png


修改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')),

运行:

但是我们发现运行以后只是后台提交了该评论,没有在网页上展示
image.png
image.png
修改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
    ...

效果如下:
image.png
修改评论模型:comment/models.py

但如果评论内容则不能提交,给一个错误提示:在comment的views.py中:strip()用于将前后空格去掉;另外如果object\_id不存在,要返回一个错误信息;在error.html中新增一个返回链接

{{ message }},<a href="{{ redirect_to }}">返回</a>

image.png


笨小孩
20 声望3 粉丝

你,要怎样度过这一生?有的人二十岁已经死了,有的人七十岁还在发现生命的可能,有人终其一生,不知道自己要的是什么;有人简单执拗,终其一生;忠于自我未必有结果,坚持努力也不一定换来成功,但有天,回望过...