Code


Version 3 (modified by syntruth@…, 9 years ago) (diff)

--

Here's how to dodge some of the more obvious template pitfalls:

Debugging

Not a pitfall, but a tip:

Use {% debug %} in a template block if you want to know what is defined and can be used in a template.

The debug output is pretty ugly unless you look at it through View Source, or you can do it this way:

{% filter linebreaks %}
  {% debug %}
{% endfilter %}

Anonymity

user.is_anonymous is a method, not an attribute, which makes it hard to test against in a template. Set your own context variable is_anonymous, instead.

Context variables and template inheritance

To solve Anonymity above, it's handy to define a method each view can call to fill in its Context with the right variables. If you're inheriting templates, you should also do the same with the method. I've ended up with an app_vars method in each app's views module which calls site_vars in the site.

site_vars goes in sitename/views/sitename.py if you're trying to match the default shape of the application namespace, or in sitename/views.py if you're flattening it:

def site_vars(request, **kwargs): 
    """Determine context variables for the site's base template."""
    user = request.user
    is_anonymous = user.is_anonymous()
    if is_anonymous: 
        username = name = '(anonymous)'
    else: 
        username = user.username
        name = user.get_full_name()
        if not name: 
            name = username
    vars = {
        'is_anonymous': is_anonymous,
        'name': name,
        'username': username,
    }
    vars.update(kwargs)
    return vars

A custom version of app_vars goes in each sitename/apps/appname/views/appname.py (or, if you're flattening the namespace, sitename/apps/appname/views.py):

def app_vars(request, **kwargs): 
    """Determine context variables for the application and site base templates."""
    vars = {} # set your app variables here
    vars.update(site_vars(request, **kwargs))
    return vars

The keyword arguments let you define additional useful variables for your page without having to further manipulate the dictionary: just keep piling on the arguments to app_vars. Let's say your base template likes to have a title variable available to it:

def index(request): 
    """View the appname index."""

    # Customise the app variables the hard way
    vars = app_vars(request)
    vars['title'] = "Index" 

    # Or, the easy way
    vars = app_vars(request, title="Index")

    # Load the template, construct the context, and render one against the other: 
    t = template_loader.get_template('appname_index')
    c = Context(request, vars)
    return HttpResponse(t.render(c))