Beginning Django E Commerce
398 pág.

Beginning Django E Commerce


DisciplinaProgramação I24.583 materiais280.005 seguidores
Pré-visualização50 páginas
way for us to control the appearance of our output directly inside 
our template code. There are a ton of template filters that come with Django by default, and it\u2019s well 
worth your trouble to have a look at the Django documentation so that you know which ones are 
available for your use. Among the more important ones are those for encoding or stripping HTML (to 
prevent cross-site scripting attacks), converting text to all upper- or lowercase, taking operations on sets 
or groups, or formatting strings. We already used one of these in the last chapter, the pluralize filter that 
customizes the display of a word based on a numeric value (for example, \u201ccategory\u201d versus \u201ccategories\u201d 
on the product page). 
If any of the default filters don\u2019t do what you want, you are free to create your own. Since we\u2019re 
creating an e-commerce site, I already feel myself putting dollar signs ($) all over the site, which might 
be fine for the moment, but will pose a problem for us when we want to start selling stuff in other 
countries. To make sure that our site propagates as needed, we\u2019re going to create a custom \u201ccurrency\u201d 
filter for displaying price information. 
In order to create a custom template filter, we just need to create a Python function definition that 
takes a value as an argument, and returns a string to display in our template. This function just needs to 
be in a directory called templatetags inside one of our project\u2019s installed apps. Go ahead and create this 
folder inside your project\u2019s catalog app, and add two files to it: __init__.py, and catalog_filters.py. 
The first, of course, is the obligatory empty file that merely identifies your directory as a Python package. 
The second will contain our code. Add the following to catalog_filters.py: 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
97 
 
from django import template 
import locale 
 
register = template.Library() 
 
@register.filter(name='currency') 
def currency(value): 
 try: 
 locale.setlocale(locale.LC_ALL,'en_US.UTF-8') 
 except: 
 locale.setlocale(locale.LC_ALL,'') 
 loc = locale.localeconv() 
 return locale.currency(value, loc['currency_symbol'], grouping=True) 
I\u2019m using a very useful part of the standard Python distribution, called locale, which is used for 
formatting and displaying currency values based on the locale that is set by our code. The preceding 
function definition will use a comma to separate dollar values by the thousands, and use a dollar sign for 
the currency symbol. We use decorators to register our filter with the template system using the Python 
decorator syntax and name it currency. 
I have to admit that before I found the locale module in Python, I spent about a half-hour trying to 
design my own custom solution to this problem. Never underestimate the resourcefulness of the Python 
community. Keep in mind that if you dig deep enough, you can probably find a solution to your problem 
somewhere on the Internet. 
\u25a0 Note The locale module is dependent upon the locales that have been configured with your operating system. If 
you run into problems with the preceding code, you may need to take explicit steps to set these up on your system. 
On Unix systems, you may trying running the following as root locale-gen en_US.UTF-8 to configure the locale. 
In order to use the filter in our template, we just need to load it inside our template file, with the 
following line of code at the top of the file (but make sure it\u2019s below the extends directive. That must 
always come first!): 
{% load catalog_filters %} 
The load directive is the Django template equivalent of the Python import statements at the top of 
your Python files. It scans through all of the templatetags subdirectories that it finds in your project\u2019s list 
of installed apps, and loads in any custom template tags or filters that it finds. 
After you\u2019re finished with the cart page, go back into your product page template file and add your 
new currency filter. You just need to add the {% load %} directive and add the filter to any price you\u2019re 
displaying on the page. 
Creating the Cart Page 
Open up your CSS file and add the following style definitions for your shopping cart table: 
/* styles for shopping cart page */ 
table#shopping_cart{ 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
98 
 
 width:100%; 
 border-collapse:collapse; 
 color:#616161; 
} 
h1,caption{ 
 text-align:left; 
 font-size:x-large; 
 margin-bottom:15px; 
 color:Black; 
} 
th,td{ 
 text-align:left; 
 padding:3px; 
} 
thead th{ 
 color:White; 
 background-color:#616161; 
} 
tfoot th{ 
 height:40px; 
} 
 
