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)

results matching ""

    No results matching ""