0

models.py

class Comments(UUID):
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    post = models.ForeignKey(Posts, on_delete=models.CASCADE)
    comment = models.ForeignKey(
        "self", on_delete=models.CASCADE, blank=True, null=True
    )
    text = models.TextField()
    files = models.ImageField()

serializers.py

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comments
        fields = "__all__"
        extra_kwargs = {
            "user": {"read_only": True},
            "text": {"required": False},
            "files": {"required": False}
        }

    def create(self, validated_data):
        user = self.context["request"].user
        return Comments.objects.create(user=user, **validated_data)

views.py

class PostCommentsRetrieveAPIView(generics.RetrieveAPIView):
    serializer_class = CommentSerializer

    def get(self, request, *args, **kwargs):
        replies_count = Subquery(Comments.objects.filter(
            comment=OuterRef("pk")
        ).values("comment").annotate(count=Count("pk")).values("count"))
        comment_remarks = Subquery(Remarks.objects.filter(
            comment=OuterRef("pk")
        ).values("comment").annotate(count=Count("pk")).annotate(
            popularities=popularities
        ).values("popularities"))

        # https://stackoverflow.com/questions/63020407/return-multiple-values-in-subquery-in-django-orm
        replies = Subquery(Comments.objects.filter(
            comment=OuterRef("pk")
        ).values("comment", "created_at", "updated_at").annotate(
            created=Now() - F("created_at"), created_=created_,
            updated=Now() - F("updated_at"), updated_=updated_
        ).annotate(
            details=ArrayAgg(
                JSONObject(
                    id="id",
                    user_id="user_id",
                    username="user__profile__username",
                    text="text",
                    files="files",
                    created="created_",
                    updated="updated_",
                    profile_link=profile_link,
                    profile_image=profile_picture,
                    comment_remarks=comment_remarks,
                    replies_count=replies_count
                )
            )
        ).values("details"))

        comment = Subquery(Comments.objects.filter(
            post=OuterRef("pk"), comment=None
        ).values("post", "created_at", "updated_at").annotate(
            created=Now() - F("created_at"), created_=created_,
            updated=Now() - F("updated_at"), updated_=updated_
        ).values("created_").annotate(
            details=ArrayAgg(
                JSONObject(
                    id="id",
                    user_id="user_id",
                    username="user__profile__username",
                    text="text",
                    files="files",
                    created="created_",
                    updated="updated_",
                    profile_link=profile_link,
                    profile_image=profile_picture,
                    comment_remarks=comment_remarks,
                    comment_replies=replies
                )
            )
        ).values("details"))

        post = Posts.objects.filter(id=kwargs["post_id"]).annotate(
            comment=comment,
        ).values("comment")
        return Response(post, status=status.HTTP_200_OK)

Now I just want to ask is that a best way show comments on post with nested replies, I create another files to calculate datetime, profile link, profile image, remarks on comment

this query is hitting database only one time my question is will it be fastest query to get data from database?

how to can I check that my query is fastest or not

0 Answers0