Django Forms – The difference between self.cleaned_data[‘field’], self.cleaned_data.get(‘field’) and self.data

By understanding how the attributes self.cleaned_data and self.data work and how to get its values, you can control and use them efficiently in your forms.

Defining the form

This is a simple ModelForm example for a model named Car.

I created the clean_price method to change the original format of the price field that will be passed to the form. This is particularly important, because it’s a key to understand the difference between self.cleaned_data and self.data.

class CarForm(ModelForm):

    price = forms.CharField(max_length=20)

    class Meta:
        model = Car
        fields = ['name','brand','color','price']

    def clean_price(self):
        price = self.cleaned_data['price']
        price = re.sub('[.]', '', price)
        price = re.sub('[,]', '.', price)
        return price

Passing data to the form

The first thing to do is to create a dictionary and pass to the form as the first parameter.

>>> data = {'name': 'Focus',
    'brand': 'Ford',
    'color': 'Blue',
    'price': '17.000,00'}
>>> f = CarForm(data)

What is self.data?

self.data is simply the original data passed to the form. So it will return the original data:

>>> f.data
{'color': 'Blue', 'brand': 'Ford', 'price': '17.000,00', 'name': 'Focus'}
>>> f.data.get('price')
'17.000,00'
>>> f.data['price']
'17.000,00'

What is self.cleaned_data?

self.cleaned_data is an dictionary that receives all cleaned and validated data after calling the is_valid() method.

At this point, if we try to access the cleaned_data attribute, an AttributeError will be raised.

>>> f.cleaned_data
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'CarForm' object has no attribute 'cleaned_data'

This happened because the cleaned_data attribute is created when we call the is_valid() method. After calling the is_valid() method, we have access to the cleaned_data attribute.

>>> f.is_valid()
True
>>> f.cleaned_data
{'color': u'Blue', 'brand': u'Ford', 'price': u'17000.00', 'name': u'Focus'}

And, of course, we also have access to the original data passed to the form. Now, we can see the original and modified price after validation by the clean_price method:

>>> f.data
{'color': 'Blue', 'brand': 'Ford', 'price': '17.000,00', 'name': 'Focus'}
>>> f.data.get('price')
'17.000,00'
>>> f.cleaned_data.get('price')
u'17000.00'

The difference between self.cleaned_data[‘field’] and self.cleaned_data.get(‘field’)

cleaned_data is a Python dictionary and an attribute of the form object. As a Python dictionary, you can access its values by:

  • Specifying the key between [ ]: self.cleaned_data[‘field’]
  • Using get() method: self.cleaned_data.get(‘field’)

The difference between these two approaches is that if the key does not exists, self.cleaned_data[‘field’] will raise a KeyError, while self.cleaned_data.get(‘field’) will return None.

As you can see in the example below, the get() method also allows us to specify a default value if the key does not exists:

>>> f.cleaned_data['size']
Traceback (most recent call last):
  File "", line 1, in 
KeyError: 'size'
>>> f.cleaned_data.get('size')
>>> f.cleaned_data.get('size', 'Data unavailable')
'Data unavailable'