18

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?

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
MK_Dev
  • 3,291
  • 5
  • 27
  • 45

4 Answers4

26

If your form is validated then you can access myForm cleaned_data:

print myForm.cleaned_data.get('description')

If you want to see why you cannot access myForm.description then you can see the data dictionary of your myForm:

print myForm.__dict__
Zubair Afzal
  • 2,016
  • 20
  • 29
  • I understand that I can access it using cleaned_data. What I don't understand is why I can't access it using the property itself: myForm.description. What exactly happens under the hood that prevents me from accessing it? – MK_Dev Mar 13 '12 at 16:20
20

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.

Community
  • 1
  • 1
Jonny Buchanan
  • 61,926
  • 17
  • 143
  • 150
7

You can access the fields of a Form instance from its fields attribute.

myForm.fields['description']

And some property like label can be accessed like this:

myForm.fields['description'].label

Not sure how to display the value corresponding. Anybody having idea?

here is my reference

https://docs.djangoproject.com/en/dev/ref/forms/api/#accessing-the-fields-from-the-form

Snigdha Batra
  • 867
  • 8
  • 16
Ajeeb.K.P
  • 1,013
  • 1
  • 13
  • 21
4

You can access your field trought dict.

form.__dict__["fields"]["description"]
  • Thank you! How can I set to show only certain form field? I want to do it from view. – Ulvi Sep 18 '20 at 21:01