Who should format my data for display? - django

I have a django view, and this view returns a table which is populated asynchronously with an ajax call.
From the design point of view, which one should I follow:
the django view, called via ajax, returns the content of the table as a json response, containing html markups for each cell. The javascript callback handler takes the contents and slaps them untouched into the table cells.
the django view, called via ajax, returns pure data about what should go into the table, again as a json response. The async javascript callback takes the data, formats them with proper markup, and puts it into the table.
In other words, who should have the responsibility for markup formatting of the cell contents? the view or the javascript ?
I would be tempted to say the first, since the view already returns marked up content. If it returns a json containing marked-up content, there's not much difference.
I would like to hear your point of view.

If you're populating the whole table, you can put your table in its own template and return the table's html via ajax/json.
You'll need to edit the original template to include the table template:
{% include "myapp/_table.html" %}
And in the view, return the rendered template as a json variable, which your javascript will substitute in:
return { 'table': render_to_string("myapp/_table.html", context) }
This approach is good where you always want to update the entire table, and the rendering of the table doesn't require the full context. I'm not sure what the performance is like, but it is a clean way of updating part of the page, because you only define your table once.

It depends (as so often).
If the data is requested only here and now, it would be easier and less error prone to just let it render on server-side with the same set of templates that already rendered the standard view.
If you could think of use cases however, where the data would be needed in other places (like auto-complete fields), it would be better to let JavaScript do the job and create a clean, reusable JSON export.
These options add to all the other answers, and finally it's up to you to decide.

In a MVP system such as Django, the View decides what data should be shown, and the Presenter decides how it should be shown. Therefore the JavaScript should do the bulk of the formatting unless it proves intractably difficult to do so.

It is a good to practice Unabstrusive javascript, also called by some people as Hijax
So, you first have a standard page, that presents the table along with the rest of the page, with table in a particular django-template block.
Once you have this, you can include the extends part of the django template within an "if not ajax", so you only get the required table part in the ajax response which you can load in the client to the required div.
It is un-necessary and redundant to maintain the markup twice once at the server and once at the client, in javascript.
hence, I'd prefer the first option, of server redering, and client only loading the rendered html.

I've come across this several times before, and I generally opt for the latter, where the view returns pure JSON.
However, the approach you choose should definitely depend on several factors, one of which is targeted devices (and their CPU/network constraints). Pure JSON will generally result in smaller payloads and so may be optimal for mobile devices.
It may also make sense to expose both HTML and JSON versions of your content. This is especially helpful if you're looking to create a very lightweight API at some point for your site.
Finally, you can use a library such as John Resig's micro-templating or Closure Templates to simplify client-side HTML generation.

I would go with first choice, sine it presents more pros for user: page loads instantly (no wait for async call), no JS required (e.g. for mobile device)

Related

Django: Is there any performance differences when using ajax?

I'm working on refactoring project in the middle of the work. There are a lot of context when view return render. I want to change it to get response when dom rendered using ajax.
I know it makes more request, but I wondered if there are any performance differences. If not, I want to do that.
According to my understanding, using AJAX and context are completely different methods.
AJAX does things on the client-side, while the Django context works on the server.
According to this basic difference, and considering the size of your page is large and multiple time changes, the AJAX is faster because you will only be requesting the data and not the whole page
But
If we assume the size of your page is large but data don't change frequently, the Django-Context is better in the scope of security and usability, because you will not expose the data that is to be rendered as it will be if used AJAX.
So it depends on your use case, if it's a static page then it is better to use django-context than AJAX and if it's a dynamic page use AJAX.

django call to custom method in model when rendering the page

If I have a custom method in my Model that I am calling in my template, does it mean there are multiple roundtrips happening from client(browser) to server?
I am pretty sure when I return render() from my view, rendering happens on the server side and the output as HTML is returned to the client.
Please correct me if my understanding is off.
Django renders at server side
Rendering happens at server side. If you thus write {{ foo.bar }} in your template, the client never knew that there was a foo.bar in the template. Substituting tags, etc. by (HTML)output is done by the Django render engine.
The result of that rendering is given to the client through a HTTP response. So the response itself, does not contain the render logic, it contains the "product" of the rendering. If you thus perform a {{ SomeModel.objects.all() }} in the template (given you of course passed a reference to the model), then it will typically result in an extra database query, but this is not managed by the client. The client does not know what logic the template is calling.
This can make an application more safe as well, since the client has no access to the template itself, and thus can not change the template to obtain sensitive information. Of course by designing specific query input, it can still aim to let the template return sensitive data.
Furthermore the template can contain some logic, that you do not want to share with the clients. By rendering it at the server, the client actually does not see how the HTML was rendered (of course an experienced developer can do some "guesswork" and after a while can have some ideas about how the rendering took place).
But still the "product" of the rendering can result in additional calls
It is however possible that the result will result in extra calls. For example if your result contains <img src="">s, stylesheet links, etc. and other URLs, the browser typically will start fetching these as well. Furthermore if you define JavaScript that performs AJAX calls, these calls result in extra HTTP requests, but those are not done at rendering time of that specific template. These are "independent" calls later that again can result in rendering.
Some technologies render at client side
Note that it does not per se is always that way. Some technologies, like Angular, do (most of) the rendering at the client side. In that case, there is JavaScript code that makes calls to the API, and then "unfolds" the "HTML" as specified by the developer. So it is perfectly possible to make a call to a webservice asking for tweets, and then let some JavaScript "inject" HTML code in the DOM to render the tweets accordingly. The advantage of this is that it makes it easy to change content dynamically (for example update the value of a certain product frequently in the browser).
This however requires that the data that is rendered is available through an API (well an API that can be accesses through HTTP requests), and those calls might need some extra security (for calls asking for data, the credentials usually need to be checked a second time).

