JSON 응답


💡 View에서 JSON응답

모든 View는 HttpResponse 타입의 응답을 해야합니다.

일반적으로 아래의 2가지 방법이 있다.


  1. 직접 json.dumps를 통해 직렬화된 문자열을 획득하여 HttpResponse를 통해 응답

  2. JsonResponse(HttpResponse를 상속 받은 클래스) 사용

    • 내부적으로 json.dumps를 사용

    • DjangoJSONEncode가 defualt로 지정


그리고 JsonResponse에서 QuerySet을 JSON 직렬화를 할 수 없다.

따라서 앞에서 정의했던 MyJSONEncoder를 활용할 수 있다.

qs = Post.objects.all()

encoder = MyJSONEncoder

# True: data가 dict일 경우
# False: data가 dict일 아닐 경우
safe = False

json_dumps_params = {'ensure_ascii':False}

# HttpResponse에 전해지는 Keyword 인자
kwargw = {}

from Djagno.http import JsonResponse

responser = JsonResponse(qs, encorder, safe, json_dumps_params, **kwargs)


💡 DRF를 통한 JSON응답

qs = Post.objects.all()

serializer = PostSerializer(qs, many=True)

from rest_framework.responser import Response
responser = Responser(serializer.data) # content-type : text/html 디폴트 지정

Response에는 내부적으로 다양한 DRF 설정들이 있다.

따라서 Response에서는 “JSON 직렬화”가 Lazy하게 동작한다.

실제 응답 생성 시에는 .rendered_content 속성에 접근하며, 이때 변환이 이루어진다.



Response와 APIView

DRF의 모든 View는 APIView를 상속 받는다.

APIView를 통해 Response에 다양한 속성이 지정된다.

from rest_framework.views import APIView 

renderer_cls = APIView.renderer_classes[0]
renderer_obj = renderer_cls()

# JSON 변환을 위한 JSONRenderer 인스턴스
response.accepted_renderer = renderer_obj    
            
response.accepted_media_type = renderer_obj.media_type   # 'application/json'

response.renderer_context = {'view': None, 'args': (), 'kwargs': {}, 'request': None}

response 
# <Response status_code=200, "application/json">


💡 실제 DRF Serializer 활용

아래와 같이 간결하게 사용할 수 있다.

from rest_framework import generics

class PostListAPIView(generics.ListAPIView):
    queryset = Post.objects.all()
    serializer_class = PostModelSerializer

post_list = PostListAPIView.as_view()

ListAPIView는 오직 list 기능만을 한다.

ListCreateAPIView는 list + Create 기능을 한다.

추가적으로 ModelViewSet은 CRUD를 모두 지원하는데,

ModelViewSet을 사용할 경우 urls.py에서 router를 꼭 설정해줘야 한다.



포스팅 조회 응답에 username 응답하기.

1. ReadOnlyField 활용

# serializers.py

from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    username = serializers.ReadOnlyField(source='author.username')

    class Meta:
        model = Post
        fields = [
            'pk',
            'username',
            'message',
            'created_at',
            'updated_at'
        ]


2. Class 상속 방식

# serializers.py
from django.contrib.auth import get_user_model 
from rest_framework import serializers
from .models import Post

class AuthSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['username','email']

class PostSerialize(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = [
            'pk',
            'author',
            'message',
            'created_at',
            'updated_at'
        ]