我正在开发一个Django购物车应用程序。我有两个型号Cart和Item。我正在尝试将项目添加到购物篮时获取更新数量,但无法使视图正常工作。我在将item_obj赋值工作时遇到问题 - 我是否需要在此处对模型管理器执行任何操作?任何帮助都非常感谢。
Models.py
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
products = models.ManyToManyField(Product, blank=True)
total = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
objects = CartManager()
def __str__(self):
return str(self.id)
class Item(models.Model):
item = models.ForeignKey(Product, null=True)
cart = models.ForeignKey(Cart, null=True)
quantity = models.PositiveIntegerField()
Views.py extract
def cart_update(request):
product_id = request.POST.get('product_id')
product_obj = Item.objects.get(id=product_id)
print(item_id)
item_obj = Item.objects.get(id=product_id)
cart_obj, new_obj = Cart.objects.new_or_get(request)
if item_obj in cart_obj.products.all():
cart_obj.products.add(product_obj)
item_obj.quantity += 1
item_obj.save()
else:
cart_obj.products.add(product_obj)
return redirect("cart:home")
EDIT
Views.py update(12/02/2018)
def cart_update(request):
# Based on the user who is making the request, grab the cart object
cart_obj, new_obj = Cart.objects.new_or_get(request)
# Get entries in the cart
my_carts_current_entries = Entry.objects.filter(cart=cart_obj)
# Get a list of your products
products = Product.objects.all()
if request.POST:
# Get the product's ID from the POST request.
product_id = request.POST.get('product_id')
# Get the quantity of the product desired.
product_quantity = request.POST.get('product_quantity')
# Create the new Entry...this will update the cart on creation
Entry.objects.create(cart=cart_obj, product=product_id, quantity=product_quantity)
return HttpResponse('carts/carts.html')
return render(request, 'carts/carts.html', {'cart_obj': cart_obj, 'my_carts_current_entries': my_carts_current_entries,
'products': products})
此外,我还有一个单独的购物车模型管理器,用于创建新购物车或为用户分配一个购物车,如下所示:
class CartManager(models.Manager):
def new_or_get(self, request):
cart_id = request.session.get("cart_id", None)
qs = self.get_queryset().filter(id=cart_id)
if qs.count() == 1:
new_obj = False
cart_obj = qs.first()
if request.user.is_authenticated() and cart_obj.user is None:
cart_obj.user = request.user
cart_obj.save()
else:
cart_obj = Cart.objects.new(user=request.user)
new_obj = True
request.session['cart_id'] = cart_obj.id
return cart_obj, new_obj
def new(self, user=None):
user_obj = None
if user is not None:
if user.is_authenticated():
user_obj = user
return self.model.objects.create(user=user_obj)
调试日志中的错误可在此处获得:
提前致谢
更新2:
这就是我的模板文件目前的读取方式。
{% for product in cat_appetizers %}
<table>
<tr>
<td><h5>{{ product.name }}</h5>
<td><p><strong>£ {{ product.price }}</strong></p></td>
<td>
<form class='form-product-ajax' method="POST" action='{% url "cart:update" %}' data-endpoint='{% url "cart:update" %}' class="form"> {% csrf_token %}
<input type="hidden" name='product_id' value='{{ product.id }}'>
<span class='submit-span'>
{% if product in cart.products.all %}
<button>Remove</button>
{% else %}
<button>Add to Basket</button>
</span>
{% endif %}
</form>
</td>
</tr>
</table>
{% endfor %}
答案 0 :(得分:5)
我们可以在模型中使用post-save signal更新购物车模型。以下保存后接收器将在创建条目时更新购物车模型。
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.datetime_safe import datetime
class Product(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64, unique=True)
description = models.TextField(default='')
cost = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True, on_delete='CASCADE')
count = models.PositiveIntegerField(default=0)
total = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "User: {} has {} items in their cart. Their total is ${}".format(self.user, self.count, self.total)
class Entry(models.Model):
product = models.ForeignKey(Product, null=True, on_delete='CASCADE')
cart = models.ForeignKey(Cart, null=True, on_delete='CASCADE')
quantity = models.PositiveIntegerField()
def __str__(self):
return "This entry contains {} {}(s).".format(self.quantity, self.product.name)
@receiver(post_save, sender=Entry)
def update_cart(sender, instance, **kwargs):
line_cost = instance.quantity * instance.product.cost
instance.cart.total += line_cost
instance.cart.count += instance.quantity
instance.cart.updated = datetime.now()
def test_my_cart():
apple, created = Product.objects.get_or_create(name='apple', cost=0.25)
my_cart, created = Cart.objects.get_or_create(user=None)
print(my_cart)
# STDOUT --> User: None has 0 items in their cart. Their total is $0.00
entry1 = Entry.objects.create(product=apple, cart=my_cart, quantity=3)
print(entry1)
# STDOUT --> This entry contains 3 apple(s)
print(my_cart)
# STDOUT --> User: None has 3 items in their cart. Their total is $0.75
如果您想稍后从购物车中删除行条目,Django中也会有删除后信号。
祝你好运
要在管理面板中使用此功能,请尝试following:
# admin.py
from django.contrib import admin
from django.utils.datetime_safe import datetime
from app.models import Product, Cart, Entry
class EntryAdmin(admin.ModelAdmin):
# Overide of the save model
def save_model(self, request, obj, form, change):
obj.cart.total += obj.quantity * obj.product.cost
obj.cart.count += obj.quantity
obj.cart.updated = datetime.now()
obj.cart.save()
super().save_model(request, obj, form, change)
# Register your models here.
admin.site.register(Product)
admin.site.register(Cart)
admin.site.register(Entry, EntryAdmin)
我还要注意,因为有多种方法可以给猫皮肤涂抹#34;我们可以override the save method in the model而不是使用信号。我认为这取决于申请和个人偏好。
这是一个示例视图:
from django.shortcuts import render
from scratchwork.models import Cart, Entry
from django.contrib.auth.models import User
def test_view(request):
""" This view displays what is in a user's cart. """
# Based on the user who is making the request, grab the cart object
my_cart = Cart.objects.get_or_create(user=User)
# Get a queryset of entries that correspond to "my_cart"
list_of_entries = Entry.objects.filter(cart=my_cart)
# Make a list of the product's names
list_of_products = list(list_of_entries.values_list('product__name', flat=True))
# Remove redundant product names
list_of_products = list(set(list_of_products))
return render(request, 'something.html', {'list_of_products': list_of_products})
在我谈论代码之前,我将进行快速比较,以便我们在模型类的相同页面上。
想象一下你在亚马逊上购物。您作为亚马逊客户拥有 的车即可。当您在网站上购物时,购物车会向您显示您添加的任何条目。
当你去浏览亚马逊的奇妙商品时,你偶然发现了一个 你想买的那双鞋。这些鞋是产品并且有 名称,价格和对它们的描述。
您决定购买这些鞋子,然后点击&#34;添加到购物车&#34;。在 这次亚马逊网络服务生成一个条目链接到 购物车,其中包含有关产品的信息。
因此,您单击按钮将POST数据发送回视图。假设您要么使用表单或AJAX数据来获取信息,这就是我设计视图的方法。
from django.http import HttpResponse
from django.shortcuts import render
from scratchwork.models import Cart, Entry, Product
from django.contrib.auth.models import User
def test_view(request):
# Based on the user who is making the request, grab the cart object
my_cart = Cart.objects.get_or_create(user=User)
# Get entries in the cart
my_carts_current_entries = Entry.objects.filter(cart=my_cart)
# Get a list of your products
products = Product.objects.all()
if request.POST:
# Get the product's ID from the POST request.
product_id = request.POST.get('product_id')
# Get the object using our unique primary key
product_obj = Product.objects.get(id=product_id)
# Get the quantity of the product desired.
product_quantity = request.POST.get('product_quantity')
# Create the new Entry...this will update the cart on creation
Entry.objects.create(cart=my_cart, product=product_obj, quantity=product_quantity)
return HttpResponse('somewhereelse.html')
return render(request, 'something.html', {'my_cart': my_cart, 'my_carts_current_entries': my_carts_current_entries,
'products': products})