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로 변환시키면 정상적으로 작동하는 것을 확인할 수 있습니다.
'Python > Django' 카테고리의 다른 글
[Django] HTTP_REFERER 사용하여 이전 페이지로 가기 (0) | 2021.07.30 |
---|---|
[Django] models.py의 함수를 이용하여 subcategory 표현하기 (0) | 2021.07.26 |
[Django] AWS Lightsail 사용하여 프로젝트 공개 (0) | 2021.07.19 |
[Django] Permission은 뭐야? (0) | 2021.07.15 |
[Django] Proxy Model은 뭐야? (0) | 2021.07.14 |