在django中开发带有会话的购物车

时间:2019-05-18 15:19:10

标签: python django shopping-cart django-sessions django-2.2

我要创建shoppig购物车。我从“ Beginning Django E-Commerce”一书中使用了很多代码(作者:Jim McGaw)。

  

代码错误已得到修复,系统几乎已准备就绪,因此   可以用作购物车的完整项目。

但是,它仍然不完整,还有一些问题需要我继续讨论。

现在,请参阅我的文件:

urls.py

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'),

]

Views.py

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
            add_to_cart(request)
            print("************^^^^(((((((((((")
            # if test cookie worked, get rid of it
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
            return redirect('show_cart')
    else:
        # 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
    request.session.set_test_cookie()
    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':
            remove_from_cart(request)
        if postdata['submit'] == 'Update':
            update_cart(request)
    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)

cart.py

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

CART_ID_SESSION_KEY = 'cart_id'


# Create random str with 50 length for each cart_id
def _generate_cart_id():
    cart_id = ''
    characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()'
    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
            cart_item.augment_quantity(quantity)
            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)
        ci.save()


# 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)
            cart_item.save()
        else:
            remove_from_cart(request)


# 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:
        cart_item.delete()


# 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

models.py

class Product(models.Model):
    STATUE_CHOICE = (
        ('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])

forms.py

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

single_product.html

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



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

        <form method="post" action="" class="cart">
            {% csrf_token %}
            {{ form.as_p }}
            <br/>
            <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"/>
        </form>
        <div class="cb"></div>

        <br>
       Description: {{ product.short_description }}
    {% endblock %}
{% endblock %}

cart.html

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

    <table summary="Your Shopping Cart" id="shopping_cart">
        <caption>Your Shopping Cart</caption>
        <thead>
        <tr>
            <th scope="col">Product</th>
            <th scope="col">Price</th>
            <th></th>
            <th></th>
            <th></th>
            <th scope="col" class="right">Total</th>
        </tr>
        </thead>
        <tfoot>
        <tr>
            <th class="right" colspan="5">
            </th>
            <th class="right">
                {{ cart_sub_total }}
            </th>
        </tr>
        {% if cart_items %}
            <tr>
                <th class="right" colspan="6">
                    <a href="#">Checkout Now</a>
                </th>
            </tr>
        {% endif %}
        </tfoot>
        <tbody>
        {% if cart_items %}
            {% for item in cart_items %}
                <tr>
                    <td>
                        <a href="{{ item.get_absolute_url }}" class="cart">
                            {{ item.name }}
                        </a>
                    </td>
                    <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"/>
                    </td>
                    <td>
                        <form method="post" action="." class="cart">
                            <input type="hidden" name="item_id" value="{{ item.id }}"/>
                            <input type="submit" name="submit" value="Remove"/>
                        </form>
                    </td>
                    <td class="right">{{ item.total }}</td>
                </tr>
            {% endfor %}
        {% else %}
            <tr>
                <td colspan="6" style="height:30px;">
                    Your cart is empty.
                </td>
            </tr>
        {% endif %}
        </tbody>
    </table>
{% endblock %}

我可以看到单个产品页面,但是我有这个问题:

  
      
  1. 我无法将产品添加到购物车。
  2.   
  3. 我看不到购物车页面并且它不起作用。
  4.   

我尝试解决问题,但无法解决。我也看到了这些1234资源,但我的问题没有解决解决。 我不知道该怎么办。可以帮忙吗?

0 个答案:

没有答案