Debugging email on Django application development

One of the common functionalities in Django applications is to send emails, such as for user password resets.

Python SMTP

Since Python comes with it’s own SMTP, it’s easy to redirect the emails from the local Django application being developed to this dummy mail server and see the emails on the console.
Here’s how to do it:

  • Run Python SMTP with this command line:
    python -m smtpd -n -c DebuggingServer localhost:1025
  • Define Django email server as:
    EMAIL_HOST = 'localhost'
    EMAIL_PORT = 1025

And that’s it. All emails sent will be seen on the console where you’r running the Python SMTP.
This technique is actually quite useful since you can use this for any application you are developing locally.

Redirect to Console

There’s another way to see the emails on the console with no dependencies.
To do so, just configure the email to use the console email backend.

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

This will actually redirect all emails to the standard output, which usually is the console.

Redirect to File

Another approach is to redirect the emails into a local file for prior usage.
To do so, just configure the email to use the file email backend.

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location

This will write all emails into separate files located in

/tmp/app-messages

and you can analyze them latter.

Testing for Internet Explorer

While developing for the web, one has to take into account the various browsers that people use.
Depending on the kind of project and target users, this may range from an easy option focused on a single browser up to the dawnting task of supporting the most used browsers world wide.

To help in this task, Microsoft has provided a set of combinations of Windows and Internet Explorer versions in ready to use virtual machines available to all major operating systems.
You can get them here in the Modern.IE web site in the virtual tools section.

Maintaining .Net Browser Compatibility

The .Net framework has a set of predefined browser capabilities. In short, this means that dependending of the browser being used, .Net will create the appropriate HTML.
Unfortunately, sometimes it does not work as expected. Plus, .Net is not capable of keeping up with the speed of the release cycles of all the browsers that are available.

The end result is that sometimes, our .Net application render differently in some browsers, even if they shouldn’t, and, even worst, some functionalities may not work.
To overcome this problem, .Net has a property that allows to specify what to do with the distinct HTTP agents.
Using the ClientTarget property from the Page class, developers can, for instance, assume everyone is using, at least FireFox 3 or Internet Explorer 7.

In short, the solution is to force all “old” browsers to behave as a certain browser and code it from there. This can be achieved either through the clientTarget options in the web.config application file, setting this property to the entire application, or specifically on a page as an attribute of the Page directive.

Step-byStep Tuturial of Ajax in Django Using dajaxice

Using Ajax in Django applications is quite easy when using dajaxproject, Dajax and Dajaxice.
I assume you have pip installed on your system, if that’s not the case, install it.

The first step is to download and install Dajax core:

pip install -e git://github.com/jorgebastida/django-dajax.git#egg=django-dajax

Copy your flavoured prototype function.

Download and install Dajaxice:

pip install -e git://github.com/jorgebastida/django-dajaxice#egg=django-dajaxice

In the application where the Ajax funtionality is required, create an “ajax.py” file with the required Ajax functions.
In the example below it will load cities from a selected country, a tipical problem of master-detail chained selects.

from dajax.core import Dajax
from dajaxice.decorators import dajaxice_register
from my_app.models import City

@dajaxice_register
def updateCity(request, option):
    dajax = Dajax()
    options = City.objects.filter(country.id=option)
    out = ""
    for o in options[int(option)]:
        out += "%s%s" % (out,o,)

    dajax.assign('#id_city','innerHTML',out)
    return dajax.json()

The Ajax function is a simple function that must be registered with the @dajaxice_register anotation.
It gets the cities from a specific country and assigns those values to the innerHTML of the id_city HTML object.

In the forms, the country must call the “updateCity” Ajax funtion to load the cities on the select country.

[...]
#
# Address
#
class AddressForm(forms.Form):
"""
Address form
"""


[...]

    country = forms.ModelChoiceField(widget = forms.Select(attrs = {'onchange' : "Dajaxice.acg.updateCity(Dajax.process,{'option':this.value});"}), queryset=Country.objects.all(), required=True,  empty_label = lcountry_empty, label=lcountry, help_text = lcountry_help, error_messages={'required': lcountry_required})
    city = forms.ModelChoiceField(queryset=City.objects.all(), required=False, empty_label = lcity_empty, label=lcity, help_text = lcity_help)
    address = forms.CharField(widget=forms.Textarea(attrs={'cols': 20, 'rows': 3}), min_length=10, max_length=50, label='Address')
    zip = forms.CharField(max_length=60, required=True, label='Zip code' )
[...]

The only change here, regarding to a common form definition, is to inject the call of the Ajax “updateCity” function on the “onChange” event. Note that the city must be called “city” in order to bind with the HTML id_city object (remember, Django gives “id_” to the id)

Finally, your HTML file must include the jquery.dajax.core.js file in the HEAD section. Copy it to someplace where the browser will be able to load it, like

<script src="/media/dajax/jquery.dajax.core.js" type="text/javascript" charset="utf-8"></script>

And this is all one requires to do in order to have Ajax working on a Django application.