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>