Tag Archives: django

AJAX + Django (Part 1)

Asynchronous JavaScript and XML: getting data asynchronously, without page reloads… It’s not a technology but a technique that requires the interaction of several technologies. What technologies? A dash of a decent web framework (Django), a nice JavaScript library (jQuery) and some understanding of web requests and responses. Optionally, you might want to use some kind of Web UI framework such as Twitter Bootstrap (I do), which allows you to focus on what’s really important: system design and development.

So this is how I AJAXified an application…


First, a little on the basics of how a typical web request works:

  1. Client requests a resource from the server (new URL entered or form submitted),
  2. Server receives the request and builds a response (fetches a document or builds it dynamically),
  3. Server returns a response with the resulting document (which is opened by the browser).

That’s all there is to a synchronous request, and if everything goes well all this happens in a few milliseconds. And asynchronous requests? Almost the same, with a minor difference in the first and last steps: the URL request and form submits are triggered by JavaScript, and document updates (if any) are done by JavaScript as well, without loading a new page.

The Garden of the Forking Paths

So how to do it? First, let’s consider that the only difference is that instead of returning a whole document, we need to return only a portion that will be used to update the document. This document is an HTML page, so we need to replace some portion of HTML by another (updated) portion of HTML. Nothing new here.

Since we’re using Django, we’ll build the response with a view, of course (read controller for other web frameworks). So, the view must return an HTML string that the JavaScript code will use to replace another one, right? Not necessarily: we can return any string, we could even use JavaScript to format it before pasting it on the document.

So that means that the question that bares the core of the issue is where will the HTML code be constructed? But this question can arise at two different level:

  • Formatted vs. Raw: server-side vs. client-side,
  • Python vs. Django: view vs. template.

The first classification is clear enough: will the server return the resulting HTML or will it only return raw data that will be formatted (with JavaScript)? The second one might seem confusing at first sight, since Django is a Python library. To understand the difference you need to think how loyal to the Django way it is: will it be built directly in the view (in pure Python) or will it use the render function to do so in a template?

So these are in fact the three possible paths:

  1. The Python Way
  2. The Django Way
  3. The JavaScript Way

Anyone who has any experience in Django will automatically discard the first, more intuitive option. Building an HTML string (with all the tags we might forget) in a Python function is a horrible idea. In fact, it defeats the very purpose of using a nicely layered framework with a powerful templating language such as Django. Exeunt the Python Way.

Isn’t the third option also uglier? Perhaps… until we consider two things about the data: transmission and versatility. On the first angle, this option can be the best when transmission speed is a major issue, because a JSON-formatted string is more compact than an equal HTML string (emphasis on equal, I’ll explain why on the second part!). On the usefulness side, returning pure JSON data will allow you to use this to build a RESTful API that could be used by any service to fetch that data (mobile apps, websites, email, you-name-it), regardless of the implementation of those services… which is very, very awesome.

The Application

To show the implementation I will use a small accounting application I built to track accounts, transactions and provide useful financial stats and projections. Its model is rather simple, so adapting it to other models should be very easy.

Filtering accounts by type

We’ll focus on one page only: the Accounts page, which consists (mostly) of a table of accounts with their relevant information (code, total credit, total debit, currency, balance, etc.) There are also a set of multi-select filters used to update the list of accounts displayed: one allows to filters by currencies, another by account type, and another one contains several options to show or hide totals and the like. The idea is to apply every filter asynchronously in each click instead of on every submit.

The Django Way

The easiest implementation (and nicer, if you will) is done using Django’s templating to render the response. There are three things to consider: the URLs mapping, the view definitions and the templates. Let’s see each in detail.


Being very RESTful about it, we need to make sure that URLs only define resources and behaviour is defined by methods, so using class-based views is called for because they make it so much easier. The urlpatterns in the urls.py file includes these lines:

