장고 시작하기 22. 장고 DRF 시작

장고는 MVT 패턴으로 진행할 수 있고 DRF로 진행할 수 있습니다. MTV는 모델이 데이터를 처리하고, 뷰가 비즈니스 로직을 처리하고, 템플릿이 프레젠테이션을 처리하는 아키텍처를 였습니다. 그러나 웹 애플리케이션이 발전함에 따라 다양한 클라이언트에 데이터를 제공하기 위해 RESTful API를 구축해야 할 필요성이 대두 되었습니다. 때문에 등장한 것이 Django Rest Framework( 장고 DRF )입니다.

Django Rest Framework ( 장고 DRF )

DRF(Django Rest Framework)는 Django에서 웹 API를 구축하기 위한 강력한 툴입니다.

DRF는 RESTful 요청 및 응답을 처리하는 Django의 기능을 확장하여 클라이언트와 통신하는 API를 더 쉽게 구축할 수 있게 해줍니다.

DRF는 API 구축 프로세스를 간소화하기 위해 직렬화, 인증, 권한 및 뷰 세트를 포함한 강력한 기능 세트를 제공합니다.

MVT와 DRF 차이

  • Django의 MVT 패턴은 주로 웹 페이지에 대한 HTML 응답 생성에 중점
  • DRF는 HTML 템플릿을 렌더링하는 대신에 모델의 데이터를 JSON 또는 XML 형식으로 직렬화하고 이를 HTTP 응답으로 반환
  • 이를 통해 웹 브라우저나 모바일 앱과 같은 클라이언트가 구조화된 형식으로 데이터를 사용 가능
  • DRF는 프런트엔트와 협업에 유리

MVT 방법

HTML response로 반환

urls.py

from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("html/", views.article_list_html, name="article_list_html"),
]

views.py

from django.shortcuts import render
from .models import Article


def article_list_html(request):
    articles = Article.objects.all()
    context = {"articles": articles}
    return render(request, "articles/articles.html", context)

templates

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>API PJT</title>
</head>
<body>
    <h1>Article List</h1>
    <hr><br>

    {% for article in articles %}
        <h3>title: {{ article.title }}</h2>
        <p>content: {{ article.content }}</p>
        <p>created_at: {{ article.created_at }}</p>
        <p>updated_at: {{ article.updated_at }}</p>
        <hr>
    {% endfor %}

</body>
</html>

브라우저

장고 직렬화 매소드 이용한 API 개발

장고에서 template가 아닌 JSON 데이터를 반환하는 API를 만들 수도 있습니다.

우선 직렬화 (시리얼라이져(serializer)) 메소드를 사용하기 전에 queryset을 딕셔너리로 변환 후 JSON으로 응답하는 방법을 보겠습니다.

JSON response로 반환

urls.py

  • HTML 렌더링 방식 외에 json 방식을 보여주기 위해 url 추가
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("html/", views.article_list_html, name="article_list_html"),
    path("json1/", views.json1, name="json1"),
]

views.py

  • model에서 받은 데이터를 딕셔너리 혹은 리스트 안의 딕셔너리 형태로 넣음
  • JsonResponse로 반환함
  • 리스트를 JsonResponse에 인자로 전달하는 경우 safe=False로 전달
def json1(request):
    articles = Articles.objects.all()
    json_res = []

    for article in articles:
        json_res.append(
            {
                "title": article.title,
                "content": article.content,
                "created_at": article.created_at,
                "updated_at": article.updated_at,
            }
        )
    # JsonResponse에 첫번째로 넘겨주는 인자가 딕셔너리면 safe=False할 필요 없음
    return JsonResponse(json_res, safe=False)

브라우저

  • 브라우저에 HTML 화면이 아니라 JSON 형식으로 데이터가 전송 됨을 볼 수 있음

장고 serializers 사용하여 직렬화

위의 방법도 가능하지만 serializers 메소드를 사용하면 더욱 간단하게 JSON 데이터로 직렬화 할 수 있습니다.

urls.py

  • 새로운 방법을 새로운 url로 받도록 설정
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("html/", views.article_list_html, name="article_list_html"),
    path("json1/", views.json1, name="json1"),
    path("json2/", views.json2, name="json2"),
]

views.py

  • serializers.serialize() 메소드를 사용해서 데이터를 직렬화 함
  • HttpResponse로 보내주면서 content_type을 “application/json”로 명시함
from django.http import HttpResponse
from django.core import serializers

def json2(request):
    articles = Articles.objects.all()
    res_data = serializers.serialize("json", articles)
    return HttpResponse(res_data, content_type="application/json")

브라우저

  • JsonResponse로 반환할 때와 마찬가지로 JSON 형태이지만 데이터 구조가 조금 다름
  • model, pk와 같은 내용이 추가되면서 더 계층화 됨

장고의 Serializer는 내부적으로 직렬화를 제공해주지만 모델 구조로만 직렬화를 해줍니다.

이는 데이터 구조의 변경을 원할 때는 추가 작업이 필요함을 의미합니다.

유연한 API를 위한 기능이라기 보다는 모델의 데이터를 export 해주는 용도에 가까운 거죠

장고 DRF

웹 API를 구축하기 위한 DRF는 RESTful한 API를 손쉽게 구현할 수 있게 해줍니다.

앞서서 보았던 방법보다 간단하면서 유연하게 API를 수정할 수 있게 해줍니다.

장고 DRF 설치 및 설정

  • 우선 djangorestframework를 설치
pip install djangorestframework

settings.py

  • INSTALLED_APPS에 ‘rest_framework’을 추가
INSTALLED_APPS = [
        ...
        'rest_framework',
        ...
]

장고 DRF 구현

urls.py

  • 테스트를 위해 drf로 받을 URL 추가
from django.urls import path
from . import views

app_name = "articles"
urlpatterns = [
    path("html/", views.article_list_html, name="article_list_html"),
    path("json1/", views.json1, name="json1"),
    path("json2/", views.json2, name="json2"),
    path("json-drf/", views.json_drf, name="json_drf"),
]

serializers.py

  • serializers.py 파일을 앱 하위에 생성 후, 시리얼라이저 생성
  • model form과 굉장히 유사한 구조로 만들어져 있습니다.
  • serializers.ModelSerializer를 상속 받아서 특정 모델에 대한 시리얼라이저를 만들어 줍니다.
  • model에는 모델명을 fields에는 모델의 어떤 필드를 직렬화 할 것인지 명시해 줍니다.
from rest_framework import serializers
from .models import Articles


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Articles
        fields = "__all__"

views.py

  • serializers.py에서 정의한 시리얼라이져를 사용
  • 함수형으로 API를 만들 경우 @api_view 를 반드시 사용해야함
  • get() 처럼 단일 데이터인 경우, 시리얼라이져의 may=True 입력할 필요가 없으나 all() 처럼 다양한 데이터의 경우, many=True 인자 입력
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ArticleSerializer

@api_view(["GET"])
def json_drf(request):
    articles = Articles.objects.all()
    serializer = ArticleSerializer(articles, many=True)
    return Response(serializer.data)

브라우저

훨씬 깔끔한 형태로 JSON 데이터를 보여줍니다.

마치며

장고 DRF 를 사용하면 CRUD에 해당하는 API를 손쉽게 구현할 수 있습니다. 해당 포스트는 다음에 올리도록 하겠습니다.

MVT 보다는 DRF 가 프런트엔드하고 협업하기도 훨씬 좋아 보이고 API를 구조적으로 만들 수 있는 것 같아서 좋은 것 같습니다…!!

참고하면 좋은 글

Leave a Comment

목차