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.