코린이의 DRF(Django REST Framework) 사용해버리기~
안녕하세요! 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
저장되어 있는 데이터가 없기 때문에 빈 배열을 넘겨줍니다. 그럼 데이터를 저장한 다음 다시 호출 해보겠습니다,.
POST/movies/
다시 GET으로 확인해보겠습니다.
제대로 데이터가 저장된 것을 확인할 수 있습니다.
특정 id를 가진 movie 를 조회 해보도록 하겠습니다.
POST/movies/{pk}
DELETE/movies/{pk}
3번 id의 영화를 DB에서 삭제해 보겠습니다.
삭제 후 GET으로 확인 결과
PUT/movies/{pk}
마지막으로 수정을 해보겠습니다.
2번 영화를 아쿠아 -> 아쿠아맨 으로 바꾸려고 했는데 id를 잘못썼네요 ㅎㅎ 쨌든 4번 마약왕->아쿠아맨로 수정되었습니다.
이상으로 '코린이의 DRF 사용해버리기' 포스팅이 끝났습니다.
다른분들에게 조금이라도 도움이 되었으면 좋겠으며, 다음 포스팅은 API문서 자동화 관리를 할 수 있는 패키지에 대해 알아보겠습니다.
다들 즐거운 코딩하세요~:D