본문 바로가기

Python/Django

[Django] context_processor는 뭐야?

728x90

django를 사용한 개발에 있어 모든 페이지에서 정보를 필요로 하는 경우가 있습니다. 예를 들어 header 부분에 표시하는 장바구니 상품 개수 같은 것이 있습니다. 이럴 경우 모든 app의 views.py에 그 정보를 넘겨주는 것은 효율적이지 않습니다. 이때 사용 가능한 기술이 바로 context_processor입니다. 다음은 Cart 앱의 model.py의 일부분입니다.

 

...
class CartItem(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE, null=True)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField()
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.product.product_name
...

 

CartItem에는 누가 넣었는지에 대한 user와 어떤 것을 넣었는지에 대한 product, 수량을 저장하는 quantity, 활성화 여부를 나타내는 is_active가 존재합니다.

 

다음은 navbar.html 코드의 일부분입니다. navbar는 웹페이지에서 많은 부분 포함되게 됩니다.

 

...
<div class="icon"><i class="text-primary fa fa-lg fa-shopping-cart"></i>
</div>
<div class="text">
	<small class="text-muted">장바구니</small>
	<div>0</div>
</div>
...

 

위의 코드는 fontawesome의 아이콘을 사용하여 장바구니 아이콘을 표현하고, 장바구니의 아이템의 개수를 알려주는 코드입니다. 위의 코드에서 0이 있는 부분을 context_processor를 통해 현재 CartItem에 있는 아이템의 개수로 대체할 것 입니다. 다음은 context_processor.py 코드입니다.

 

from .models import CartItem

def counter(request):
    cart_count = 0
        try:
            if request.user.is_authenticated:
                cart_items = CartItem.objects.filter(user=request.user)
            for cart_item in cart_items:
                cart_count += cart_item.quantity
        except Cart.DoesNotExist:
            cart_count = 0
    return dict(cart_count=cart_count)

 

만약 request.user가 인증되었다면 CartItem.objects.filter를 통해서 현재 로그인된 유저의 CartItem을 가져옵니다. 장바구니 상품 개수를 표현하기 위해서는 각 아이템의 수량을 더해주어야 하므로 반복문을 통해서 cart_count에 전체 수량을 저장해줍니다. 마지막으로 필요한 정보를 dictionary 형태로 반환해줍니다. 다음은 settings.py 코드의 일부분입니다.

 

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'carts.context_processors.counter', # <- 이부분을 추가해줍니다.
            ],
        },
    },
]

 

settings.py 에서 TEMPLATES의 context_processors에 방금 전에 작성한 코드의 경로를 추가해줍니다.

 

...
<div class="icon"><i class="text-primary fa fa-lg fa-shopping-cart"></i>
</div>
<div class="text">
	<small class="text-muted">장바구니</small>
	<div>{{cart_count}}</div>
</div>
...

 

다음으로 0이었던 부분을 cart_count로 변환시키면 정상적으로 작동하는 것을 확인할 수 있습니다.

728x90