This question is related to (but perhaps not quite the same as):
Does Django have HTML helpers?
My problem is this: In Django, I am constantly reproducing the basic formatting for low-level database objects. Here’s an example:
I have two classes, Person and Address. There are multiple Addresses for each Person, setup likeso (in their respective models.py)
class Person(models.Model): ... class Address(models.Model): contact = models.ForeignKey(Person)
Now, whenever I look at a Person, I want to see all their Addresses. So suppose Persons/views.py has something likeso:
def detail(request, person_id): person = get_object_or_404( Person, pk=person_id ) return render_to_response('persons/details.html', { 'title' : unicode(person), 'addresses': person.address_set.all() } )
And, I have a template, persons/details.html, with code, for example, like-so:
{% extends 'base.html' %} {% for address in addresses %} <b>{{ address.name }}</b> {{ address.type }} <br> {{ address.street_1 }}<br> {{ address.street_2 }}<br> {{ address.city }} {{ address.stateprov }} {{ address.postalcode }}<br> {{ address.country }} <hr> {{ endfor }}
I am repeating this code quite a bit, often with minor variations, such when it’s in a table, and then < br > must be substituted by < /td >< td >. Other times, I don’t want a street_2 to display (or the < br > after it). All to say, there is fundamental logic that I want to express, that I am even more loath to tote around with block-and-copy!
What I want is a persons/details.html with, for example, the following:
{% extends 'base.html' %} {% for address in addresses %} {% address.as_html4 %} {% endfor %}
And if I want inline table, something likeso (I guess!):
{% extends 'base.html' %} <table><tr> {% for address in addresses %} <tr><td> {% address.as_html4 </td><td> %} </td></tr> {% endfor %} </table>
The question is, then: Where is the best place to put the formatting? The logic?
Django seem to have the following (plausible) options:
-
Put the formatting in models.py
-
Put the logic/formatting in views.py
-
Put the logic/formatting in some other sub-class of Person or Address (i.e. addresses/html4.py)
-
Create custom tags
Help / insight much appreciated!
Sounds like an inclusion tag is what you’re looking for. You could have a template and tag for each major variation and use the tag’s arguments to customise the context for each template as required.
Basic tag definition:
Use in templates (assuming the templatetag module containing it has already been
{% load %}-ed):