簡體   English   中英

Django購物車和商品模型-獲取數量以進行更新

[英]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)

調試日志中的錯誤在這里可用:

http://dpaste.com/1NX02JW

提前致謝

更新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模型。 每當創建條目時,以下保存后的接收器都會更新購物車模型。

models.py

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中還會有一個后刪除信號。

祝您好運


編輯#1

要在管理面板中使用此功能,請嘗試以下操作

# 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方法,而不使用信號。 我認為這取決於應用程序和個人喜好。


編輯#2

這是一個示例視圖,它將:

  1. 獲取用戶的購物車
  2. 從該購物車中獲取條目列表
  3. 在這些條目中獲取產品的所有唯一名稱的列表

example_view.py

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})

編輯#3

在討論代碼之前,我將進行快速比較,因此我們在同一頁上討論了模型類。

假設您在亞馬遜購物。 您作為亞馬遜客戶擁有購物車 購物車將顯示您在網站上購物時添加到其中的所有條目

當您瀏覽亞馬遜奇妙的商品時,偶然發現了一雙想要購買的鞋子。 這些鞋子是產品,並有名稱,價格和描述。

您決定購買這些鞋子,因此單擊“添加到購物車”。 此時,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM