Django REST Framework를 사용하다 - 3

Django REST Framework를 사용하기 위해서는 몇 가지 사항들을 숙지해야 합니다.

실제로 REST API를 만드는데 필요한 개념들만 검토 후, 빠르게 Django REST Framework(이하 DRF)를 사용하여 REST API를 만들어봅니다.

DRF를 사용하기 위해서는 다음의 사항들을 숙지해야 합니다.

  • Django Basic
  • Database Setting
  • Django ORM
  • Python에서의 상속
  • Serializer
  • ViewSets
  • Routers

위의 개념들을 숙지하고 어떻게 사용하는지 알게 되면 DRF를 통해 REST API를 간편하게 만들 수 있습니다.

이번에는 아래의 사항들을 검토합니다.

  • Python에서의 상속
  • Serializer
  • ViewSets
  • Routers



Python에서 상속

Python에서는 기본적인 상속과 다중 상속을 모두 제공합니다.

다음의 예를 통해 Python에서 상속하는 방법을 파악해봅니다.

class Animal:
def __init__(self, name, age, classify):
self.Name = name
self.Age = age
self.Classify = classify
def aboutMe(self):
print("I'am a " + self.Classify + " And I'm " + self.Age + "years old")

class Dog(Animal):
def __init__(self, name, age, classify, owner):
Animal.__init__(self, name, age, classify)
self.Owner = owner
def aboutMe(self):
Animal.aboutMe(self) //부모 클래스의 메서드를 호출합니다.
print("My boss is " + self.Owner)

Python이 익숙하지 않은 사용자라면 뒤에 나올 ViewSets이 어떻게 동작하는지 파악하기 어렵습니다.

임의로 만들 ViewSet이 DRF에서 제공하는 Viewsets를 상속하여 구현되기 때문에 상속에 대한 개념을 짚고 넘어갑니다.

Dog 클래스가 Animal 클래스를 상속하고 있으며 상속하는 클래스를 ()안에 넣어서 표현합니다.

위에 명시된 것처럼 부모 클래스의 메서드를 호출할 수 있습니다.

이외에도 부모 클래스를 의미하는 super를 사용하여 부모 클래스의 메서드를 호출할 수 있습니다.


Serializer

Serializer는 Model로부터 가져온 데이터베이스의 데이터들을 JSON이나 XML같은 형식으로 쉽게 변환할 수 있게 해줍니다.
Serializer는 또한 JSON이나 XML같은 형태의 데이터를 Model형태의 데이터로 변경하는 Deserializing 기능도 제공합니다.

#앞서 생성한 모델을 가져옵니다. from [app이름].models import [Model 이름]으로 가져옵니다.
from rest.models import UserInfo
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
#model의 이름을 적어줍니다.
model = UserInfo
#fileds에는 Model에서 추출할 필드명들을 반드시 리스트 형태로 적어줍니다.
fields = ('name', 'email', 'phone_num')

Serializer는 ViewSet에서 Model을 통해 가져온 데이터를 가공하여 사용자의 요청에 응답합니다.


ViewSets


대중적인 웹 어플리케이션 설계 모델인 MVC(Model - View - Controller)에 따르면 위의 요청은 Controller에서 처리가 됩니다.

Django에서는 View라는 것에서 로직이 처리가 됩니다. 즉, 모델에서 사용자에게 건네줄 데이터를 추출한 뒤 View에서 최종적으로 응답을 보내줍니다.

Django REST framework에서는 이러한 View들의 집합인 ViewSet을 사용합니다.
ViewSet을 사용하면 View를 사용할 때보다는 덜 명확합니다.
하지만 Router에 ViewSet을 등록하면 자동으로 URL 패턴을 생성해주기 때문에 매우 편리합니다.

다음의 예제를 통해 ViewSet을 어떻게 사용하는지 살펴봅니다.

from django.contrib.auth.models import User
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer

class UserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
serializer_class = UserSerializer

@detail_route(methods=['post'])
def set_password(self, request, pk=None):
return Response({'status': 'password set'})

set_password 메서드는 간단하게 Json형태의 값을 리턴하고 있습니다.

$ python manage.py runserver 0:9000

이제 PostMan으로 요청을 보내봅니다.


@detail_route 부분을 데코레이터라고 부릅니다.

이 부부은 ViewSet에서 기본적으로 제공하는 Action이외의 메서드를 라우팅할 때 사용합니다.

기본적으로 ViewSet에서는 다음과 같은 Action을 제공합니다.

  • list → 전체 목록 조회
  • retrieve → 특정 아이템을 검색 조회
  • create → 아이템 생성
  • update → 아이템 수정
  • destroy → 아이템 삭제

데코레이터에는 두 가지 종류가 있습니다.

  • detail_route → 특정 아이템을 반환하는 메서드일 때 사용합니다.
  • list_route → 아이템 목록을 반환할 때 사용합니다.


데코레이터에 method를 적용할 수 있습니다.

get , post, delete등을 적용할 수 있습니다. 만약 여기에 적힌 메소드가 아닌 다른 메소드로 호출하면 다음과 같은 에러가 나타납니다.

{"detail":"Method \"GET\" not allowed."}


Post 메서드를 사용하는 경우 요청 URL을 보낼 때 주의해야 합니다.

메서드 뒤에 슬래시를 붙이지 않으면 Redirect 에러가 발생하게 됩니다.
그렇기 때문에 반드시 다음과 같이 슬래시를 붙여줍니다.




위의 set_password 메서드에서 반환한 JSON형식의 데이터가 출력되는 것을 확인할 수 있습니다.


Routers




REST Framework에서는 URL에 따라 다른 로직이 실행될 수 있도록 자동으로 라우팅하는 기능을 제공합니다.
Router에서는 사용자의 요청을 확인하고 어디에서 이 요청이 처리되어야 하는지 알려줍니다.

사용법

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
#urlpatterns = router.urls
url(r'^', include(router.urls)) //include 함수를 사용하는 방법입니다.

router의 register() 메서도를 사용하기 위해서는 두 개의 인자값이 필요합니다.

  • prefix → 사용자의 요청에 따라 라우팅을 할 때 어디로 갈지 구분하기 위한 명칭을 의미합니다.
  • viewset → ViewSet 클래스를 의미합니다.

위의 예제는 다음의 URL 패턴을 만들어냅니다.

  • URL pattern: ^users/$ Name: 'user-list'
  • URL pattern: ^users/{pk}/$ Name: 'user-detail'
  • URL pattern: ^accounts/$ Name: 'account-list'
  • URL pattern: ^accounts/{pk}/$ Name: 'account-detail'


API 가이드에 명시되어 있는 것처럼 개발자가 일일히 URL 패턴을 매핑시킬 필요가 없습니다.

ViewSet을 만들고 이를 Router에 등록하면 위처럼 URL 패턴을 자동으로 생성합니다.
그리고 위의 패턴에 맞게 GET, UPDATE, POST, DELETE 요청을 보내면 그에 맞는 로직이 수행됩니다.

Router에서 생성된 URL 패턴을 추가하는 방법은 여러가지 입니다.

urlpatterns += router.urls  //현재 URL패턴에 추가합니다.

url(r'^', include(router.urls)) //include 함수를 사용하는 방법입니다.


댓글()
  1. Favicon of http://only1wolf.egloos.com BlogIcon 만주고토수복 2019.09.24 20:00 댓글주소  수정/삭제  댓글쓰기

    지금 기존 로직에서 api를 뜯어내는 작업을 하고 있는데... 잘 보고 갑니다.
    -노령견-