Beginning Django E Commerce
398 pág.

Beginning Django E Commerce


DisciplinaProgramação I24.815 materiais282.481 seguidores
Pré-visualização50 páginas
and load up a web page with some local news on it, you\u2019re doing just 
that: you\u2019re GETting something. 
Now, the POST verb is used when you want to do something. It\u2019s telling the server to create or 
modify some resource on the server instead of just passively asking for a web page. Usually, in order to 
make a POST request to a page, you have to click something with your mouse, like a button that submits 
a web form to the server. 
So what does that have to do with our \u201cAdd To Cart\u201d form? Think about how you\u2019re going to 
implement the form for adding items to the cart. You might be thinking it will end up looking something 
like this: 
<form action=&quot;/add/to/cart/product_slug/&quot; method=&quot;post&quot;>\u2026etc 
The problem with this approach is that you\u2019ve got this funky URL to which you\u2019re posting your 
form, which means that you\u2019ll need to set up that URL and map it to a view function, which isn\u2019t even 
really a view function because no one will ever see it. It\u2019s just going to process adding to cart and redirect 
to the cart page when it\u2019s done. 
We\u2019re going to keep out this clutter by having the \u201cAdd To Cart\u201d form on the product page post back 
right onto the product page itself. Just like the scarecrow in The Wizard of Oz, we\u2019re going to give our 
view function a brain, so that it can differentiate what it does based on whether the request coming in is 
a GET or a POST. Here\u2019s the general idea: 
def show_product(reqest, product_slug): 
 # \u2026 more code here \u2026 
 if request.method == 'POST': 
 # someone's adding to cart\u2026do something here. 
 else: 
 # just a normal GET request 
 # \u2026 etc \u2026 
So if a POST request comes in, we assume that someone just tried to add our product to the cart, 
then, um\u2026 add it, and send them off to the cart page. If it\u2019s just a boring old GET, then we do just 
what the view does now, and display the product page. The flow of this can be tricky to get your head 
around because you\u2019re skipping a whole block of it the first time around, so the whole process just 
doesn\u2019t seem linear. 
Don\u2019t worry about adding this code to your view right now. We\u2019ll get to it in a moment. 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
89 
 
Putting It All Together 
Okay, now, in order to get our \u201cAdd To Cart\u201d form working so that you can start testing your code, we\u2019ve 
got to jump around a lot and implement a lot of little things all at once. If you\u2019ve been skimming the rest 
of this chapter so far, sit up in your chair and pay attention. This won\u2019t take long. 
Let\u2019s take a quick moment to set up the URLs for our cart app, as well as a dummy \u201cCart\u201d template 
that will show up after we\u2019ve added something to the cart. Open up the urls.py file in the root and add 
the following line to your patterns tuple: 
(r'^cart/', include('cart.urls')), 
Then create a urls.py file within your cart app and add this code to it: 
from django.conf.urls.defaults import * 
 
urlpatterns = patterns('ecomstore.cart.views', 
 (r'^$', 'show_cart', { 'template_name': 'cart/cart.html' }, 'show_cart'), 
) 
Now, we need to create a template for this URL so that it doesn\u2019t spit up a TemplateNotFound 
exception like we got at the end of Chapter 2. We\u2019re passing in a variable named template_name, just like 
in the last chapter, to specify the template our cart page will use. 
In your project\u2019s templates directory, create a cart subdirectory and a cart.html file that contains 
the following simple code: 
{% extends &quot;catalog.html&quot; %} 
 
{% block content %} 
 <h1>Cart Page Here</h1> 
 Cart item count: {{ cart_item_count }} 
{% endblock %} 
And then, finally, create the view function in views.py: 
from django.shortcuts import render_to_response 
from django.template import RequestContext 
from ecomstore.cart import cart 
 
def show_cart(request, template_name=&quot;cart/cart.html&quot;): 
 cart_item_count = cart.cart_item_count(request) 
 page_title = 'Shopping Cart' 
 return render_to_response(template_name, locals(), 
context_instance=RequestContext(request)) 
It\u2019s far from complete, but now, when we add in the \u201cAdd To Cart\u201d functionality, it will at least have 
someplace to go. Now, we\u2019re going to create all of those fun cart functions we were talking about earlier. 
With your project\u2019s cart app directory, create a new file, and call it cart.py. Add the following code to 
this file: 
from ecomstore.cart.models import CartItem 
from ecomstore.catalog.models import Product 
from django.shortcuts import get_object_or_404 
from django.http import HttpResponseRedirect 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
90 
 
import decimal # not needed yet but we will later 
import random 
 
CART_ID_SESSION_KEY = 'cart_id' 
 
# get the current user's cart id, sets new one if blank 
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 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij \ufffd 
 klmnopqrstuvwxyz1234567890!@#$%^&*()' 
 cart_id_length = 50 
 for y in range(cart_id_length): 
 cart_id += characters[random.randint(0, len(characters)-1)] 
 return cart_id 
 
# return all items from the current user's cart 
def get_cart_items(request): 
 return CartItem.objects.filter(cart_id=_cart_id(request)) 
 
# add an item to the cart 
def add_to_cart(request): 
 postdata = request.POST.copy() 
 # get product slug from post data, return blank if empty 
 product_slug = postdata.get('product_slug','') 
 # get quantity added, return 1 if empty 
 quantity = postdata.get('quantity',1) 
 # fetch the product or return a missing page error 
 p = get_object_or_404(Product, slug=product_slug) 
 #get products in cart 
 cart_products = get_cart_items(request) 
 product_in_cart = False 
 # check to see if item is already in cart 
 for cart_item in cart_products: 
 if cart_item.product.id = p.id: 
 # update the quantity if found 
 cart_item.augment_quantity(quantity) 
 product_in_cart = True 
 if not product_in_cart: 
 # create and save a new cart item 
 ci = CartItem() 
 ci.product = p 
 ci.quantity = quantity 
 ci.cart_id = _cart_id(request) 
 ci.save() 
 
# returns the total number of items in the user's cart 
def cart_distinct_item_count(request): 
 return get_cart_items(request).count() 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
91 
 
This code is almost twice as long as it really needs to be, because I\u2019ve commented the heck out of it. 
I\u2019m generally very liberal with my commenting, because a week later, when I have to come back to it and 
change something, I don\u2019t have to decode it all. Also, it helps my co-workers when they\u2019re using my 
code. (At least I think it does.) 
The art of commenting your code isn\u2019t terribly difficult to get the hang of. My first inclination is to 
say you should comment liberally, but you can go overboard. The point of commenting your code is not 
to document it thoroughly, but to explain to those reading your code things about your code that may 
not be immediately obvious from the code itself. When in doubt, comment your code when you need to 
explain why you\u2019re doing something, and avoid too many cases when you\u2019re merely explaining what 
your code is doing. 
In the last chapter, I didn\u2019t use many comments in my code because there wasn\u2019t a whole lot of logic 
in what was happening. There were some Django models and views, and not a whole lot more. But look 
at the add_to_cart() function. It makes perfect sense to me because I