user15440172
user15440172

Reputation: 134

Pass django model query as json response

I'm working on a social network. I want to load the comments of each post so I make an API call to the server to fetch all the comments of the required posts. The code will make everything clear:

urls.py

path("comments/<int:post_id>", views.load_comments)

models.py

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    commented_by = models.ForeignKey(User, on_delete=models.CASCADE)
    comment = models.CharField(max_length=128)

views.py

def load_comments(request, post_id):
    """Returns the comments to index.js"""

    try:
        # Filter comments returned based on post id
        post = Post.objects.get(pk=post_id)

        comments = list(Comment.objects.filter(post=post).values())
        
        return JsonResponse({"comments": comments})
    except:
        return JsonResponse({"error": "Post not found", "status": 404})

index.js

fetch(`/comments/${post_id}`)
.then(res => res.json())
.then(res => {

    // Appoints the number of comments in the Modal title
    document.querySelector("#exampleModalLongTitle").textContent = `${res.comments.length} Comments`;

    res.comments.forEach(comment => {
        
        modal_body = document.querySelector(".modal-body")

        b = document.createElement("b");
        span = document.createElement("span");
        br = document.createElement("br");
        span.classList.add("gray")

        b.textContent = comment.commented_by_id + " ";
        span.textContent = comment.comment;

        modal_body.appendChild(b);
        modal_body.appendChild(span);
        modal_body.appendChild(br);

    })

I can get the comment value using comment.comment in js. However, the problem arises when I convert the comments objects to list.values so now I lose the ability to get the user who posted the comment (commented_by)

Any help to get the comment and commented_by values is appreciated.

I also tried in views.py:

def load_comments(request, post_id):
    """Returns the comments to index.js"""
    try:
        # Filter comments returned based on post id
        post = Post.objects.get(pk=post_id)

        post_comments = Comment.objects.filter(post=post)
        
        comments = []

        for comment in post_comments:
            comments.append({
                "comment": comment.comment,
                "commented_by": commented_by,
                })

        comments = serializers.serialize('json', comments)
        return HttpResponse(comments, content_type='application/json')
        
    except:
        return JsonResponse({"error": "Post not found", "status": 404})

However when I try this, it outputs the error.

Upvotes: 1

Views: 869

Answers (2)

Igor Moraru
Igor Moraru

Reputation: 7729

In Django, the values() function for a ForeignKey field by default returns the id of the related object with the key formed by appending the name of the field with "_id". So in your case, you have your user ID under the key commented_by_id.

If by "loosing the ability to get the user who posted the comment" you mean other user info, like username, then you can pass the fields that you need to the values() function.

comments = list(Comment.objects
                       .filter(post=post)
                       .values("comment", 
                               "commented_by__username"
                               ))

will give a dict with the comment text and the user name (assuming that you have a username field in your User model.

Upvotes: 1

zain al-abdeen
zain al-abdeen

Reputation: 95

1- you should use django_Rest_framework cuz it's very easy to work with api and show related field

2- use Post.objects.get(id=post_id) instead of pk

or you should skip this step by filter the comments depend on post id directly likeComment.objects.all().filter(post_id=post_id)

Upvotes: 0

Related Questions