Django REST Framework
Django안에서 RESTful API서버를 쉽게 구축할 수 있도록 도와주는 오픈소스 라이브러리이다.
직렬화는 데이터구조나 오브젝트를 저장하고 재구성할 수 있는 포맷으로 만드는 것을 말한다. 예를 들면 클래스의 인스턴스를 db에 저장하는 것이 아니라 그 객체 자체를 메모리상에 저장하는 과정을 말한다.
Serializer는 말 그대로 직렬화하는 클래스로서 쿼리셋, 모델 인스턴스 등의 복잡한 데이터를 JSON, XML 등의 컨텐트 타입으로 쉽게 변환가능한 python 데이터타입으로 변환시켜준다.
예를 들어 사용자의 DB안에 사용자 프로필 사진, 이메일, 이름, 성별이 있다고 가정하면, 사용자 모델 인스턴스를 JSON형태 혹은 Dictionary형태로 직렬화 할 수 있다.
user = User(email="user@user.user", name="user", sex="male", profile_image="user.png")
UserSeriallizer(user).data
{
"email" : "user@user.user",
"name" : "user",
"sex" : "male",
"profile_image" : "user.png"
}
위와 같은 기능을 하는 Serializer를 ModelSerializer라고 부른다. 위의 UserSeriallizer는 아래와 같이 구현할 수 있다.
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = ("email", "name", "sex", "profile_image",)
우선 하나의 프로젝트를 생성한 후 movie라는 앱을 생성.
pip install django-rest-framework
django-admin startapp movie
# settings.py
INSTALLED_APPS = [
...,
'movie',
'rest_framework',
]
# movie/models.py
from django.db import models
class Movie(models.Model):
title = models.CharField(max_length = 30)
genre = models.CharField(max_length = 15)
year = models.IntegerField()
# serializers.py
from rest_framework import serializers
from .models import Movie
class MovieSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = ('id', 'title', 'genre', 'year')
# movie/views.py
from .models import Movie
from .serializers import MovieSerializer
from django.http import Http404
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
class MovieList(APIView):
def post(self, request, format=None):
serializer = MovieSerializer(data = request.data)
if serializer.is_valid(): # is_valid() : POST 데이타에 잘못된 데이타가 전달되었는지를 체크
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) # movie에는 하나의 객체만 담겨있어 serializer에 many=True 인자는 필요 없다.
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)
# movie/urls.py
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')
]