如何在Django实现CMS内容管理系统mptt评论功能?,django管理页面

10个月前 (02-18) 首席小编
35分钟
323
0

目录

日常开发与内容相关的Web系统时,不管是 Blog 还是 CMS,如果需要增加与用户互动的环节那肯定需要评论的功能,接下来基于Python的 MPTT框架 在 Django 中实现评论回复功能。

注意:由于用户评论功能会涉及到一些问题,很多内容管理平台都没有开放这个功能,主要考虑人工成本,因此本方法收藏起来用的时候再拿出来吧。

基于框架自动生成的评论恢复模板。实现起来虽然说很简单,但是要静下心来慢慢看,否则你懂得。

安装与配置

CMD使用命令行安装

pip install mptt

创建应用

cd Project
python manage.py startapp Comment

配置应用模块

INSTALLED_APPS = [
...
# 添加文章应用
apps.Comment,

.......

MPTT_COMMENTS_ALLOW_ANONYMOUS = True # True 为允许匿名评论,否则不允许
COMMENTS_APP = django_mptt_comments
SITE_ID = 1

MIDDLEWARE = [
......
crequest.middleware.CrequestMiddleware,
]

X_FRAME_OPTIONS = SAMEORIGIN # 设置弹窗显示

不需要修改该的文件

admin.py 这个我们使用xadmin代替的原有版本的admin,因此这个文件不需要修改该apps.py 应用的配置文件,不需要动test.py 测试执行脚本,不需要动

应用 models.py

# coding:utf-8
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from apps.User.models import *
from ckeditor.fields import RichTextField
from apps.Blog.models import *

# 替换 models.Model 为 MPTTModel
class Comment(MPTTModel):
article_slug = models.SlugField(
default="",
verbose_name=文章slug, help_text=填写英文、字母、下划线、数字,不可重复,用于标签快速查找,
)

user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name=comments
)

# mptt树形结构
parent = TreeForeignKey(
self,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name=children
)

# 记录二级评论回复给谁, str
reply_to = models.ForeignKey(
UserProfile,
null=True,
blank=True,
on_delete=models.CASCADE,
related_name=replyers
)

comment_message = RichTextField()
created = models.DateTimeField(auto_now_add=True)

class MPTTMeta:
order_insertion_by = [created]

def __str__(self):
return self.comment_message[:20]

管理 adminx.py

# coding:utf-8
import xadmin
from .models import *

# 评论管理
class CommentAdmin(object):
list_display = [id,article_slug, user, reply_to,comment_message]
show_bookmarks = False

xadmin.site.register(Comment, CommentAdmin)

视图 Views.py

# coding:utf-8
from .models import *
from apps.Blog.models import *
from django.contrib.auth.decorators import *
from django.shortcuts import *
from .Forms import *

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
from .models import Comment
from MyHome.settings import *
from notifications.signals import notify
from django.contrib.auth.models import User

# 文章评论
@login_required(login_url=/userprofile/login/)
def post_comment(request):
# 处理 POST 请求
if request.method == POST:
article_slug = request.GET.get(article_slug)
comment_message = request.POST.get(comment_message)
parent_comment_id = request.GET.get(parent_comment_id)
comment_form = CommentForm(request.POST)

# print("=" * 50)
# print(article_slug)
# print("=" * 50)

if comment_form.is_valid():
new_comment = Comment()
new_comment.comment_message = comment_message
new_comment.user = request.user
new_comment.article_slug = article_slug

# 返回文章当前页
redirect_url = WebBaseUrl + "MyBlogDetail?article_slug=" + article_slug

