in django, python, software

Django: How to find the url/path you’re into, in a template loaded by a generic view

In a Django project, I have a template that is used by two urls, which is quite common (generic views, using ‘create_object’ and ‘update_object’). The problem is that I had to add a supplementary menu just when the template is loaded from the ‘update’ generic view, and not from the ‘create’ generic view.

Making the difference between the two urls calls at the template level is a problem because it’s managed by generic views, so the same template is used.

Anyways, there are several possibilities:

In urls.py, use the ‘template_name’ variable, where you can speficy a specific template for this url(). That is instead of using the default <model>_form.html.
What I don’t like in this situation, is that I will have two nearly similar templates, just for an added menu. Not cool. Another problem is that I use a loop to create all my urls. So if I add a special template, I’ll add it to ALL my models :-(.

Another solution, is to find a way to use a variable in the template that would be different wether the template has been loaded by update_object or create_object.

In our urlpatterns in urls.py, we can use the ‘extra_context‘ variable (takes a dictionnary as parameter). It is correctly managed, even when using generic views. So, you’ll have :

url(r'foo/ajouter/$', 'django.views.generic.create_update.create_object',  
		dict(form_class=modelForm,
                extra_context={'usage':'create'},
                name='foo_create',))

url(r'foo/%s/(?P\d+)/modifier/$',
                'django.views.generic.create_update.update_object',
		dict(form_class=modelForm,
                extra_context={'usage':'modify'},
                name='foo_update'))

We can also use, in urls.py, the ‘context_processors’ variable. For more information about the context processors, have a look at this tutorial. The goal is to add ‘django.core.context_processors.request’, like this:

from django.core.context_processors import request

and in the url(), add context_processors:

url(r'foo/ajouter/$', 'django.views.generic.create_update.create_object',  
		dict(form_class=modelForm,
		context_processors=[request,]),
                name='foo_create',))

The last possiblity is a more global solution. It’s like the context_processors usage above, but added into every templates automatically.
To do this, you’ll have to edit the list of Template Processors in your settings.py file. That list is run each time a template is loaded, and allows one to add any variable to the template automatically. By default (on Django 1.0.x) this list is commented out, so it has by default the list:

("django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media")

You’ll have to uncomment it, and add ‘django.core.context_processors.request’. By doing this, you get the variable ‘request.path’ available in your template.

Finally, you’ll be able to test your variable with {% ifequal %} and display your conditional elements.