[DRF] Django REST framework Overview

Django REST framework 사용법을 익히고 사용해본다.

Posted by Seoyoung Lee on August 06, 2020 · 6 mins read

Django REST framework (Overview)


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)),
]