According to the Django tutorial, you should access form fields using cleaned_data dictionary. I'm wondering why I can't access the properties of the form directly? My form validates just fine, but when I try to access it, Django complains that the object does not have the attribute. I added some code below that I hope will help diagnose the problem.
Form:
class CustomForm(forms.Form):
description = forms.CharField(widget = forms.TextInput(attrs = {'placeholder' : 'enter some text'}), label = "My form")
View:
def process_form(request):
if request.method != 'POST':
raise Http404
myForm = CustomForm(request.POST)
if not myForm.is_valid():
c = RequestContext(request)
return render_to_response('home/index.html', {'form' : myForm }, c)
# debug
print 'Description: ' + myForm.description # this does NOT work
# print 'Description: ' + myForm.cleaned_data['description'] # this does work
I get the following error: 'CustomForm' object has no attribute 'description'. Did I miss something in the docs that says I can't do that?
The way you define fields using django.forms
is just a convenient, declarative syntax; it's not really representative of what the final Form class, or an instance of it, looks like in terms of attributes.
Forms have a metaclass (without getting too deep into it, a metaclass is to declaring a class using the class
keyword as an __init__
method is to creating an instance of a class using parentheses -- a hook to customise the object being created, which in the case of a metaclass, is a class
!) which picks off Fields from the form class at definition time and adds them to a base_fields
dict. When you instantiate a form, its base_fields
are deep-copied to a fields
attribute on the instance.
One point of confusion might be that you use .
to access fields for display in templates -- what's actually happening there is that Django's template engine first attempts to use dictionary-style []
access to resolve property lookups and the base form class defines a __getitem__
method to take advantage of this, looking up the appropriate field from the form instance's fields
dict and wrapping it with a BoundField
, a wrapper which knows how to use the field and data from the form for displaying the field.