💻 프로그래밍/Django

코린이의 DRF(Django REST Framework) 사용해버리기~

피트웨어 제이 (FitwareJay) 2018. 12. 31. 17:54

안녕하세요! Jay 입니다. 정말 오랜만에 글을 쓰는 것 같아요! ㅎㅎ 

그동안 많은 일들이 있기도 했고~ 연말이라 조금 게을러진 마음을 다시 한번 다잡고자 다시 글을 씁니다!

새로운 것들을 배우기도 했고요ㅎㅎㅎ:D

오늘은 DRF(Django REST Framework)를 CBV(Class-Based_view)로사용하는 방법을 알아보려고 합니다.


※ DRF를 사용한 API만들기


먼저 DRF를 사용하려면 해당 라이브러리를 설치해야겠죠?

 $ pip install django-rest-framework

DRF 패키지를 설치하고 pip list 해보시면 아래와 같이 패키지가 설치된 걸 볼 수 있습니다.


이제 API로 사용할 App을 생성해보도록 하겠습니다.


$ django-admin startapp movie


movie 앱을 생성하였습니다. 이제 movie 디렉토리 하위에 urls.py 와 serializers.py 를 만들면 다음과 같이 됩니다.

다음은 settings.py에 가서 생성한 movie app을 추가해주고 REST_FRAMWORK 기본 세팅을 추가해 줍니다.

DRF setting에서 API를 호출할때 JSON형식으로만 보이게 아래와 같이 세팅해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Django REST Framework
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
}
 
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'movie',
    'rest_framework',
]


movie 앱에서 model을 만들어 줍니다. Movie 모델은 영화제목, 장르, 제작년도를 값으로 가집니다.

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-
from django.db import models
 
class Movie(models.Model):
    title = models.CharField(max_length=30# 제목
    genre = models.CharField(max_length=15# 장르
    year = models.IntegerField()  # 제작 년도


다음으로 model에 대한 시리얼라이저를 만들어 줍니다.

1
2
3
4
5
6
7
8
from rest_framework import serializers
from .models import Movie
 
class MovieSerializer(serializers.ModelSerializer):
    class Meta:
        model = Movie # 모델 설정
        fields = ('id','title','genre','year'# 필드 설정
 


Meta 클래스를 설정할때 feilds의 경우 이렇게 따로 설정해주거나 __all__로 해줘야 합니다. 

이제 view 를 만들어 보겠습니다. view에는 두가지 클래스를 추가해 줄겁니다.

하나는 movie list에 대한 view, 다른 하나는 특정 객체에 대한 view입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from .models import Movie
from django.http import Http404
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import MovieSerializer
 
class MovieList(APIView):
        """
            영화 리스트 생성
        """
    def post(self, request, format=None):
        serializer = MovieSerializer(data=request.data)
        if serializer.is_valid() :
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
      """
            영화 리스트 조회
      """
    def get(self, request, format=None):
        queryset = Movie.objects.all()
        serializer = MovieSerializer(queryset, many=True)
        return Response(serializer.data)
 
class MovieDetail(APIView) :
    def get_object(self, pk):
        try :
            return Movie.objects.get(pk=pk)
        except :
            raise Http404
 
    def get(self, request, pk):
        movie = self.get_object(pk)
        serializer = MovieSerializer(movie)
        return Response(serializer.data)
 
    def put(self, request, pk, format=None):
        movie = self.get_object(pk)
        serializer = MovieSerializer(movie, data=request.data)
        if serializer.is_valid() :
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
    def delete(self, request, pk, format=None):
        movie = self.get_object(pk)
        movie.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
 


이제 URL 맵핑을 해보겠습니다. 

위 view를 두가지 생성한 것 처럼 URL도 두가지를 맵핑해야합니다. 특정 객체를 위한 view는 <int:pk>라고 정의 해줍니다. 

<int:pk> 로 url표현이 될 줄 알았는데 url을 인식하지 못하네요ㅎㅎ 그래서 장고 정규표현식(Regex)를 참고해 아래와 같이 적었습니다.

  • ^post/ : url이(오른쪽부터) post/로 시작합니다.
  • (\d+) : 숫자(한 개 이상)가 있습니다. 이 숫자로 조회하고 싶은 게시글을 찾을 수 있어요.
  • / : /뒤에 문자가 있습니다.
  • $ : url 마지막이 /로 끝납니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.conf.urls import url
from . import views
 
urlpatterns = [
    url(r'(?P<pk>[0-9]+)/', views.MovieDetail.as_view(), name='detail'),
    #url(r'<int:pk>/', views.MovieDetail.as_view()) # 정규표현식 에러
    url(r'', views.MovieList.as_view(), name='movies')
]
]]></script><p></p>
<p style="line-height: 2;"><span style="font-size: 12pt;">다음으로 장고 프로젝트 URL에 movie 앱 url을 추가합니다.</span></p>
<script type="syntaxhighlighter" class="brush: python"><![CDATA[
from django.conf.urls import url, include
from django.contrib import admin
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'movie/', include('movie.urls')),
]
 


이제 새로운 model을 정의했으니 마이그레이션을 해줘야 합니다.

 $ ./manage.py makemigrations

 $ ./manage.py migrate

※ API 호출 확인해보기
Postman으로 API호출이 제대로 되는지 확인해보도록 하겠습니다.
GET/movies/

저장되어 있는 데이터가 없기 때문에 빈 배열을 넘겨줍니다. 그럼 데이터를 저장한 다음 다시 호출 해보겠습니다,.

POST/movies/

다시 GET으로 확인해보겠습니다.

제대로 데이터가 저장된 것을 확인할 수 있습니다.

특정 id를 가진 movie 를 조회 해보도록 하겠습니다.

POST/movies/{pk}


DELETE/movies/{pk}

3번 id의 영화를 DB에서 삭제해 보겠습니다.

삭제 후 GET으로 확인 결과

PUT/movies/{pk}

마지막으로 수정을 해보겠습니다.


2번 영화를 아쿠아 -> 아쿠아맨 으로 바꾸려고 했는데 id를 잘못썼네요 ㅎㅎ 쨌든 4번 마약왕->아쿠아맨로 수정되었습니다.

이상으로 '코린이의 DRF 사용해버리기' 포스팅이 끝났습니다. 

다른분들에게 조금이라도 도움이 되었으면 좋겠으며, 다음 포스팅은 API문서 자동화 관리를 할 수 있는 패키지에 대해 알아보겠습니다.

다들 즐거운 코딩하세요~:D