Alex Yu
Alex Yu

Reputation: 25

What API request should I send to receive graph parameters?

I have a blog on django. I have two models article and comment. Each comment can be added to another one. If I send an API request localhost:8000/comments/1 I receive the comment with id="1" and all the nested comments to the third level.

json after api request localhost:8000/comments/ :

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

[
    {
        "id": 9,
        "text": "First comment",
        "owner": "alex",
        "article": 3,
        "parent": null,
        "reply_set": [
            {
                "id": 10,
                "text": "Comment to comment",
                "owner": "alex",
                "article": 3,
                "parent": 9,
                "reply_set": [
                    {
                        "id": 11,
                        "text": "Third level nested comment",
                        "owner": "alex",
                        "article": 3,
                        "parent": 10
                    }
                ]
            }
        ]
    },
    {
        "id": 10,
        "text": "Comment to comment",
        "owner": "alex",
        "article": 3,
        "parent": 9,
        "reply_set": [
            {
                "id": 11,
                "text": "Third level nested comment",
                "owner": "alex",
                "article": 3,
                "parent": 10,
                "reply_set": [
                    {
                        "id": 12,
                        "text": "Forth level nested comment",
                        "owner": "alex",
                        "article": 3,
                        "parent": 11
                    }
                ]
            }
        ]
    },
    {
        "id": 11,
        "text": "Third level nested comment",
        "owner": "alex",
        "article": 3,
        "parent": 10,
        "reply_set": [
            {
                "id": 12,
                "text": "Forth level nested comment",
                "owner": "alex",
                "article": 3,
                "parent": 11,
                "reply_set": []
            }
        ]
    },
    {
        "id": 12,
        "text": "Forth level nested comment",
        "owner": "alex",
        "article": 3,
        "parent": 11,
        "reply_set": []
    }
]

How to receive the third level comment with all others nested comment? What should I write in views and urls?

Comment model:

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']

Comment serializer:

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']

Comment views

class CommentList(generics.ListCreateAPIView):
    queryset = Comment.objects.all()
    serializer_class = serializers.CommentSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

class CommentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Comment.objects.all()
    serializer_class = serializers.CommentSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly]

In urlpatterns:

path('comments/', views.CommentList.as_view()),
path('comments/<int:pk>/', views.CommentDetail.as_view())

Upvotes: 0

Views: 47

Answers (1)

Sherif Hassan
Sherif Hassan

Reputation: 167

if your question is how can you receive all 3rd level comments (without their parents just the third level comments) of a specific 1st level comment, then you could filter the queryset like this

third_level_comment = Comment.objects.filter(replay_set__replay_set__id = <the 1st level comment id>)

you use the double under score "__" to go up a level on the relation chain

Upvotes: 1

Related Questions