使用 Django 创建会话和按钮,通过模板和 views.py 将产品连接到购物车

Posted

技术标签:

【中文标题】使用 Django 创建会话和按钮,通过模板和 views.py 将产品连接到购物车【英文标题】:Using Django to create sessions and buttons connecting Products to a shopping cart through templates and views.py 【发布时间】:2018-07-20 14:48:42 【问题描述】:

抱歉冗长(认为信息是相关的),并感谢您帮助了解其工作原理。我正在尝试使用会话和 Django 模板将商品添加到购物车。我对学习 Django 还很陌生,并且仔细阅读了一堆类似的文档和 Stack Overflow 问题。我的数据保存到 mysql 数据库(可能会发生变化),如下所示:

sql_entry = 
        'model': 'App.Product',
        'pk': 1, # unique for each item
        'fields': 
                    'Name': 'name',
                    'Price': 1.0,
                    'Quantity': 1
        

和我的模特:

    class Product(models.Model):
    Name = models.CharField(max_length=200, default='')
    Price = models.FloatField()
    Quantity = models.IntegerField()


    def __str__(self):
        return self.Name

    class Meta:
        ordering = ['Name']

因为实际产品每天都会变化,我想避免硬编码类别,并认为最好只拥有与可用产品相关的数据。所以我使用 Django 的模板来创建每个产品的基本表格视图,并带有一个将其添加到购物车的按钮。我现在想避免任何类型的登录。我读到会话是唯一客户将商品添加到购物车并将那里的数据保存到我的数据库的最佳方式。我相信我的“添加到购物车”按钮需要将他们的条目临时保存到我的数据库中,以某种方式与他们的会话 ID 相对应。这是我遇到很多麻烦的地方。在以下代码块中,我试图将一个项目添加到每个浏览器应该是唯一的会话购物车。当我单击按钮时,它会重定向到购物车,但没有任何反应。如果你能让我知道我的设置配置有多糟糕,那就太棒了。以下是视图、购物车模板和 url 模式:

views.py 中的会话设置

    def index(request):
    response = render_to_response('buylist/Home.html')
    visits = int(request.COOKIES.get('visits', '0'))
    if 'last_visit' in request.COOKIES:
        last_visit = request.COOKIES['last_visit']
        last_visit_time = datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S")
        if (datetime.now() - last_visit_time).days > 0:
            response.set_cookie('visits', visits + 1)
            response.set_cookie('last_visit', datetime.now())
    else:
        response.set_cookie('last_visit', datetime.now())
    return response

在views.py中添加到购物车功能

# add Product to cart after button click
def add_to_cart(request, product_id):
    cart = request.session.get('cart', )
    product = Product.objects.get(id=product_id)
    cart[product_id] = product
    request.session['cart'] = cart
    return HttpResponseRedirect(reverse("cart"))


# Cart View
def get_cart(request):
    cart = request.session.get('cart',)
    return render(request, 'buylist/cart.html', cart)

这是我拥有的模板和 url 模式:

basic.html #Product 有按钮的产品页面

% for item in file %
    <tbody>
      <tr>
        <td>item.fields.Name</td>
        <td>$item.fields.Price</td>
        <td>item.fields.Quantity</td>
        <td>
            <a href="http://127.0.0.1:8000/cart/item.id"><button>Add</button></a>      
        </td>

      </tr>
    </tbody>
% endfor %

App.urls 中的网址模式

    path('cart/<int:product_id>/', views.add_to_cart, name='add'),
    path('cart/', views.get_cart, name='cart'),

cart.html

<table>
    <tr>
        <center><h2>Shopping Cart</h2></center>
        <th>Product|</th>
        <th>Quantity|</th>
        <th>Total Price</th>
    </tr>

    % for item in cart %
    <tr>
        <td>item</td>
    </tr>
    % endfor %
</table>

【问题讨论】:

【参考方案1】:

要更新您的购物车,请这样做。如果添加了产品,它将删除该产品,如果购物车中不存在该产品,它将添加该产品。两种功能。 product_id 来自最后给出的 HTML 表单。这是您要添加到购物车中的产品。

def cart_update(request):
    p = request.POST.get("product_id")
    if p is not None:
        product_obj = Product.objects.get(id =p)
        c,n = Cart.objects.get_or_new(request)
        if product_obj not in c.products.all():
            c.products.add(product_obj)

    else:
        c.products.remove(product_obj)
        print("to be added")

    return redirect("cart:home")

购物车型号是

class Cart(models.Model):
    user = models.ForeignKey(User, null = True, blank = True)
    products = models.ManyToManyField(Product, blank= True)

    subtotal = models.DecimalField(default = 0.00, max_digits= 12, decimal_places=2)

    total = models.DecimalField(default = 0.00, max_digits= 12, 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 CartManager(models.Manager):
    def get_or_new(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:
            new_obj = True
            cart_obj = Cart.objects.new_cart(user = request.user)
            request.session['cart_id'] = cart_obj.id
       return cart_obj, new_obj

您的 HTML 表单

<h1>Your Cart</h1>

% for a in cart.products.all %
<form action="% url "cart:update" %" method="POST">% csrf_token %

<input type="hidden" name="product_id" value='a.id' placeholder="
 a.id"/>

<h4>Your Product: <a href= ' a.get_absolute_url'>a.title</a><small>
<br><button type="submit">Remove?</button></small></h4>
<p>Price :

a.price</p>
</form>
% endfor %

<b>Subtotal: cart.subtotal</b><br>

总计:cart.total

<a href="% url "cart:checkout" %"> Checkout</a>

这就是你所要做的。阅读代码以完全理解它。这有点棘手。如果用户是新用户,我已经使用管理器创建了一个新的购物车对象。产品模型是您可以在其中添加许多不同产品的模型。

【讨论】:

以上是关于使用 Django 创建会话和按钮,通过模板和 views.py 将产品连接到购物车的主要内容,如果未能解决你的问题,请参考以下文章

通过 django 模板和 JS 的动态喜欢和不喜欢按钮的问题

如何在模板django中请求会话值

Django:将会话信息传递给下一个模板和视图

如何通过按钮更改 Django 模板使用的 CSS?

FastAPI 中的会话

Django:将模板值发布到视图