Wednesday, November 7, 2012

Writing Custom Template Tags in Django

Django templates are the view part of the Django MVC. So, the templates should just handle the display part and any login in templates should be kept to a minimum. However, there are times when we just have to include logic in the templates, and using template tags is the most elegant way to handle this. Creating your own custom template tags is fairly simple.

One template tag needed often is to get the value from a dictionary.

We like passing dictionaries to templates because dictionaries keep everything readable, especially when I have a long list of parameters to pass to the template. Django templates have no in-built mechanism to retrieve a specific key from the dictionary. So we will write our custom template tag to do that.

Create a directory tempatetags/ under your apps directory. In this directory create a file custom_filters.py.

from django import template

register = template.Library()

@register.filter('key')
def key(d, key_name):
    try:
       value = d[key_name]
    except KeyError:
       # handle the error
       raise Http404  
    return value


Now, from views.py, we pass a dictionary to the template. Say
valdict = {'parent':'Mr John Doer', 'child1':'Emily Doer', 'child2':'Mark Doer'}

To access the dictionary keys in the template we do,

template.html.

{% load custom_filters %}

{% block main_content%}
Parent: {{ valdict|key:parent }}
Child1: {{ valdict|key:child1 }}
Child2: {{ valdict|key:child2 }}
{% endblock %}


Read More

Thursday, June 7, 2012

Testing PayPal on Website


PayPal provides a testing tool called PayPal Sandbox to test website's PayPal's deployment. We can create pseudo buyer and seller accounts, provide the accounts with pseudo money and cards, and test the transaction and user experience. All this without putting up real money or fees. They have a User's Guide here. However, the basic steps are simple:
  • Create a Sandbox account first with some email other than the regular PayPal email. 
  • Login to the account. 
  • Inside this account, click on 'Create Preconfigured Account" and create a couple of buyer accounts and one seller account. Once these accounts are created, they are assigned a randomly generated email address. This is the login email address for that account.
  • Now, click on the radio button near buyer's account and then click on "Enter Sandbox Test Site" button below the form. This will direct you to login with buyer's generated email account and password. Without this step, Paypal will not recognize the buyer's sandbox account when we try to psedo-pay the seller later. 
  • In the website's code where the PalPal form was created, set the business email address to the sandbox's seller account's generated email address.
    <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
      <input name="business" type="hidden" value="seller_45681279_biz@mywebsite.com" />
      <input name="cmd" type="hidden" ...
    </form type="submit" value="PayPal">
  • Once the Sandbox seller account is set as business, all the payments go to that account, and no fees are charged
  • Now, go through the buyer's transaction. When Paypal asks for login to pay, use the Sandbox buyer generated email and pwd and login to pay with the Sandbox buyer. 
Thus the complete website flow can be tested. To check the emails PayPal will send to your account on completion of transaction, click on 'Test Email' link in Sandbox nav-bar.

Normally Sandbox transactions do not go through IPN. However, Sandbox provides separate hooks to test this. Go to the 'Test Tools' bar in the Sandbox nav-bar. Here they have IPN Simulator with which the all the different configurations of IPN can be tested.
Read More

Wednesday, June 6, 2012

Paypal Shopping Cart

PayPal's documentation has really very subtle hints about what needs to be done to get Paypal working for a website, and you need to plough through a lot of links to figure out anything useful.

On sign up, they take the user to a page with customizable buttons for Buy Now, Subscribe, Shopping Cart. Now, if the site has only one item to sell, it should use the 'Buy Now', if it is selling subscriptions, use the Subscription Button. For a site that sells multiple items and needs a shopping cart, Paypal has tied up with some Shopping Cart providers.

There is however an option of creating your own light weight shopping carts. Its called Third Party Shopping Cart. This is especially useful when a website is just starting out and it doesn't need the whole armada of a formal Shopping Cart, but it needs something beyond a Buy Now or Subscription Button.

To create your own shopping cart, we need to have a list of items, quantities and price. Then we pass it to Paypal as follows:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_cart">
   <input type="hidden" name="upload" value="1">
   <input type="hidden" name="business" value="seller@mywebsite.com">
   <input type="hidden" name="item_name_1" value="Item Name 1">
   <input type="hidden" name="amount_1" value="1.00">
   <input type="hidden" name="quantity_1" value="2">
   <input type="hidden" name="shipping_1" value="1.75">
   <input type="hidden" name="item_name_2" value="Item Name 2">
   <input type="hidden" name="amount_2" value="2.00">
   <input type="hidden" name="quantity_2" value="3">
   <input type="hidden" name="shipping_2" value="2.50">
   <input type="submit" value="PayPal">
</form>


The suscript-ing numbers item_name_1, amount_1 all refer to the first item on list. There are other options like tax_x, handling_x, discount_amount_x, weight_x. The value of x must increase by 1 for each new item in the cart.

There are some options that can be applied to the entire cart like: currency can be specified with hidden currency, units of weight can be given as weight_unit, tax can be calculated for the entire cart instead of per-item by using tax_cart, discount_amount_cart to charge a single discount amount for the entire cart, discount_rate_cart to give a discount percentage for the entire cart.

This will display a PalPal button on the site. Clicking on that button takes the user to PayPal's site where it shows the list of all the items purchased and the total quantity, and invites the user to pay using the PayPal account or a credit card.

To make Paypal really integrate with a website though, the website needs IPN or PDT.  Stackoverflow has a good discussion on which one to use. We use IPN and are happy with it so far.
Read More

Thursday, May 24, 2012

Adding placeholders, autofocus and other attributes to Django forms

Placeholder is a short hint (a word or short phrase) intended to aid the user with data entry in forms. With HTML5, adding placeholders to forms is as simple as including a keyword:

<label>Name: <input name="name" placeholder="John Doe" type="text" /></label>

This would appear in the form as:

  

To add placeholders to Django forms, simply specify placeholder as an attribute to the form widget.

  name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'John Doe'})

This is actually a pretty general and useful way of passing attributes to Django forms. We can pass other attributes like 'autofocus':'autofocus'. Autofocus is when we want the form field to be in focus automatically when the page loads.

This is for forms created in our app's own forms.py. If we want to pass attributes to forms created by a Django package, we have to pass those attributes at the form's init.

Say, to add attributes to a form called RegistrationForm from some Django package with fields username and password, first create a form in project's forms.py that inherits RegistrationForm. In the __init__ function of the inherited form, pass all the attributes to the form widgets.

class MyRegistrationForm(RegistrationForm):
    def __init__(self, *args, **kwargs):          
        super(MyRegistrationForm, self).__init__(*args, **kwargs)
        self.fields['username'].widget.attrs['placeholder'] = u'Username'
        self.fields['password'].widget.attrs['placeholder'] = u'Password'


Now while using the form, use it as
form = MyRegistrationForm()

This will display base form with the attributes passed to to it at init.
Read More

Wednesday, May 23, 2012

Changing Django Password

Go to the directory where your settings.py resides:

$ python manage.py shell
>>from django.contrib.auth.models import User
>> users = User.objects.all()
>> users
(output) [<User: foo>, <User: adminlogin>, <User: bar>]
>> user = User.objects.filter(name='adminlogin')
>> user.set_password('newpassword')
>> user.save()

This can be used to do most user object management.
Read More