[英]Django Cart and Item Model - getting quantity to update
我正在開發Django購物車應用程序。 我有兩種型號的購物車和物品。 我正在嘗試將數量添加到購物籃中時更新數量,但無法使視圖正常工作。 我在使item_obj分配工作時遇到問題-在這里我需要對模型管理器做任何事情嗎? 任何幫助都非常感謝。
型號
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提取
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更新(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 %}
我們可以通過在模型中使用保存后的信號來更新Cart模型。 每當創建條目時,以下保存后的接收器都會更新購物車模型。
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中還會有一個后刪除信號。
祝您好運
要在管理面板中使用此功能,請嘗試以下操作 :
# 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)
我還想指出的是,由於存在“多種方法來給貓換皮”,我們可以在模型中覆蓋save方法,而不使用信號。 我認為這取決於應用程序和個人喜好。
這是一個示例視圖,它將:
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})
在討論代碼之前,我將進行快速比較,因此我們在同一頁上討論了模型類。
假設您在亞馬遜購物。 您作為亞馬遜客戶擁有購物車 。 購物車將顯示您在網站上購物時添加到其中的所有條目 。
當您瀏覽亞馬遜奇妙的商品時,偶然發現了一雙想要購買的鞋子。 這些鞋子是產品,並有名稱,價格和描述。
您決定購買這些鞋子,因此單擊“添加到購物車”。 此時,Amazon Web服務會生成一個鏈接到購物車的條目 ,其中包含有關產品的信息。
因此,您單擊一個按鈕將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})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.