DRF 4-7 댓글 CRUD

Grace Goh·2022년 11월 12일
0

Django Rest Framework

목록 보기
18/36

articles/models.py

from django.db import models
from users.models import User


class Article(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE) # 삭제할 때 없애준다
    title = models.CharField(max_length=50)
    content = models.TextField()
    image = models.ImageField(blank=True, upload_to='%Y/%m/')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.title)


# 댓글. 필요한 필드를 생각해보기. class를 def 위치에 쓰지 않도록 주의
class Comment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    article = models.ForeignKey(Article, on_delete=models.CASCADE) # 게시글 삭제시 댓글도 삭제됨
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
        
    # string method를 추가한다.
    def __str__(self):
        return str(self.content)

model을 만들었으니 makemigrations, migrate
만든 model을 테스트해보려면 admin에서 테스트해본다.

admin에 등록하기

# articles/admin.py

from django.contrib import admin
from articles.models import Article, Comment # 추가

admin.site.register(Article)
admin.site.register(Comment) # 추가

# articles/urls.py

from django.urls import path 
from articles import views


urlpatterns = [
    path('', views.ArticleView.as_view(), name='article_view'),
    path('<int:article_id>/', views.ArticleDetailView.as_view(), name='article_detail_view'),
    path('<int:article_id>/comment/', views.CommentView.as_view(), name='comment_view'),
    path('<int:article_id>/comment/<int:comment_id>', views.CommentDetailView.as_view(), name='comment_detail_view'),
    path('<int:article_id>/like/', views.LikeView.as_view(), name='like_view'),
]

Serializer 작성 후
# articles/serializers.py

from rest_framework import serializers
from articles.models import Article, Comment


class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = '__all__'


class CommentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ("content",)
        # fields 안에 1개만 쓸 때 ,를 꼭 붙여야 한다. 안 쓰면 str로 인식

import 한다. Article(Create)View를 복사해서 Comment(Create)View를 만든다.
# articles/views.py

from rest_framework.generics import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status, permissions
from rest_framework.response import Response
from articles.models import Article, Comment # 추가
from articles.serializers import ArticleSerializer, ArticleListSerializer, ArticleCreateSerializer, CommentSerializer, CommentCreateSerializer


class ArticleView(APIView):
    def get(self, request):
        articles = Article.objects.all() # 모두
        serializer = ArticleListSerializer(articles, many=True) # 복수
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        # 먼저 serializer를 불러온다. () 안에 데이터를 저장한다.
        serializer = ArticleCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# id가 있어야 쓰는 API. 인자가 1개 더 있다.
class ArticleDetailView(APIView):
    def get(self, request, article_id):
        # article = Article.objects.get(id=article_id) 아래가 더 효율적인 코드
        article = get_object_or_404(Article, id=article_id)
        serializer = ArticleSerializer(article)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 수정
    def put(self, request, article_id):
        article = get_object_or_404(Article, id=article_id)
        if request.user == article.user:
            serializer = ArticleCreateSerializer(article, data=request.data)
            if serializer.is_valid():
                serializer.save() # article에 user 정보 있기 때문에 (user=request.user) 생략
                return Response(serializer.data, status=status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)

    # 삭제
    def delete(self, request, article_id):
        article = get_object_or_404(Article, id=article_id)
        if request.user == article.user:
            article.delete()
            return Response("삭제되었습니다.", status=status.HTTP_204_NO_CONTENT)
        else: 
            return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)


class CommentView(APIView):
    # 해당 게시글의 댓글을 불러오기. 댓글은 상세페이지 없고 댓글 리스트, 수정, 삭제 있다.
    def get(self, request, article_id):
        article = Article.objects.get(id=article_id)
        comments = article.comment_set.all() # article에 대해 작성된 comment와 쿼리셋을 불러온다.
        serializer = CommentSerializer(comments, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request, article_id):
        serializer = CommentCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user, article_id=article_id) # article=Article.objects.get(id=article_id)
            return Response(serializer.data, status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CommentDetailView(APIView):
    def put(self, request, article_id, comment_id):
        comment = get_object_or_404(Comment, id=comment_id)
        if request.user == comment.user:
            serializer = CommentCreateSerializer(comment, data=request.data)
            if serializer.is_valid():
                serializer.save() # article에 user 정보 있기 때문에 (user=request.user) 생략
                return Response(serializer.data, status=status.HTTP_200_OK)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)

    def delete(self, request, article_id, comment_id):
        comment = get_object_or_404(Comment, id=comment_id)
        if request.user == comment.user:
            comment.delete()
            return Response("삭제되었습니다.", status=status.HTTP_204_NO_CONTENT)
        else: 
            return Response("권한이 없습니다.", status=status.HTTP_403_FORBIDDEN)


class LikeView(APIView):
    def post(self, request, article_id):
        pass

profile
Español, Inglés, Coreano y Python

0개의 댓글