stop overprocessing views
Date: March 31st 2016
Last updated: March 31st 2016
This entry follows on from custom template filters. I have realised that I am overprocessing in views.py. This example shows how to pass an object to a template and provide some filtering using custom templatetags.
The objective of the following code is to convert a decimal field into a fraction which is rendered in HTML. Previously I had been evaluating/processing data in views.py and then sending a new dictionary to the HTML template. Here I use a custom template filter to do the work.
views.py
@login_required
def profilepage(request, surfer_id):
surfer = get_object_or_404(Surfer, pk=surfer_id)
#<- snipped ->
boardstest = (surfer.boards.all()) #<===== query all boards for this surfer
return render(request, 'surferprofile/profile.html',
{'boardstest': boardstest})
surferprofile_extra.py
from django import template
import math
from fractions import Fraction
register = template.Library()
def fractioncreator(value):
"""
Convert a decimal field into a fraction
E.g.
fractioncreator(2.375)
>>> 2 3/8
"""
return '{} {}'.format(str(math.floor(value)), str(Fraction(value % 1)))
@register.filter
def width_as_fraction(value):
return fractioncreator(value)
profile.html (minimal)
<div>
{% for board in boardstest %}
<!-- use the templatetag to filter the decimal field: boardwidth -->
{{board.boardwidth|width_as_fraction}}
{% endfor %}
</div>
profile.html (Used with other fields)
<div>
{% for board in boardstest %}
<!-- get models.py str function -->
{{board}}
<!-- use the templatetag to filter the decimal field: boardwidth -->
(w/ {{board.boardwidth|width_as_fraction}}
<!-- capture display label for boardtail for each object -->
{{board.get_boardtail_display}})
{% if request.user.id == board.user.id %}
edit
{% else %}
{% endif %}
{% endfor %}
</div>
http://127.0.0.1:8080/1/ (profile page)