いよいよショッピングカートを作っていきます。
$ python3 manage.py startapp cart
setting.py
1 2 3 4 5 6 7 8 | INSTALLED_APPS = [ 'shop' , 'search' , 'cart' , / / 省略 ] / / 省略 'DIRS' : [os.path.join(BASE_DIR, 'shop' , 'templates/' ), os.path.join(BASE_DIR, 'search' , 'templates/' ), os.path.join(BASE_DIR, 'cart' , 'templates/' )], |
cart/models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from django.db import models from shop.models import Product class Cart(models.Model): cart_id = models.CharField(max_length = 250 , blank = True ) date_added = models.DateField(auto_now_add = True ) class Meta: db_table = 'Cart' ordering = [ 'date_added' ] def __str__( self ): return self .cart_id class CartItem(models.Model): product = models.ForeignKey(Product, on_delete = models.CASCADE) cart = models.ForeignKey(Cart, on_delete = models.CASCADE) quantity = models.IntegerField() active = models.BooleanField(default = True ) class Meta: db_table = 'CartItem' def sub_total( self ): return self .product.price * self .quantity def __str__( self ): return self .product.name |
$ python3 manage.py makemigrations cart
$ python3 manage.py migrate
cart/urls.py
1 2 3 4 5 6 7 8 | from django.urls import path from . import views app_name = 'cart' urlpatterns = [ path(' ', views.cart_detail, name=' cart_detail'), ] |
urls.py
1 2 3 4 5 6 | urlpatterns = [ path( 'admin/' , admin.site.urls), path( 'shop/' , include( 'shop.urls' )), path( 'search/' , include( 'search.urls' )), path( 'cart/' , include( 'cart.urls' )), ] |
cart/views.py
L session.session_keyでセッションの値を取得する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from django.shortcuts import render, redirect from .models import Cart, CartItem from django.core.exceptions import ObjectDoesNotExist def _cart_id(request): cart = request.session.session_key if not cart: cart = request.session.create() return cart def cart_detail(request, total = 0 , counter = 0 , cart_items = None ): try : cart = Cart.objects.get(cart_id = _cart_id(request)) cart_items = CartItem.objects. filter (cart = cart, active = True ) for cart_item in cart_items: total + = (cart_item.product.price * cart_item.quantity) counter + = cart_item.quantity except ObjectDoesNotExist: pass return render(request, 'cart/cart.html' , dict (cart_items = cart_items, total = total, counter = counter)) |
cart/template/cart/cart.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | {% extends "base.html" %} {% load static %} {% block metadescription %} This is the shopping cart page.. Proceed to review your items and place the order. {% endblock %} {% block title %} Cart - Various Product Store {% endblock %} {% block content %} {% if not cart_items %} < div > < div class = "text-center" > < br > < h1 class = "text center my_title" >Your shopping cart is empty</ h1 > < br > < p class = "text-center" > Please click < a href = "{% url 'shop:all_product' %}" >here</ a > to continue shopping. </ p > </ div > </ div > {% else %} < div > < div class = "text-center" > < br > < h1 class = "text-center my_title" > Your shopping cart </ h1 > </ div > < br > </ div > < div class = "row mx-auto" > < div class = "col-12 col-sm-12 col-lg-6 text-center" > < table class = "table my_custom_table" > < thread class = "my_custom_thread" > < tr > < th colspan = "5" > Your items </ th > </ tr > </ thread > < tbody > {% for cart_item in cart_items %} < tr > < td >< a href = "cart_item.product.get_absolute_url" >< img src = "{{cart_item.product.image.url}}" alt = "" class = "float-left rounded custom_image" ></ a ></ td > < td class = "text-left" > {{cart_item.product.name}} < br > SKU: {{cart_item.product.id}} < br > Unit Price: ${{cart_item.product.price}} < br > Qty: {{cart_item.quantity}} x ${{cart_item.product.price}} </ td > < td > ${{cart_item.sub_total}} </ td > {% if cart_item.quantity < cart_item.product.stock %} <td> < a href = "{% url 'cart:add_cart' cart_item.product.id %}" class = "custom_a" >< i class = "fas fa-plus-circle custom_icon" ></ i ></ a > < a href = "" class = "custom_a" >< i class = "fas fa-minus-circle custom_icon" ></ a > < a href = "" class = "custom_item" >< i class = "far fa-trash-alt" ></ a > </ td > {% else %} < td > < a href = "" class = "custom_a" >< i class = "fas fa-minus-circle custom_icon" ></ a > < a href = "" class = "custom_item" >< i class = "far fa-trash-alt" ></ i ></ a > </ td > < td ></ td > {% endif %} </ tr > {% endfor %} </ tbody > </ table > </ div > < div class = "col-12 col-sm-12 col-lg-6 text-center" > < table class = "table my_custom_table" > < thread class = "my_custom_thead" > < tr > < th > Checkout </ th > </ tr > </ thread > < tbody > < tr > < td > Please review your shopping cart item before proceeding with the order payment. </ td > </ tr > < tr > < td class = "text-left" > Your total is: < strong >${{total}}</ strong > </ td > </ tr > </ tbody > </ table > < div class = "mx-auto" > < a href = "{% url 'shop:all_product' %}" class = "btn-secondary btn-block my_custom_button" >Continue Shopping</ a > </ div > </ div > </ div > {% endif %} {% endblock %} |
models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from shop.models import Product def add_cart(request, Product_id): product = Product.objects.get( id = product_id) try : cart = Cart.objects.get(cart_id = _cart_id(request)) except Cart.DoesNotExist: cart = Cart.objects.create( cart_id = _cart_id(request) ) cart.save() try : cart_item = CartItem.objects.get(product = product, cart = cart) cart_item.quantity + = 1 cart_item.save() except CartItem.DoesNotExist: cart_item = CartItem.objects.create( product = product, quantity = 1 , cart = cart ) cart_item.save() return redirect( 'cart:cart_detail' ) |
urls.py
1 2 3 4 | urlpatterns = [ path( 'add/<int:product_id>/' , views.add_cart, name = 'add_cart' ), path(' ', views.cart_detail, name=' cart_detail'), ] |
product_detail.html
1 | < a class = "btn btn-secondary" href = "{% url 'cart:add_cart' product.id %}" >Add to Cart</ a > |
cart/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def cart_remove(request, product_id): cart = Cart.objects.get(cart_id = _cart_id(request)) product = get_object_or_404(Product, id = product_id) cart_item = CartItem.objects.get(product = product, cart = cart) if cart_item.quantity > 1 : cart_item.quantity - = 1 cart_item.save() else : cart_item.delete() return redirect( 'cart:cart_detail' ) def full_remove(request, product_id): cart = Cart.objects.get(cart_id = _cart_id(request)) product = get_object_or_404(Product, id = product_id) cart_item = CartItem.objects.get(product = product, cart = cart) cart_item.delete() return redirect( 'cart:cart_detail' ) |
urls.py
1 2 3 4 5 6 7 8 | app_name = 'cart' urlpatterns = [ path( 'add/<int:product_id>/' , views.add_cart, name = 'add_cart' ), path(' ', views.cart_detail, name=' cart_detail'), path( 'remove/<int:product_id>/' , views.cart_remove, name = 'cart_remove' ), path( 'full_remove/<int:product_id>/' , views.full_remove, name = 'full_remove' ) ] |
cart/context_processors.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from .models import Cart, CartItem from .views import _cart_id def counter(request): item_count = 0 if 'admin' in request.path: return {} else : try : cart = Cart.objects. filter (cart_id = _cart_id(request)) cart_items = CartItem.objects. all (). filter (cart = cart[: 1 ]) for cart_item in cart_items: item_count + = cart_item.quantity except Cart.DoesNotExist: item_count = 0 return dict (item_count = item_count) |
settings.py
1 2 3 4 5 6 7 | 'context_processors' : [ 'django.template.context_processors.debug' , 'django.template.context_processors.request' , 'django.contrib.auth.context_processors.auth' , 'django.contrib.messages.context_processors.messages' , 'cart.context_processors.counter' , ], |
navbar.html
1 2 3 4 5 | {% if item_count > 0 %} < li class = "nav-item" > < a class = "nav-link" href = "{% url 'cart:cart_detail' %}" >({{item_count}})</ a > </ li > {% endif %} |
cart.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {% if cart_item.quantity < cart_item.product.stock %} <td> < a href = "{% url 'cart:add_cart' cart_item.product.id %}" class = "custom_a" >< i class = "fas fa-plus-circle custom_icon" ></ i ></ a > < a href = "{% url 'cart:cart_remove' cart_item.product.id %}" class = "custom_a" >< i class = "fas fa-minus-circle custom_icon" ></ a > < a href = "{% url 'cart:full_remove' cart_item.product.id %}" class = "custom_item" >< i class = "far fa-trash-alt" ></ a > </ td > {% else %} < td > < a href = "{% url 'cart:cart_remove' cart_item.product.id %}" class = "custom_a" >< i class = "fas fa-minus-circle custom_icon" ></ a > < a href = "{% url 'cart:full_remove' cart_item.product.id %}" class = "custom_item" >< i class = "far fa-trash-alt" ></ i ></ a > </ td > < td ></ td > {% endif %} |
なるほど、ただこれだと、ログアウトした時の処理などが入ってないから、完成には遠いな。Libraryはないのかしら?