Добавление элементов в корзину
Чтобы добавить элементы в корзину, нам нужна форма, позволяющая пользователю выбрать количество добавляемого товара. Создайте файл forms.py в каталоге приложения cart и добавьте в него следующий код:
from django import forms
PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]
class CartAddProductForm(forms.Form):
quantity = forms.TypedChoiceField(choices=PRODUCT_QUANTITY_CHOICES, coerce=int)
update = forms.BooleanField(required=False, initial=False, widget=forms.HiddenInput)
Эта форма будет использоваться для добавления продуктов в корзину. Класс CartAddProductForm содержит следующие поля:
quantity : позволяет пользователю выбрать количество между 1-20. Мы используем поле TypedChoiceField с coerce=int для преобразования ввода в целое число.
update : позволяет указать, следует ли добавлять сумму к любому существующему значению в корзине для данного продукта (False) или если существующее значение должно быть обновлено с заданным значением (True). Для этого поля используется графический элемент HiddenInput, поскольку не требуется показывать его пользователю.
Создадим представление для добавления элементов в корзину. Отредактируйте файл views.py приложения cart и добавьте в него следующий код:
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
@require_POST
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
cart.add(product=product,
quantity=cd['quantity'],
update_quantity=cd['update'])
return redirect('cart:cart_detail')
Это представление для добавления продуктов в корзину или обновления количества для существующих продуктов. Мы используем декоратор require_POST, чтобы разрешить только POST запросы, поскольку это представление изменит данные. Представление получает ID продукта в качестве параметра. Мы извлекаем экземпляр продукта с заданным ID и проверяем CartAddProductForm. Если форма валидна, мы либо добавляем, либо обновляем продукт в корзине. Представление перенаправляет по URL-адресу cart_detail, который будет отображать содержимое корзины. Мы собираемся создать cart_detail представление в ближайшее время.
Нам также требуется представление для удаления товаров из корзины. Добавьте следующий код в файл views.py приложения cart:
def cart_remove(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
cart.remove(product)
return redirect('cart:cart_detail')
Представление cart_remove получает id продукта в качестве параметра. Мы извлекаем экземпляр продукта с заданным id и удаляем продукт из корзины. Затем мы перенаправляем пользователя на URL-адрес cart_detail.
Наконец, требуется представление для отображения корзины и ее товаров. Добавьте следующий вид в файл views.py:
def cart_detail(request):
cart = Cart(request)
return render(request, 'cart/detail.html', {'cart': cart})
Представление cart_detail выводит на экран текущее состояние корзины.
Мы создали представления для добавления товаров в корзину, обновления количества, удаления товаров из корзины и отображения корзины. Рассмотрим добавление шаблонов URL-адресов для этих представлений. Создайте новый файл в каталоге приложения cart и назовите его urls.py. Добавьте к нему следующие URL-адреса:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.cart_detail, name='cart_detail'),
url(r'^add/(?P<product_id>\d+)/$', views.cart_add, name='cart_add'),
url(r'^remove/(?P<product_id>\d+)/$', views.cart_remove, name='cart_remove'),
]
Измените основной файл urls.py прректа myshop и добавьте следующий шаблон URL-адреса для включения URL-адресов корзины:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^cart/', include('cart.urls', namespace='cart')),
url(r'^', include('shop.urls', namespace='shop')),
]
Убедитесь, что этот шаблон URL-адреса был включен до shop.urls, поскольку он является более ограничительным, чем последний.