如何获取查询嵌套评论?

How to get with query nested comments?

我是 django 的新手。我正在尝试处理对嵌套评论的查询。有一个博客项目,可以添加文章,也可以给文章添加评论。对于每一条评论,都可以递归添加一条评论,依此类推。

├── blog_api
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├──── blog_api/api
|    ├── admin.py
|    ├── apps.py
|    ├── __init__.py
|    ├── migrations
|    │   └── __init__.py
|    ├── models.py
|    ├── permissions.py
|    ├── serializers.py
|    ├── tests.py
|    ├── urls.py
|    └── views.py
└── manage.py

我描述了以下模型

api/models.py

from django.db import models

class Article(models.Model):
    date_pub = models.DateTimeField(auto_now_add=True)
    title = models.CharField (max_length = 60,  blank=True, default='')
    text = models.TextField(blank=True, default='')
    owner = models.ForeignKey('auth.User', related_name='posts', on_delete=models.CASCADE)

    class Meta:
        ordering = ['date_pub']


class Comment(models.Model):
    date_pub = models.DateTimeField(auto_now_add=True)
    text = models.TextField(blank=False)
    owner = models.ForeignKey('auth.User', related_name='comments', on_delete=models.CASCADE)
    article = models.ForeignKey('Article', related_name='comments', on_delete=models.CASCADE)
    parent = models.ForeignKey('self', related_name='reply_set', null=True, on_delete=models.PROTECT)

    class Meta:
        ordering = ['date_pub']

api/serializers.py

from rest_framework import serializers
from api.models import Article
from api.models import Comment

from django.contrib.auth.models import User

class ArticleSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Article
        fields = ['id', 'title', 'text', 'owner', 'comments']


class UserSerializer(serializers.ModelSerializer):
    posts = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'posts', 'comments']


class RecursiveSerializer(serializers.Serializer):
    def to_representation(self, value):
        serializer = self.parent.parent.__class__(value, context=self.context)
        return serializer.data


class CommentSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    reply_set = RecursiveSerializer(many=True, read_only=True)

    class Meta:
        model = Comment
        fields = ['id', 'text', 'owner', 'article', 'parent', 'reply_set']

GET查询returns如下评论结构:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 1,
        "text": "First comment",
        "owner": "alex",
        "article": 1,
        "parent": null,
        "reply_set": [
            {
                "id": 2,
                "text": "Comment to comment",
                "owner": "alex",
                "article": 1,
                "parent": 1,
                "reply_set": []
            }
        ]
    },
    {
        "id": 2,
        "text": "Comment to comment",
        "owner": "alex",
        "article": 1,
        "parent": 1,
        "reply_set": []
    },
    {
        "id": 3,
        "text": "Second article comment",
        "owner": "alex",
        "article": 2,
        "parent": null,
        "reply_set": [
            {
                "id": 4,
                "text": "Comment to second article comment",
                "owner": "alex",
                "article": 1,
                "parent": 3,
                "reply_set": [
                    {
                        "id": 5,
                        "text": "some comment",
                        "owner": "alex",
                        "article": 1,
                        "parent": 4,
                        "reply_set": [
                            {
                                "id": 6,
                                "text": "some more comment",
                                "owner": "alex",
                                "article": 1,
                                "parent": 5,
                                "reply_set": []
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id": 4,
        "text": "Comment to second article comment",
        "owner": "alex",
        "article": 1,
        "parent": 3,
        "reply_set": [
            {
                "id": 5,
                "text": "some comment",
                "owner": "alex",
                "article": 1,
                "parent": 4,
                "reply_set": [
                    {
                        "id": 6,
                        "text": "some more comment",
                        "owner": "alex",
                        "article": 1,
                        "parent": 5,
                        "reply_set": []
                    }
                ]
            }
        ]
    },
    {
        "id": 5,
        "text": "some comment",
        "owner": "alex",
        "article": 1,
        "parent": 4,
        "reply_set": [
            {
                "id": 6,
                "text": "some more comment",
                "owner": "alex",
                "article": 1,
                "parent": 5,
                "reply_set": []
            }
        ]
    },
    {
        "id": 6,
        "text": "some more comment",
        "owner": "alex",
        "article": 1,
        "parent": 5,
        "reply_set": []
    }
]

我不知道如何解决以下问题:

如何获取该评论的所有评论,在第三层嵌套?

如何根据评论 API 响应重新创建树结构?

发送API请求localhost:8000/comments/1 我收到了id="1"的评论和所有嵌套的评论到第三层。如何请求获得第三级嵌套评论和所有其他评论? views和urls应该写什么?

你能检查一下这个代码是否适合你吗?

class FinalLevelRepliesSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = Comment
        fields = ['id', 'text', 'owner', 'article', 'parent']

class FirstLevelRepliesSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    reply_set = FinalLevelRepliesSerializer(many=True, read_only=True)
    class Meta:
        model = Comment
        fields = ['id', 'text', 'owner', 'article', 'parent', 'reply_set']

class CommentSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    reply_set = FirstLevelRepliesSerializer(many=True, read_only=True)

    class Meta:
        model = Comment
        fields = ['id', 'text', 'owner', 'article', 'parent', 'reply_set']