Change Django Templates Based on User-Agent

I've made a Django site, but I've drank the Koolaid and I want to make an IPhone version. After putting much thought into I've come up with two options:

  1. Make a whole other site, like i.xxxx.com. Tie it into the same database using Django's sites framework.
  2. Find some time of middleware that reads the user-agent, and changes the template directories dynamically.

I'd really prefer option #2, however; I have some reservations, mainly because the Django documentation discourages changing settings on the fly. I found a snippet that would do the what I'd like. My main issue is having it as seamless as possible, I'd like it to be automagic and transparent to the user.

Has anyone else come across the same issue? Would anyone care to share about how they've tackled making IPhone versions of Django sites?

Update

I went with a combination of middleware and tweaking the template call.

For the middleware, I used minidetector. I like it because it detects a plethora of mobile user-agents. All I have to do is check request.mobile in my views.

For the template call tweak:

 def check_mobile(request, template_name):
     if request.mobile:
         return 'mobile-%s'%template_name
     return template_name

I use this for any view that I know I have both versions.

TODO:

  • Figure out how to access request.mobile in an extended version of render_to_response so I don't have to use check_mobile('template_name.html')
  • Using the previous automagically fallback to the regular template if no mobile version exists.


Asked by: Vanessa180 | Posted: 01-10-2021






Answer 1

Rather than changing the template directories dynamically you could modify the request and add a value that lets your view know if the user is on an iphone or not. Then wrap render_to_response (or whatever you are using for creating HttpResponse objects) to grab the iphone version of the template instead of the standard html version if they are using an iphone.

Answered by: Emily557 | Posted: 02-11-2021



Answer 2

Detect the user agent in middleware, switch the url bindings, profit!

How? Django request objects have a .urlconf attribute, which can be set by middleware.

