custom template filters

Date: March 30th 2016
Last updated: March 30th 2016

I have been modifying objects in views.py and then sending them through to an html template as a dictionary. My logic behind this was to keep all the processing away from the template. Today I discovered custom template filters. First, I will show the code that I was using in views.py and then show the use of custom template filters.

views.py (my old way of doing things)

@login_required
def profilepage(request, surfer_id):
    surfer_profile = dict()
    surfer = get_object_or_404(Surfer, pk=surfer_id)
    #<- snipped ->
    # create empty list - this will get added to a dictionary later
    boards = []
    # Surfer and Board have a many to many relationship
    # loop over each board that the surfer has selected for themselves
    for board in surfer.boards.values_list():
        # get each board based on the primary key
        eachboard = get_object_or_404(Board, pk=board[0])
        tailshape = eachboard.get_boardtail_display()
        boardstring = '{} {} ({} {} {})'.format(board[5], board[12],
                                                board[6], board[7],
                                                tailshape)
        boards.append(boardstring)
    surfer_profile['boards'] = boards #(', '.join(boards))

The problem is that the variables that are sent to the html template have lost a majority of their information (e.g. user id's and primary keys). The reason I need the user id is to provide an ifelse statement that changes the html logic.

views.py (my new way)

@login_required
def profilepage(request, surfer_id):
    surfer_profile = dict()
    surfer = get_object_or_404(Surfer, pk=surfer_id)
    #<- snipped ->
    # send the values list straight to the template
    surfer_profile['boardtest'] = surfer.boards.values_list()

tree
Create a templatetags directory next to models.py and views.py

├── manage.py
├── mysite
#<- snipped ->
└── surferprofile
    # <- snipped ->
    ├── models.py
    ├── templates
    │   └── surferprofile
    │       ├── profile.html #<===== LOCATION I WANT TO RENDER A FILTERED STRING
    # <- snipped ->
    ├── templatetags #<===== NEW DIRECTORY
    │   ├── __init__.py #<==== REQUIRES EMPTY INIT FILE
    │   └── surferprofile_extras.py #<==== CREATE .PY FILE
    ├── urls.py
    └── views.py

surferprofile_extras.py

from django import template

register = template.Library()

# help
# https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/

@register.filter #<==== SHORTCUT
def modstring(infolist): #<==== TAKES A LIST
    return infolist[12] #<==== RETURN THE 12 ELEMENT

profile.html

{% load surferprofile_extras %}

{% for board in surfer.boardtest %}
  <!-- pass the board variable to the filter to return the 12th element -->
  <p>{{ board|modstring }}

    <!-- If the user created the board then they can edit it -->
    {% if request.user.id == board.1 %}
      edit
    {% else %}
      No prvileges
     {% endif %}
  </p>
{% endfor %}

results matching ""

    No results matching ""