def test_view(request):
ctx = {}
objects = MyModel.objects.all()
ctx['objects'] = zip(range(1,objects.count()+1), objects)
return render_to_response("app/test.html", ctx)
And for the template:
<table>
{% for el in objects %}
<tr>
<td>el.0</td>
<td>el.1.some_field</td>
{% comment %} Other fields.... {% endcomment %}
</tr>
{% endfor %}
</table>
This is a great python solution, but it's not a django solution. First of all, by using zip function we select the records from the database, adding pagination now would be a bit complicated (using the PaginationMiddleware won't be effecient since it works well only on lazy QuerySets). Another Disadvantage is the need of addressing the counter and data by index. Of course we could make the counter an attribute of the data objects... but it's still not THE solution.
Django provides a better way of solving this problem. Inside each for-loop you may access a forloop template variable. According to the django docs the following attributes are available:
forloop.counter | The current iteration of the loop (1-indexed) | ||
forloop.counter0 | The current iteration of the loop (0-indexed) | ||
forloop.revcounter | The number of iterations from the end of the loop (1-indexed) | ||
forloop.revcounter0 | The number of iterations from the end of the loop (0-indexed) | ||
forloop.first | True if this is the first time through the loop | ||
forloop.last | True if this is the last time through the loop | ||
forloop.parentloop | For nested loops, this is the loop "above" the current one |
Now the template could look like this:
<table>
{% for el in objects %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{el.some_field}}</td>
{% comment %} Other fields.... {% endcomment %}
</tr>
{% endfor %}
</table>
This is more elegant and practical. It's also easy to combine it with the PaginationMiddleware. Ale you need to do is add forloop.counter with each page start index.
Cheers!
KR
No comments:
Post a Comment