drf์์ ๊ฒ์๊ธ ์กฐํ์, ์ถ์ฒ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
์กฐํ์์ ์ถ์ฒํ๊ธฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด ์ฐ์ ๋ชจ๋ธ์ likes์ views ํ๋(ManyToManyField)๋ฅผ ์ถ๊ฐํ๋ค.
likes = models.ManyToManyField(User, blank=True, related_name='article_likes')
views = models.ManyToManyField(User, related_name='article_views')
๊ทธ ๋ค์ ๊ฒ์๊ธ ์์ธ serializer์์ views๋ฅผ SerializerMethodField()๋ก obj.views.count()๋ก ์ปค์คํ ํ ํ count + 1์ ํด์ฃผ์๋๋ฐ save๊ฐ ๋์ง ์์๋ค.
class ArticleDetailSerializer(serializers.ModelSerializer):
views = serializers.SerializerMethodField()
def views(self, obj):
return obj.views.count() +1
class Meta:
model = Article
exclude = ('created_at',)
๋ค์ views์์ serializer๋ฅผ is_valid()๋ก ๊ฒ์ฆ ํ save๋ฅผ ํ๋๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด์ views์ count๋ฅผ ๋๋ฆด ์ ์์๋ค.
๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก like ๋ก์ง์ฒ๋ผ ์๋์ ๊ฐ์ด ์๋ํ์ฌ views ํ ์ด๋ธ์ request user๊ฐ ์์ ๊ฒฝ์ฐ add๋ก ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์ฑ๊ณตํ์ผ๋ ๋ก๊ทธ์ธ ๋ ์ฌ์ฉ์๊ฐ ์กฐํํ์ ๋๋ง ์กฐํ ์๊ฐ ์ฌ๋ผ๊ฐ๋๋ก ํ ์ ์์๊ณ , ํ์๋ค๊ณผ ์์ํ์ ๋น๋ก๊ทธ์ธ ์ ์ ๋ ์กฐํํ์ ๋ ์กฐํ์๊ฐ ์ฆ๊ฐํ๋ ๊ฒ์ผ๋ก ๊ฒฐ์ ๋์ด ๋ค์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์์ ํ๋ค.
class ArticleDetailView(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get(self, request, article_id):
article = get_object_or_404(Article, id=article_id)
if request.user.is_authenticated:
article.views.add(request.user)
serializer = ArticleDetailSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
๋จผ์ ๋ชจ๋ธ๋ถํฐ ManyToManyField ๋์ BigIntegerField๋ฅผ ์ฌ์ฉํ์ฌ serializer์์ viewsํ๋๋ฅผ .count๋ก ์ปค์คํ ํ ํ์๊ฐ ์์ด views๋ฅผ ๋ฐ๋ก +1๋ก ์ฌ๋ฆด ์ ์๋๋ก ์์ ํ๋ค.
like = models.ManyToManyField(User, blank=True, related_name='article_like')
views = models.BigIntegerField(default=0)
๊ทธ๋ฆฌ๊ณ ์ด๋ฒ์ serializer๋ก saveํ๋ ๋ฐฉ๋ฒ๊ณผ views ํ ์ด๋ธ์ add๋ก ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ ๋์ views.py์ ArticleDetailView์์ article์ ํน์ ํ ํ article์ viewsํ๋์ +1๋ก views๊ฐ ๋์ด๋๊ฒ ํ๊ณ , save๋ก ์ ์ฅํด๋ณด์๋ค.
class ArticleDetailView(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get(self, request, article_id):
article = get_object_or_404(Article, id=article_id)
article.views += 1
article.save()
serializer = ArticleDetailSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
์ฑ๊ณต์ ์ผ๋ก GET์์ฒญ์ด ์ฌ ๋ ๋ง๋ค ํด๋น ๊ฒ์๊ธ์ ์กฐํ์๊ฐ ๋์ด๋๋ ๊ฒ์ ํ์ธํ ์ ์์๊ณ ์ถ์ฒ ๊ธฐ๋ฅ์ ์์์ ์๋ํ ๋ฐฉ๋ฒ์ผ๋ก article์ Like ํ ์ด๋ธ์ request.user๊ฐ ์๋ ๊ฒฝ์ฐ addํ๋ ๋ฐฉ์์ผ๋ก ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์๋ค.