# 二级回复
if parent_comment_id:
parent_comment = Comment.objects.get(id=parent_comment_id)
# 若回复层级超过二级,则转换为二级
new_comment.parent_id = parent_comment.get_root().id
# 被回复人
new_comment.reply_to = parent_comment.user
new_comment.save()
context = {
"message": "回复成功,请关闭窗口"
}
return render(request, Comment/reply.html, context)
new_comment.save()
return redirect(redirect_url)
else:
return HttpResponse("表单内容有误,请重新填写。")
# 处理 GET 请求
elif request.method == GET:
article_slug = request.GET.get(article_slug)
parent_comment_id = request.GET.get(parent_comment_id)
comment_form = CommentForm()
context = {
comment_form: comment_form,
article_slug: article_slug,
parent_comment_id: parent_comment_id,
}
return render(request, Comment/reply.html, context)
# 处理其他请求
else:
return HttpResponse("仅接受GET/POST请求。")

配置 url.py

from django.urls import path
from apps.Comment.views import *

app_name = Comment

urlpatterns = [
# 已有代码,处理一级回复
path(post-comment, post_comment, name=post_comment),
# 新增代码,处理二级回复
path(comment_reply, post_comment, name=comment_reply)
]

表单验证 Forms.py

# coding:utf-8
from captcha.fields import CaptchaField
from django import forms
from .models import *

class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = [comment_message]

前端渲染模板

内容回复窗口(弹窗) / reply.html

<!DOCTYPE html>
<html lang="zh-cn">
{% load static %}
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% static Blog/bootstrap.min.css %}">
<link rel="stylesheet" href="{% static Blog/prism.css %}">
<script src="{% static Blog/prism_patched.min.js %}"></script>
<script src="{% static ckeditor/ckeditor-init.js %}"></script>
<script src="{% static ckeditor/ckeditor/ckeditor.js %}"></script>
<script src="{% static Blog/js/jquery/jquery-3.3.1.js %}"></script>
<script src="{% static Blog/js/popper/popper-1.14.4.js %}"></script>
<script src="{% static Blog/js/bootstrap/js/bootstrap.min.js %}"></script>
<script src="{% static Blog/js/csrf.js %}"></script>
<style>
.class_form{
width: 100%;
}
</style>
</head>
<body>
{% if message %}
{{ message }}
点击窗口外任意位置返回。
{% else %}
<form action="{% url comment:comment_reply %}?article_slug={{ article_slug }}&parent_comment_id={{ parent_comment_id }}"
method="POST" class="class_form">
{% csrf_token %}
<div class="col-md-12 col-sm-12">
{{ comment_form.comment_message }}
</div>
<button class="btn btn-primary">提交评论</button>
</form>
{% endif %}
</body>
</html>

发表评论部分 / article.html

