42.Django(장고) - ecommerce 프로젝트 - 쇼핑몰 - 장바구니(쇼핑카트) 구현

JungSik Heo·2024년 12월 8일

1.cart 앱 만들기

python manage.py startapp cart

2.config\settings.py

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    'home',
    'boards',
    'accounts',
    'store',
    'cart',
]

config\urls.py

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include('store.urls')),
    path("home/", include('home.urls')),
    path("boards/", include('boards.urls')),
    path('account/', include('accounts.urls')),
    path("cart/", include('cart.urls')), 
]

3.cart\urls.py

urlpatterns = [
    path("", views.cart_summary,name="cart_summary"),
    path("add/", views.cart_add,name="cart_add"), 
    path("delete/", views.cart_delete,name="cart_delete"), 
    path("update/", views.cart_update,name="cart_update"),      
]

4.cart\views.py

from django.shortcuts import render

# Create your views here.
from django.shortcuts import render

def cart_summary(reqeust):
    return render(reqeust, "cart_summary.html",{})

def cart_add(request):
    cart  = Cart(request)

    print("카트========",cart)

    if request.POST.get('action') == 'post':
        print('=========')
        
        #get stuff
        product_id = int(request.POST.get('product_id'))
        print('product_id', product_id)

        # lookup proudct in DB
        product = get_object_or_404(Product,id=product_id)

        print("프로덕트",product)

        #save to session
        cart.add(product=product)
        response = JsonResponse({'Product Name': product.name})

        return response
    
    print("카트========마지막")

def cart_delete(reqeust):
    pass

def cart_update(reqeust):
    pass

5.제품상세에서 장바구니 버튼을 넣자

templates\store\product.html

                <br><br><a class="btn btn-secondary" href="{% url 'store:home' %}">홈으로</a>
                <button type="button" value="{{product.id}}" id="add-cart" class="btn btn-secondary">장바구니 담기</button>
              </center>

아래와같이 장바구니 담기 버튼 확인

templates\store\head.html - Jquery 작업도 해보자
아래와 같이 추가

    (... 생략 ...)
<!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>

templates\store\product.html

    (... 생략 ...)
<script>
  $(document).on('click', '#add-cart',function(e){
    $.ajax({
      type:"POST",
      url:'{% url 'cart:cart_add' %}',
      data:{
        product_id: $('#add-cart').val(),
        csrfmiddlewaretoken:'{{  csrf_token }}',
        action: 'post'
      },
      success : function(json){
        console.log(json)
      },
      error : function(e){
        console.log(e)
      }
    })
  });
</script>

{% endblock%}

cart\urls.py 아래를 추가

app_name = 'cart'

6.cart\cart.py

파일 생성

class Cart():
    def __init__(self, request):
        self.session = request.session
        
        # Returning user = obtain his/her existing session
        cart = self.session.get('session_key')

        # New user - generate a new session
        if 'session_key' not in request.session:
            cart = self.session['session_key'] = {}
        self.cart = cart
   
   def add(self,product):

        product_id  = str(product.id)

        #>>> a[3] = [1, 2, 3]
        #>>> a
        #{1: 'a', 2: 'b', 'name': 'pey', 3: [1, 2, 3]}

        if product_id in self.cart:
            pass
        else:
            self.cart[product_id] = {'price': str(product.price)}
        
        # Set session as modified to force data updates/cookie to be saved.
        self.session.modified = True

장바구니에서 crud 작업을 해야한다.

  • session 을 self.session 으로 저장한뒤 session_key 라고 이름을 설정해주고 세션이 생성되어있는지 조건문을 실행하고 세션이 생성되어 있지 않으면(신규유저 유입시) 새션을 생성해준다.
  • 세션을 딕셔너리 키값 ‘session_key’ 로 객체 cart에 다시 저장해준다.

cart\context_processors.py

from .cart import Cart # 현재폴더 cart.py 에서 Cart객체를 가져옴

def cart(request):
    return {'cart':Cart(request)}
  • TEMPLATES에서 좀 더 간편하게 따로 관리할 겸 따로 뺴줌
  • 뷰에 있던 어디에 있던 위치는 상관 없음

https://blog.choyoungil.com/2016/07/22/pythondjango%EB%A1%9C-%EC%87%BC%ED%95%91%EB%AA%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0/

정보를 session에 저장하기 때문에 삭제 되면 안되는 장바구니 정보(회원 로그인 후 장바구니에 담은 물건) 가 휘발되는 문제 발생, 결제 완료 이전 장바구니정보를 JSON으로 serialize 하여 db에 저장하는 기능 추가 구현

모든페이지에서 쓸 수 있게 TEMPLATES에 등록

ecom\settings.py

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                   (... 생략 ...)
                'cart.context_processors.cart'
            ],
        },
    },
]

cart.context_processors.cart 를 템플렛에 등록해주면 모든 페이지에서 자유롭게 사용 가능하다.

좀더 설명과 참고 사항은 아래의 참고 페이지 참조

session 에 대한 이해는 정리된 제 블로그에서 참고 하세요.

장바구니 담기 클릭후 옆의 로그가 뜨는지 확인

https://ramyo564.github.io/django/session/
https://nbalance97.tistory.com/236

profile
쿵스보이(얼짱뮤지션)

0개의 댓글