Skip to content

Commit

Permalink
189 - Like Post (#231)
Browse files Browse the repository at this point in the history
* feat: introduce model for post reaction

* feat: add post in PostReaction

* feat: add missing related name

* feat: post reactions retreive and admin registery

* feat: post reaction create/update view
  • Loading branch information
MAbdurrehman1 authored Aug 27, 2024
1 parent 6611cb6 commit 7523ce2
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 10 deletions.
3 changes: 2 additions & 1 deletion thenewboston/social/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.contrib import admin

from .models import Comment, Follower, Post
from .models import Comment, Follower, Post, PostReaction

admin.site.register(Comment)
admin.site.register(Follower)
admin.site.register(Post)
admin.site.register(PostReaction)
51 changes: 51 additions & 0 deletions thenewboston/social/migrations/0006_postreaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Generated by Django 4.2.3 on 2024-08-18 13:48

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("social", "0005_follower_follower_unique_follower_following"),
]

operations = [
migrations.CreateModel(
name="PostReaction",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_date", models.DateTimeField(auto_now_add=True)),
("modified_date", models.DateTimeField(auto_now=True)),
("reaction", models.CharField(max_length=10)),
(
"post",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="user_reactions",
to="social.post",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
]
1 change: 1 addition & 0 deletions thenewboston/social/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .comment import Comment # noqa: F401
from .follower import Follower # noqa: F401
from .post import Post # noqa: F401
from .post_reaction import PostReaction # noqa: F401
13 changes: 13 additions & 0 deletions thenewboston/social/models/post_reaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.db import models

from thenewboston.general.models import CreatedModified


class PostReaction(CreatedModified):
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
post = models.ForeignKey('social.Post', related_name='user_reactions', on_delete=models.CASCADE)

reaction = models.CharField(max_length=10)

def __str__(self):
return f'{self.user}-{self.reaction}'
12 changes: 5 additions & 7 deletions thenewboston/social/serializers/post.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from rest_framework import serializers

from thenewboston.general.utils.image import process_image
from thenewboston.social.serializers.post_reaction import PostReactionsReadSerializer
from thenewboston.users.serializers.user import UserReadSerializer

from ..models import Post
Expand All @@ -10,17 +11,14 @@
class PostReadSerializer(serializers.ModelSerializer):
comments = CommentReadSerializer(many=True, read_only=True)
owner = UserReadSerializer(read_only=True)
user_reaction = serializers.CharField()
user_reactions = PostReactionsReadSerializer(many=True, read_only=True)

class Meta:
model = Post
fields = (
'comments',
'content',
'created_date',
'id',
'image',
'modified_date',
'owner',
'comments', 'content', 'created_date', 'id', 'image', 'modified_date', 'owner', 'user_reaction',
'user_reactions'
)
read_only_fields = (
'comments',
Expand Down
32 changes: 32 additions & 0 deletions thenewboston/social/serializers/post_reaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from rest_framework import serializers

from thenewboston.users.serializers.user import UserReadSerializer

from ..models import PostReaction


class PostReactionsReadSerializer(serializers.ModelSerializer):
user = UserReadSerializer(read_only=True)

class Meta:
model = PostReaction
fields = ('reaction', 'user')
read_only_fields = (
'user',
'reaction',
)


class PostReactionCreateUpdateSerializer(serializers.ModelSerializer):

class Meta:
model = PostReaction
fields = ['post', 'reaction']

def create(self, validated_data):
post = validated_data.get('post')
reaction = validated_data.get('reaction')
user = self.context['request'].user

post_reaction, _ = PostReaction.objects.update_or_create(user=user, post=post, defaults={'reaction': reaction})
return post_reaction
7 changes: 6 additions & 1 deletion thenewboston/social/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from django.urls import include, path
from rest_framework.routers import SimpleRouter

from .views.comment import CommentViewSet
from .views.follower import FollowerViewSet
from .views.post import PostViewSet
from .views.post_reaction import PostReactionCreateUpdateView

router = SimpleRouter(trailing_slash=False)
router.register('comments', CommentViewSet)
router.register('followers', FollowerViewSet)
router.register('posts', PostViewSet)

urlpatterns = router.urls
urlpatterns = [
path('', include(router.urls)),
path('post_reaction/', PostReactionCreateUpdateView.as_view(), name='post-reaction-create-update'),
]
17 changes: 16 additions & 1 deletion thenewboston/social/views/post.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.db.models import OuterRef, Subquery
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, viewsets
from rest_framework.parsers import FormParser, MultiPartParser
Expand All @@ -8,7 +9,7 @@
from thenewboston.general.permissions import IsObjectOwnerOrReadOnly

from ..filters.post import PostFilter
from ..models import Post
from ..models import Post, PostReaction
from ..serializers.post import PostReadSerializer, PostWriteSerializer


Expand All @@ -34,6 +35,20 @@ def get_serializer_class(self):

return PostReadSerializer

def get_queryset(self):
queryset = super().get_queryset()
if self.action in ['retrieve', 'list']:
print('YES: ', self.action)

queryset = queryset.annotate(
user_reaction=Subquery(
PostReaction.objects.filter(user=self.request.user, post=OuterRef('pk')
).values_list('reaction', flat=True)[:1]
)
).prefetch_related('user_reactions', 'owner')

return queryset

def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
Expand Down
17 changes: 17 additions & 0 deletions thenewboston/social/views/post_reaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from ..serializers.post_reaction import PostReactionCreateUpdateSerializer


class PostReactionCreateUpdateView(APIView):
permission_classes = [IsAuthenticated]

def post(self, request, *args, **kwargs):
serializer = PostReactionCreateUpdateSerializer(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
serializer.save()

return Response(status=status.HTTP_200_OK)

0 comments on commit 7523ce2

Please sign in to comment.