4

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
claymation
  • 2,475
  • 4
  • 27
  • 36

3 Answers3

3

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.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • How would I select which view to use? Currently, all three client types (desktop, mobile, iphone app) access the view via the same URL. The view then uses the HTTP_HOST header to determine how to render the response. If I had separate views for each response type, I'm not sure how I'd determine to which view to route a particular request. – claymation Feb 07 '10 at 19:30
  • Create a view which looks at the various headers (User-agent, etc.) and routes to one of the other views as appropriate. – Ignacio Vazquez-Abrams Feb 08 '10 at 03:39
1

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.

Tomasz Zieliński
  • 16,136
  • 7
  • 59
  • 83
  • A 'view' in Django is different than the usual MVC usage of the term. A Django view more closely corresponds to a controller in the usual terms, and templates to views. – JAL Mar 29 '10 at 01:01
0

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
airtonix
  • 4,772
  • 2
  • 38
  • 36