django-Vue搭建博客 :评论的评论

教程来源 杜塞-django-vue系列
博客链接 传送门

上一章我们做好了评论功能,就有了作者和读者沟通的方式。

但是有的时候读者和读者也需要沟通,评论别人的评论,俗称多级评论

本章就将实现基础的多级评论功能。

精确的讲是二级评论。

模型

多级评论,也就是让评论模型和自身相关联。使其可以有一个父级。

修改评论模型,新增parent字段:

# comment/models.py
class Comment(models.Model):
	···
	 parent = models.ForeignKey(
        'self',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='children'
    )
  • 一个父评论可以拥有多个自评论,而子评论只能有一个父评论,因此用了一个一对多外键。
  • 之前的一对多外键,第一个参数直接引用对应模型,但是由于python语法限制,这里显然不能引用自己,因此用了
    传递字符串的self方法,作用是一样的。

需要数据迁移!!!

序列化器

在原有序列化器上进行修改:

# comment/serializers.py

# 新增类
class CommentChildrenSerializer(serializers.ModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='comment-detail')
    author = UserDescSerializer(read_only=True)

    class Meta:
        model = Comment
        exclude = [
            'parent',
            'article'
        ]


class CommentSerializer(serializers.ModelSerializer):
    url = ···
    author = ···
    # 新增代码
    article = serializers.HyperlinkedRelatedField(view_name='article-detail',read_only=True)
    article_id = serializers.IntegerField(write_only=True,allow_null=False,required=True)

    parent = CommentChildrenSerializer(read_only=True)
    parent_id = serializers.IntegerField(write_only=True,allow_null=True,required=True)

    def update(self, instance, validated_data):
        validated_data.pop('parent_id',None)
        return super().update(instance,validated_data)

新增代码大致可以分三块,让我们拆解:

  • 为了让文章更人性化,我们将article改为超链接字段用的HyperlinkedRelatedField,他和之前的HyperlinkedIdentityField
    差别很小,我们可以把HyperlinkedIdentityField理解为用于外键关系,而HyperlinkedRelatedField用于本身。(完整的解释看这里
  • parent为父评论,用了嵌套序列化器CommentChildrenSerializer。注意这个学历恶化其的Meta用的是exclude来定义不需要的字段。
  • 由于我们希望父评论只能在创建时被关联,后续不能更改(很合理),因此覆写 def update(...) ,使得在更新评论时忽略掉 parent_id 参数。

这就完成了。接下来测试。

测试

新建一个文章主键为17,评论主键为1的一级评论:

>http -a Obama:admin123456 POST http://127.0.0.1:8000/api/comment/ article_id=17 content=one
HTTP/1.1 201 Created
···
{
    "article": "http://127.0.0.1:8000/api/article/17/",
    "author": {
        "date_joined": "2021-06-13T06:47:00",
        "id": 2,
        "last_login": null,
        "username": "Obama"
    },
    "content": "one",
    "created": "2021-06-21T19:36:30.437816",
    "id": 1,
    "parent": null,
    "url": "http://127.0.0.1:8000/api/comment/1/"
}

在此基础上创建文章主键为17,父评论为1的评论:

>http -a Obama:admin123456 POST http://127.0.0.1:8000/api/comment/ parent_id=1 article_id=17 content="comment to parent comment 17"
HTTP/1.1 201 Created
···
{
    "article": "http://127.0.0.1:8000/api/article/17/",
    "author": {
        "date_joined": "2021-06-13T06:47:00",
        "id": 2,
        "last_login": null,
        "username": "Obama"
    },
    "content": "comment to parent comment 17",
    "created": "2021-06-21T19:44:27.768074",
    "id": 3,
    "parent": {
        "author": {
            "date_joined": "2021-06-13T06:47:00",
            "id": 2,
            "last_login": null,
            "username": "Obama"
        },
        "content": "one",
        "created": "2021-06-21T19:36:30.437816",
        "id": 1,
        "url": "http://127.0.0.1:8000/api/comment/1/"
    },
    "url": "http://127.0.0.1:8000/api/comment/3/"
}

article改为了嵌套序列化器(只读),因此我们要用article_id进行赋值。

如果我们想在更新评论内容的时候修改父评论:

>http -a Obama:admin123456 put http://127.0.0.1:8000/api/comment/3/ parent_id=99 article_id=17 content="update"
HTTP/1.1 200 OK
···
{
    ···
    "content": "update",
    "created": "2021-06-21T19:44:27.768074",
    "id": 3,
    "parent": {
        ···
        "id": 1,
        "url": "http://127.0.0.1:8000/api/comment/1/"
    },
    "url": "http://127.0.0.1:8000/api/comment/3/"
}

content修改成功而parent_id无变化。符合预期功能。

其他请求大家自行测试,这里的多级评论和一级评论会让人们分不出来,等前端开发就可以了,可以持续跟进学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值