본문 바로가기

web/Django

django middleware


포스팅의 내용은 django1.10 버전에서의 미들웨어 설명 입니다. 

최신 버전인 2.* 이상은 


https://docs.djangoproject.com/en/2.2/topics/http/middleware/


위의 링크를 참조하세요. (기본 함수가 달라졌습니다.)





https://docs.djangoproject.com/ja/1.10/topics/http/middleware/



django에서의 middleware는 모든 request/response의 프로세싱의 훅에 해당합니다. 즉 모든 요청 이벤트를 통과하는 중간 처리과정입니다. 


그렇다면 middleware가 언제 필요한가?! 라고 한다면 


만일 특정 url이 들어왔을 경우에만 처리해야 하는 로직이 있다거나 뷰를 리턴할때마다 무엇인가를 추가하거나 빼거나를 할수도 있습니다. 


즉 특정한 app단에서의 django가 아닌 전체 권한을 가지고 움직일때 쓰이는것이 middleware입니다. ( 윈도우에서의 hooking를 생각하시면 됩니다.)


간단하게 소스로 구현한다면 



testmiddle.py

from django.conf import settings
from django.db import connection
from django.template import Template, Context


class SimpleMiddleware(object):
def __init__(self):
pass
# One-time configuration and initialization.

def process_request(self, request):
return

def process_view(self, request, view_func, view_args, view_kwargs):

print(request, view_args, view_func, view_kwargs)
respose = None
return respose

def process_template_response(self, request, response):
print(request, response)
return response

def process_response(self, request, response):
print(request, response)
return response


파일을 만들어 주고 


settings.py 에서



MIDDLEWARE_CLASSES = [
..................
'post.testMiddle.SimpleMiddleware'
]

MIDDLEWARE_CLASSES = [] 부분에 추가해주면 동작합니다. 쉽죠?!



위의 소스는 간단하게 어떤 함수(훅)이 언제 동작하는지를 간단하게 볼수 있습니다. (django v1.9)


사진출처 : https://docs.djangoproject.com/ja/1.9/topics/http/middleware/#middleware


위의 이미지에서 보는바와 같이 각 요청시에 꼭 통과하는 미들웨어 들이 있고 해당 요청에 따라 작동하는 middleware의 훅이 달라지게 됩니다. 



각 이벤트에 따라 작동하는 훅은 달라지며 특정 요청시에만 훅을 적용하는게 성능상 좋습니다.



좀더 알아보기 위해서 process_response()부분에 다음과 같이 추가합니다.


def process_response(self, request, response):

if connection.queries:
execution_sql_time = sum([float(q['time']) for q in connection.queries])
t = Template(
"""
{{nb_sql}} requet{{nb_sql|pluralize:"e,es"}} en {{execution_sql_time}} second{{execution_sql_time|pluralize:"e,es"}}:
{% for sql in sql_log %}
[{{forloop.counter}}] {{sql.time}}s: {{sql.sql|safe}}
{% endfor %}
""")
print("---------------")
print(t.render(Context({'sql_log':connection.queries,'nb_sql':len(connection.queries),'execution_sql_time':execution_sql_time})))
print("---------------")
print(request, response)
return response

바로 해당 url요청에 실행되는 모든 쿼리와 쿼리 시간을 가져 옵니다. 



정상적으로 잘 가져 오는군요. 이렇듯 django의 전체적인 로직에 관여하고 싶다면 middleware로 구현하면 됩니다. 


단!! 서비스 전체에 걸리는 부하이기 때문에 서비스에 영향이 갈수 있습니다. 


'web > Django' 카테고리의 다른 글

uwsgi -- unavailable modifier requested: 0 --  (0) 2019.01.10
ubuntu uwsgi  (0) 2019.01.10
django-summernote 사용하기  (4) 2016.07.23
get 방식의 글자 256자 제한은 잘못된 상식  (3) 2016.05.24
Django South migration error   (0) 2015.09.30