Home > Mobile >  How do I add a post method for the api view so that posts can be commented on?
How do I add a post method for the api view so that posts can be commented on?

Time:02-03

I'm building an API using DRF, and as I am a beginner, I can't get my head across this. I'm building an instagram clone using DRF and was able to attach comments and likes to each post object, but I can only attach likes and comments using the admin panel. I can see the total number of likes/comments and the user who added them as JSON Output though. Is there a way to add an add comment_form to the post_detail view?

Here's my models.py file

from __future__ import unicode_literals
import uuid
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings

# Create your models here.



class Createpost(models.Model):
    id = models.UUIDField(
          primary_key = True,
          default=uuid.uuid4,
          editable= False,
    )
    author = models.ForeignKey(User , on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    post_image = models.ImageField(upload_to='images/',blank=True)


    @property
    def total_likes(self):
        return Like.objects.filter(post_id = self.id).count()

    @property
    def likes(self):
        array = []
        for like in Like.objects.filter(post_id = self.id):
            array.append(like.author.username)
        return array
    
    @property
    def total_comments(self):
        return Answers.objects.filter(post_id = self.id).count()

    @property
    def comments(self):
        array = []
        for comment in Answers.objects.filter(post_id = self.id):
            c = {}
            c['body'] = comment.body
            c['username'] = comment.author.username
            c['created_at'] = comment.created_at
            array.append(c)
        return array

    def __str__(self):
        return self.title

class Answers(models.Model):
    post = models.OneToOneField(
        Createpost,
        primary_key=True,
        on_delete = models.CASCADE,
    )
    body = models.TextField()
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    Updated_At = models.DateTimeField(auto_now=True)
    active = models.BooleanField(default=False)

    
    def __str__(self):
        return 'Comment {} by {} '.format(self.body,self.author)
class Like(models.Model):
    post = models.OneToOneField(
        Createpost,
        primary_key=True,
        on_delete = models.CASCADE,
    )
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('post','author',)

Here's my Views.py file:

from django.shortcuts import render
from rest_framework import generics
from .models import Createpost
from .permissions import IsAuthorOrReadOnly
from .serializers import PostSerializer,PostDetailSerializer,CommentSerializer

# Create your views here.

class PostList(generics.ListCreateAPIView):
    queryset = Createpost.objects.all()
    serializer_class = PostSerializer


class PostDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsAuthorOrReadOnly,)
    queryset = Createpost.objects.all()
    serializer_class = PostDetailSerializer

Here's my serializers.py file:

from rest_framework import status
from rest_framework import serializers
from rest_framework.decorators import APIView
from .models import Createpost,Answers
from django.contrib.auth.models import User


class PostSerializer(serializers.ModelSerializer):
    totallikes = serializers.ReadOnlyField(source = 'total_likes')
    totalcomments = serializers.ReadOnlyField(source = 'total_comments')
    class Meta:
        fields = ('id','author','title','body','created_at','totallikes','totalcomments')
        model = Createpost

class CommentSerializer(serializers.Serializer):
    field1 = serializers.CharField()

class PostDetailSerializer(serializers.ModelSerializer):
    li_kes = serializers.ReadOnlyField(source = 'likes')
    com_ments = serializers.ReadOnlyField(source = 'comments')
    
    class Meta:
        fields = ('id','author','title','body','created_at','updated_at','post_image','li_kes','com_ments',)
        model = Createpost

CodePudding user response:

I don't see a comment model in your code, so it's hard to know exactly how you're going about this. But one pattern for adding comments to a post object would to create an endpoint that accepts the comment details in the request and saves them to the post. Something like:

from rest_framework import viewsets, status

class PostComment(viewsets.ModelViewSet):

    """ API endpoint for adding comments to posts """

    def create(self, request):

        Data = request.data
        payload = {'post': Data['post_id'], 'user': self.request.user.id, 'comment': Data['comment']]}
        post = UserPost.objects.get(uniqueID=Data['post_id'])
        payload['post'] = post.id

        serializer = UserCommentReplyPOSTSerializer(data=payload)

        if serializer.is_valid():
            serializer.save()
            return Response('Comment saved', status=status.HTTP_200_OK)
        else:
            print(serializer.errors)
            return Response('There was a problem with your request', status=status.HTTP_400_BAD_REQUEST)

You would then register this endpoint in your urls.py and use it in your front-end comment POST routine.

Obviously you'd need a Comment model with a foreign key to to your Post model for this to work. I'm assuming you have that and didn't show it.

  • Related