On Oct 4, 1:04 pm, Andrew Godwin <and...@aeracode.org> wrote:
> On 04/10/10 17:28, legutierr wrote:
>
> >    * First, treat data processing and retrieval as separable from
> > rendering.  Create a bright line of separation between the two
> > conceptual elements of the view (data and rendering), and do it early
> > on, at a high level, inside dispatch().  Instead of expecting the
> > ListView.GET to return an HTTPResponse, for example, have it return a
> > context or a context dictionary that could be reused with several
> > render_result() implementations.
>
> This is problematic if I want to return something that isn't a context,
> or like it (for example, if I'm rendering images, or fetching content
> wholesale out of a database).

What I am suggesting is not that overriding render_result would be
sufficient for 100% of cases, but that it would be sufficient for 99%
of cases where a standard data dictionary could be used to generate
the response, whatever it may be.  And while it is *conceivable* that
one would want to use ListView, DetailView, etc. functionality in
combination with image rendering, or other kind of unexpected content,
it is not likely.

However, it *is* likely that one would want to use ListView,
DetailView, etc. to produce JSON, XML, PDF or other text-like content,
which is the common user expectation that *needs* to be addressed.
Overriding dispatch() to implement less standard functionality, or
overriding get() at the same time as render_result(), would still be
feasible for other cases where a simple data dictionary is
insufficient for rendering.  But if it is just a question of how text
is being output, then custom implementation of
render_result(data_dictionary) would be sufficient in 99% of cases.

> So, bfirsh's previous iteration had content formats built into the base
> class - I ripped it out and replaced it with a simpler base class, and
> he seemed to agree, so that's where we currently are.

Your simpler base class seems like a big improvement.  What I'm
addressing is the fact that instead of subclassing directly from the
simple base class (which makes no assertion about what type of data is
being returned, a very good thing), ListView, DetailView et al.
subclass TemplateView.  I would assert that the actual rendering logic
should be implemented as a mixin, and combined with ListView,
DetailView, etc. in order to produce the user-oriented generic view
classes.  That way, alternative rendering implementations would be
much more trivial to add, and without creating a misleading class
hierarchy (i.e., by having the JSONView also be a TemplateView).

> My main concern is getting rid of the simplicity - e.g. of calling
> render() on a template/context mix. In this aforementioned previous
> iteration, if I wanted to supply custom context to a custom template, I
> had to override both self.get_template_name() and self.get_context() -
> even though it would have been a lot easier to override GET and just
> call self.render(). It's a similar problem to passing everything around
> as keyword arguments - reusability doesn't turn out to be much better
> than starting from scratch.

In the particular approach that I am describing, you could still
override GET to modify what data is to be put into the context.  And
since the TemplateView render_template() implementation would use
self.request to build a RequestContext, you would still be able to use
context processors.  The difference is that if you wanted to modify
*both* what data is being added to the context and do custom stuff
with the output data, you would have to override both GET() and
render_result()/render_template().  Or you could just override
dispatch()/as_view() in any case.

> I just don't want us to build in all these abstraction layers and have
> the ability to customise everything perfectly but in a verbose fashion.
> That said, if render_result() in your example just calls a normal
> render() method itself, it's easy to not use it if you don't have to, so
> a reasonable approach to get both of these angles in is possible.

render_result(data_dictionary) would call render_template(template,
context) in the case of the TemplateViewMixin, just as
render_to_response() does in the current implementation.  However, in
the case of a JSONViewMixin, render_result() would process the data
dictionary to produce json output instead.  I actually think that this
makes things much less verbose overall.

The trickier question is whether one might want to implement a
MultiViewMixin, capable of outputing *both* html documents and json,
for example by registering MyView.as_view and MyView.as_ajax_view in
urls.py.  If you look through the use cases I list below, in each of
these use cases a user would benefit from being able to register two
different views with two different urls using the same view class
implementation.  The current implementation makes this impossible
without overriding mostly everything.

> Also, what use cases do people have for returning arbitary pages as JSON
> or XML?
> I'm not saying there aren't any - far from it - but I much prefer
> evidence to speculation, so some concrete examples would be great

Some use cases:
 * A search result implementation *similar* to Google Instant (say, in
an online store), where the search results are either displayed as a
template rendering, or are returned as JSON for dynamic display
through ajax.  The data-processing component here is the same in both
cases; the sole difference is rendering.
 * A commenting system that defaults to ajax for submissions, but that
permits users to enter comments via a standard html form if javascript
is turned off on the browser.  The same form processing logic could be
reused, but the way that the data is used to create the response is
different.
 * A billing system that allows a user to view an invoice as HTML on
the website, but provides a link to output a PDF of the invoice for
hard-copy record-keeping, and re-uses the same get() logic in both
cases, but uses a different rendering engine in each.
 * An atom or rss feed that uses the same data in its rendering as the
list of articles that are rendered on the site in html.  Urls that are
analogous between the blog's html and feed implementations would
actually point to the same class.

> (There's also the issue of whether you apply context processors to the
> JSON replies, and so forth, but that's going even further down the
> rabbit hole)

There's no reason that the self.request object cannot be used inside
render_result() to create a RequestContext there.  In fact, it should.

Regards,
Eduardo

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to