购物车应用
models.py
from decimal import Decimal
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save, post_save
from products.models import Variation
# Create your models here.
class CartItem(models.Model):
cart = models.ForeignKey("Cart")
item = models.ForeignKey(Variation)
quantity = models.PositiveIntegerField(default=1)
line_item_total = models.DecimalField(max_digits=10, decimal_places=2)
def __unicode__(self):
return self.item.title
def remove(self):
return self.item.remove_from_cart()
def cart_item_pre_save_receiver(sender, instance, *args, **kwargs):
qty = instance.quantity
if qty >= 1:
price = instance.item.get_price()
line_item_total = Decimal(qty) * Decimal(price)
instance.line_item_total = line_item_total
pre_save.connect(cart_item_pre_save_receiver, sender=CartItem)
def cart_item_post_save_receiver(sender, instance, *args, **kwargs):
instance.cart.update_subtotal()
post_save.connect(cart_item_post_save_receiver, sender=CartItem)
class Cart(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
items = models.ManyToManyField(Variation, through=CartItem)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
subtotal = models.DecimalField(max_digits=50, decimal_places=2)
def __unicode__(self):
return str(self.id)
def update_subtotal(self):
print "updating..."
subtotal = 0
items = self.cartitem_set.all()
for item in items:
subtotal += item.line_item_total
self.subtotal = subtotal
self.save()
views.py
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404, JsonResponse
from django.shortcuts import render, get_object_or_404
from django.views.generic.base import View
from django.views.generic.detail import SingleObjectMixin
# Create your views here.
from products.models import Variation
from carts.models import Cart, CartItem
class CartView(SingleObjectMixin, View):
model = Cart
template_name = "carts/view.html"
def get_object(self, *args, **kwargs):
self.request.session.set_expiry(0) #5 minutes
cart_id = self.request.session.get("cart_id")
if cart_id == None:
cart = Cart()
cart.save()
cart_id = cart.id
self.request.session["cart_id"] = cart_id
cart = Cart.objects.get(id=cart_id)
if self.request.user.is_authenticated():
cart.user = self.request.user
cart.save()
return cart
def get(self, request, *args, **kwargs):
cart = self.get_object()
item_id = request.GET.get("item")
delete_item = request.GET.get("delete", False)
item_added = False
if item_id:
item_instance = get_object_or_404(Variation, id=item_id)
qty = request.GET.get("qty", 1)
try:
if int(qty) < 1:
delete_item = True
except:
raise Http404
cart_item, created = CartItem.objects.get_or_create(cart=cart, item=item_instance)
if created:
item_added = True
if delete_item:
cart_item.delete()
else:
cart_item.quantity = qty
cart_item.save()
if not request.is_ajax():
return HttpResponseRedirect(reverse("cart"))
#return cart_item.cart.get_absolute_url()
if request.is_ajax():
try:
total = cart_item.line_item_total
except:
total = None
try:
subtotal = cart_item.cart.subtotal
except:
subtotal = None
data = {
"deleted": delete_item,
"item_added": item_added,
"line_total": total,
"subtotal": subtotal,
}
return JsonResponse(data)
context = {
"object": self.get_object()
}
template = self.template_name
return render(request, template, context)
view.html
{% extends "base.html" %}
<script>
{% block jquery %}
$(".item-qty").change(function(){
// $(this).next(".btn-update").fadeIn();
// event.preventDefault();
// .prev(h1)
var item = $(this).prev("input[type='hidden']").val();
var qty = $(this).val()
var data = {
item: item,
qty: qty
}
console.log(data);
$.ajax({
type: "GET", // "POST"
url: "{% url 'cart' %}",
data: data,
success: function(data) {
$("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted)
if (data.deleted){
$("#item-"+item).fadeOut();
} else {
$("#item-line-total-"+item).text(data.line_total);
$("#subtotal").text(data.subtotal);
}
},
error: function(response, error) {
// console.log(response)
// console.log(error)
$("#add-form").submit()
}
})
});
{% endblock %}
</script>
{% block content %}
<table class='table'>
{% for item in object.cartitem_set.all %}
<tr id='item-{{ item.item.id }}'>
<td>{{ item.item.get_title }}</td>
<td><form action="." method="GET" ><input type='hidden' name='item' value='{{ item.item.id }}' /><input type='number' class='item-qty' name='qty' value='{{ item.quantity }}' /><input type='submit' class='btn-update btn btn-link' value='Update item' style='display:none;'/></form></td>
<td id='item-line-total-{{ item.item.id }}'>{{ item.line_item_total }}</td>
<td class='text-right' ><a href='{{ item.remove }}'>X</a>
</td>
</tr>
{% endfor %}
<tr>
<td id='subtotal' colspan='4' class='text-right'>Subtotal: {{ object.subtotal }}</td>
</tr>
</table>
{% endblock %}
当我更新数量时,购物车小计也在更新,但仅在项目删除时才更新。
对于购物车的自动更新,我使用的是Ajax
更新:
包含{{item.remove}}在内部但仍然没有更改小计并且也没有错误
我还注意到,在我的管理员手动删除购物车中的商品时,小计也没有改变
答案 0 :(得分:0)
在看了我的模型后,我发现有些东西丢失了,这是删除后的内容,在添加了一行后,小计开始获得更新项目的删除
from decimal import Decimal
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save, post_save, post_delete
from products.models import Variation
# Create your models here.
class CartItem(models.Model):
cart = models.ForeignKey("Cart")
item = models.ForeignKey(Variation)
quantity = models.PositiveIntegerField(default=1)
line_item_total = models.DecimalField(max_digits=10, decimal_places=2)
def __unicode__(self):
return self.item.title
def remove(self):
return self.item.remove_from_cart()
def cart_item_pre_save_receiver(sender, instance, *args, **kwargs):
qty = instance.quantity
if qty >= 1:
price = instance.item.get_price()
line_item_total = Decimal(qty) * Decimal(price)
instance.line_item_total = line_item_total
pre_save.connect(cart_item_pre_save_receiver, sender=CartItem)
def cart_item_post_save_receiver(sender, instance, *args, **kwargs):
instance.cart.update_subtotal()
post_save.connect(cart_item_post_save_receiver, sender=CartItem)
post_delete.connect(cart_item_post_save_receiver, sender=CartItem)
class Cart(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
items = models.ManyToManyField(Variation, through=CartItem)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
subtotal = models.DecimalField(max_digits=50, decimal_places=2)
def __unicode__(self):
return str(self.id)
def update_subtotal(self):
print "updating..."
subtotal = 0
items = self.cartitem_set.all()
for item in items:
subtotal += item.line_item_total
self.subtotal = subtotal
self.save()