<div class="comments mt-30">
{% load mptt_tags %}
{% if comments.count != 0 %}
<h4 class="title-t text-uppercase text-bold d-black mb-40">{{ comments.count }}
Comments</h4>
{% recursetree comments %}
{% with comment=node %}
<div class="comment mt-30">
<div class="{% if comment.parent %} comment mt-30 pull-in {% else %} comment mt-30 {% endif %}">
<img class="pull-left"
src="{{ MEDIA_URL }}{{ comment.user_image }}"
style="width: 63px"
alt="">
<div class="comment-content bubble">
<h5 class="fz-13 text-bold text-uppercase d-black">{{ comment.user }}</h5>
<h6 class="orange-light text-uppercase mt-10">
{{ comment.created|date:"Y-m-d H:i"}}</h6>
<p class="fz-13 lh-28 mt-10">{{ comment.comment_message|safe }}</p>
<div class="text-right mt-30">
<!-- 加载 modal 的按钮 -->
{% if user.is_authenticated %}
<button type="button"
class="btn btn-trans text-uppercase ls-2"
onclick="new_comment({{ blog_info.article_slug }}, {{ comment.id }})">
回复
</button>
{% else %}
<a class="btn btn-light btn-sm text-muted"
href="{% url User:UserLogin %}">
登录后方可回复
</a>
{% endif %}
</div>
<div class="modal fade"
id="comment_{{ comment.id }}"
tabindex="-1"
role="dialog"
aria-labelledby="CommentModalCenter"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg"
role="document">
<div class="modal-content" style="height: 400px">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
回复 {{ comment.user }}</h5>
</div>
<div class="modal-body"
id="modal_body_{{ comment.id }}"></div>
</div>
</div>
</div>
{% if not comment.is_leaf_node %}
<div class="children">
{{ children }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="clearfix"></div>
{% endwith %}
{% endrecursetree %}
{% else %}
<h3>暂无评论,快来发表你的观点吧</h3>
{% endif %}
</div>

显示评论部分 / article.html

<div class="leave-comment mt-50">
<h4 class="title-t text-bold text-uppercase d-black">留言</h4>
<div class="clearfix"></div>
<hr>
{% if user.is_authenticated %}
<form action="{% url comment:post_comment %}?article_slug={{ blog_info.article_slug }}"
method="POST">
{% csrf_token %}
{{ comment_form.comment_message }}
<div class="mt-30">
<input name="submit" type="submit" class="btn btn-orange-light text-uppercase"
id="submit" value="提交评论">
</div>
</form>
{% else %}
<br><h5 class="row justify-content-center">
<a href="{% url User:UserLogin %}">登录</a>后回复
</h5><br>
{% endif %}
</div>
</div>

ckeditor 和 js调用部分

<script src="{% static ckeditor/ckeditor-init.js %}"></script>
<script src="{% static ckeditor/ckeditor/ckeditor.js %}"></script>
<script>
// 加载 modal
function new_comment(article_slug, comment_id) {
let modal_body = #modal_body_ + comment_id;
let modal_id = #comment_ + comment_id;

// 加载编辑器
if ($(modal_body).children().length === 0) {
let content = <iframe src="{% url comment:post_comment %}?article_slug= +
article_slug +
&parent_comment_id= +
comment_id +
" frameborder="0" style="width: 100%; height: 100%;"></iframe>;
$(modal_body).append(content);
}
;
$(modal_id).modal(show);
}
</script>

本文由:首席小编 发布于 酷主题,转载请注明出处:https://www.kuzhuti.cn/blog/4972.html
酷客_WP小编
作者

相关推荐

10个月前 (02-20)

wms系统在仓库管理主要体现哪些内容

原标题:wms系统在仓库管理主要体现哪些内容 wms系统在仓库管理主要体现哪些内容?仓库管理具备规范化和智能的面对过程的管理。而好的仓库管理机制能提高仓库管理者工作效率,缓解他的压力,完成高效率精确的工作中。 1、仓库管理 伴随着时代的进步...
10个月前 (02-18)

2022年最佳CMS内容管理系统,2021好看的长篇小说

正在寻找最好的CMS软件来构建您的网站?在高层次上,CMS或内容管理系统可帮助您创建功能性网站,而无需使用代码从头开始构建每个页面。 但是,不同的CMS软件有不同的优缺点,因此您需要选择最适合您的特定需求和预算的工具。 为了提供帮助,我们收...
10个月前 (02-18)

深圳推动全市5G基站储能系统接入虚拟电厂管理中心,深圳5g政府补贴流量包收费吗

新华社深圳12月14日电(记者王丰)在此间深圳举行的2022碳达峰碳中和论坛暨深圳国际低碳城论坛上,深圳虚拟电厂管理中心13日与中国铁塔、中国电信、中国移动、中国联通、华为数字能源等单位签订虚拟电厂建设合作协议,将合力推动全市5G基站储能系...
10个月前 (02-16)

《互联网信息服务深度合成管理规定》答记者问,互联网信息服务包括什么内容

本文转自【网信中国】; 一、问:请您简要介绍《规定》出台的背景? 答:制定《规定》主要基于以下几个方面的考虑。一是深入贯彻落实党中央决策部署。《法治社会建设实施纲要(2020-2025年)》明确提出制定完善对算法推荐、深度伪造等新技术应用的...

评论

已有0人参与了评论

扫码添加微信

联系我们

微信:Kuzhuti
在线咨询:QQ交谈