Django-debug-toolbar: POST ์š”์ฒญ์— ๋Œ€ํ•ด ๋„๊ตฌ ๋ชจ์Œ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์Œ

์— ๋งŒ๋“  2017๋…„ 10์›” 04์ผ  ยท  6์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jazzband/django-debug-toolbar

์•ˆ๋…•ํ•˜์„ธ์š”, POST ์š”์ฒญ์œผ๋กœ ์ธํ•ด ๋„๊ตฌ ๋ชจ์Œ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊ทธํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ GET ์š”์ฒญ์— ๋Œ€ํ•ด ๋””๋ฒ„๊ทธ ๋„๊ตฌ ๋ชจ์Œ์ด ์ œ๋Œ€๋กœ ํ‘œ์‹œ๋˜๊ณ  ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋„๊ตฌ ๋ชจ์Œ์ด ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ด๊ฒƒ์ด ์ง€์›๋˜๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹Œ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ViewSets , ModelViewSet django rest ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์š”์ฒญํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‹ค์Œ์€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฏธ๋“ค์›จ์–ด์ž…๋‹ˆ๋‹ค.

def Fix_XMLHttpRequest(get_response):
    def middleware(request):
        # When `POST`ing data from the DRF browsable API, it will set the
        # header `X_REQUESTED_WITH: XMLHttpRequest`. (Not sure if the browser
        # adds that header of if DRF's front-end does, but that doesn't matter,
        # the header is there.) It's a little contradictory that the header is
        # there since the browser also requests that the response be 'text/html'.
        # Anyway, that's fine except for one thing. Django Debug Toolbar will
        # not show the debug toolbar whenever that header is set on the request!
        #
        # See:
        #   - https://github.com/jazzband/django-debug-toolbar/blob/c201ce34cea3ba4ce99d1642db17f2cb31c6204e/debug_toolbar/middleware.py#L59
        #   - https://docs.djangoproject.com/en/2.1/_modules/django/http/request/#HttpRequest.is_ajax
        #
        # My workaround is to remove that header whenever the request explicitly
        # asks for 'text/html'. Again, in my opinion, that header doesn't really
        # make sense anyway when the browser wants to receive HTML back.
        #
        # This makes is so that when you POST data from the DRF browsable API,
        # you can still see the Django Debug Toolbar. It maintains the desired
        # behavior of _not_ showing the toolbar when you POST from Javascript
        # to obtain JSON data.

        if 'text/html' in request.META.get('HTTP_ACCEPT', ''):
            if request.META.get('HTTP_X_REQUESTED_WITH', '') == 'XMLHttpRequest':
                del request.META['HTTP_X_REQUESTED_WITH']

        response = get_response(request)

        return response

    return middleware

Django Debug Toolbar์˜ ๋ฏธ๋“ค์›จ์–ด _์•ž์—_ ํ•ด๋‹น ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  6 ๋Œ“๊ธ€

๊ฐ๊ฐ SHOW_TOOLBAR_CALLBACK ์‚ฌ์šฉํ•˜์—ฌ https://github.com/jazzband/django-debug-toolbar/blob/master/debug_toolbar/middleware.py#L58 ์—์„œ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋„๊ตฌ ๋ชจ์Œ์—์„œ POST ์š”์ฒญ์„ ๋ฌด์‹œํ•˜๋Š” ์ด์œ ๋ฅผ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฏธ๋“ค์›จ์–ด์ž…๋‹ˆ๋‹ค.

def Fix_XMLHttpRequest(get_response):
    def middleware(request):
        # When `POST`ing data from the DRF browsable API, it will set the
        # header `X_REQUESTED_WITH: XMLHttpRequest`. (Not sure if the browser
        # adds that header of if DRF's front-end does, but that doesn't matter,
        # the header is there.) It's a little contradictory that the header is
        # there since the browser also requests that the response be 'text/html'.
        # Anyway, that's fine except for one thing. Django Debug Toolbar will
        # not show the debug toolbar whenever that header is set on the request!
        #
        # See:
        #   - https://github.com/jazzband/django-debug-toolbar/blob/c201ce34cea3ba4ce99d1642db17f2cb31c6204e/debug_toolbar/middleware.py#L59
        #   - https://docs.djangoproject.com/en/2.1/_modules/django/http/request/#HttpRequest.is_ajax
        #
        # My workaround is to remove that header whenever the request explicitly
        # asks for 'text/html'. Again, in my opinion, that header doesn't really
        # make sense anyway when the browser wants to receive HTML back.
        #
        # This makes is so that when you POST data from the DRF browsable API,
        # you can still see the Django Debug Toolbar. It maintains the desired
        # behavior of _not_ showing the toolbar when you POST from Javascript
        # to obtain JSON data.

        if 'text/html' in request.META.get('HTTP_ACCEPT', ''):
            if request.META.get('HTTP_X_REQUESTED_WITH', '') == 'XMLHttpRequest':
                del request.META['HTTP_X_REQUESTED_WITH']

        response = get_response(request)

        return response

    return middleware

Django Debug Toolbar์˜ ๋ฏธ๋“ค์›จ์–ด _์•ž์—_ ํ•ด๋‹น ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ดœ์ฐฎ์€์ง€ ์•„๋‹Œ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์‹œ ์š”์ฒญ์„ ์บก์ฒ˜ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, 'get' ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น์‚ฌ์ดํŠธ์—์„œ ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ถ„๋ช…ํžˆ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Django๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชฉ์ ์€ ๋ชจ๋ฐ”์ผ ํด๋ผ์ด์–ธํŠธ์šฉ ์„œ๋ฒ„๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ์š”์ฒญ ๋ฐฉ์‹์€ 'POST'์ž…๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์ด ์ €๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•œ ๊ฒƒ์€ (Django REST Framework์˜ ํƒ์ƒ‰ ๊ฐ€๋Šฅํ•œ API์™€ ํ•จ๊ป˜) ์ด django-debug-toolbar-history ์ž…๋‹ˆ๋‹ค.

django-debug-toolbar-history ๋Š” ํƒ์ƒ‰ ๊ฐ€๋Šฅํ•œ DRF ๊ฐœ๋ฐœ์ž ํŽ˜์ด์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ €์—๊ฒŒ๋„ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด POST ๋™์•ˆ ์‚ฌ์šฉ๋œ SQL ์ฟผ๋ฆฌ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํžˆ์Šคํ† ๋ฆฌ ํŒจ๋„์ด ๊ณต๊ฐœ๋จ์— ๋”ฐ๋ผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฐ˜ํ™˜๋˜๋Š” POST ์š”์ฒญ ๋ฐ HTML ์‘๋‹ต์˜ ๊ฒฝ์šฐ ๋ฐ๋ท” ๋„๊ตฌ ๋ชจ์Œ์ด ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ๋„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  ๋ฆด๋ฆฌ์Šค๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๊ณ„์†ํ•ด์„œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ƒˆ๋กœ์šด ์„ธ๋ถ€ ์ •๋ณด๋กœ ๋‹ค์‹œ ์—ฌ์‹ญ์‹œ์˜ค. ๊ฐ์‚ฌ ํ•ด์š”.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