Renderer


๐Ÿ’ก Renderer

Renderer๋ฅผ ๊ฐ™์€ Endpoint์— ๋Œ€ํ•ด์„œ ๋™์ผํ•œ ๋กœ์ง์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ ํ•˜๊ณ  ๋‚˜์„œ

์ตœ์ข…์ ์œผ๋กœ ์‘๋‹ต์„ ์ค„ ๋•Œ์— ์–ด๋–ค ์‘๋‹ต ํฌ๋งท์œผ๋กœ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

Content-Type, URL์˜ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด์„œ Renderer ์ง€์ • ๊ฐ€๋Šฅํ•˜๋‹ค.



๐Ÿ’ก ๊ธฐ๋ณธ ์ง€์› ๋˜๋Š” Renderer

1. JSONRenderer (default ์ง€์ •)

โ–ช media_type โ†’ application/json โ†’ json

json.dumps๋ฅผ ํ†ตํ•œ JSON ์ง๋ ฌํ™”


2. BrowsableAPIRenderer (default ์ง€์ •)

โ–ช media_type โ†’ text/html, format โ†’ api

self-document HTML ๋ Œ๋”๋ง


3. Template(HTML)Renderer

โ–ช media_type โ†’ text/html, format โ†’ api

์ง€์ • ํ…œํ”Œ๋ฆฟ์„ ํ†ตํ•œ ๋ Œ๋”๋ง

Response์—์„œ template_name ์ธ์ž ์ง€์ • ํ•„์š”

API ์„œ๋ฒ„๋ผ๊ณ  ํ•ด์„œ ๋ชจ๋“  ์‘๋‹ต์„ JSON์œผ๋กœ ๋ฐ›์ง€ ์•Š์•„๋„, ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ HTML์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ๋‹ค.


class PostDetailAPIView(RetrieveAPIView):
    queryset = Post.objects.all()
    renderer_template = [TemplateHTMLRender]
    template_name = 'instagram/post_detail.html'

    """
    template_name์€ ์—ฌ๊ธฐ์— ์„ ์–ธํ•ด๋„ ๋˜๊ณ ,

    ๋˜๋Š” getํ•จ์ˆ˜์˜ kwargs๋กœ ๋„˜๊ฒจ๋„ ์ƒ๊ด€์—†๋‹ค.
    """

    def get(self, request, *args, **kwargs):
        post = self.get_object()

        return Response({
            'post':PostSerializer(post).data
        })

์œ„ ์ฝ”๋“œ์—์„œ get_object()๋Š” RetrieveAPIView ํด๋ž˜์Šค ๋‚ด๋ถ€์— ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  kwargs์—์„œ โ€˜postโ€™:PostSerializer(post).data ๊ฐ™์ด ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋˜๋ฉด

์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

๋ฐ˜๋ฉด์— ๊ทธ๋ƒฅ post๋งŒ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋œ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.



๐Ÿ’ก ๋‹ค์–‘ํ•œ Renderer

StaticRenderer

๋ฏธ๋ฆฌ ๋ Œ๋”๋ง๋œ HTML์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด, Response๊ฐ์ฒด ์ƒ์„ฑ์‹œ์— HTML๋ฌธ์ž์—ด์„ ์ง์ ‘ ์ง€์ •ํ•ด ์ค€๋‹ค.

@api_view(['GET'])
@renderer_classes([StaicHTMLRenderer])
def static_view(request):
    html = """<html><body>example</body><html>"""
    return Response(html)

์ด ์™ธ์—๋„ AdminRenderer, HTMLFormRenderer, MultiPartRenderer๋“ฑ์ด ์ง€์›๋œ๋‹ค.



๐Ÿ’ก Renderer ํด๋ž˜์Šค ๋ฆฌ์ŠคํŠธ ์ง€์ •ํ•˜๊ธฐ


1. ์ „์—ญ ์ง€์ • (์ถ”์ฒœ โœ”)

settings > REST_FRAMEWORK > DEFAULT_RENDERER_CLASSES ๋ฆฌ์ŠคํŠธ์— ๋ฌธ์ž์—ด๋กœ ์ง€์ •.

โ–ช rest_framework/settings.py


2. APIView ๋งˆ๋‹ค ์ง€์ •

queryset, serializer_class์™€ ๋”๋ถˆ์–ด, renderer_classes ๋ฆฌ์ŠคํŠธ


3. @api_view ๋งˆ๋‹ค ์ง€์ •

๋ณ„๋„์˜ renderer_classes ์žฅ์‹์ž๊ฐ€ ์žˆ๋‹ค.



๐Ÿ’ก Renderer ์‘๋‹ต ํฌ๋งท


1. ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ์‘๋‹ต ํฌ๋งท

โ–ช api : API EndPoint์— ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ๋•Œ, ์›น UI๋กœ ์กฐํšŒ ๊ฐ€๋Šฅ

http://127.0.0.1:8000/post/1.api

http://127.0.0.1:8000/post/1/?format=api

โ–ช json : ๋ณดํ†ต์˜ API์ ‘๊ทผ

http://127.0.0.1:8000/post/1.json

http://127.0.0.1:8000/post/1/?format=json


2. ์‘๋‹ต ํฌ๋งท์€ ์–ด๋–ป๊ฒŒ ๊ฒฐ์ •๋˜๋Š”๊ฐ€?

Accept ํ—ค๋”

โ€ข Accept: application/json

โ€ข Accept: text/html


GET์ธ์ž format

โ€ข ?format=json

โ€ข ?format=api


URL Captured Values์—์„œ์˜ format ์ธ์ž

โ€ข .json

โ€ข .api



๐Ÿ’ก URL Captured Values์—์„œ์˜ format ์ธ์ž

router๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด format ์ธ์ž๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•ด์ค€๋‹ค.

<URLPattern '^post\.(?P<format>[a-z0-9]+)/?$' [name='post-list']>


๋ฐ˜๋ฉด์— ๊ฐœ๋ฐœ์ž๊ฐ€ โ€œํ•จ์ˆ˜๊ธฐ๋ฐ˜ viewโ€๋ฅผ ๊ตฌํ˜„ํ•  ๊ฒฝ์šฐ์—๋Š” ํ•„ํžˆ URLPatterns์— ์ง€์ •๋œ

format=None์„ kwargs๋กœ ๋„˜๊ฒจ์ค˜์•ผํ•œ๋‹ค.

โ€œํด๋ž˜์Šค ๊ธฐ๋ฐ˜ viewโ€๋Š” ํฌ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„์ด ์—†๋‹ค.

None์œผ๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ์ด์œ ๋Š” format์ด ์—†์„ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด default๊ฐ’์„ ์ง€์ •ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

# views.py
from rest_framework.decorators import api_view

@api_view(['GET'])
def hello(request, format=None):
    return Response([])

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ทธ๋ฆฌ๊ณ  router๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , format ์ธ์ž๋ฅผ URLPatterns์— ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

# urls.py
from rest_framework.url.patterns import format_surfix_patterns

urlpatterns = format_suffix_patterns([
    paht('hello/', views.hello)
])

์ƒ์„ฑ๋œ URLPatterns๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

[
    <URLPatterns 'hello'/>,
    <URLPaatters 'hello<drf_format_suffix:format>'>
]