url(r'^accounts/$', AccountsView.as_view(), name='accounts'),
url(r'^accounts/(?P<code>new)/$', AccountView.as_view(), name='create_account'),
url(r'^accounts/(?P<code>[^/.]+)/$', AccountView.as_view(), name='show_account'),
url(r'^accounts/(?P<code>[^/.]+)/edit/$', AccountView.as_view(), {'edit': True}, name='edit_account'),

The first URL maps to the AccountsView class (plural), which accepts GET and POST requests (to show the list or add a new account). The remaining three URLs map to the AccountView class (singular), which accepts GET, PUT and DELETE to get one account (show or edit), update one account or delete one account.

You have probably noticed that the second and third lines could be just one, as whether the code is new or not will be checked in the view anyway, but I like to keep a different name to make the reverse look up in templates easier.

AccountView class

One of the nice things about class-based views is that they have one method for each web request method, so instead of checking the request.method in the view, you simply define the corresponding instance method for each web method: the method named get will be triggered if the request method is GET, post if it’s a POST, and so on—and when not found, a 405 Method Not Allowed response is given automatically.

Class-based views need to inherit from one of the django.views classes. In this case we’ll use the generic view, which provides the basic hooks.

from django.views.generic.base import View

class AccountsView(View):

And on to the method definitions…

GET Requests

  def get(self, request):
    a = Account.objects.all()
    form_f = AccountsFilterForm(request.GET)
    form_o = AccountsOptionsForm(request.GET)
    if form_f.is_valid():
      a = filter_accounts(a, form_f)
    if form_o.is_valid():
      opts = get_opts(form_o)
    c = {'accounts': a, 'filter_form': form_f, 'options_form': form_o, 'options': opts}
    return render(request, get_template('accounts', request.is_ajax()), c)

As you can see the get function uses two forms: AccountsFilterForm that picks up attribute-based filters for the list of accounts, and AccountsOptionsForm that simply determines some display options (which are mostly taken care of in the template). They are very simple, so you needn’t worry about the form definitions.

I am sure you can guess that the function filter_accounts filters its first argument (queryset of Account objects) according to the selected fields in its second argument (a form which consists of checkboxes of account attributes, such currency and type.) The function get_opts builds a list of selected options (booleans) that the template will use to display optional data (balances, subtotals, etc.)

Then it builds the context, including both forms, the list of accounts and the dictionary of options and renders all that on a template. Which template? That decision is made by the get_template function, that takes up to three parameters to select the correct one based on the resource name, the type of request (sync vs. async) and whether the view is for editing objects.

def get_template(resource, partial, edit=False):
  return 'accountant/{}{}{}.html'.format('partial/' if partial else '', resource, '-edit' if edit else '')

POST Requests

def post(self, request):
  na = AccountModelForm(parse_form(request.raw_post_data))
  c = {}
  s, c['alert'] = save_form(na)
  return render(request, get_template('alert', request.is_ajax()), c, status=s)

The post function defines a new account using the post data on the AccountModelForm, and tries to save it, saving the status code and a message with the result of the operation (save_form returns that tuple), then renders all that data on the correct template.

AccountView class

This class takes care of all requests to specific accounts, and accepts get, put and delete methods to act on them.

GET Requests

class AccountView(View):

  def get(self, request, code, edit=False):
    if code == 'new':
      c = {'form': AccountModelForm()}
      account = get_object_or_404(Account, code__iexact=code)
      c = {'account': account}
      if edit:
        c['form'] = AccountModelForm(instance=account)
    return render(request, get_template('account', request.is_ajax(), edit), c)

The get method checks for three possibilities: the view is to create a new account, in which case it includes an unbound AccountModelForm form; it is to display the data of one account, in which case it picks up the account object; or it’s to edit an existing one, in which it also includes an AccountModelForm, but using the account as instance. Then it just renders the context on the template defined by the get_template function.

POST and PUT Requests

def post(self, request, code):
  return self.put(request, code)

