택시짱의 개발 노트

9장. 함수 기반 뷰의 모범적인 이용 본문

Django(장고)

9장. 함수 기반 뷰의 모범적인 이용

택시짱 2021. 10. 10. 15:13

9장. 함수 기반 뷰의 모범적인 이용

9.1 함수 기반 뷰의 장점

  • 함수 기반 뷰는 코드 재사용을 희생하여 나온 결과 ???

  • 함수 기반 뷰는 클래스 뷰처럼 상속하는 기능 없다.

  • 가이드 라인

    • 뷰 코드는 작을수록 좋다.
    • 뷰에서 절대 코드를 반복해서 사용하지 말자
    • 뷰는 프레젠테이션 로직을 처리해야 한다. 비즈니스 로직은 가능한 모델 로직에 적용시키고 만약 해야 한다면 폼 안에 내제시켜야 한다.
    • 뷰를 가능한 단순하게 유지하자.
    • 403, 404, 500을 처리하는 커스텀 코드를 쓰는데 이용하라. ???
    • 복잡하게 중첩된 if 블록 구문을 피하자.

9.2 HttpResponse 객체 전달하기

  • 뷰에서도 마찬가지로 코드를 재사용하기 원하는 경우가 생긴다.

  • 하지만 미들 웨어(middleware)나 콘텍스트 프로세서(context processors) 같은 글로벌 액션에 연동되어 있지 않은경우 재사용에 문제가 생긴다.

    • middleware ( 링크 )

    • context processors ( 링크 )

      컨텍스트 프로세서는 request객체를 인수로 사용하고 요청 컨텍스트에 추가되는 사전을 반환 하는 Python 함수입니다 . 모든 템플릿에서 전역적으로 사용할 수 있도록 해야 할 때 유용합니다.

      기본적으로 startproject명령을 사용하여 새 프로젝트를 만들 때 프로젝트에는 설정 context_processors내의 옵션 에 다음 템플릿 컨텍스트 프로세서가 포함됩니다 TEMPLATES.

  • 프로젝트 전체를 아우르는 유틸리티 함수를 만드는 것을 추천한다

  • 많은 유틸리티 함수 중에서 django.http.HttpRequest 객체의 속성을 가지고와 데이터를 가공 했다.

# 예제 1
from django.core.exceptions import PermissionDenied
from django.http import HttpRequest

def check_sprinkle_rights(request: HttpRequest) -> HttpRequest:
    if request.user.can_sprinkle or request.user.is_staff:
        return request

    # 403 error return
    raise PermissionDenied
# 강화된 예제 1 - HttpRequest에 좀 더 여러 추가적인 속성 추가
from django.core.exceptions import PermissionDenied
from django.http import HttpRequest

def check_sprinkle_rights(request: HttpRequest) -> HttpRequest:
    if request.user.can_srinkle or request.user.is_staff:
        #  HttpRequest에 속성을 추가 하기 전에는 아래와 같이 템플릿에서 사용
        #  {% if request.user.can_sprinkle or request.user.is_staff %}
        #  HttpRequest에 속성을 추가 하여 템플릿에 전달을 한다면 아래와 같이 사용 가능
        #  {% if request.can_srinkle %}
        request.can_sprinkle = True
        return request

    # 403 error return
    raise PermissionDenied
from django.shortcuts import get_object_or_404
from django.shortcuts import render

from .utils import check_sprinkles_rights
from .modesl import Sprinkle

def sprinkle_list(request):
    """표준 리스트 뷰"""
    pass

def sprinkle_detail(request, pk):
    """표준 상세 뷰"""
    request = check_sprinkles_rights(request)
    sprinkle = get_object_or_404(Sprinkle, pk=pk)
    return render(request, "sprinkles/sprinkle_detail.html", {"sprinkle": sprinkle})

def sprinkle_preview(request):
    """새 스프링클의 미리보기"""
    pass

----

from django.views.generic import DetailView

from .utils import check_sprinkles
from .models import Sprinkle

class SprinkleDetail(DetailView):
    """표준 상세 뷰"""
    model = Sprinkle

    def dispatch(self, request, *args, **kwargs):
        request = check_sprinkles(request)
        return super().dispatch(request, *args, **kwargs)

9.3 편리한 데코레이터

  • 데코레이터란?
함수를 받아 명령을 추가한 뒤 이를 다시 함수의 형태로 반환하는 함수이다.

함수의 내부를 수정하지 않고 기능에 변화를 주고 싶을 때 사용한다 .

일반적으로 함수의 전처리나 후처리에 대한 필요가 있을때 사용을 한다.

또한 데코레이터를 이용해, 반복을 줄이고 메소드나 함수의 책임을 확장한다
  • 함수 기반 뷰에서 사용
import functools

def decorator(view_func): 
    @functools.wraps(view_func)
    def new_view_func(request, *args, **kwargs):
        # 여기서 request(HttpRequest) 객체를 수정하면 된다.
        response = view_func(request, *args, **kwargs)
        # 여기에서 response(HttpResponse) 객체를 수정하면 된다.
    return new_view_func
  • 데코레이터 예제
import functools
from . import utils

# based off the decorator template from the previous example
def check_sprinkles(view_func):
    """사용자가 스프링클을 추가할 수 있는지 확인"""
    @functools.wraps(view_func)
    def new_view_func(request, *args, **kwargs):
        # request 객체를 utils.can_sprinkle()에 넣는다.
        request = utils.can_sprinkle(request)

        # 뷰 함수를 호출
        response = view_func(request, *args, **kwargs)
        # HttpResponse 객체를 반환
        return response
    return new_view_func

데코레이터 남용하지 않기

  • 너무 많은 데코레이터의 집합은 데코레이터 자체를 난해하게 만들어, 복잡하게 얽힌 상속 과정을 지닌 뷰가 오히려 단순해 보일 정도가 되기도 한다.
  • 해결방법
    • utils로 빼야되나?
    • class view로 변경해야되나?
    • 그냥 쓰면되나?

9.4 HttpResponse 객체 넘겨주기

  • HttpRequest 객체에서 그랬듯이, HttpResponse 객체 또한 함수와 함수 사이에서 서로 전달받을 수 있다. Middleware.process_request() 메서드를 생각하자.

9.5 요약

  • 장고에서 함수 기반 뷰는 꾸준히 건재함.
  • 모든 함수 기반 뷰는 HttpRequest 객체를 받고 HttpResponse 객체를 반환한다는 사실을 명심 또 명심해야 한다.
반응형
Comments