30

Sep

Filed in Code, Django, Jinja |

One of the many issues which one must overcome with Jinja2 is using it with 3rd party modules. A lot of these already have built-in views, and many have yet to realize the benefit of class-based views. Today, I’m going to explain how we approached this for DjangoSpot (GitHub) and django-registration.

The goal, as always, is the write the least amount of code. However, extending function-based views is now an easy task. So our approach involves using some tricky Python code (thanks to Chris Leary for the ideas!).

Let’s talk about requirements real quick. You’ll need Django 1.1 (or newer), Jinja2, and Coffin 0.3.1 or newer (which as of writing, is not on PyPi).

First off, we’re going to use inspect.getsource to retrieve source code for functions, and exec to evaluate that source code. One thing to note here, is that if the function you are trying to modify is using a decorator, it may not be possible to get the actual functions source code. Some, however, can be obtained by using my_function.func_var_name.

So let’s take a look at our urls.py in djangospot.accounts.urls:

import inspect
 
from registration import urls
 
exec inspect.getsource(urls)\
    .replace('django.contrib.auth', 'coffin.contrib.auth')

As you can see above, we’re importing the urls from django registration, and then running getsource on it. This gets us the source code from that entire file. From there, we simply swap out django.contrib.auth for our drop-in coffin.contrib.auth.

Next up, we need to handle the views. It’s a similar approach, except we’re not doing any tricky string replacement:

import inspect
 
from registration.views import *
 
from coffin.shortcuts import render_to_response
from coffin.template import RequestContext
 
exec inspect.getsource(activate)
exec inspect.getsource(register)

What we’re doing here, is getting the source code for the actual methods, and simply executing it. To ensure we have all the needed imports, we first import everything from the registration.views. Afterwards, we replace the render_to_response and RequestContext imports with the ones made available in Coffin.

Overall, it’s a fairly sketchy process, but it works beautiful. We approach the problem in a similar fashion with Coffin and the generic and contrib views in there.

5 Responses to "Jinja2 and django-registration"

Subscribe to this topic with RSS or get the Trackback URL
Jacob (Oct 1st):

You might also look at how django-smorgasbord does this. I use it to use mako, currently, with 3rd party applications, but it should work with other template languages as well, including jinja2. It involves a very minor monkeypatch to django’s template loader, with the result that you can use several template systems at once.

teepark (Oct 5th):

seems pretty roundabout. if you know that the registration views are using render_to_response and RequestContext from their own global namespace, why not just monkeypatch?

registration.views.render_to_response = coffin.shortcuts.render_to_response
registration.views.RequestContext = coffin.template.RequestContext

David (Oct 5th):

@teepark

That is definitely a way you could handle it. However you then lose the ability to interact with the original code as it was. In our project this isn’t such a big deal, but the generic accessors in Coffin this definitely isn’t a possibility.

Jorge Vargas (Oct 5th):

This is both awesome and scary at the same time. controllers as classes for the win :)

Leave A Reply

 Username (*required)

 Email Address (*private)

 Website (*optional)

Note: Comments moderation may be active so there is no need to resubmit your comment.