Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django template inheritance and context

I am reading the definitive guide to django and am in Chapter 4 on template inheritance. It seems that I am not doing something as elegant as should be possible as I am having to duplicate some code for the context to appear when calling the child view. Here is the code in views.py:

def homepage(request):
    current_date = datetime.datetime.now()
    current_section = 'Temporary Home Page'
    return render_to_response("base.html", locals())
def contact(request):
    current_date = datetime.datetime.now()
    current_section = 'Contact page'
    return render_to_response("contact.html", locals())

It seems redundant to have to include the current_date line in each function.

Here is the base html file that homepage calls:

<html lang= "en">
<head>
    <title>{% block title %}Home Page{% endblock %}</title>
</head>
<body>
    <h1>The Site</h1>
    {% block content %}
        <p> The Current section is {{ current_section }}.</p>
    {% endblock %}

    {% block footer %}
    <p>The current time is {{ current_date }}</p>
    {% endblock %}
</body>
</html>

and a child template file:

{% extends "base.html" %}

{% block title %}Contact{% endblock %}

{% block content %}
<p>Contact information goes here...</p>
    <p>You are in the section {{ current_section }}</p>
{% endblock %}

If I don't include the current_date line when calling the child file, where that variable should appear is blank.

like image 320
Steve Avatar asked Sep 15 '10 21:09

Steve


People also ask

How do I inherit a template in Django?

All that is needed is to add a {% extend %} tag: The home page. The {% extends “base. html” %} inherits everything from the base template.

What is context in Django template?

context_processors is a list of dotted Python paths to callables that are used to populate the context when a template is rendered with a request. These callables take a request object as their argument and return a dict of items to be merged into the context. It defaults to an empty list.

What does {% %} mean in Django?

{% %} and {{ }} are part of Django templating language. They are used to pass the variables from views to template. {% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.

What is template inheritance?

Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override. Sounds complicated but is very basic. It's easiest to understand it by starting with an example.


1 Answers

You can pass a variable to every template by using a Context Processor:

1. Adding the context processor to your settings file

First, you will need to add your custom Context Processor to your settings.py:

# settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    'myapp.context_processors.default', # add this line
    'django.core.context_processors.auth', 
)

From that you can derive that you will need to create a module called context_processors.py and place it inside your app's folder. You can further see that it will need to declare a function called default (as that's what we included in settings.py), but this is arbitrary. You can choose whichever function name you prefer.

2. Creating the Context Processor

# context_processors.py

from datetime import datetime
from django.conf import settings  # this is a good example of extra
                                  # context you might need across templates
def default(request):
    # you can declare any variable that you would like and pass 
    # them as a dictionary to be added to each template's context:
    return dict(
        example = "This is an example string.",
        current_date = datetime.now(),                
        MEDIA_URL = settings.MEDIA_URL, # just for the sake of example
    )

3. Adding the extra context to your views

The final step is to process the additional context using RequestContext() and pass it to the template as a variable. Below is a very simplistic example of the kind of modification to the views.py file that would be required:

# old views.py
def homepage(request):
    current_date = datetime.datetime.now()
    current_section = 'Temporary Home Page'
    return render_to_response("base.html", locals())

def contact(request):
    current_date = datetime.datetime.now()
    current_section = 'Contact page'
    return render_to_response("contact.html", locals())


# new views.py
from django.template import RequestContext

def homepage(request):
    current_section = 'Temporary Home Page'
    return render_to_response("base.html", locals(),
                              context_instance=RequestContext(request))

def contact(request):
    current_section = 'Contact page'
    return render_to_response("contact.html", locals(),
                              context_instance=RequestContext(request))
like image 133
airstrike Avatar answered Oct 29 '22 23:10

airstrike