html表单提交评论

1.提交评论

评论对象、评论内容、评论时间、评论者

request发送请求的时候还会发送一些其他东西,请求头记录了一些信息,包括它是从那个页面进来的。

上次登录成功的时候跳转到了首页,为了改善用户体验,应该跳转到登录之前那个页面,reverse为反向解析

referer = request.META.get('HTTP_REFERER', reverse('home'))
获取到了跳转之前的链接,这个登录页面是写在了博客页面中,点击登录时,记录的是点之前本页面的链接,可以让点击登录后返回本页面。
登录成功后我们用form标签进行提交评论。
                <div class="comment-area">
                    <h3 class="comment-area-title">提交评论</h3>
                    {% if request.user.is_authenticated %}
                        <form action="{% url 'update_comment' %}" method="POST" style="overflow: hidden">
                            {% csrf_token %}
                            <div class="form-grpup">
                                <label for="comment_text">{{ user.username }},欢迎评论~</label>
                                <textarea id="comment_text" class="form-control" name="text" rows="4"></textarea>
                            </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>

提交的东西为评论内容、评论对象,评论者可以通过request获取,评论时间是当前时间。评论对象为隐藏提交。

form的样式采用了bootsrap的表单基本实例。

再设置表单提交的链接

from django.urls import path
from . import views

urlpatterns = [
    path('update_comment',views.update_comment,name='update_comment'),
]

再去主路由中添加了path('comment/',include('comment.urls')),

之后在comment的views中写处理方法,首先指明评论或评论失败后需要跳转到之前的路径,

然后分别获取到评论者,评论内容,评论对象,并对他们一一检查;检查评论者采用user.is_authenticated验证是否登录;

获取评论内容时可以采用strip()方法把开头和结尾的空格删除,防止多个空格的评论

评论对象的获取有2中办法,一般方法为导入Blog模型,通过object_id筛选出对应的博客,另一种为通用方法,可以适应各种模型

model_class = ContentType.objects.get(model=content_type).model_class()

首先通过content_type获取到相应的ContentType对象,然后通过.model_class()返回此ContentTyoe实例表示的模型类,此时返回Blog模型类。

model_obj = model_class.objects.get(pk=object_id)

通过获取到的模型类获得对应的对象

使用这些方法,您可以编写对任何已安装模型执行查询的高级通用代码-无需导入和使用单个特定的模型类,而是可以在运行时app_label和 传递model给 ContentType查找,然后使用模型类或从中检索对象。

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):
    referer = request.META.get('HTTP_REFERER', reverse('home'))
    #数据检查
    user = request.user
    if not 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 = user
    comment.text = text
    comment.content_object = model_obj
    comment.save()
    return redirect(referer)

检查通过后,保存数据,并返回之前的页面,如果发生错误则跳转到错误页面,并设置返回链接。

数据保持后需要显示到博客前端页面,博客详情里需要获取评论内容,并发送给前端。

def blog_detail(request, blog_pk):
    blog = get_object_or_404(Blog, pk=blog_pk)
    read_cookie_key = read_statistics_once_read(request, blog)
    blog_content_type = ContentType.objects.get_for_model(blog)
    comments = Comment.objects.filter(content_type=blog_content_type,object_id=blog.pk)

    context = {}
    context['comments'] = comments

给get_for_model中传入博客对象获取到博客的content_type,然后用content_type和博客id从评论模型筛选出对应的评论,之后传到前端页面。

                <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:i:s" }}):
                            {{ comment.text }}
                        </div>
                    {% empty %}
                        暂无评论
                    {% endfor %}
                </div>
 
原文地址:https://www.cnblogs.com/lag1/p/13864942.html