Field labels in templates
There’s no way in Django (that I’ve found) to render a field’s name in a
template. This means you end up with <th>Field Name</th> all over your
templates. Why hello there, DRY violation!
The fields are stored in model._meta.fields, but templates don’t allow you to
access variables which start with an underscore. I’ve got two little utility
functions I wrote for myself to generate a dict of labels I can use in my
templates:
def get_labels_for(model, cap=True, esc=True):
from django.template.defaultfilters import capfirst
from django.utils.html import escape
labels = {}
for field in model._meta.fields:
label = field.verbose_name
if cap:
label = capfirst(label)
if esc:
label = escape(label)
labels[field.name] = label
return labels
def with_labels(context, cap=True, esc=True):
from django.db.models import Model
result = context.copy()
for k, v in context.iteritems():
if isinstance(v, Model):
result[k + '_labels'] = get_labels_for(v, cap, esc)
elif hasattr(v, '__getitem__') and len(v) > 0:
if isinstance(v[0], Model):
result[k + '_labels'] = get_labels_for(v[0], cap, esc)
return resultThe parameters:
modelcan be a model class or a model instance.- If
capisTrue, the first letter of each label will be capitalized. - If
escisTrue, the labels will be escaped for HTML.
So, in your view:
def some_view(request, foo_id):
foo = get_object_or_404(Foo, id=foo_id)
context = {'foo': foo, 'foo_labels': get_labels_for(foo)}
return render_to_response('foo.html', context)And in your template:
{{ foo_labels.bar }}: {{ foo.bar }}with_labels works the same way, except you can just surround your context
with it:
def some_view(request, foo_id):
foo = get_object_or_404(Foo, id=foo_id)
bars = Bars.objects.all()
context = {'foo': foo, 'bars': bars}
return render_to_response('foo.html', with_labels(context))It will detect the models and lists of models in the context and add
foo_labels and bars_labels to the context.