Question

Our site can be accessed from a full browser, from mobile browsers, and from a custom iPhone app. Since the logic is mostly the same regardless of the client, we're using the same views to process all types of requests. But at the bottom of every one of our views, we have something like:

if request.is_mobile():
    return render_to_response('foo/bar/baz_mobile.html', context)
elif request.is_api():
    return json.dumps(context)
else:
    return render_to_response('foo/bar/baz.html', context)

Clearly there's a better way to do it :)

I've thought of just having our views return the context dictionary, and wrapping them in a decorator that determines how to render the response. Alternatively, maybe there's something I can do with class-based views.

How would you do it?

Was it helpful?

Solution

Have a function that returns a dict, and then have two views, one of which encodes it as JSON and the other that shoves it through a template.

OTHER TIPS

Ignacio Vazquez-Abrams is right.

As you've said, logic is mostly the same - but logic is not view. According to the original MVC paper: "a view is a (visual) representation of its model". So you should have separate views for different purposes, sharing same logic.

As described here :

http://docs.djangoproject.com/en/dev/ref/request-response/#attributes

So including the request argument from your view into the context of your template :

@auto_render
def base_index(request, template_name="desktop-home.html") :
  user_agent = request.META["HTTP_USER_AGENT"]
  if "mobile" in user_agent :
    template_name = "mobile-home.html"

  return template_name, {
    "Navigation" : NavigationManager.db,
    "Headers"    : request
  }

Provides thus in your template :

{{ Headers.META.HTTP_USER_AGENT }}

Which reports :

Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Ubuntu/10.04 Chromium/8.0.552.237 Chrome/8.0.552.237 Safari/534.10
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top