[장고] 데코레이터란?

소요 시간: 2분

장고 프로젝트를 진행하다 보면 @login_required와 같은 데코레이터를 자주 사용하게 됩니다.


데코레이터란?

데코레이터는 말 그대로 '장식'이라는 뜻을 가지고 있으며, 함수에 추가적인 코드를 덧붙여주는 기능을 합니다. 이는 함수에 모자를 씌우듯이 새로운 기능을 덧붙이는 방식입니다.

예시

def a(function):
    def b():
        print("1")
        function()
    return b

@a
def c():
    print("2")

# 실행
c()

# 결과
1
2

위의 예시에서 @a 데코레이터는 함수 c를 감싸서 실행할 때 b 함수를 먼저 실행하게 만듭니다. 따라서 c 함수가 호출될 때, 먼저 1이 출력되고, 그 다음에 c 함수의 본래 내용인 2가 출력됩니다.


실제 사용 예

예를 들어, 웹사이트에서 새로운 글을 추가하거나 기존의 글을 수정하려면 사용자가 로그인되어 있는지 확인해야 합니다. 만약 로그인 여부를 확인하는 코드가 글 생성, 수정, 삭제 함수 각각에 있다면 이는 매우 비효율적입니다. 코드가 길어질 뿐만 아니라, 한 번 수정할 때마다 모든 함수를 고쳐야 하기 때문입니다.

데코레이터를 사용하면 여러 곳에서 사용되는 같은 코드를 하나로 묶을 수 있습니다.


데코레이터 구성

데코레이터는 아래와 같이 외부 함수와 내부 함수로 구성되어 있습니다.

def login_required(function):
    def decorator():
        # is_login()은 로그인한 상태라면 True를 반환하는 임의의 함수입니다.
        if is_login():
            function()
        else:
            print("로그인해주세요")
    return decorator

작성한 데코레이터는 적용하려는 함수 바로 위에서 @로 호출됩니다.

@login_required
def PostAdd():
    print("새로운 글을 추가한다")

위 코드에서 PostAdd 함수는 @login_required 데코레이터의 인자로 전달되어 function 자리에 위치하게 됩니다. 로그인 상태라면 "새로운 글을 추가한다"가 출력되고, 그렇지 않다면 "로그인해주세요"가 출력됩니다. 이처럼 공통된 코드를 데코레이터로 묶으면 수정도 쉽고, 코드도 짧아져서 관리가 용이해집니다.


장고에서의 실제 예

장고에서 자주 사용되는 @login_required 데코레이터를 예로 들면, 사용자가 로그인하지 않은 상태에서 특정 뷰에 접근하려고 할 때 로그인 페이지로 리디렉션시키는 역할을 합니다. 이 데코레이터를 사용하면 각 뷰 함수마다 로그인 검사를 반복적으로 작성하지 않아도 되므로 코드의 재사용성과 가독성이 크게 향상됩니다.

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    # 이 뷰는 로그인된 사용자만 접근할 수 있습니다.
    return render(request, 'my_template.html')

이와 같이 데코레이터를 사용하면 코드의 중복을 줄이고, 유지보수성을 높일 수 있습니다.

장고 리스트