Previous Page Next Page

Manipulating Lists

This section discusses using filters to create and manipulate lists inside the template files. You probably will work quite a bit with lists inside the templates, and you won't have the control that you normally would inside Python code. However, the template engine does provide some much-needed filters to help you manage lists.

The following sections describe the slice, make_list, join, and random filters and how to apply them to lists.

slice

The slice filter accepts an argument containing Python list slicing syntax. Depending on the argument's value, it renders a subset of the original list.

This is useful if you need to limit the number of entries from the list that you want to render to the HTML output. For example, if a template is used to render items returned from a search, you could use the slice filter in the following line of code to filter only the top ten:

{{ searchResults|slice":10" }}

Just as in Python, the number on the left of the : refers to the starting index, and the number on the right refers to the ending index. If no value is specified for the starting index, the slice filter starts at the first item. If no value is specified for the ending index, the slice filter stops after the last item.

Also, just like Python, the index is 0-based, and negative numbers access items from the end of the list. If you wanted the template in the preceding example to retrieve the last 10 items in the search routine, you would use the following syntax:

{{ searchResults|slice"-10:" }}

Did you Know?

The slice filter can be applied to a string variable as well. For example, if you have a string, str, with a value of Hello World, you could use the slice filter in the following code to display only Hello:

{{ str|slice:":5" }}


make_list

The make_list filter renders the variable as a list. The make_list filter accepts no arguments. If the variable is numeric, the make_list filter renders a list of digits. If the variable is a string, it renders a list of characters.

The following example shows the result of applying the make_list filter to a string, s, with a value of Python:

{{ s|make_list }}

It renders the following:

['P','y','t','h','o','n']

The following example shows the result of applying the make_list filter to a number, n, with a value of 2008:

{{ n|make_list }}

It renders the following:

['2','0','0','8']

The make_list filter can be used in many different ways, depending on how creative you get. For example, you can split a large number into a list of characters and then process each digit separately.

join

The join filter works similarly to the Python str.join(list) function. The join filter accepts a string object as the only argument. The entries in the list are joined, with the value of the string argument placed between each entry and rendered as a string.

The join filter is useful if you need to display the elements of a list in comma- or space-separated form. For example, if you simply want to display names in a person list, you could use the following code in a template:

{% filter linebreaks %}
There are {{ people.length }} people in the list.
Their names are : {{ people|join:", " }}.
{% endfilter %}

The rendered output from this filter would look something like this:

There are 5 people in the list.
Their names are: Arthur, Lancelot, Galahad, Robin, Tim.

Did you Know?

The join filter can be applied to a string variable as well. For example, if you have a string, s, with a value of Title, you could use the join filter as follows to display T-i-t-l-e:

{{ s|join:"-" }}


random

The random filter selects a random item from a list. This can be useful for keeping web content from getting too stale. For example, if you use a quote of the day on your website, you could pass a list of quotes, and the random filter would allow you to generate a random quote each time the web page is accessed.

Here's the syntax for using the random filter:

{{ QuoteOfTheDay|random }}

Try It Yourself: Apply a Filter to a List Object

In this section, you will modify the quote.html template to select a random quote from the list. Currently the quote is hard-coded in, so you need to add code to the details view function to send the quote as part of the context dictionary.

By the Way

In this section, you will stop the development server and create a new application called Quotes. After the application is created, you will add some quotes to the database using the admin interface. If you've forgotten how to do some of these tasks, refer to Hours 2 and 3.


Following these steps to randomize the quote displayed on the person details view:

1.
Stop the development server.

2.
From the iFriends root directory, use the following command to create an application called Quotes:

python manage.py startapp Quotes

3.
Open the iFriends/Quotes/models.py file in an editor.

4.
Add the following line of code to the file to import the models class:

from django.db import models

5.
Add the following code to the file, as shown in Listing 9.2, to define a Quotes model and enable it in the admin interface:

class Quote(models.Model):
    text = models.TextField('text', max_length=200)
    by = models.CharField ('by', max_length=50)

    def __str__(self):
        return '%s' % (self.text)
    class Admin:
       pass

6.
Save the iFriends/Quotes/models.py file.

7.
Open the iFriends/settings.py file in an editor.

8.
Add the following line to the INSTALLED_APPS setting of the settings.py file to activate the Quotes model:

'iFriends.Quotes',

9.
Save the iFriends/settings.py file.

Watch Out!

Whenever you run the syncdb utility, you change the structure of the database. The syncdb utility should be able to install new applications into the database without problems. I've noticed that Django sometimes has a hard time updating the database. If you get errors, check the structure of the database to make sure the application was added. You might need to add 'iFriends.Quotes' as the first line in the settings.py file to get it added to the database. Hopefully, database synching will be improved in the future.

10.
Use the following command from the iFriends root directory to synchronize the new Quotes model to the database:

python manage.py syncdb

11.
Use the following command from the iFriends root directory to start the development server:

python manage.py runserver

12.
Access the admin interface at the following address, and add some Quote objects to the database.

http://127.0.0.1:8000/admin

13.
Open the iFriends/People/views.py file in an editor.

14.
Add the following line of code, as shown in Listing 9.3, to import the Quotes model:

from iFriends.Quotes.models import Quote

15.
Make the following change to the details() function, as shown in Listing 9.3, to get a list of Quote objects and pass it into the render_to_response() function:

def details(request, pID='0', opts=()):
    rDict = {}
    p = get_object_or_404(Person, pk=pID)
    rDict['p'] = p
    quotes = Quote.objects.all()
    rDict['quotes'] = quotes
    return render_to_response('people/person_details.html', rDict)

16.
Save the iFriends/People/views.py file.

17.
Open the iFriends/templates/quote.html file in an editor.

18.
Add the following with tag block on the outside of the <font> tags, as shown in Listing 9.4, to assign a random item from the quotes list to the variable quote using the random filter:

{% with quotes|random as quote %}
...
{% endwith %}

By the Way

No changes are needed to iFriends/templates/People/person_details.html because the quotes variable is passed to the quote.html template.

19.
Replace the quote and the byline text with variable references to the quote.text and quote.by fields of the Quote object, as shown in Listing 9.4:

{{ quote.text }}
. . .
{{quote.by }}

20.
Save the iFriends/templates/quote.html file.

21.
Access one of the Person details pages from the following address in a web browser, and click the Refresh button. Each time you refresh the browser, the quote should change, as shown in Figures 9.4 and 9.5.

Figure 9.4. The first quote of the day.


Figure 9.5. The next quote of the day.


http://127.0.0.1:8000/People/Info/1/

Listing 9.2. Full Contents of iFriends/Quotes/models.py

from django.db import models

class Quote(models.Model):
    text = models.TextField('text', max_length=200)
    by = models.CharField('by', max_length=50)

    def __str__(self):
        return '%s' % (self.text)

    class Admin:
       pass

Listing 9.3. Full Contents of iFriends/People/views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from iFriends.People.models import Person
from iFriends.Quotes.models import Quote

def index(request):
    pList = Person.objects.all()
    return render_to_response('people/person_index.html', {'pList': pList})

def details(request, pID='0', opts=()):
    rDict = {}
    p = get_object_or_404(Person, pk=pID)
    rDict['p'] = p
    quotes = Quote.objects.all()
    rDict['quotes'] = quotes
    return render_to_response('people/person_details.html', rDict)

Listing 9.4. Full Contents of iFriends/templates/quote.html

<table width="100%">
<tr bgcolor="aa22aa" width="100%"><td align="center">
<font size="4">Quote of the Day</font>
</td></tr>
<tr><td align="center">
{% with quotes|random as quote %}
<font size="5">{{ quote.text }}</font>
</td></tr>
<tr><td align="center">
<font size="2">- {{quote.by }}</font>
{% endwith %}
</td></tr>
</table>


Previous Page Next Page