def put(self, request, code):
  account = get_object_or_404(Account, code__iexact=code)
  form = AccountModelForm(parse_form(request.raw_post_data), instance=account)
  c = {}
  s, c['alert'] = save_form(form)
  return render(request, get_template('alert', request.is_ajax()), c, status=s)

Why does the class define a post method? Shouldn’t updates use the PUT method? Yes, but HTML forms cannot use but GET or POST methods (for whatever reason), so if the request is made directly from a webpage (without JavaScript or another service), it cannot be a PUT request. But since it should still behave like a PUT request, it just forwards the request to the put method.

Edit account modal form

The put method picks up the account object, reads the form data (parse_form is used to abstract POST vs. PUT issues away), gets the status code and alert message, and returns the rendered response (with the correct status code). Simple.

DELETE Requests

def delete(self, request, code):
  account = get_object_or_404(Account, code__iexact=code)
  c = {}
  s, c['alert'] = delete_object(account) 
  return render(request, get_template('alert', request.is_ajax()), c, status=s)

Almost identical to the put method, nothing to explain.


This is where the key really is, I think. Not so much in the whole template idea, but on one specific tag, the include tag. That is the one templating weapon that makes AJAX extremely simple with Django.


First let’s take a look at the base template…

  • <body>
      <div class="navbar">
        # navigation bar stuff
      <div class="container">
        {% block header %}{% endblock %}
        {% block alerts %}{% endblock %}
        {% block modals %}{% endblock %}
        {% block content %}{% endblock %}
          # footer stuff
      <script src="{{ STATIC_URL }}js/jquery.min.js" type="text/javascript"></script>
      <script src="{{ STATIC_URL }}js/bootstrap.min.js" type="text/javascript"></script>
      {% block scripts %}{% endblock %}

So there are five blocks to consider, four inside the main container: header, alerts, modals and content; and one for the custom scripts (loaded after jQuery and Twitter Bootstrap libraries).


This is the main template for the Accounts page, but as you’ll see, not the only one…

{% block header %}
  <h3 class="well well-small">Accounts</h3>
{% endblock %}
{% block alerts %}
  <div id='alerts'>
  {% if alert %}
    {% include "accountant/partial/alert.html" %}
  {% endif %}
{% endblock %}
{% block modals %}
  <div id="modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
{% endblock %}
{% block content %}
  <div id="data">
    {% include "accountant/partial/accounts.html" %}
{% endblock %}
{% block scripts %}
  <script type="text/javascript" src="{{ STATIC_URL }}js/csrf.js"></script>
  <script type="text/javascript" src="{{ STATIC_URL }}js/scripts.js"></script>
{% endblock %}

So you see that there are three blocks for which the content is not directly there: alerts and data blocks are included, and the modals portion is missing altogether. This is actually quite logical, because the fact that they are displayed at the same time (on the same page) is irrelevant, they are indeed independent pieces of information.

On to these included and missing templates…


{% if alert %}
  <div class="alert alert-{{ alert.type }}">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <strong>{{ alert.type|title }}:</strong> {{ alert.text }}
{% endif %}

Very simple: it only displays a Bootstrap alert message with the correct colour to indicate success or failure, and a dismiss button to remove the alert dynamically. If there is an alert, otherwise it’s empty.

Alerting about saved items

Alerting about saved items

Accounts (Partial)

<table id="accounts" class="table table-striped">
{% if accounts %}
    <th colspan="2">Name</th>
    {% if options.show_balance %}
    {% endif %}
{% for account in accounts %}
      <a title='Details' href="{% url show_account account.code %}"><i class="icon-search"></i></a>
      <a title='Edit' class="modal-trigger" href="{% url edit_account account.code %}"><i class="icon-edit"></i></a>
      <a title='Remove' class="deleter" href="{% url edit_account account.code %}"><i class="icon-remove"></i></a>
    <td>{{ account.name }}</td>
    # Rest of the account data here... you get the picture
{% else %}
  <caption>No accounts with those attributes</caption>
{% endif %}