From django docs:

Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has an attribute called urlconf (set by middleware request processing), its value will be used in place of the ROOT_URLCONF setting.

  1. In yourproj/middlware.py, write a class that checks the http_user_agent string:

    import re
    MOBILE_AGENT_RE=re.compile(r".*(iphone|mobile|androidtouch)",re.IGNORECASE)
    class MobileMiddleware(object):
        def process_request(self,request):
            if MOBILE_AGENT_RE.match(request.META['HTTP_USER_AGENT']):
                request.urlconf="yourproj.mobile_urls"
    
  2. Don't forget to add this to MIDDLEWARE_CLASSES in settings.py:

    MIDDLEWARE_CLASSES= [...
        'yourproj.middleware.MobileMiddleware',
    ...]
    
  3. Create a mobile urlconf, yourproj/mobile_urls.py:

    urlpatterns=patterns('',('r'/?$', 'mobile.index'), ...)
    

Answered by: Agata278 | Posted: 02-11-2021



Answer 3

I'm developing djangobile, a django mobile extension: http://code.google.com/p/djangobile/

Answered by: Emily964 | Posted: 02-11-2021



Answer 4

You should take a look at the django-mobileadmin source code, which solved exactly this problem.

Answered by: Max867 | Posted: 02-11-2021



Answer 5

Other way would be creating your own template loader that loads templates specific to user agent. This is pretty generic technique and can be use to dynamically determine what template has to be loaded depending on other factors too, like requested language (good companion to existing Django i18n machinery).

Django Book has a section on this subject.

Answered by: Byron614 | Posted: 02-11-2021



Answer 6

There is a nice article which explains how to render the same data by different templates http://www.postneo.com/2006/07/26/acknowledging-the-mobile-web-with-django

You still need to automatically redirect the user to mobile site however and this can be done using several methods (your check_mobile trick will work too)

Answered by: Aida652 | Posted: 02-11-2021



Answer 7

How about redirecting user to i.xxx.com after parsing his UA in some middleware? I highly doubt that mobile users care how url look like, still they can access your site using main url.

Answered by: Ted263 | Posted: 02-11-2021



Answer 8

best possible scenario: use minidetector to add the extra info to the request, then use django's built in request context to pass it to your templates like so

from django.shortcuts import render_to_response
from django.template import RequestContext

def my_view_on_mobile_and_desktop(request)
    .....
    render_to_response('regular_template.html', 
                       {'my vars to template':vars}, 
                       context_instance=RequestContext(request))

then in your template you are able to introduce stuff like:

<html>
  <head>
  {% block head %}
    <title>blah</title>
  {% if request.mobile %}
    <link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
  {% else %}
    <link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
  {% endif %}
  </head>
  <body>
    <div id="navigation">
      {% include "_navigation.html" %}
    </div>
    {% if not request.mobile %}
    <div id="sidebar">
      <p> sidebar content not fit for mobile </p>
    </div>
    {% endif %>
    <div id="content">
      <article>
        {% if not request.mobile %}
        <aside>
          <p> aside content </p>
        </aside>
        {% endif %}
        <p> article content </p>
      </aricle>
    </div>
  </body>
</html>

Answered by: Marcus272 | Posted: 02-11-2021



Answer 9

A simple solution is to create a wrapper around django.shortcuts.render. I put mine in a utils library in the root of my application. The wrapper works by automatically rendering templates in either a "mobile" or "desktop" folder.

In utils.shortcuts:

from django.shortcuts import render
from user_agents import parse

def my_render(request, *args, **kwargs):
  """
  An extension of django.shortcuts.render.

  Appends 'mobile/' or 'desktop/' to a given template location
  to render the appropriate template for mobile or desktop

  depends on user_agents python library
  https://github.com/selwin/python-user-agents

  """
  template_location = args[0]
  args_list = list(args)

  ua_string = request.META['HTTP_USER_AGENT']
  user_agent = parse(ua_string)

  if user_agent.is_mobile:
      args_list[0] = 'mobile/' + template_location
      args = tuple(args_list)
      return render(request, *args, **kwargs)
  else:
      args_list[0] = 'desktop/' + template_location
      args = tuple(args_list)
      return render(request, *args, **kwargs)

In view:

from utils.shortcuts import my_render

def home(request):    return my_render(request, 'home.html')

Answered by: Walter775 | Posted: 02-11-2021



Similar questions

python - Parsing HTTP User-Agent string

What is the best method to parse a User-Agent string in Python to reliably detect Browser Browser version OS Or perhaps any helper library that does it


python - Problem making a GET request and spoof User-Agent in urllib2

With this code, urllib2 make a GET request: #!/usr/bin/python import urllib2 req = urllib2.Request('http://www.google.fr') req.add_header('User-Agent', '') response = urllib2.urlopen(req) With this one (which is almost the same), a POST request: #!/usr/bin/python import urllib2 headers = { 'User-Agent' : '' } req = urllib2.Request('http://www.google.fr', '', headers) respon...


python - Http header User-Agent

I am trying to get list of browsers from the User-Agent strings in HTTP header. In many of the strings, the browser info is the second entry in the string, like the following: (compatible;.MSIE.8.0;.Windows.NT.5.1;.Trident/4.0) But in some of the strings, there is either no browser info, or the info comes as the 3rd entry like in the followings: (Macintosh;.Intel.Mac.OS.X.1...


python - How to login to webpage with cookies and user-agent?

I am trying to log to certain server and download pictures from there programatically. I know login and I was able to get which variables are username and password. I was also able to download pictures which needed no password with this code. Web page keeps telling me my user agent is unsupported, so I assume I am setting user agent incorrectly. It needs cookies and user-agent. I know how to login to pages...


python - What's a good User-Agent parsing plugin for django

Is there a User-Agent-String parsing plugin or middleware that you can recommend. Right now I am using django-smartagent, but its dictionary is not complete and not updated very often.


mozilla - How to set User-Agent in Python MozEmbed?

I have build a simple dedicated browser (like Prism) which I use for different sites. Sadly Google+ blocks all browsers, but four. So it blocks mine too. How can I set the User-Agent in MozEmbed, so I can tell Goolge, I am using Firefox? mozembed = gtkmozembed.MozEmbed() mozembed.load_url("https://plus.google.com") mozembed.show()


python - Pass the user-agent through webdriver in Selenium

I am working on a website scraping project using Selenium in Python. When I open the homepage through a browser, it opens properly. But, when I try to open the webpage through webdriver() in Selenium, it opens a completely different page. I think, it is able to detect the user-agent( not sure what it is called) and is able to check the properties of the browser or something.


url - How do I add a user-agent to this Python opener?

This question already has answers here:


http headers - Python and a user-agent parser

I am looking for a user-agent parser in python that if passed a user agent such as the below, it will provide OS, browser type but most import the device type e.g. desktop/laptop versus tablet or mobile and if possible what kind..such as android, iPhone, nokia etc. Is there such a parser or python libary before I go off and build by own? user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv...


python - Mechanize random User-Agent

I'm trying to get Mechanize to use a random User-Agent every time I initiate opening a URL. Can someone point me in the right direction that I need to take in order to do this? - I've searched everywhere and couldn't find a reference. Thanks!






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top