Form labels not rendering with Django & WTForms
I'm trying to use WTForms with Django & a MongoEngine/MongoDB database backend. The forms are outputting properly, but I can't for the life of me get the labels to show up.
Here is my template code:
{% load wtforms %}
<form>
{% for f in form %}
{{ f.label }}: {% form_field f %}<br/>
{% endfor %}
</form>
This is what I am passing in the view:
form = StrandForm()
return render_to_response('create_strand.html', locals(),开发者_运维百科 context_instance = RequestContext(request))
The StrandForm class I have tried both creating from the WTForm mongoengine extension's model_form class, and from WTForm's Form class. The label exists in the view, I can print it to the console and it shows the rendered form label, but somehow it gets lost when transferring to the template. Am I doing something wrong?
Django 1.4 has a new feature: do_not_call_in_templates
attribute.
If you set it on wtforms.Field
class, every child class inherits and all fields will work fine in django templates.
import wtforms
wtforms.Field.do_not_call_in_templates = True
Now following code works as expected:
{% load wtforms %}
{{ f.label }}: {% form_field f %}
I encountered the same problem today. It has to do with the way WTForms is programmed so that it will work with many different templating libraries. Django 1.3 will only see f as it's HTML string even though it has other attributes.
In order to fix this you must add a template tag to retrieve the attribute.
Add the following to your projects hierarchy:
- templatetags
- templatetags / init.py
- templatetags / templatetags
- templatetags / templatetags / init.py
- templatetags / templatetags / getattribute.py
Then in your settings.py file, add the following line to INSTALLED_APPS
'templatetags',
Open up getattribute.py and paste the following code:
from django import template
from django.conf import settings
register = template.Library()
@register.tag
def getattribute(parser, token):
try:
tag_name, tag_object, tag_function = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError("%r tag requires two arguments" % token.contents.split()[0])
return getattrNode(tag_object, tag_function)
class getattrNode(template.Node):
def __init__(self, tag_object, tag_function):
self.tag_object = tag_object
self.tag_function = tag_function
def render(self, context):
return getattr(context[self.tag_object], self.tag_function)()
This will allow you to use the follow code whenever you're inside a template and need an attribute that won't show up:
{% load getattribute %}
{% getattribute OBJECT ATTRIBUTE %}
In your case:
{% getattribute f label %}
Hope that helped!
精彩评论