where do functions that don't display go in django

I have some links on an html page like , , currently I handle them as so
<p> rate down
and have a url.py entry:
(r'^cases/(?P<case_id>\d+)/case_rate/(?P<oper>.)$', 'mysite.cases.views.case_rate'),
then I have a view function that handles the logic and hits the DB, then does this:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
I's there a better way to do this? I can see how this would be OK because it does have to redraw the screen to show the new rating...
The typical way to handle this is with an ajax request.
Instead of a link, you put a javascript handler that calls a view, wich updates the db, and returns a json / xml object with the new rating for the item. Then another javascript handle receives that response and updates the rating number on the screen, without a page reload.
Ideally, you'll keep both versions: plain html (the one you currently have) and the ajax one. The ajax one can be attach to the element after page load, so if javascript is not available, you'll still have a working site.
Then, regarding organization, you can have an "ajax" parameter on your view. The view should update the db accordingly, and if it's an ajax call, return the json / xml response, otherwise, return the new page. That way you can keep the logic (fetching the object, updating the db) on one place.
If you're asking whether case_rate should still go in the views.py given that it returns a redirect rather than providing content, the answer is yes, since case_rate is handling an request and returning a response.
But consider a situation where you had two view functions in views.py that had some duplicate code, and you chose to factor that duplicate code into another function that didn't both take request and return a response. Would that be fair game to leave in views.py? Sure, if moving it elsewhere would make the code harder to read. Or you might choose to put it elsewhere. It's really your call based on your sense of taste.

How can I put a block of dynamically generated content into a django template?

I want to include things like twitter status, or delicious tags, in my django templates.
These things are dynamic, yet regular. How would this be done?
There are a number of ways to handle this, so you can choose a method that best matches your own personal style or requirements:
Template context variable: as answered by Alex you can put your content into a context variable that is included in the context of every template created by every view. Django even provides a mechanism for doing this automatically, called a context processor. Pros: very straightforward. Cons: won't dynamically refresh new content on client browsers.
AJAX dynamic loading: as mentioned by Alex and Dave you can dynamically load your content using AJAX methods. As an example using jQuery, you would put a placeholder in your template something like <div id="twitterfeed"></div> and then in a javascript block in your template put $("#twitterfeed").load("{% url twitterfeed %}"); where twitterfeed is a url so named in your urls.py. Pros: will dynamically update browsers. Cons: can be tricky if you don't know Javascript.
Inclusion tag: Django provides a type of template tag called an inclusion tag, which is basically a custom template tag that can render dynamic content. In a way it's similar to a context variable, except your code to generate the content will only be called when you use the custom template tag in your template instead of being called for every view. Another benefit is the content is generated from a template of its own. You could do this with a normal context variable of course, but it's not as clean (IMHO) as using an inclusion tag. Pros: very straightforward, clean. Cons: won't dynamically refresh new content on client browsers.
The simplest approach is to use {{ mycontent }} in your template (where you want the dynamically generated content to appear) and put the correspondence between mycontent and its value in the context you use to render the template -- i.e., the most fundamental part of django's templating.
If what you mean is that you want Ajax support whereby Javascript on the page continuously refreshes such content according to what the server wants it to be at any given time, I suggest looking into dojango, the Dojo/Django integration project -- it's not yet as fully mature as each of Dojo and Django are on their own (not version 0.4 yet), but it is already usable and useful.
A common technique is to leave a placeholder div in the generated content, then fill the div in on the client side via an AJAX call from Javascript that you include in the page.
That gives you the benefit of having a cacheable (fast loading) primary page, with separate dynamic bits. Depending on how live you want the dynamic bits, you can can even cache them for shorter durations.

Controller logic and template logic, where do you draw the line with pagination?

The whole point of an MVC framework is to separate design (templates) from logic (controllers). However, template languages often afford a limited degree of "design logic" to occur. This includes basic if statements, loops, filtering, etc.
I've created a Django template tag that can take any list or QuerySet and "pagify" it. It splits the list up into pages based on a specified page size then adds the pages into the Context. The usage is as follows:
{% pagify articles by 20 as pages %}
I can then call a separate include to iterate over the pages and produce a nice list of pages wherever I needed it.
This seemed like an optimal way to do it because it allowed me to page any list in the context; I didn't have to rely on the controller to return paged results. But a colleague argued that this seemed like too much logic for the template. I thought this still fell within the realm of design-based logic since the page would still function even without paging, and determining page size feels like a template responsibility.
My question, is this too much logic for the template? or is this a clean way to be handling this?
It's always been my understanding that the view isn't supposed to be devoid of logic. It's just supposed to be devoid of any controller logic. Paging just has to do with how the data is displayed which is exactly what the view logic is supposed to contain.
Put it this way; what if you were using your data model in another medium, say, not on the web but via some kind of console-based application or background task? Wouldn't it be nice to be able to get "pages" of data through a controller (or manager) rather than having to somehow rely on a template to do this work for you?
While I'd certainly agree that the "look" of the paged data should be handled by your template, the "act" of paging should be left up to a controller (Django view) or even through some kind of custom manager (models.Manager) method.
The view should not contain business logic or navigation logic. What you are describing is presentation functionality (carefully avoiding the l-word here), which can be placed in the view layer.
You may want to check out django-pagination, which provides a similar template tag.
I agree with your colleague; the template should be fed paginated data rather than performing the pagination. The key question, I think, is whether determining page size is a template duty, and I don't think so; I'd say it should be handled at a higher level.