views:

147

answers:

2

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?

+3  A: 

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
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.
Clay McClure
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
A: 

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 Zielinski
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.
Alex JL