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.