DRF

Nam Eun-Ji·2020년 11월 27일
1
post-custom-banner

DRF란?

Django REST Framework
Django안에서 RESTful API서버를 쉽게 구축할 수 있도록 도와주는 오픈소스 라이브러리이다.

장점

  • API 지원
  • 다양한 authentication 지원
  • class 기반의 구현 방식
  • 유저 권한 별 데이터 제한 가능
  • 다양한 return 타입 제공 e.g) json, csv, excel…
  • custom을 통해 확장 가능

Serializer

직렬화는 데이터구조나 오브젝트를 저장하고 재구성할 수 있는 포맷으로 만드는 것을 말한다. 예를 들면 클래스의 인스턴스를 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')
]
profile
한 줄 소개가 자연스러워지는 그날까지
post-custom-banner

0개의 댓글