DRF+React로 Blog(유사 velog) 만들어보기 (4) 게시글 모델 Serializer, View 만들기 + Urls 연결

HEYDAY7·2021년 4월 19일
0

이번 글은 분량 조절의 실패로 내용이 아주 길다... 천천히 짤라가며 읽어보는 것을 추천한다.

앞서 만들었던 Post, Comment, Series 모델에 대응되는 serializer와 view를 만들어본다.

시작전에 팁을 하나 주자면, Serializer와 Views에 대해서 그 구조를 공부하는 것이 가장 좋은 공부법이다. 작동 방식을 직접 배울 수 있기 때문이다. 이에 좋은 사이트를 하나 소개한다.
내가 DRF에 대해 공부하기 시작할 때부터 사용해서 지금도 유용하게 사용하고 있다!! 모르는게 생길 때 마다 들어가서 구조를 들여다보자

Serializer

Django-rest-framework의 기본 틀에 포함되는 구현으로 queryset이나 model instance를 JSON과 같은 형태로 쉽게 렌더링 할 수 있게 도와준다. 또 역으로 JSON같은 형태로 들어오는 데이터를 객체형태로 바꿔주는 Deserialization 기능도 제공해서 input 데이터에 대한 validation 역할을 수행한다.

board/serializers.py 파일을 생성하고 그 안에 코드를 작성해보자

우선 다음과 같이 rest_framework가 제공하는 serializers 기능과, 앞서 만들었던 모델들을 import 해오고서 작성을 시작하자.


  • Comment Serializer
    Serializer에는 여러가지 형태가 있지만, 지금과 같이 하나의 모델에 직접적으로 관계되는 serializer의 경우 ModelSerializer를 이용하면 편하다.

    코드는 보시다시피 매우 간단하다. Model Serializer를 사용할 경우 Meta class를 정의해서 model을 명시하고 serializer에서 쓸 field를 fields 안에 넣어주기만 하면 된다.
    한 가지 짚고 넘어갈 점은 위에서 주석처리해둔 코드들은 사실 쓰지 않아도 큰 상관이 없다. user와 post 모두 foreign key field이기 때문이다. 다만 serializer의 data를 호출했을 때는 차이가 있다.
    이것이 적지 않았을 경우
    이것이 적었을 경우이다.
    개인적으로 적었을 경우를 선호해서 위 코드에서 주석처리를 풀고 작성했다.

  • Post와 Series Serializer

    새로운 내용은 딱 하나로 그 점만 짚고 넘어간다. 두 Serializer 모두 다른 Serializer를 serializerField로 받고 있는 것을 볼 수 있다. 이러한 구현은 NestedSerializer라고 한다. 이해를 위해 예시를 하나 든다.

    Post와 Series는 N:1의 관계이며, 따라서 Post는 Series 하나를 칭하는 field(series), Series는 Post 여러개를 갖는 field를 지니게 된다(posts). 이 경우 posts field를 PostSerializer로 지정하고 many=True와 read_only=True를 주는 것으로 간단하게 1:N 관계를 나타낼 수 있다.

Views

Django에서는 MVC를 MTV라고 표현한다. Model-Template-View로, 위치상 View -> Template, Controller -> View이다. 즉, Django에서의 View는 controller의 역할을 하며 model과 template을 이어준다. 따라서!! View에 CRUD를 포함한 비즈니스 로직이 들어가고, View를 통해서만 model이 CRUD 되어야한다!

아주 행복한 얘기를 하나 하자면 DRF에서는 Viewset이라는 아름다운 기능을 제공한다. 이게 왜 아름다운지는 바로 살펴보겠다.(Views와 비교해보면 좋다)