table#shopping_cart th.right, td.right{ 
 text-align:right; 
} 
a.cart{ 
 color:DarkOrange; 
} 
Then, open up your cart template that you create earlier and replace what\u2019s in there with the 
following markup: 
{% extends "catalog.html" %} 
 
{% load catalog_filters %} 
 
{% block content %} 
<table summary=&quot;Your Shopping Cart&quot; id=&quot;shopping_cart&quot;> 
 <caption>Your Shopping Cart</caption> 
 <thead> 
 <tr> 
 <th scope=&quot;col&quot;>Product</th> 
 <th scope=&quot;col&quot;>Price</th> 
 <th></th> 
 <th></th> 
 <th></th> 
 <th scope=&quot;col&quot; class=&quot;right&quot;>Total</th> 
 </tr> 
 </thead> 
 <tfoot> 
 <tr> 
 <th class=&quot;right&quot; colspan=&quot;5&quot;> 
 Cart Subtotal: 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
99 
 
 </th> 
 <th class=&quot;right&quot;> 
 {{ cart_subtotal|currency }} 
 </th> 
 </tr> 
 {% if cart_items %} 
 <tr> 
 <th class=&quot;right&quot; colspan=&quot;6&quot;> 
 <a href=&quot;/url/to/checkout/&quot;>Checkout Now</a> 
 </th> 
 </tr> 
 {% endif %} 
 </tfoot> 
 <tbody> 
 {% if cart_items %} 
 {% for item in cart_items %} 
 <tr> 
 <td> 
 <a href=&quot;{{ item.get_absolute_url }}&quot; class=&quot;cart&quot;> 
 {{ item.name }} 
 </a> 
 </td> 
 <td>{{ item.price|currency }}</td> 
 <td class=&quot;right&quot;> 
 <form method=&quot;post&quot; action=&quot;.&quot; class=&quot;cart&quot;> 
 <label for=&quot;quantity&quot;>Quantity:</label> 
 <input type=&quot;text&quot; name=&quot;quantity&quot; value=&quot;{{ item.quantity }}&quot; id=&quot;quantity&quot; \ufffd 
 size=&quot;2&quot; class=&quot;quantity&quot; maxlength=&quot;5&quot; /> 
 <input type=&quot;hidden&quot; name=&quot;item_id&quot; value=&quot;{{ item.id }}&quot; /> 
 </td> 
 <td> 
 <input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Update&quot; /> 
 </form> 
 </td> 
 <td> 
 <form method=&quot;post&quot; action=&quot;.&quot; class=&quot;cart&quot;> 
 <input type=&quot;hidden&quot; name=&quot;item_id&quot; value=&quot;{{ item.id }}&quot; /> 
 <input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Remove&quot;/> 
 </form> 
 </td> 
 <td class=&quot;right&quot;>{{ item.total|currency }}</td> 
 </tr> 
 {% endfor %} 
 {% else %} 
 <tr> 
 <td colspan=&quot;6&quot; style=&quot;height:30px;&quot;> 
 Your cart is empty. 
 </td> 
 </tr> 
 {% endif %} 
 </tbody> 
</table> 
{% endblock %} 
www.it-ebooks.info
CHAPTER 4 \u25a0 THE SHOPPING CART 
 
100 
 
The indentation in this code is somewhat mashed, for the sake of preserving space. You can see that 
we\u2019re using our new currency filter function definition for all of our prices. Before you start trying to type 
that in, have a look at Figure 4-3, so you have so idea of what it\u2019s supposed to look like. 
Notice that we\u2019ve got two forms for each line item that have a POST method that post back to the cart 
page. That means that we\u2019re going to handle these processing requests in our view function, right? Exactly. 
 
Figure 4-3. Our cart page, with