I want to create shoppig cart. I use a lot of my code from "Beginning Django E-Commerce" book (author: Jim McGaw).

Code errors have been fixed and the system is almost ready so that it can be used as a complete project for the shopping cart.

However, it is still not complete and there are problems that I will continue to discuss.

For now, see my files:


app_name = 'shop'
urlpatterns = [
    path('product/', views.all_product, name='all_product'),
    path('product/<slug:slug>/', views.single_product, name='single_product'),
    path('cart/', views.show_cart, name='show_cart'),



def single_product(request, slug):
    p = get_object_or_404(Product, slug=slug)
    # need to evaluate the HTTP method
    if request.method == 'POST':
        # add to cart…create the bound form
        postdata = request.POST.copy()
        form = ProductAddToCartForm(request, postdata)
        # check if posted data is valid
        if form.is_valid():
            # add to cart and redirect to cart page
            # if test cookie worked, get rid of it
            if request.session.test_cookie_worked():
            return redirect('show_cart')
        # it’s a GET, create the unbound form. Note request as a kwarg
        form = ProductAddToCartForm(request=request)
    # assign the hidden input the product slug
    form.fields['product_slug'].widget.attrs['value'] = slug
    # set the test cookie on our first GET request
    template = 'shop/client_shop/single_product.html'
    context = {'product': p}
    return render(request, template, context)
def show_cart(request):
    if request.method == 'POST':
        postdata = request.POST.copy()
        if postdata['submit'] == 'Remove':
        if postdata['submit'] == 'Update':
    cart_items = get_cart_items(request)
    page_title = 'Shopping Cart'
    cart_sub_total = cart_subtotal(request)
    context = {'cart_items': cart_items, 'page_title': page_title, 'cart_sub_total': cart_sub_total}
    template = "shop/cart/cart.html"
    return render(request, template, context)


from .models import CartItem, Product
from django.shortcuts import get_object_or_404
import decimal
import random


# Create random str with 50 length for each cart_id
def _generate_cart_id():
    cart_id = ''
    characters = '[email protected]#$%^&*()'
    cart_id_length = 50
    for y in range(cart_id_length):
        cart_id += characters[random.randint(0, len(characters) - 1)]
    return cart_id

# get the current user's cart id, sets new one if blank
def _cart_id(request):
    if request.session.get(CART_ID_SESSION_KEY, '') == '':
        request.session[CART_ID_SESSION_KEY] = _generate_cart_id()
    return request.session[CART_ID_SESSION_KEY]

# return all items from the current user's cart
def get_cart_items(request):
    return CartItem.objects.filter(cart_id=_cart_id(request))

# add an item to the cart
def add_to_cart(request):
    postdata = request.POST.copy()
    # get product slug from post data, return blank if empty
    product_slug = postdata.get('product_slug', '')
    # get quantity added, return 1 if empty
    quantity = postdata.get('quantity', 1)
    # fetch the product or return a missing page error
    p = get_object_or_404(Product, slug=product_slug)
    # get products in cart
    cart_products = get_cart_items(request)
    product_in_cart = False
    # check to see if item is already in cart
    for cart_item in cart_products:
        if cart_item.product.id == p.id:
            # update the quantity if found
            product_in_cart = True
    if not product_in_cart:
        # create and save a new cart item
        ci = CartItem()
        ci.product = p
        ci.quantity = quantity
        ci.cart_id = _cart_id(request)

# returns the total number of items in the user's cart
def cart_distinct_item_count(request):
    return get_cart_items(request).count()

def get_single_item(request, item_id):
    return get_object_or_404(CartItem, id=item_id, cart_id=_cart_id(request))

# update quantity for single item
def update_cart(request):
    postdata = request.POST.copy()
    item_id = postdata['item_id']
    quantity = postdata['quantity']
    cart_item = get_single_item(request, item_id)
    if cart_item:
        if int(quantity) > 0:
            cart_item.quantity = int(quantity)

# remove a single item from cart
def remove_from_cart(request):
    postdata = request.POST.copy()
    item_id = postdata['item_id']
    cart_item = get_single_item(request, item_id)
    if cart_item:

# gets the total cost for the current cart
def cart_subtotal(request):
    cart_total = decimal.Decimal('0.00')
    cart_products = get_cart_items(request)
    for cart_item in cart_products:
        cart_total += (cart_item.product.price * cart_item.quantity)
    return cart_total


class Product(models.Model):
        ('draft', 'draft'),
        ('future', 'future'),
        ('trash', 'trash'),
        ('publish', 'publish'),
    author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    category = models.ForeignKey(ProductCategory, null=True, blank=True, on_delete=models.SET_NULL)
    name = models.TextField(max_length=100, blank=True)
    slug = models.SlugField(null=True, blank=True, unique=True)
    publish_time = models.DateTimeField(null=True, auto_now_add=True)
    price = models.PositiveIntegerField()
    weight = models.PositiveIntegerField()
    short_description = models.TextField(max_length=250, blank=True)
    exist_amount = models.PositiveIntegerField(null=True, blank=True)
    is_live = models.BooleanField(default=False)
    statue = models.CharField(max_length=10, choices=STATUE_CHOICE, default=STATUE_CHOICE[3][0])


class ProductAddToCartForm(forms.Form):
    quantity = forms.IntegerField(
        widget=forms.TextInput(attrs={'size': '2', 'value': '1', 'class': 'quantity', 'maxlength': '5'}),
        error_messages={'invalid': 'Please enter a valid quantity.'}, min_value=1)
    product_slug = forms.CharField(widget=forms.HiddenInput())

    # override the default __init__ so we can set the request
    def __init__(self, request=None, *args, **kwargs):
        self.request = request
        super(ProductAddToCartForm, self).__init__(*args, **kwargs)

    # custom validation to check for cookies
    def clean(self):
        if self.request:
            if not self.request.session.test_cookie_worked():
                raise forms.ValidationError("Active your cookies!")
            return self.cleaned_data


<!DOCTYPE html>
{% extends "base/website_header.html" %}
{% block body_block %}
    {% block content %}

        <a href="{% url 'shop:single_product' product.slug %}">{{ product.name }}</a>
        Category: <a href=#>{{ product.category }}</a>

        <form method="post" action="" class="cart">
            {% csrf_token %}
            {{ form.as_p }}
            <label for=”quantity”>Quantity</label><input type="text" id="quantity" value="1" />
            <input type="submit" value="Add To Cart" name="submit" alt="Add To Cart"/>
        <div class="cb"></div>

       Description: {{ product.short_description }}
    {% endblock %}
{% endblock %}


<!DOCTYPE html>
{% extends "base/website_header.html" %}
{% block body_block %

    <table summary="Your Shopping Cart" id="shopping_cart">
        <caption>Your Shopping Cart</caption>
            <th scope="col">Product</th>
            <th scope="col">Price</th>
            <th scope="col" class="right">Total</th>
            <th class="right" colspan="5">
            <th class="right">
                {{ cart_sub_total }}
        {% if cart_items %}
                <th class="right" colspan="6">
                    <a href="#">Checkout Now</a>
        {% endif %}
        {% if cart_items %}
            {% for item in cart_items %}
                        <a href="{{ item.get_absolute_url }}" class="cart">
                            {{ item.name }}
                    <td>{{ item.price }}</td>
                    <td class="right">
                        <form method="post" action="" class="cart">
                            <label for="quantity">Quantity:</label>
                            <input type="text" name="quantity" value="{{ item.quantity }}" id="quantity"
                                   size="2" class="quantity" maxlength="5"/>
                            <input type="hidden" name="item_id" value="{{ item.id }}"/>
                            <input type="submit" name="submit" value="Update"/>
                        <form method="post" action="." class="cart">
                            <input type="hidden" name="item_id" value="{{ item.id }}"/>
                            <input type="submit" name="submit" value="Remove"/>
                    <td class="right">{{ item.total }}</td>
            {% endfor %}
        {% else %}
                <td colspan="6" style="height:30px;">
                    Your cart is empty.
        {% endif %}
{% endblock %}

I can see the single product page, But I have this problems:

  1. I can't add product to cart.
  2. I can't see cart page andt it doesn't work.

I tried to fix my problem, but I could not do it.I also saw these 1,2,3 and 4 resources but my problem did not resolve. I have no idea what to do.Is it possible to help?

0 Answers