Django For Mobile Devices

We are living what some people call the “mobile explosion”, a time where an increasing number of portable devices — like tablets and smartphones — are becoming a significant part of the Web. This is the reason why having your website tailored for these devices is becoming increasingly important.

Fortunately, Django is one of the few web frameworks that makes this an easy problem to solve.

How we solved it

A simple way is to create a separate settings module for the mobile version. Doing this, we’re able to run two different webapps while reusing the existing codebase. Also, each version can have its own template directory, URL root configuration, etc.

Let’s do this. In the project root directory, create a file m_settings.py with the following content:

# File: myproject/m_settings.py
 
"""Django settings for the mobile-specific website.
"""
 
# Load the default settings
from settings import *
 
# Domain "m.mydomain.com"
SITE_ID = 2
PREPEND_WWW = False
 
# Used elsewhere to determine which version is running
DEFAULT_VERSION = False
MOBILE_VERSION  = True
 
# URLs for the mobile version
ROOT_URLCONF  = 'myproject.m_urls'
 
# Templates for the mobile version
TEMPLATE_DIRS = (
    os.path.normpath(os.path.dirname(__file__) + '/template/mobile'),
)
 
# Other settings...

These two webapps share the same codebase, but that doesn’t mean they have to use the same URL root configuration. In fact, websites suitable for mobile devices are usually simpler, with fewer URL mappings.

To define separate URL root configuration for the mobile version, create a file m_urls.py with the following content:

# File: myproject/m_urls.py
 
"""Mobile-specific URL definition.
"""
 
from django.conf import settings
from django.conf.urls.defaults import *
# from django.contrib import admin
 
# admin.autodiscover()
 
# Error page handlers
handler404 = 'website.views.error_404_handler'
handler500 = 'website.views.error_500_handler'
 
# Root URL patterns
urlpatterns = patterns('',
    # I18N
    (r'^i18n/', include('django.conf.urls.i18n')),
 
    # Internal apps
    (r'^contact/', include('contact.urls')),
 
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    # (r'^admin/', include(admin.site.urls)),
 
    # Other settings...
)

Note that, in this particular example, the Admin app isn’t accessible from mobile version. This just shows that we can structure each webapp differently without too much trouble.

Developing

You already know how to run the development server for the default version. Most people don’t know, however, that it’s possible to choose a different port number and settings module, which allows us to launch one development server for each webapp version:

# Terminal window 1: default version
$ python manage.py runserver 8000
 
# Terminal window 2: mobile version
$ python manage.py runserver --settings=m_settings 8001

Just develop your stuff and see the results in both versions right away. Easy peasy.

Testing

You probably noticed that we have two settings that can be used to identify what webapp version is being run, DEFAULT_VERSION and MOBILE_VERSION.

So it’s just a matter of checking those settings when you need to do different things in each webapp version. This is particularly useful when you use an app in both versions and want to create separate tests for each version:

# File: myproject/myapp/tests/__init__.py
 
"""Unit tests module for MyApp.
"""
 
from django.conf import settings
 
if getattr(settings, 'DEFAULT_VERSION', False):
    # Tests the default version
    from default_models_tests import *
    from default_navigation_tests import *
 
if getattr(settings, 'MOBILE_VERSION', False):
    # Tests the mobile version
    from mobile_models_tests import *
    from mobile_navigation_tests import *

We can run the tests for each version in a similar way we did before with the runserver command:

# Default version
$ python manage.py test [appname...]
 
# Mobile version
$ python manage.py test --settings=m_settings [appname...]

Deploying

Despite what you may think, this is the easy part.

Since deploying Django with Apache and mod_wsgi is the recommended way to get Django into production, it’s likely that you already have a WSGI file like this:

import os, sys
 
APPS_PATH   = '/home/user/wsgi_apps'
MYPROJECT_PATH = '%s/myproject' % APPS_PATH
 
# Third-party eggs
import site
site.addsitedir('/home/user/.python/lib')
 
sys.path += [APPS_PATH, MYPROJECT_PATH]
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
 
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

All we need to do is configure another WSGI-enabled subdomain on our server, e.g. m.mywebsite.com, that refers to another WSGI file like this one:

import os, sys
 
APPS_PATH   = '/home/user/wsgi_apps'
MYPROJECT_PATH = '%s/myproject' % APPS_PATH
 
# Third-party eggs
import site
site.addsitedir('/home/user/.python/lib')
 
sys.path += [APPS_PATH, MYPROJECT_PATH]
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.m_settings' # This line
 
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

The only difference between these two WSGI files is that each one points to a different settings module. And no, you don’t need to have a separate copy for each version. We are using the same codebase for both versions, remember? :-)

Minimizing the traffic

Amazingly, not everyone has access ultra-fast internet connections on their devices, so it’s very important to keep your sites as lightweight as possible.

There are several open source projects that try to address this problem. One of them is django-compress, a Django app that provides an automated system for compressing CSS and JavaScript files.

In fact, doesn’t matter if your websites target mobile devices or not; you should always try to minimize the amount of traffic.

What’s left?

There’s one small problem though: when someone visit the regular website from a mobile device, or vice-versa, they are not redirected to the appropriate version. But this is a topic for another article!

Sobre Daniel Martins

Fundador da Destaquenet, ele é graduado em Sistemas de Informação pela Faculdade Gennari & Peartree e desenvolve softwares como hobby e profissão desde 2000. Especializado na plataforma Java, ele utiliza a tecnologia há vários anos, sendo programador e desenvolvedor web certificado pela Sun Microsystems. Também se interessa por assuntos ligados à cultura open source, metodologias ágeis, engenharia de software, frameworks e linguagens dinâmicas tais como Python, Ruby e Smalltalk.
Esta entrada foi publicada em English, Programming, Tutorials e marcada com a tag , , , , , , , , , , , . Adicione o link permanente aos seus favoritos.

Uma resposta a Django For Mobile Devices

  1. Pingback: Tweets that mention Django For Mobile Devices | Destaqueblog -- Topsy.com

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">