Mobile Template Mixin for Django Class Based Views

I am currently working on a web app and the application would have mobile and desktop versions respectively. At first, I considered the all so beautiful responsive approach but I figured what I wanted the mobile user to see should be straight to the point as opposed to giving the desktop users some more content and then hiding or realigning the view. I just thought instead of making CSS 3 Queries to determine what platform is making the HTTP request, and then respond appropriately, I decided to create one application that would display different but all so familiar views depending on where the user is making the request.

Now I know many school of thought have argued about whether building one application and using queries is the best or whether building different application for each platform is the best. I don’t think any side wins this argument. It often depends on what type of application you are building. But I choose to build one application but different display endpoint (in this case templates to render the HTML). However, that’s not the gist of this article. I think I’m beginning to bore myself with all this story.

I wanted to write a mixin that would spew the right template depending on where the request is coming from. I google’d different tutorials and articles but nobody was giving me exactly what I needed. So I went to look at the Django source code itself. The Django documentation also helped. To cut the long story short, here is my mixin below.

appname/mixin.py

class MobileTemplateMixin(object):
"""
Use this mixin if you have a different templates for your mobile and desktop applications.
"""
template_source = None
template_name = None

def get_template_names(self, *args, **kwargs):
if self.request.is_mobile:
self.template_source = "mobile/"
else:
self.template_source = "desktop/"
self.template_name = self.template_source + self.template_name
return [self.template_name]

But pls note that you will need a middleware to enable the is_mobile feature on the request. You could check this rather succinct middleware I stumbled on http://sullerton.com/2011/03/django-mobile-browser-detection-middleware/ You will need to add this middleware to the MIDDLEWARE_CLASSES in settings.py. It would look something like this

settings.py

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
#add middleware to support mobile detection
'myapp.middleware.RequestDetectionMiddleware',
)

Its important that this middleware comes after the django.contrib.sessions.middleware.SessionMiddleware.

However, I stumbled upon a road block and hopefully someone out there could help clean up this piece of code or give me a better way of implementing this. You will have to created a template directory like so;

templates
desktop
appname
index.html
mobile
appname
index.html

I don’t like that structure because it looks very redundant. So what I would want to do is determine what app a template is been requested for and parse that into the mixin. However, this is what I have so far and it work.

so to use this, just add the mixin to your class view

appname/views.py

class MyView(MobileTemplateMixin, TemplateView):

template_name='appname/index.html'

This would resolve to the template name; desktop/appname/index.html for desktop request and mobile/appname/index.html for mobile device request.

I hope someone finds this useful. I’m sorry if the code is not properly indented. I’m not sure how to go about it but I’m sure it would be easy to figure out.

Advertisements