danirus / django-comments-xtd

A pluggable Django comments application with thread support, follow-up notifications, mail confirmation, like/dislike flags, moderation, a ReactJS plugin and Bootstrap 5.3.
https://django-comments-xtd.readthedocs.io
BSD 2-Clause "Simplified" License
594 stars 158 forks source link

Include comment id in Comment Create API response #255

Closed rollue closed 3 years ago

rollue commented 3 years ago

Currently the comment id is missing from the comment create API response. When a user leaves a comment, he/she might want to delete the comment immediately. Unless we get the id in response to create(POST) request, this means we have to refresh the page to fetch the comment list on another request.

I have looked at the code to customize this behavior, but currently, it seems difficult to override the view or the serializer to achieve this. The best try is to use the self.resp_dict that contains XtdComment instance in CommentCreate API view, but I still have to rewrite the post method - it doesn't look pretty to me.

class CommentCreate(generics.CreateAPIView):
    """Create a comment."""
    serializer_class = serializers.WriteCommentSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            response = super(CommentCreate, self).post(request, *args, **kwargs)  
            # but using the self.resp_dict still requires rewriting the logic below here.
            # something like this works, but it's kind of an ugly hack.
            # response.data["id"] = self.resp_dict["comment"]["xtd_comment"].id
        else:
            if 'non_field_errors' in serializer.errors:
                response_msg = serializer.errors['non_field_errors'][0]
            else:
                response_msg = [k for k in six.iterkeys(serializer.errors)]
            return Response(response_msg, status=400)
        if self.resp_dict['code'] == 201:  # The comment has been created.
            return response
        elif self.resp_dict['code'] in [202, 204, 403]:
            return Response({}, status=self.resp_dict['code'])

    def perform_create(self, serializer):
        self.resp_dict = serializer.save()  # may use the self.resp_dict

Any suggestions? I think it's worth making this field as default.

rollue commented 3 years ago

This was the best I can do - just in case someone needs this.

class CommentCreate(base_views.CommentCreate):
    ...

    def post(self, request, *args, **kwargs):
        resp = super().post(request, *args, **kwargs)
        if self.resp_dict['code'] == 201:  # The comment has been created.
            resp.data["id"] = self.resp_dict["comment"]["xtd_comment"].id
        return resp
danirus commented 3 years ago

Hi @mhoonjeon. Indeed, when the response code is 201, it should return the id of the new created message.

danirus commented 3 years ago

The fix for this issue has been released with v2.8.2.