django rest framework는 REST API 컨셉을 쉽게 만들 수 있도록 도와주지만, 이것이 REST API의 전부는 아니다.
아래는 DRF를 사용하지 않고 API서버를 구현하는 방법이다.
#
# myapp/models.py
#
from django.db import models
class Post(models.Model):
message = models.TextField()
#
# myapp/forms.py
#
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
#
# myapp/views.py
#
from django.http import HttpResponse, JsonResponse
from django.http import QueryDict
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from .models import Post
from .forms import PostForm
@csrf_exempt
def post_list(request):
if request.method == 'GET':
qs = Post.objects.all()
# 수동 JSON 직렬화
data = [{'pk': post.pk, 'message': post.message} for post in qs]
return JsonResponse(data, safe=False)
elif request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save()
return HttpResponse(status=201) # created status code
data = form.errors
return JsonResponse(data, status=400) # bad request status code
@csrf_exempt
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'GET':
return JsonResponse({'pk': post.pk, 'message': post.message})
elif request.method == 'PUT':
put = QueryDict(request.body)
form = PostForm(put, instance=post)
if form.is_valid():
post = form.save()
data = {'pk': post.pk, 'message': post.message}
return JsonResponse(data=data, status=201)
return JsonResponse(form.errors)
elif request.method == 'DELETE':
post.delete()
return HttpResponse('', status=204)
#
# myapp/urls.py
#
from django.conf.urls import url
from .views import post_list, post_detail
urlpatterns = [
url(r'^post/$', post_list, name='post-list'),
url(r'^post/(?P<pk>\d+)/$', post_detail, name='post-detail'),
]
DRF는 REST API 구현을 도와주는 "Class Based View"를 제공해주는 프레임워크이다. 먼저 DRF를 사용하기 위해 django REST framework를 설치한다.
$ pip install djangorestframework
그리고 settings.py
에 INSTALLED_APPS 부분에도 'rest_framework'를 추가하고 코드를 구현해본다.
DRF에서는 forms.py파일 대신 serializers.py
를 사용한다. serialize를 한다는 것은 객체와 같은 보기 힘든 데이터를 JSON이나 XML처럼 보기 쉬운 데이터로 바꾸어 통신하게 해주는 것을 말한다.
DRF에서는 views.py
에서 ViewSet이라는 class를 사용해서 편하게 작성할 수 있다. ViewSet에서는 @csrf_exempt
토큰을 빼주어야 한다.
또한, view 대신에 viewset을 사용해서 자동적으로 URLconf를 우리의 API에 생성할 수 있기 때문에 urls.py
에서도
그냥 라우터 클래스에 등록해주기만 하면 된다. 또, API URL들을 기본 제공하는 기능보다 더 추가하고싶다면 URL conf를 명시해주면 된다.
#
# myapp/models.py
#
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
#
# myapp/serializers.py (Form과 유사)
#
from rest_framework import serializers
from .models import Post
# ModelForm 대신에 ModelSerializer
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
#
# myapp/views.py
#
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
#
# myapp/urls.py
#
from django.conf.urls import include
from rest_framework.routers import DefaultRouter
from .views import PostViewSet
router = DefaultRouter()
router.register(r'post', PostViewSet)
urlpatterns = [
url(r'', include(router.urls)),
]