📅  最后修改于: 2023-12-03 15:00:27.366000             🧑  作者: Mango
在网站开发中,购物车是不可避免的功能。Django 作为一款 Python 的 Web 框架,自然也提供了相应的库来实现购物车的功能。
Django 的购物车实现方式主要通过 session 来实现,即将购物车信息保存在用户的 session 中。用户在添加商品到购物车后,应该需要登录才能进行购物车的操作。
使用 Django 实现购物车需要以下几个步骤:
首先,我们需要创建一个购物车类 Cart
,用于保存购物车信息。
class Cart(object):
def __init__(self, request):
"""
初始化购物车
"""
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
def add(self, product, quantity=1, update_quantity=False):
"""
添加商品到购物车或者修改商品数量
"""
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {'quantity': 0, 'price': str(product.price)}
if update_quantity:
self.cart[product_id]['quantity'] = quantity
else:
self.cart[product_id]['quantity'] += quantity
self.save()
def save(self):
"""
保存购物车信息到 session 中
"""
self.session[settings.CART_SESSION_ID] = self.cart
self.session.modified = True
然后,在视图函数中,我们可以通过获取产品的 id 和数量,将其添加到购物车中。
from django.shortcuts import get_object_or_404, render
from .models import Product
from .cart import Cart
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
cart.add(product=product)
return render(request, 'cart/detail.html', {'cart': cart})
在模板中,我们可以通过设置一个表单,让用户选择商品的数量,然后将其数量作为参数传递给视图函数 cart_add
,实现添加购物车的功能。
{% extends "base_generic.html" %}
{% block content %}
<h1>{{ product.name }}</h1>
<form action="{% url 'cart:add' product.id %}" method="post">
{% csrf_token %}
<input type="number" name="quantity" min="1" max="99" value="1">
<button type="submit" class="btn btn-primary">添加到购物车</button>
</form>
{% endblock %}
如果用户需要修改购物车中的商品数量,我们可以通过 update_quantity
参数来实现。
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
if request.method == 'POST':
quantity = request.POST['quantity']
cart.add(product=product, quantity=quantity, update_quantity=True)
return HttpResponseRedirect(reverse('cart:cart_detail'))
else:
cart.add(product=product)
return render(request, 'cart/detail.html', {'cart': cart})
在模板中,我们需要根据实际情况来判断修改商品数量的表单是什么样子的。如果购物车中已经有了当前商品,那么我们就需要显示修改商品数量的表单,否则就需要显示添加到购物车的表单:
{% extends "base_generic.html" %}
{% block content %}
<h1>{{ product.name }}</h1>
{% if product.id|string in cart.cart %}
<h2>商品已经在购物车中</h2>
<form action="{% url 'cart:add' product.id %}" method="post">
{% csrf_token %}
<input type="number" name="quantity" min="1" max="99" value="{{ cart.cart.product.id.quantity }}">
<button type="submit" class="btn btn-primary">修改数量</button>
</form>
{% else %}
<form action="{% url 'cart:add' product.id %}" method="post">
{% csrf_token %}
<input type="number" name="quantity" min="1" max="99" value="1">
<button type="submit" class="btn btn-primary">添加到购物车</button>
</form>
{% endif %}
{% endblock %}
如果要实现从购物车中删除商品的功能,我们可以在购物车类 Cart
中添加一个 remove
方法:
class Cart(object):
def __init__(self, request):
"""
...
def remove(self, product):
"""
从购物车中删除商品
"""
product_id = str(product.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
在视图函数中,我们可以通过调用 remove
方法来实现从购物车中删除商品的功能。
def cart_remove(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
cart.remove(product)
return HttpResponseRedirect(reverse('cart:cart_detail'))
在模板中,我们需要为每个商品添加一个删除按钮:
{% extends "base_generic.html" %}
{% block content %}
<h1>购物车</h1>
<table class="table">
<thead>
<tr>
<th>产品</th>
<th>数量</th>
<th>单价</th>
<th>总价</th>
<th></th>
</tr>
</thead>
<tbody>
{% for product in cart.cart.values %}
<tr>
<td>{{ product.name }}</td>
<td>
<form action="{% url 'cart:update' product.id %}" method="post">
{% csrf_token %}
<input type="number" name="quantity" min="1" max="99" value="{{ product.quantity }}">
<button type="submit" class="btn btn-primary">修改数量</button>
</form>
</td>
<td>{{ product.price }}</td>
<td>{{ product.quantity|mul:product.price }}</td>
<td>
<form action="{% url 'cart:remove' product.id %}" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">删除</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
<th>总计:</th>
<td>{{ cart.get_total_price }}</td>
</tr>
</tfoot>
</table>
{% endblock %}
最后,我们需要计算购物车中所有商品的总价。在购物车类 Cart
中,我们可以添加一个 get_total_price
属性来计算总价。
class Cart(object):
def __init__(self, request):
"""
...
@property
def get_total_price(self):
"""
计算购物车中所有商品的总价
"""
return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
在模板中,我们可以通过渲染 cart.get_total_price
属性来显示购物车中所有商品的总价。
{% extends "base_generic.html" %}
{% block content %}
<h1>购物车</h1>
<table class="table">
<thead>
<tr>
<th>产品</th>
<th>数量</th>
<th>单价</th>
<th>总价</th>
<th></th>
</tr>
</thead>
<tbody>
{% for product in cart.cart.values %}
<tr>
<td>{{ product.name }}</td>
<td>
<form action="{% url 'cart:update' product.id %}" method="post">
{% csrf_token %}
<input type="number" name="quantity" min="1" max="99" value="{{ product.quantity }}">
<button type="submit" class="btn btn-primary">修改数量</button>
</form>
</td>
<td>{{ product.price }}</td>
<td>{{ product.quantity|mul:product.price }}</td>
<td>
<form action="{% url 'cart:remove' product.id %}" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">删除</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
<th>总计:</th>
<td>{{ cart.get_total_price }}</td>
</tr>
</tfoot>
</table>
{% endblock %}
以上就是通过 Django 实现添加到购物车的详细步骤,购物车的实现方式虽然简单,但是功能却十分强大,为网站的开发提供了很大的便利。