Nothing overly complex either, just display the table of accounts if there are accounts remaining after applying the filters; otherwise display a caption. But pay attention to the fact that every row includes three links as little buttons (show, delete and edit), which do link to the proper URL. This is key for two reasons: without JavaScript the button will still work (although linking to a full-page form instead of a modal window), and it will also make the JavaScript to handle it more generic.


The Add/Modify Account modal window is powered by Twitter Bootstrap…

<div class='modal-header'>
  <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>
  <h3>Edit Account</h3>
{% if account %}
  <form id='modal-form' action='{% url show_account account.code %}' method='PUT'>
{% else %}
  <form id='modal-form' action='{% url accounts %}' method='POST'>
{% endif %}
  <div class='modal-body'>
    {% csrf_token %}
    {{ form.as_table }}
  <div class='modal-footer'>
    <button type="button" class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <button type="submit" class="btn btn-primary">Save</button>

This is not included in the Accounts template from the beginning because even though this modal will be pasted on the Accounts page, it responds to a different resource (URL).It’s the AccountView class that knows how to deal with this, the AccountsView’s get method doesn’t even know about any form, so it wouldn’t render anything on the template if included.


The main JavaScript is not very long (remember that we are using jQuery and Bootstrap), and it starts with the typical handlers attachers

  $('#filters input').on('click', updateTable);
  $('#actions input').on('click', updateTable);
  $('body').on('click', '.modal-trigger', displayModal);
  $('body').on('click', '.deleter', deleteObject);
  $('body').on('submit', '#modal-form', saveForm);

updateTable simply selects the correct filtering/updating function to run based on the id of main table on the page, so regardless of the page (accounts, transactions, entries) it always works as expected. In this case (the Accounts page) it simply calls the filterAccounts function passing the accounts table as parameter.


