Reputation: 1317
I have a Django project that interfaces with a PostgreSQL database; one of my tables is about 450 rows long and each row contains about a dozen columns.
Each column's value must be put into a different formula to produce the final data I want to display in the template layer, but each row will be processed with the same set of calculations. (In other words, I want to perform 12 different calculations 450 times each.)
My question is, of the following methods, which is the generally accepted method of doing so, and which is the best in terms of performance:
A) Write each calculation as a model method in models.py, query all objects of interest (again, about 450 of them) in views.py and pass them directly to the template, and then use Django's template language to write things like:
<table>
{% for item in list %}
<tr>
<td>{{item.name}}</td>
...
</tr>
{% endfor %}
</table>
(where .name
is a model method)
B) Peform the query and calculations in the views.py file and pass the results organized into one big dictionary or list or JSON to the template (and then parse it using template tags),
C) Pass all of the objects of interest to the template as in A), but perform calculations on each object's fields using Javascript or jQuery,
D) Combine B) and C) to perform all database queries in views.py and then pass the raw values as a big dictionary/list/JSON object to the template and perform calculations on those values using Javascript/jQuery.
To my mind, method A) seems the least efficient as it requires you to hit the database a ton of times in the template layer. But it makes writing the view and template extremely simple (just requires you to write 12 different model methods). Method B) seems to follow the general tenet of performing as much logic as possible in your view, and simply passing along the final results to be displayed in the template. But it makes the view function long and ugly. Methods C) and D) put most of load on the end user's browser, which seems like it could really take a load off the server, but then obviously won't work if the user has JS turned off.
But again, I'd like to know if there's an accepted best practice for this kind of situation, and whether that contradicts the fastest method from a computational standpoint.
And obviously, if I've missed the best method of all, please let me know what it would be.
Upvotes: 2
Views: 1639
Reputation: 1630
Methods (C) and (D), though tempting are not the way to go. The client's computer might be slow in which case the page might just freeze their browser while it performs all of these calculations.
(A) seems like the best option, and it shouldn't incur in additional queries. If you pass the objects to the template in a single queryset (Model.objects.all() for example), then Django should perform a single query to fetch all of the objects, then when calling the method in the template no additional query should be performed. If your objects are related to others, and this relation is used in the calculation, make sure to use select_related or prefetch_related because querying a related object on each model call will indeed incur in a single query per object unless you prefetch/select what you're going to use beforehand (https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related).
Upvotes: 2