[D.R.F] Generic CBV로 게시글 C.R.U.D API 구현하기

2021. 11. 22. 20:44코딩일지/DRF

 

Django Generic CBV 

이전 게시글에서는 Mixin의 상속이라는 특성을 사용해서 이미 구현되어있는 로직을 불러와서 사용해 코드의 중복을 줄였습니다.

 

이번에는 또 다른 방법인 Generic CBV의 상속을 통해 불필요한 중복을 없애주는 로직을 짜 보겠습니다. 

 

Mixin CBV에서 수정한 models.py와 serializers.py를 사용하겠습니다.

 

1. generic을 활용한 Views.py 작성

원래 불러와져있던 mixins를 지워주고 generic만 불러와줍니다.

 

APIView와 mixins을 사용했을 때보다 코드가 훨씬 더 간결해진 것을 확인할 수 있습니다.

  • views.py 작성
from .models      import Board, Comment
from .serializers import BoardSerializers, CommentSerializers, BoardDetailSerializers

from rest_framework 	     import generics, status
from rest_framework.response import Response


# 게시글의 목록과 생성
class BoardList(generics.ListCreateAPIView):
    queryset         = Board.objects.all()
    serializer_class = BoardSerializers

# 게시글불러오기와 수정, 삭제
class BoardDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Board.objects.all()
    serializer_class = BoardSerializers

    '''1개의 게시글을 불러올 때 댓글을 같이 불러와야 한다.
    'GET'요청이 들어올 때 불러오는 serializer_class에 따로 생성한
    Serializers를 불러오게 합니다.'''
    def get_serializer_class(self):
        if self.request.method == 'GET':
            self.serializer_class = BoardDetailSerializers
        return self.serializer_class

# 게시글에 댓글달기
class CommentCreate(generics.CreateAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializers

    #board = pk값을 지정해서 원하는 게시글의 댓글만 생성하게끔 오버라이드한다.
    def create(self, request, pk, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer, pk)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    #save()변수를 지정해 시리얼라이저에서 따로 지정해줄 필요 없다.
    def perform_create(self, serializer, pk):
        serializer.save(board_id = pk)

# 댓글 수정,삭제
class CommentUpdate(generics.RetrieveUpdateDestroyAPIView):

    queryset = Comment.objects.all()
    serializer_class = CommentSerializers
    lookup_url_kwarg = 'comment_pk'

 

generics.py의 APIView구조에 들어가 보면 아래의 사진처럼 되어있습니다.

 

어디서 많이본 구조이지 않나요? 

 

맞습니다. MixinsCBV를 짠 구조와 동일합니다.

 

이처럼 상속을 통해서 우리는 중복을 제거하고 편하게 Views.py를 작성할 수 있습니다.

 

  • generis.py /ListCreateAPIView, RetrieveUpdateAPIView

 



2. URL 지정

url 또한 전에 사용했던 urls.py를 그대로 사용합니다.

  • urls.py 작성
from django.urls import path

from .views import BoardList, BoardDetail, CommentCreate, CommentUpdate


app_name = 'boards'

urlpatterns = [
    path('', BoardList().as_view()),
    path('<int:pk>/', BoardDetail.as_view()),
    path('<int:pk>/comments/', CommentCreate.as_view()),
    path('<int:pk>/comments/<int:comment_pk>', CommentUpdate.as_view())
]

 

3. 서버 가동

  • 서버 실행
python manage.py runserver

 

4. 기능 확인

Mixins에서 게시글 CRUD를 했으니 댓글 기능 확인해보겠습니다.

 

  • GET/1 

 

127.0.0.1:8000/Board/1 [GET/PUT/DELETE]

 

  • COMMENTS POST

 

127.0.0.1:8000/Board/1/comments [POST]

 

  • COMMENTS/22 DELETE UPDATE 

 

127.0.0.1:8000/Board/1/comments [GET/PUT/DELETE]

 

  • 삭제 성공 및 1번 게시글 확인

 

삭제 성공~!
사라진 22번 댓글

 

이번엔 generics를 기반으로 한 C.R.U.D를 작성해보았습니다.

 

보시다시피 Mixins CBV에서 상속을 받아와 코드를 작성하기에 더 간결해졌습니다. 

 

처음 FBV와 CBV APIView와 비교해보면 확연히 많이 줄어든 코드를 보여줍니다.

 

다음 시간에는 마지막 Viewset으로 작성해서 DRF C.R.U.D 마무리하겠습니다.

 

긴 글 읽어주셔서 감사합니다