function filterAccounts(t) {
  form = $('#filters');
  data = $(form).find('input:checked');
  qs = addFiltersData(data, '');
  form = $('#actions');
  data = $(form).find('input:checked');
  qs = addOptionsData(data, qs);
  qs = qs.substring(0, qs.length - 1);
  $(t).load("/accountant/accounts/?" + qs);

The function receives a parameter t (in this page the accounts table), it parses the forms data as one single querystring and then updates the table with the result of the asynchronous GET request triggered by jQuery’s load function, which in turn updates the html of the calling element with the response of the request sent to the URL. Yes, I know, this load method is really awesome!

Recapping a bit what goes on behind stage: whenever that function is called it sends a simple GET request to the server with the forms data, which uses to the AccountsView.get function to filter the accounts and return the template rendered as an HTML string, which is then used to update the content of the table with id accounts. All this in a few milliseconds, without refreshing the page.

And what about data modification? There are three sides to that: getting the add/edit form, submitting the new/modified data and deleting some data.


function displayModal(e) {
  url = $(this).attr('href');

Is that it? But it doesn’t even specify what it should display!

Remember that the edit links have the correct URL already. JavaScript is only preventing the browser from send a synchronous request (e.preventDefault()), sending instead an asynchronous request to the same URL to update the modal div, and then display it as a modal window.

Account add modal form

Account add modal form


function saveForm(e) {
    url: $('#modal-form').attr('action'),
    type: $('#modal-form').attr('method'),
    data: $('#modal-form').serialize(),
    success: function(response, status, request) {

The function is quite generic and uses the $.ajax method because of its flexibility. Remember that the forms templates define the resource (action) and method? The function takes advantage of that and simply obeys the form’s directives (so the form works on any page). The response is used to update the content of the alerts div (because all modals do return an alert), and then the modal windows is hidden. Then the table is updated (by doing sending another GET request asynchronously.)


function deleteObject(e) {
    url: $(this).attr('href'),
    type: 'DELETE',
    success: function(response, status, request) {

Deleting an object is quite similar, with the difference that since no form is used, the method is set manually to DELETE. You should add a confirm alert as well… I’ve no clue why I hadn’t until now.

What’s Next?

Checking requests and responses

Checking requests and responses

In the next part, we’ll see how we can implement The JavaScript Way, and why would we want to…

Django Form Inheritance

Data exploration is a major part of the systems I build.
And I found that the best approach is to provide search tools, all over the place, for all data: equipment deployed, personnel, activities, quantities, consumables, phone numbers… everything. There is no such a thing as too much information when you are in Project Control.

The consequence is that the number of forms used in the system is staggering.
However, careful analysis will show that some features are shared among them:

  • A text search field
  • A paging choice field (to select the number of items per page)
  • A date range field

Since I hate to write similar code twice, I decided to use inheritance to accomplish most of the work, using three base classes: SearchFromBasePagedFormBase and DateRangeFormBase.
Note: I always end the name in -Base when I intend to use the class as parent only. Just being explicit, nothing major.

So first we get on with the text filter:

    class SearchFormBase(forms.Form):

        def __init__(self, *args, **kwargs):
            super(SearchFormBase, self).__init__(*args, **kwargs)
            self.fields['q'] = forms.CharField(max_length=30, required=False, label='')

Very simple: we just add an optional char field on the initialization of the form object.
Why call the field q? Well, most of use are used to see it in the query string, so… Plus, I can avoid changing it for every different search.

Now get define the paging part, used by most filters to decide how many items per page are displayed.
Why? Because it is just rude to assume that everyone will be happy with 20 items per page. Some people do like choices. Most don’t, I know.

    class PagedFormBase(forms.Form):

        def __init__(self, *args, **kwargs):
            clipp = kwargs.get('clipp')
            if clipp is None:
                clipp = consts.CHOICES_LIST_IPP
                del kwargs['clipp']
            super(PagedFormBase, self).__init__(*args, **kwargs)
            self.fields['i'] = forms.ChoiceField(widget=widgets.RadioSelect, choices=clipp,\
                                                 initial=clipp[1][0], label='Items/Page')
            self.fields['i'].widget.attrs['class'] = 'ipp'

This one is a bit more complex, as it can take an iterable of tuples as argument to use as the choices list.
Why? Well, the data being displayed can be quite diverse in form, so giving always the same options is not a good idea.
Also, one of them is very complex and if someone tries to display 100 items per page it can get really slow. Performance counts.
Note: The argument is optional, and if none is provided we default to a constant (which is actually most cases.) And do remember to remove arguments so that the base class (forms in this case) doesn’t get confused.

And now the difficult one: the date range.

    class DateRangeFormBase(forms.Form):

        def __init__(self, *args, **kwargs):
            date_range = kwargs.get('date_range')
            if date_range is None:
                date_range = consts.LIST_DATE_RANGE
                del kwargs['date_range']
            super(DateRangeFormBase, self).__init__(*args, **kwargs)
            self.fields['fd'] = forms.DateField(required=False, label='From date',\
            self.fields['td'] = forms.DateField(required=False, label='To date',\

        def clean(self):
            cleaned_data = self.cleaned_data
            if 'fd' in cleaned_data and 'td' in cleaned_data:
                fd = cleaned_data['fd']
                td = cleaned_data['td']
                if td < fd:
                    self._errors['td'] = self.error_class(('Invalid date: final date cannot be less than start',))
                    del cleaned_data['td']
            return cleaned_data

Actually, not that difficult: pretty much the same as the previous one, plus a clean method.

So what now?
Well, those forms are pretty useless as they are, because they were created to be combined.
Here we’ll define the most basic form used by the searches: the PagedSearchForm. This form is so basic that it will also be inherited by other form classes, but due to the fact that it will be used directly as well the name does not end in -Base. Well, I am consistent.

    class PagedSearchForm(SearchFormBase, PagedFormBase):

        def __init__(self, *args, **kwargs):
            super(PagedSearchForm, self).__init__(*args, **kwargs)

And that’s how you define a form class that includes a text search field and a paging radio button field. Was that easy or what?
Well, that’s another reason you can like Python: multiple inheritance. Not so useless.