现在我们的博客已经具有评论功能了。随着文章的评论者越来越多,有的时候评论者之间也需要交流,甚至部分评论还能合并成一个小的整体。因此最好是有某种方法可以将相关的评论聚集到一起,这时候多级评论就非常的有用了。
多级评论意味着你需要将模型重新组织为树形结构。“树根”是一级评论,而众多“树叶”则是次级评论。本教程会以第三方库django-mptt为基础,开发多级评论功能。
django-mptt模块包含了树形数据结构以及查询、修改树形数据的众多方法。
任何需要树形结构的地方,都可以用 django-mptt 来搭建。比如目录。
**注意:**本章新知识点较多,请读者做好心理准备,一定要耐心阅读。
既然要建立树形结构,老的评论模型肯定是要修改了。
首先安装django-mptt
:
(env) > pip install django-mptt
复制代码
安装成功后,在配置中注册:
my_blog/
INSTALLED_APPS = [...'mptt',...
]
...
复制代码
这些你已经轻车熟路了。
接下来,修改评论模型:
comment/
# django-mptt
dels import MPTTModel, TreeForeignKey# 替换 models.Model 为 MPTTModel
class Comment(MPTTModel):...# 新增,mptt树形结构parent = TreeForeignKey('self',on_delete=models.CASCADE,null=True,blank=True,related_name='children')# 新增,记录二级评论回复给谁, strreply_to = models.ForeignKey(User,null=True,blank=True,on_delete=models.CASCADE,related_name='replyers')# 替换 Meta 为 MPTTMeta# class Meta:# ordering = ('created',)class MPTTMeta:order_insertion_by = ['created']...复制代码
先引入MPTT
相关模块,然后改动下列几个位置:
models.Model
类,替换为MPTTModel
,因此你的模型自动拥有了几个用于树形算法的新字段。(有兴趣的读者,可以在迁移好数据之后在SQLiteStudio中查看)parent
字段是必须定义的,用于存储数据之间的关系,不要去修改它。reply_to
外键用于存储被评论人。class Meta
替换为class MPTTMeta
,参数也有小的变化,这是模块的默认定义,实际功能是相同的。这些改动大部分都是django-mptt文档的默认设置。需要说明的是这个reply_to
。
先思考一下,多级评论是否允许无限级数?无限级数听起来很美好,但是嵌套的层级如果过多,反而会导致结构混乱,并且难以排版。所以这里就限制评论最多只能两级,超过两级的评论一律重置为两级,然后再将实际的被评论人存储在reply_to
字段中。
举例说明:一级评论人为 a,二级评论人为 b(parent 为 a),三级评论人为 c(parent 为 b)。因为我们不允许评论超过两级,因此将 c 的 parent 重置为 a,reply_to 记录为 b,这样就能正确追溯真正的被评论者了。
模型修改完了,添加了很多非空的字段进去,因此最好先清空所有的评论数据,再进行数据迁移。
迁移时出现下面的提示也不要慌,一律选第 1 项、填入数据 0 就可以了:
(env) > python manage.py makemigrationsYou are trying to add a non-nullable field 'level' to comment without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:1) Provide a one-off default now (will be set on all existing rows with a null value for this column)2) Quit, and let me add a default in models.pySelect an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can w
Type 'exit' to exit this prompt
>>> 0
复制代码
要还不行,就把数据库文件删了重新迁移吧。开发阶段用点笨办法也没关系。
数据迁移还是老规矩:
(env) > python manage.py makemigrations
(env) > python manage.py migrate
复制代码
这就完成了。
前面章节已经写过一个视图post_comment
用于处理评论了,我们将复用它,以求精简代码。
改动较大,代码全贴出来,请对照改动:
comment/
# 记得引入 Comment !
from .models
@login_required(login_url='/userprofile/login/')
# 新增参数 parent_comment_id
def post_comment(request, article_id, parent_comment_id=None):article = get_object_or_404(ArticlePost, id=article_id)# 处理 POST 请求hod == 'POST':comment_form = CommentForm(request.POST)if comment_form.is_valid():new_comment = comment_form.save(commit=False)new_comment.article = articlenew_comment.user = request.user# 二级回复if parent_comment_id:parent_comment = (id=parent_comment_id)# 若回复层级超过二级,则转换为二级new_comment.parent_id = _root().id# 被回复人ply_to = parent_comment.usernew_comment.save()return HttpResponse('200 OK')new_comment.save()return redirect(article)else:return HttpResponse("表单内容有误,请重新填写。")# 处理 GET 请求hod == 'GET':comment_form = CommentForm()context = {'comment_form'
本文发布于:2024-02-02 05:45:13,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170682391241748.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |