Previous Page Next Page

Hour 6. Configuring Web Page Views

What You'll Learn in This Hour

  • How to pass extra options to a view function

  • How to implement view prefixes

  • How to create URLconf files for each application

  • How to use a callable object instead of a string in an URL pattern

In Hour 4, "Creating the Initial Views," you learned how to set up the initial views in the URLconf file. In this hour, we will expand on that topic to include more advanced configuration options for views. When designing your website, the more complete your URLconf file configuration for web page views is, the easier it is to keep your code in the view cohesive and clean.

The following sections describe some advanced configuration options that you can make in the URLconf and views.py files.

Passing Extra Options to a View

The syntax for URL patterns in the URLconf file allows you to add additional options that will be passed as additional arguments to the view function. This is different from capturing arguments inside the URL, which we have already discussed.

Django allows you to specify a Python dictionary containing arguments that will be passed to the view function by the URL dispatcher. For example, the following URL pattern passes a simple dictionary:

(r'^People/BlogArchive/$', 'iFriends.Blogs.views.index', {'label':'Archive'}),


					  

When this URL pattern is accessed, the URL dispatcher calls the index() view function:

index(request, label='Archive')

By the Way

Just as with arguments captured from the URL, you need to add the arguments to the view function definition in the views.py file.


You can also capture arguments from the URL along with passing extra options in a dictionary. For example, the following URL pattern captures the year argument and passes a simple dictionary containing a label argument:

(r'^People/BlogArchive/(?P<year>\d{4})/$', 'iFriends.Blogs.views.index',
{'label':'Archive'}),

When this URL pattern is accessed, the URL dispatcher calls the index() view function:

index(request, year='2008, label='Archive')

Watch Out!

It is possible to specify the same argument name in both the captured arguments and the extra options dictionary. If this occurs, the value in the extra options dictionary is used instead of the value that was captured from the URL.


The ability to pass options to view functions provides much more control over the views from the URLconf file. This gives you much more flexibility in the URL patterns that your website will handle. The captured arguments and the extra options dictionary also make the website easier to design and manage, because much of the control is contained in the URLconf file.

Try It Yourself: Pass Extra Options to the View Function from the URLconf File

The best way to help you understand how useful the extra options dictionary can be is to apply it to the iFriends website that we have been working with. Currently, we have two views—an index() view that displays a list of Person objects, and a details() view that displays details of a specific Person object.

In this section, you will add functionality to the details() view that will make it possible to use the URLconf file to determine what details will be displayed. Follow these steps to modify the views.py and urls.py files of the iFriends project:

1.
Open the iFriends/urls.py file in an editor.

2.
Add the following dictionary definitions to the urls.py file, as shown in Listing 6.1, to define what items of the Person object to display in the details view:

details1 = {'opts':('name','email')}
details2 = {'opts':('name','birthday')}
details3 = {'opts':('name','desc','favoriteURL')}

3.
Add the following URL patterns to the urls.py file, shown in Listing 6.1. The Contact, Birthday, and Details URL patterns pass the details1, details2, and details3 extra options dictionaries to the details() view function, respectively:

(r'^People/Contact/(?P<pID>\d+)/$', 'iFriends.People.views.details', details1),
(r'^People/Birthday/(?P<pID>\d+)/$', 'iFriends.People.views.details', details2),
(r'^People/Details/(?P<pID>\d+)/$', 'iFriends.People.views.details', details3),


					  

4.
Save the iFriends/urls.py file.

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

6.
Add the following change to the definition of the details() view function, shown in Listing 6.2, to allow the opts argument to be passed in:

def details(request, pID='0', opts=()):

7.
Replace the code that currently writes all the Person object details to the response object with the following code, shown in Listing 6.2. This code iterates through the opts list and writes the details specified by the URLconf file to the HTTP response:

for d in opts:
    response.write("<li>%s: %s</li>" % (d, p.__dict__[d]))

By the Way

The sample code here uses the __dict__ member of the Person class to find the field names specified in the opts list. The __dict__ is built into all Python objects.

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

9.
Access the People/Contact/1 URL to verify the Contact version of the details() view, as shown in Figure 6.1.

Figure 6.1. The Contact version of the details() view in a web browser.


10.
Access the People/Birthday/1 URL to verify the Birthday version of the details() view, as shown in Figure 6.2.



Figure 6.2. The Birthday version of the details() view in a web browser.


11.
Access the People/Details/1 URL to verify the Details version of the details() view, as shown in Figure 6.3.



Figure 6.3. The Details version of the details() view in a web browser.


Listing 6.1. Full Contents of the iFriends\urls.py File

from django.conf.urls.defaults import *
details1 = {'opts':('name','email')}
details2 = {'opts':('name','birthday')}
details3 = {'opts':('name','desc','favoriteURL')}

urlpatterns = patterns('',
    (r'^People/$', 'iFriends.People.views.index'),
    (r'^People/Info/$', 'iFriends.People.views.details'),
    (r'^People/Info/(?P<pID>\d+)/$', 'iFriends.People.views.details'),
    (r'^People/Contact/(?P<pID>\d+)/$', 'iFriends.People.views.details',
    details1),
    (r'^People/Birthday/(?P<pID>\d+)/$', 'iFriends.People.views.details',
    details2),
    (r'^People/Details/(?P<pID>\d+)/$', 'iFriends.People.views.details',
    details3),

    # Uncomment this for admin:
    (r'^admin/', include('django.contrib.admin.urls')),
)

Listing 6.2. Full Contents of the iFriends\People\views.py File

from django.http import HttpResponse
from iFriends.People.models import Person

def index(request):
    response = HttpResponse()

    response.write("<h1>People</h1><hr>")
    pList = Person.objects.all()    for p in pList:
        link = "<a href=\"Info/%d\">" % (p.id)
        response.write("<li>%s%s</a></li>" % (link, p.name))

    return response

def details(request, pID='0', opts=()):
    response = HttpResponse()

    response.write("<html><body>\n")
    try:
        p = Person.objects.get(id=pID)
        response.write("<h1>Details for Person %s</h1><hr>\n" % p.name)
        for d in opts:
            response.write("<li>%s: %s</li>" % (d, p.__dict__[d]))
    except Person.DoesNotExist:
        response.write("Person Not Found")
    response.write("</body></html>")

    return response


Previous Page Next Page