带有ModelMultipleChoicefield /复选框的表单,一键添加多个模型实例以进行会话

时间:2019-06-11 16:26:43

标签: django django-models django-forms django-templates django-views

我要实现的目标: 我想用Forms.ModelMultipleChoiceField和widget = forms.CheckboxSelectMultiple建立一个表单。 我可以使用该表单来实现,即可以一次选择许多产品实例,然后通过单击购物车会话将它们添加在一起。

我试图做的是: 我试图用forms.ModelMultipleChoiceField和widget = forms.CheckboxSelectMultiple来构建表单,该视图和URL路由到该表单。我将购物车对象逻辑与产品模型分离为2个独立的应用程序。

有什么问题: 当我转到注册的URL路由时,表单模板为黑色,并且在Linux终端中发生以下错误。

[2019年6月11日14:52:06]“ GET / HTTP / 1.1” 200 1083 不允许的方法(GET):/ cart / add_many_products / [11 / Jun / 2019 14:52:36]“ GET / cart / add_many_products / HTTP / 1.1” 405 0

我认为问题是: 我确定它必须对视图做些什么。 我不完全了解如何为此编写代码。 我需要将购物车添加逻辑与带有modelmultiplechice字段的表单结合起来。 我想添加许多产品形式需要转移到array / json中,以便一次将许多产品发送到购物车会话。我不确定如何处理。

我希望有人能帮助我或给我提示我如何继续。

任何帮助/提示都将不胜感激

产品型号:

from django.db import models
from django.urls import reverse

class Product(models.Model):

    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('name',)
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
            return reverse('shop:product_detail', args=[self.id, self.slug])

购物车模型/ cart.py

from decimal import Decimal
from django.conf import settings
from shop.models import Product


class Cart(object):

    def __init__(self, request):
        """
        Initialize the cart.
        """
        self.session = request.session
        cart = self.session.get(settings.CART_SESSION_ID)
        if not cart:
            # save an empty cart in the session
            cart = self.session[settings.CART_SESSION_ID] = {}
        self.cart = cart

    def __iter__(self):
        """
        Iterate over the items in the cart and get the products 
        from the database.
        """
        product_ids = self.cart.keys()
        # get the product objects and add them to the cart
        products = Product.objects.filter(id__in=product_ids)

        cart = self.cart.copy()
        for product in products:
            cart[str(product.id)]['product'] = product

        for item in cart.values():
            item['price'] = Decimal(item['price'])
            item['total_price'] = item['price'] * item['quantity']
            yield item

    def __len__(self):
        """
        Count all items in the cart.
        """
        return sum(item['quantity'] for item in self.cart.values())

    def add(self, product, quantity=1, update_quantity=False):
        """
        Add a product to the cart or update its quantity.
        """
        product_id = str(product.id)
        if product_id not in self.cart:
            self.cart[product_id] = {'quantity': 0, 'price': str(product.price)}
        if update_quantity:
            self.cart[product_id]['quantity'] = 1
        else:
            self.cart[product_id]['quantity'] += 1
        self.save()

    def save(self):
        # mark the session as "modified" to make sure it gets saved
        self.session.modified = True

    def remove(self, product):
        """
        Remove a product from the cart.
        """
        product_id = str(product.id)
        if product_id in self.cart:
            del self.cart[product_id]
            self.save()

    def get_total_price(self):
        return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())

    def clear(self):
        # remove cart from session
        del self.session[settings.CART_SESSION_ID]
        self.save()

购物车表格。py:

from django import forms
from shop.models import Product


PRODUCT_QUANTITY_CHOICES = [(1, str(1))]

class ProductCartAddManyForm(forms.Form):

    products = forms.ModelMultipleChoiceField(queryset=Product.objects.all(), widget=forms.CheckboxSelectMultiple,)
    quantity = forms.TypedChoiceField( choices=PRODUCT_QUANTITY_CHOICES, coerce=int, widget=forms.HiddenInput )
    update = forms.BooleanField(required=False,
                                initial=False,
                                widget=forms.HiddenInput)

购物车视图:

from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from shop.models import Product
from .cart import Cart
from .forms import CartAddProductForm, ProductCartAddManyForm


####writing new Form, add product queryset and connect with cart.add !


@require_POST
def cart_add_many_products(request, product_id):
    cart = Cart(request)
    form = ProductCartAddManyForm(request.POST)
    if form.is_valid():
        cd = form.cleaned_data
        cart.add(product=cd['products'], cd['products']
                    quantity=cd['quantity'],
                    update_quantity=cd['update'])
        #return redirect('cart:cart_detail')
    return render(request, 'cart/products_add.html', {'form': form})

form template:

<form action="{% url "cart:cart_add" product.id %}" method="post">
        {{ form }}
        {% csrf_token %}
        <input type="submit" value="Add to cart">
</form>

网址:

from django.urls import path
from . import views

app_name = 'cart'

urlpatterns = [
    path('', views.cart_detail, name='cart_detail'),
    path('add/<int:product_id>/', views.cart_add, name='cart_add'),
    path('remove/<int:product_id>/', views.cart_remove, name='cart_remove'),
    path('add_many_products/', views.cart_add_many_products, name='products_to_cart'),
]

0 个答案:

没有答案