base.html
is used as the base template for all other pages. base.html
has the navigation bar and in the navigation bar, I want to show the number of messages the user received. Thus, I need to have a variable like {{number_of_messages}}
in the base.html
.
However, how should I pass this variable to it? Every template extends base.html
and is rendered by a function. I don't think returning number_of_messages
in all functions is a good way. Is there better way to implement this? How can I pass this variable to all templates?
The extends tag is used to declare a parent template. It should be the very first tag used in a child template and a child template can only extend up to one parent template. To summarize, parent templates define blocks and child templates will override the contents of those blocks.
Django Template Language (DTL) is the primary way to generate output from a Django application. You can include DTL tags inside any HTML webpage. The basic DTL tag you can include in an HTML webpage is: 1. {% Tag %}
Variable names consist of any combination of alphanumeric characters and the underscore ( "_" ) but may not start with an underscore, and may not be a number.
From the documentation: {% extends variable %} uses the value of variable. If the variable evaluates to a string, Django will use that string as the name of the parent template. If the variable evaluates to a Template object, Django will use that object as the parent template.
Have a look at:
https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext
As long as:
render
shortcut in your view (or otherwise take care to use a RequestContext
to render your response)django.contrib.auth.context_processors.auth
in your TEMPLATE_CONTEXT_PROCESSORS
setting (as it is by default) ...then you have the current request's User
(or AnonymousUser
) instance available in your template as {{ user }}
...I am guessing from there you may be able to access the number of messages directly?
Or perhaps you are using Django's messages framework?
This comes with it's own context processor which (as long as you use render
or RequestContext
) will make a {{ messages }}
var (containing the messages for current user) available in your templates. For 'number of messages' you can do {{ messages|length }}
If none of these built-in options provide what you need you can either:
make your own template context processor which will run for every request and make additional variables available to all templates (when rendered with a RequestContext
)
make your own template tag which can be used only where needed... of course if this is used in your base.html
and all templates inherit from base.html
then it's still going to run for every page.
You can use tags.
#myproject/myproject/templatetags/tags.py from django import template register = template.Library() @register.simple_tag def number_of_messages(request): return _number
In your Base.html
{% load tags %} {% number_of_messages request %}
I find the simplest steps to passing variables to your base templates in django is to add a context_processor.py file like so:
In your app create context_processors.py and declare your variables e.g.:
# context_processors.py
def message_processor(request):
if request.user.is_authenticated:
no_msgs = request.user.profile.msgs
else:
no_msgs = 0
return {
'messages' : no_msgs
}
Then register your process or under TEMPLATES in your settings.py file:
TEMPLATES = [
{
...
'context_processors': [
...
# custom
'appname.context_processors.message_processor',
],
},
},
]
And then you will be able to get that variable anywhere in your app as:
{{ messages }}
If you want the variable in really all the views, then a custom template context processor is probably the best option.
https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext
If you want the variable only in some of the views, then you can make those views call a common function that populates the common variables, something like this:
def some_view(request):
params = _common_params(request)
params.update({
# params specific to .some_view
})
return render_to_response('path/to/template, params)
or create a custom decorator like this:
from functools import wraps
def render_with_params():
def _inner(view_method):
def _decorator(request, *args, **kwargs):
params = _common_params(request)
(template_path, view_params) = view_method(request, *args, **kwargs)
params.update(view_params)
return render_to_response(template_path, params, context_instance=RequestContext(request))
return wraps(view_method)(_decorator)
return _inner
@render_with_params()
def some_view(request):
params = { ... }
return ('path/to/template', params)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With