В последнии дни очень много людей спрашивали, как сделать корзину на Django сайте и вот я решил написать реализацию простейшей корзины для сайта.

В первую очередь нам нужно описать модель нашей корзины

#models.py
from django.db import models
from catalog.models import Product

class CartItem(models.Model):
    cart_id = models.CharField(max_length=50)
    date_added = models.DateTimeField(auto_now_add=True)
    quantity = models.IntegerField(default=1)
    product = models.ForeignKey(Product, unique=False)

    class Meta:
        ordering = ['date_added']

    def total(self):
        return self.quantity * self.product.price

    def name(self):
        return self.product.name

    def price(self):
        return self.product.price

    def augment_quantity(self, quantity):
         self.quantity = self.quantity + int(quantity)
         self.save()

Как мне кажется здесь все просто, корзина связана с нашим продуктом (Product) и все действия понятны и дополнительного описания не требуется.

 

Теперь давайте опишем логику работы корзины, для это в папке с приложением создадим файл файл cart.py

 
#cart.py
import decimal
import random
from django.shortcuts import get_object_or_404
from cart.models import CartItem
from catalog.models import Product

CART_ID_SESSION_KEY = 'cart_id'


def _cart_id(request):
    if request.session.get(CART_ID_SESSION_KEY,'') == '':
        request.session[CART_ID_SESSION_KEY] = _generate_cart_id()
    return request.session[CART_ID_SESSION_KEY]


def _generate_cart_id():
    cart_id = ''
    characters = '[email protected]#$%^&*() '
    cart_id_length = 50
    for y in range(cart_id_length):
        cart_id += characters[random.randint(0, len(characters)-1)]
    return cart_id


def get_cart_items(request):
    return CartItem.objects.filter(cart_id=_cart_id(request))


def add_to_cart(request):
    postdata = request.POST.copy()
    product_slug = postdata.get('product_slug', '')
    quantity = postdata.get('quantity', 1)
    p = get_object_or_404(Product, slug=product_slug)
    cart_products = get_cart_items(request)
    product_in_cart = False
    for cart_item in cart_products:
        if cart_item.product.id == p.id:
            cart_item.augment_quantity(quantity)
            product_in_cart = True
    if not product_in_cart:
        ci = CartItem()
        ci.product = p
        ci.quantity = quantity
        ci.cart_id = _cart_id(request)
        ci.save()


def cart_distinct_item_count(request):
    return get_cart_items(request).count()


def get_single_item(request, item_id):
    return get_object_or_404(CartItem, id=item_id, cart_id=_cart_id(request))


def update_cart(request):
    postdata = request.POST.copy()
    item_id = postdata['item_id']
    quantity = postdata['quantity']
    cart_item = get_single_item(request, item_id)
    if cart_item:
        if int(quantity) > 0:
            cart_item.quantity = int(quantity)
            cart_item.save()
        else:
            remove_from_cart(request)


def remove_from_cart(request):
    postdata = request.POST.copy()
    item_id = postdata['item_id']
    cart_item = get_single_item(request, item_id)
    if cart_item:
        cart_item.delete()


def cart_subtotal(request):
    cart_total = decimal.Decimal('0.00')
    cart_products = get_cart_items(request)
    for cart_item in cart_products:
        cart_total += cart_item.product.price * cart_item.quantity
    return cart_total


def is_empty(request):
    return cart_distinct_item_count(request) == 0


def empty_cart(request):
    user_cart = get_cart_items(request)
    user_cart.delete()

 

Здесь тоже все понятно и все описанно в названии функций, теперь сделаем форму для корзины

#forms.py
from django import forms
class ProductAddToCartForm(forms.Form):
	quantity = forms.IntegerField(widget=forms.TextInput(attrs={'size':'2',
		'value':'1', 'class':'input-small', 'maxlength':'5'}),
		error_messages={'invalid':'Введите правильное количество'}, min_value=1, label='Количество')
	product_slug = forms.CharField(widget=forms.HiddenInput())
	def __init__(self, request=None, *args, **kwargs):
		self.request = request
		super(ProductAddToCartForm, self).__init__(*args, **kwargs)
	def clean(self):
		if self.request:
			if not self.request.session.test_cookie_worked():
				raise forms.ValidationError("Cookies должны быть включены")
		return self.cleaned_data

И представление

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect

from cart import cart

def show_cart(request, template_name="cart/cart.html"):
    if request.method == 'POST':
        postdata = request.POST.copy()
        if postdata['submit'] == 'Remove':
            cart.remove_from_cart(request)
        if postdata['submit'] == 'Update':
            cart.update_cart(request)
    cart_items = cart.get_cart_items(request)
    page_title = 'Корзина'
    cart_subtotal = cart.cart_subtotal(request)
    return render_to_response(template_name, locals(), context_instance=RequestContext(request))

Ну и urls.py для полной картины

 
    urlpatterns = patterns('cart.views',
	url(r'^$', 'show_cart', { 'template_name': 'cart/cart.html'}, 'show_cart'),
	)

 

Думаю шаблон описывать не стоит, так как все делается также как и для любых других представлений.

Даже если вы просто скопипастите данные скрипты у вас будет полностью рабочая корзины и вчитавшись в код вы сможете ее модернизировать под свои нужды

 

Советую прочитать данные книги


23 марта 2013 г. 12:22:58    Alex Vakhitov Django 0

Комментарии (0)

    Вам нужно авторизироваться, чтобы оставить свой комментарий

    /*Вход*/

    Login with github
    /*Twitter*/
    /*Реклама*/