jQuery Mobile and Django

November 12, 2010

In our previous article (http://drumcoder.co.uk/blog/2010/nov/12/jquery-mobile-basics/) we built a basic HTML page using jQuery mobile. If you haven't read that, then read that first, because we're going to build on it with some more functionality.

Links

One the homepage we built previously, we had straightforward links to /bands/, using:

<li><a href="/bands/">Bands</a></li>

jQuery Mobile will translate this into an AJAX call, so the HTML required for this link need only contain the body, not the rest of the file. Here's the HTML we're using for this page - it simply shows a list of A-Z, 0-9 and provides links to bands that start with the selected letter or number.

<div data-role="page">

<div data-role="header">
    <h1>Bands</h1>
    <a data-icon="arrow-u" class="ui-btn-right" href="#home">Home</a>
</div>

<div data-role="content">
<ul data-role="listview" data-inset="true">
  <li><a href="/bands/A/">A</a></li>
  <li><a href="/bands/B/">B</a></li>
  <li><a href="/bands/C/">C</a></li>
  <li><a href="/bands/D/">D</a></li>
  <li><a href="/bands/E/">E</a></li>
  <li><a href="/bands/F/">F</a></li>
  <li><a href="/bands/G/">G</a></li>
  <li><a href="/bands/H/">H</a></li>
  <li><a href="/bands/I/">I</a></li>
  <li><a href="/bands/J/">J</a></li>
  <li><a href="/bands/K/">K</a></li>
  <li><a href="/bands/L/">L</a></li>
  <li><a href="/bands/M/">M</a></li>
  <li><a href="/bands/N/">N</a></li>
  <li><a href="/bands/O/">O</a></li>
  <li><a href="/bands/P/">P</a></li>
  <li><a href="/bands/Q/">Q</a></li>
  <li><a href="/bands/R/">R</a></li>
  <li><a href="/bands/S/">S</a></li>
  <li><a href="/bands/T/">T</a></li>
  <li><a href="/bands/U/">U</a></li>
  <li><a href="/bands/V/">V</a></li>
  <li><a href="/bands/W/">W</a></li>
  <li><a href="/bands/X/">X</a></li>
  <li><a href="/bands/Y/">Y</a></li>
  <li><a href="/bands/0/">0</a></li>
  <li><a href="/bands/1/">1</a></li>
  <li><a href="/bands/2/">2</a></li>
  <li><a href="/bands/3/">3</a></li>
  <li><a href="/bands/4/">4</a></li>
  <li><a href="/bands/5/">5</a></li>
  <li><a href="/bands/6/">6</a></li>
  <li><a href="/bands/7/">7</a></li>
  <li><a href="/bands/8/">8</a></li>
  <li><a href="/bands/9/">9</a></li>
</ul>
</div>

<div data-role="footer">
<h4>Page Footer</h4>
</div>

</div>

If we navigate to this page in the browser, we see the following:

AZ

Key things to note about this page are:

This last point is interesting, but not something you need to worry about unduly. This is still a bookmarkable url for this page.

Django

If we click through to one of these letters, then we show a page that lists all the band names that begin with that letter. This is done using Django.

The URL requested is /bands/D/, which lists all bands that begin with D.

Our top level urls.py contains the offset bands:

urlpatterns = patterns('',
    (r'^$', 'mobile.home.views.home'),
    (r'^bands/', include('mobile.bands.urls')),
)

Our specific urls.py inside the bands application contains the links to generate the /bands/ page contents above, and to render the bands beginning with the specified letter.

urlpatterns = patterns('',
    (r'^$', 'mobile.bands.views.bands_az'),
    (r'^([A-Z0-9])/$', 'mobile.bands.views.bands_letter'),
)

The bands_az view simply renders the template, we don't need any Django involvement:

def bands_az(request):
    """
    Show A-Z list for bands
    """
    return render_auth(request, 'bands/az.htm')

Note that I'm using the .htm suffix to indicate that the template isn't a full HTML page - it's a fragment that requires loading via AJAX.

The bands_letter view fetches the bands that start with a specific letter, and passes them to the template:

def bands_letter(request, pLetter):
    """
    Show bands beginning with specified letter
    """
    lBands = Band.objects.filter(name__istartswith=pLetter)
    return render_auth(request, 'bands/letter.htm', {"Bands" : lBands,
                                                     "Letter" : pLetter,
                                                     })

The template then outputs a line for each band that matches. Note that again this just has a .htm extension, as it is just a fragment of the page. As we're being loaded via AJAX we don't need to specify html, head, body etc.

<div data-role="page">

<div data-role="header">
    <h1>Bands {{Letter}}</h1>
    <a data-icon="arrow-u" class="ui-btn-right" href="#home">Home</a>
</div>

<div data-role="content">
<ul data-role="listview" data-inset="true">
    {% for band in Bands %} 
        <li><a href="/bands/{{band.slug}}/">{{band.name}}</a></li>
    {% empty %}
        <li>Sorry, no bands begin with {{Letter}}</li>
    {% endfor %}
</ul>
</div>

<div data-role="footer">
<h4>Page Footer</h4>
</div>

</div>

Navigating to this page shows the following:

BandsD

Key things to note here are:

  • We again have an automatic Back button, that takes us to the previous page
  • We have added a Home button manually, and said it's on the right hand side. If you don't say it's on the right, it'll display on the left and stop the Back button being displayed.
  • The URL is http://localhost:8000/#/bands/D/. jQuery Mobile has automatically linked through to the correct offset, and loaded the page via AJAX. This is again a bookmarkable URL.

Next