Posts tagged Code

Mobile Site Redirection

In recent years a major component for any popular site is to add some sort of mobile experience. By adding a mobile aspect of your site either in full or in part, you open it up to even more people. In the last few years as mobile phones have become more powerful and less money. Having a mobile phone that is capable of viewing a full sized normal webpage isn’t as heard of now as it was just a few years ago.

With phones being capable of viewing sites in full and as mobile markup, it can sometimes be harder to present the user with the experience they are looking for. Simply using the user agent can help but it doesn’t give a full indication if the user has there browser setup as full or mobile. There is another way that can be used to some extent and works on any phone with a properly implemented browser.

HTTP_ACCEPT, is a header that is sent from the browser to the server when requesting resources. Contained in this header is a description of what the browser is capable of accepting or is willing to accept. Using this header it is possible to help determine if the user is on a mobile phone viewing in “mobile mode” or as a full browser. By checking for “application/vnd.wap.xhtml+xml” you can be assured that the user is viewing the site on a “mobile” browser.


from django.http import HttpResponseRedirect
from django.conf import settings

class MobileMiddleware(object):
  def process_request(self, request):
    try:
      if(request.META.get('HTTP_ACCEPT', '').find("application/vnd.wap.xhtml+xml") >= 0):
        return HttpResponseRedirect(settings.MOBILE_SITE)
    except:
      pass
    return None

Setting this up as a middleware in your settings file, as well as adding a new directive in your settings file such as:

Settings.py


MOBILE_SITE = "http://m.domain.com/"

This will allow you to simple redirect users on viewing the site as “mobile” to be redirected to the mobile site. A couple things to keep in mind though. If you are using the same code and just using different templates for the main site and the mobile site, you will want to add in logic to make sure you don’t hit a continous loop. Since not all browers are written to full standard, this isn’t 100%, but nothing is this will just help in giving users a more seamless user experience.

Django Json Woes

Recently I have been working on a new web project, written in Python using the Django web framework. I have been using Django off and on over the last year, traditionally I really never used much of a framework. A great deal of my time prior to Python/Django work was spent on applications development for server side processes written in C#.

I have a strange love/hate relationship with python, I love some of its capabilities, ease of use, and its concise nature. On the other hand I hate that there seems to be some things that I would love to see that just isn’t there. While writing a simple view in which I planned on returning a JSON string back to the user, I found there was no “response” or internal method that I could find to return it simply. In the process of going through the documentation I found some information relating to the HttpResponse that gets returned at the end of each View. I figured that would be a great place to start.


from django.http import HttpResponse
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200):
    HttpResponse.__init__(self, content = encode(data), mimetype = 'application/json', status = status)

First revision looked something like this. At first it worked out doing what I had wanted, one problem I had was while using a mime type of ‘application/json’ was more secure it made debugging a little more difficult when hitting the view directly in the browser. So I figured if I was running in debug why not use a mime type of ‘text/html’, its less secure but debug should never run on production.


from django.http import HttpResponse
from django.conf import settings
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200):
    mimetype = 'application/json'

    if(settings.DEBUG):
      mimetype = 'text/html'

    HttpResponse.__init__(self, content = encode(data), mimetype = mimetype, status = status)

This revision looked much more what I needed. The only problem I had was when hitting this view from Javascript on the client side, some browsers would cache the return value and an additional hit to the view wouldn’t occur. I could have solved this on the client side by adding some sort of random seed to the end of the URL. However I would much prefer my view decide when something needs to be cached rather than the JavaScript code so I made a few modifications.


from django.http import HttpResponse
from django.conf import settings
from cjson import encode

class JsonResponse(HttpResponse):
  def __init__(self, data, status = 200, cache = False):
    mimetype = 'application/json'

    if(settings.DEBUG):
      mimetype = 'text/html'

    HttpResponse.__init__(self, content = encode(data), mimetype = mimetype, status = status)

    if(cache == False):
      self['Last-Modified'] = 'Mon, 01 Jan 1970 05:00:00 GMT'
      self['Cache-Control'] = 'no-store, no-cache, must-revalidate'
      self['Pragma'] = 'no-cache'

Making this change allowed me to have the flexibility of deciding if I wanted something cached, which in most instances I don’t since the data for these returns are normally always changing. With this new object I was able to perform a “standard” JSON return in a view as well as maintain a single place I can make modifications to all requests at once.


from responses import JsonResponse

def json_view(request):
  x = { 'status': True, 'message': 'Success' }
  return JsonResponse(x)