Malcolm, thank you for the elaborate response, much appreciated!


On Jan 21, 10:51 am, Malcolm Tredinnick <[email protected]>
wrote:
> On Wed, 2009-01-21 at 01:32 -0800, Guyon Morée wrote:
> > Hi,
>
> > I've built a bunch of 'normal' views rendering templates and
> > processing POST's.
>
> > Now, I'd like to build a API for my site, based on JSON. When building
> > this API I noticed most of the views are 99% the same,
>
> Excellent. :-)
>
> That's the ideal situation.
>
> >  except for
> > outputting JSON instead of HTML templates.
>
> > Any ideas how I could reduce duplication of code in these cases?
>
> A rough "general" pattern here is that most of your view is constructing
> a dictionary of values -- and it could be some other data structure, but
> we'll assume a dictionary here -- that will be used to generate the
> output. For templates, this dictionary is usually just passed to a
> Context class to create the template context. But there might be some
> other transformation you have to do to it first.
>
> In any case, that's where the split happens. One function is responsible
> for collecting the output data and putting it into a neutral data
> structure -- again, let's say, a dictionary. That output data will be
> the same, no matter what the format of the response.
>
> Then you decide, based on the request, whether to process that data into
> a json response, or an Atom response, or an HTML templated response.
> Each of those "convert the dictionary into an output response" could be
> another function. Those functions might have to do some further munging
> of the dictionary for their own circumstances -- for example, the
> template version might drop in some extra variables for "the current
> page" or something related to tab ids -- but, by and large, they'll all
> be handing off the data to a different renderer. Either
> simplejson.dumps, or render_to_string (or render_to_response) or
> whatever.
>
> In pseudo-code:
>
>         def my_view(request, ....):
>             result_data = gather_the_data(...)
>
>             if response_type == "html":
>                 return render_to_html(request, result_data)
>             if response_type == "json":
>                 return HttpResponse(render_to_json(request,
>         result_data))
>
>         def render_to_html(request, result_data):
>             template_name =
>         get_template_name(result_data["target_name"])
>             return render_to_response(template_name, result_data)
>
>         def render_to_json(request, result_data):
>             return simplejson.dumps(result_data)
>
> This is very simplistic, but it hopefully gets the idea across.
> "result_data" is the neutral form, gather_the_data() does all the heavy
> lifting and the various presentation functions do the final bit.
>
> Depending on how your code works out, it's probably going to be easy to
> make this all more regular, too. A function to work out the response
> type, which is then used as a key to look up a dictionary of
> presentation functions to call (render_to_html, render_to_json, etc).
>
> Daniel Lindsley has a blog post about a version of this that uses
> templates for all the output formats -- see [1]. I tend to go for the
> "presentation functions" approach, since templates don't feel like the
> right solution for json or Atom. But the principle is the same and
> Daniel's post (and a follow-up one James Bennett did at [2]) should give
> you some more ideas.
>
> [1]http://toastdriven.com/fresh/multiresponse/
> [2]http://www.b-list.org/weblog/2008/nov/29/multiresponse/
>
> Regards,
> Malcolm
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to