JSON 응답
💡 View에서 JSON응답
모든 View는 HttpResponse 타입의 응답을 해야합니다.
일반적으로 아래의 2가지 방법이 있다.
직접 json.dumps를 통해 직렬화된 문자열을 획득하여 HttpResponse를 통해 응답
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'
]