[Django]REST API CRUD Server 만들기 2 - DRF

2021. 11. 26. 15:18 Python/Django

지난번 포스팅을 통하여 API Server 를 만들기 위한 준비를 전부 하였다. 이제부터는 Serializer를 활용하여 데이터를 주고 받을 수 있는 페이지를 만들어 볼 것이다.

 

Serializer 생성

# app이름/serializer.py 생성

from rest_framework import serializers # serializer import
from .models import User # 선언한 모델 import

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User  # 모델 설정
        fields = ('id', 'username', 'age', 'city')  # 필드 설정

Serializer를 위해 app의 하위 폴더에 serializer.py 파일을 생성한다. seralizer 와 이전에 만든 모델을 전부 import 하여 준다.

UserSerializer 라는 클래스를 생성하는데 ModelSerializer를 활용한다.

ModelSerializer 클래스를 사용하면 Model에 정의한 필드에 해당하는 값을 Serializer 에서 사용할 수 있다.

model 로는 User 모델을 사용하고, fields 에 사용하고 싶은 필드들을 나열해주면 된다. '__all__' 을 사용할 경우에는 모든 필드를 사용하겠다는 의미이다.

 

Viewset 생성

from rest_framework import viewsets # vieset import
from .serializers import UserSerializer # 생성한 serializer import
from .models import User # User model import

class UserViewSet(viewsets.ModelViewSet): # ModelViewSet 활용
    queryset = User.objects.all()
    serializer_class = UserSerializer

ModelViewSet은 기본적으로 Create, Retrieve, Update, Partial_Update, Destroy, List 를 지원한다.

즉, ModelViewSet을 생성만하면 간단하게 CRUD 기능을 구현할 수 있음을 의미한다.

 

모델명.objects.all() 의 의미

모델에 존재하는 테이블의 데이터를 전부 가져오겠다는 뜻이다. 즉 SQL 문에서 select * from User; 에 해당하는 장고 ORM 이다.

Serializer_class 의 의미

이전에 생성하였던 UserSerializer 클래스를 이용하겠다는 뜻이다.

 

Viewset 의 장점

  • 반복되는 로직을 하나의 클래스로 결합할 수 있음 -> queryset 을 단 한번만 정의하면 됨
    (APIView 의 경우 CRUD 로직을 각각 작성해야함)
  • Router를 사용함으로써, URL 설정을 다룰 필요가 없음

 

Router 등록 

# 프로젝트명/urls.py 

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls), # admin path 지정
    path('', include('board.urls')), # board/urls.py 사용
]
# 앱이름/urls.py 생성

from django.urls import include, path
from rest_framework import routers  # router import
from . import views  # views.py import

router = routers.DefaultRouter()  # DefaultRouter 설정
router.register('user', views.UserViewSet)  # ViewSet과 함께 user라는 router 등록

urlpatterns = [
    path('', include(router.urls)),
]

기존에 존재하는 urls.py 에 새로운 파일을 include 하고, app이름/urls.py 파일을 새로 생성하여 위의 코드와 같이 작성하여 준다.

DefaultRouter 를 설정하고 user라는 router를, 만들었던 UserViewSet 과 함께 등록하여 준다.

이후에 urlpatterns 에 router의 url을 path로서 추가시켜주면 된다.

여기까지 작업을 완료하였으면 runserver를 통해 서버를 가동시키고 접속하면 새로운 화면이 나타나게 된다.

 

변경된 장고 페이지

위 페이지에서 해당 링크를 클릭하면 데이터베이스의 저장된 값을 보여주는 페이지로 이동하게 된다.(READ에 해당)

 

데이터베이스에 저장된 값 조회 (READ)

값을 아직 넣은 경우가 아니라면 출력되는 값이 없을 것이다. 하지만 밑의 form 에서 값을 넣고 POST(CREATE) 버튼을 누르면 실제로 데이터베이스에 값이 저장되고 조회할 수 있게 된다. 

이전에 Serializer 기능을 활용하였기 때문에 DB data 형식 -> JSON 형식으로 변환된 값을 받아볼 수 있는 것이다.

 

DELETE, PUT

leffept.com:801/user/id값 을 입력하게 되면 해당 컬럼에 대한 정보를 삭제하고 수정할 수 있는 페이지로 이동하게 된다. (DELETE, PUT)

이렇게 DRF를 사용하면 간단하게 CRUD 기능을 수행하는 API 서버를 만들 수 있다. 추후에는 프론트엔드(클라이언트)에서 요청을 통해 서버로 값을 전송시키는 방법에 대해 알아볼 예정이다.

 

Serializer & 백엔드와 프론트엔드의 분리

이전 포스팅에서 DRF를 사용하면 Serializer 기능, 백엔드 프론트엔드 분리가 가능하다고 설명하였다. 

여기서는 Serialization을 통하여 DB data 형식의 값을 json 형식의 데이터로 변경하여 출력하고 있다. 즉, 프론트엔드(클라이언트)에서 
서버로 값을 요청하면 위와 같은 json 형식의 데이터를 얻을 수 있고 이 값을 이용해서 다양한 로직을 구성하면 된다는 소리이다.

 

그렇다면 백엔드 프론트엔드의 분리가 가능하다는 이유는 무엇일까?

장고에선는 템플릿 언어라는 것을 지원하여 백엔드에서 사용한 값을 templates(html) 에서 {{ xx.id }} 와 같은 형태로 사용이 가능하다.

하지만 이러한 기능은 프론트엔드 개발자도 장고를 알아야 하고 사용할 줄 알아야 함을 의미한다.

이러한 점을 해결하기 위해 DRF와 Serializer가 사용될 수 있다. 

프론트엔드 개발자는 Serialization 된 json 형식의 데이터를 API 서버로부터 받아와 개발하고,

백엔드 개발자는 API 서버를 개발하는 것에 집중하여 각각 독립된 개발환경을 유지할 수 있다.

규모가 작은 프로젝트의 경우 혼자 개발한다면 프론트와 백엔드가 분리가 필요하지 않을 수 있지만 규모가 커질경우 프론트와 백엔드
개발자의 역할 구분이 명확해져야 하기 때문에 독립적인 환경을 구성할 수 있도록 하는 것이 중요하다고 생각한다.

 

지금까지 장고 DRF를 이용한 CRUD API 서버를 구축하였다.
다음 포스팅에서는 Vue 프레임워크를 활용하여 장고 API 서버로 값을 요청하고 전달받아 데이터를 보여주는
프론트 작업을 진행할 것이다.

 

출처 : https://leffept.tistory.com/286?category=950490