이에 앞서 우선적으로 필요한 것들을 import 해주자. 파일은 board/views.py이다.


  • SeriesViewSet
    가장 간단하다. Serializer와 비슷하게 ModelViewSet이라는 것이 존재하며, 이는 ViewSet의 기능이 Model의 CRUD일 경우 엄청난 효율성을 보여준다.

    ModelViewSet의 경우 request method에 따라 각기 다른 작업을 수행한다.
    POST -> Create
    GET -> Read
    PUT -> Update
    DELETE -> Delete
    View로 작성할 경우 각기 다른 View를 만들어야 하지만 ModelViewSet으로 할 경우 한 번에 이 네가지를 다 처리할 수 있다.
    이 부분이 이해가 되지 않아도 괜찮다. 1~2개의 글을 더 읽고 나면 이해할 수 있을 것이다.

위 세 줄로 SeriesViewSet 작성 완료다. ModelViewSet의 경우 queryset과 serializer_class를 지정해줘야 한다.이후에 urls 연결만 해준다면 바로 Series를 CRUD 할 수 있게 된다.


  • PostViewSet
    perform_create function을 override 하는 코드가 추가되었다. 이 perform_create는 Create를 실행하는 중간 과정에 해당하는 함수다. override 하는 이유는 바로 Post에 User를 주입시켜 주기 위해서이다.

    나중에 일이지만 우리는 authentication을 위해 sessionid를 사용할 것이고, 그렇다면 request.user를 통해 user가 누구인지 알 수 있게되어, 따로 input을 받지 않고 그 user를 글의 작성자로 주입시켜 주는 것이다.


  • CommentViewSet

    perform_create override를 통해 User를 주입하는 것은 동일하지만 추가적으로 post도 주입해준다. 이 self.kwargs를 통해 post_id를 받아오는 부분은 바로 아래 urls에서 추가 설명하겠다.

Urls 연결

이 부분은 만든 Rest API의 endpoint를 제공하는 부분이다. 즉 서버가 띄워졌을 때 A라는 Url로 request가 들어오면 B라는 View를 연결해주는 식이다.
일단 코드를 따라 적어보자


blog_back/urls.py


이 urls.py 는 root urls로 다른 urls.py에서 작성한 url들을 한군데 모아주는 역할을 한다. 우리는 board.urls에 url을 작성할 예정이라 이를 미리 연결해준다.


board/urls.py

ViewSet을 이용할 때의 강점이 바로 이거다. Router 기능을 이용하여 아주 간단하게 url연결을 할 수 있다. 관련된 정보는 위 링크에서 학습하면 된다.

위 Comment에서 self.kwargs를 사용하였던 부분이 여기 line. 7에 나온다.
line. 7을 보면 CommentViewSet과 연결되는 url이 'post/[post_id]/comment'가 되는 것을 알 수 있다. 즉 저 url을 통해서 comment에 접근할 수 있는 것이고 다시말해 request가 올 때, request url이 post_id를 알고 있는 것이다. 따라서 kwargs로 받아서 해당 Post를 Comment create 시에 주입시켜 주는 형태이다.


서버 구동 및 확인

project root에서 서버를 켜서 잘 연결되었는지 확인해보자

pipenv shell
cd blog_back
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

지난시간 model 생성 후 migrate를 안했기 때문에 해준후에 server를 키자. 그 후에 127.0.0.1:8000으로 접속했을 때 아래와 같은 화면이 뜨면 성공이다

CRUD가 잘 되는 것을 확인해보기 위해 Insomnia라는 툴을 설치해서 확인하였다.
다만 아직 User 생성에 대한 로직을 구현하지 않아서 User를 제공하지 못하기 때문에 Post와 Comment는 CRUD기능을 확인해보지 못한다.

따라서 Series로 확인해보자

  • POST를 통해 생성
  • GET Method를 통해 생성된 series 확인
  • PUT Method를 통해 series 수정 확인
  • GET Method를 통해 수정된 series 확인
  • DELETE Method를 통해서 series 삭제
  • 다시한번 GET Method으로 최종 확인

이렇게 CRUD를 성공적으로 구현했다!
이제 여러분은 모델을 마음대로 조작할 수 있게 된 것이다. 생각보다 간단하지 않은가?
다음 글에서는 User Account에 대한 작업을 진행해보겠다.

profile
(전) Junior Android Developer (현) Backend 이직 준비생

0개의 댓글