django文章评论功能
个人学习笔记,内容不作为各位学习参考
可以自己写,可以调用django自带的评论库写,不用重复造轮子,后面改上去
1、登录验证
为了防止恶意评论,必须是用户才能评论,做个登录功能,如图
在views.py下做账号密码验证
from django.contrib import auth
from django.shortcuts import render, redirect
# 登录
def login(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(request, username=username, password=password)
referer = request.META.get('HTTP_REFERER', reverse('home')) # 记录点击登录的网页,登录后还是在当前页面
if user is not None:
auth.login(request, user)
# 密码验证通过,返回登录的页面
return redirect(referer)
else:
# 密码验证失败,返回错误页面
return render(request, 'error.html', {'message': '用户名或密码不正确'})
2、新建一个comment应用记录评论数据,这样既可在前端调用
在comment下的views.py
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 user == '':
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)
评论上传路由,urls.py
from django.urls import path
from.import views
urlpatterns = [
path('update_comment', views.update_comment, name='update_comment')
]
models.py
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Comment(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
text = models.TextField()
comment_time = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
class Meta:
ordering = ['-comment_time']
admin.py
from django.contrib import admin
from .models import Comment
# Register your models here.
@admin.register(Comment)
class CommentAadmin(admin.ModelAdmin):
list_display = ('content_object', 'text', 'comment_time', 'user')
3、在主应用下的views.py,调用Comment内的评论
def detail(request,blog_pk):
words = get_object_or_404(Blog, pk=blog_pk)
read_cookie_key = read_coutn_once_read(request, words)
blog_content_type = ContentType.objects.get_for_model(words)
comments = Comment.objects.filter(content_type=blog_content_type, object_id=words.pk)
context = {}
# 上下篇 #
context['previous_blog'] = Blog.objects.filter(created_time__gt=words.created_time).last()
context['next_blog'] = Blog.objects.filter(created_time__lt=words.created_time).first()
# 正文 #
context['words_obj'] = words
# 评论 #
context['comments'] = comments
# cookies 响应 #
response = render(request, 'blog/detail.html', context)
response.set_cookie(read_cookie_key, 'true') # 是否阅读过标记
return response
4、前端,在templates文件夹下,error.html
{{ message }} <a href="{{ redirect_to }}">返回</a>
detail.html
{# 评论 #}
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-6">
<hr>
<div class="comment-area">
<h3>提交评论</h3>
<hr>
{% if user.is_authenticated %}
{{ user.username }},欢迎评论
<form action="{% url 'update_comment' %}" method="POST">
{% csrf_token %} {# CSRF验证 #}
<textarea id="comment_text" name="text" style="margin: 0px; width: 743px; height: 140px;"></textarea>
<input type="hidden" name="object_id" value="{{ words_obj.pk }}">
<input type="hidden" name="content_type" value="blog">
<input type="submit" value="评论">
</form>
{% else %}
未登录,登录后方可评论
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="登录">
</form>
{% endif %}
</div>
<hr>
<div class="comment-area">
<h3>评论列表</h3>
<hr>
{% 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>