Index: django/contrib/localflavor/br/forms.py
===================================================================
--- django/contrib/localflavor/br/forms.py	(revision 10620)
+++ django/contrib/localflavor/br/forms.py	(working copy)
@@ -86,6 +86,10 @@
     """
     This field validate a CPF number or a CPF string. A CPF number is
     compounded by XXX.XXX.XXX-VD. The two last digits are check digits.
+    By default, the cleaned value is in the same format as entered. 
+    If you'd like to keep a unique format for cleaned values use
+    the parameters "always_return_formatted" set to `True` and 
+    adjust "return_format" to your needs, the default format is '%s.%s.%s-%s'.
 
     More information:
     http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
@@ -96,8 +100,12 @@
         'digits_only': _("This field requires only numbers."),
     }
 
-    def __init__(self, *args, **kwargs):
-        super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
+    def __init__(self, always_return_formatted=False, 
+                 return_format=u'%s.%s.%s-%s', *args, **kwargs):
+        self.always_return_formatted = always_return_formatted
+        self.return_format = return_format
+        super(BRCPFField, self).__init__(max_length=14, min_length=11, 
+                                         *args, **kwargs)
 
     def clean(self, value):
         """
@@ -116,8 +124,12 @@
             raise ValidationError(self.error_messages['digits_only'])
         if len(value) != 11:
             raise ValidationError(self.error_messages['max_digits'])
+
+        # exclude cases of only 0 or only 9 digits
+        if value in ('0' * 11, '9' * 11):
+            raise ValidationError(self.error_messages['invalid'])
+
         orig_dv = value[-2:]
-
         new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
         new_1dv = DV_maker(new_1dv % 11)
         value = value[:-2] + str(new_1dv) + value[-1]
@@ -127,14 +139,35 @@
         if value[-2:] != orig_dv:
             raise ValidationError(self.error_messages['invalid'])
 
+        # return a formatted string if asked
+        if self.always_return_formatted:
+            value = re.sub(r'[-\.]', '', orig_value)
+            return self.return_format % tuple(re.findall(r'(\d{2,3})', value))
+
         return orig_value
 
-class BRCNPJField(Field):
+class BRCNPJField(CharField):
+    """
+    This field validates a CNPJ number or a CNPJ string. A CNPJ number is
+    compounded by XX.XXX.XXX/XXXX-XX.
+    By default, the cleaned value is in the same format as entered. 
+    If you'd like to keep a unique format for cleaned values use
+    the parameters "always_return_formatted" set to `True` and 
+    adjust "return_format" to your needs, the default format is 
+    '%s.%s.%s/%s-%s'.
+    """
     default_error_messages = {
         'invalid': _("Invalid CNPJ number."),
         'digits_only': _("This field requires only numbers."),
         'max_digits': _("This field requires at least 14 digits"),
     }
+    
+    def __init__(self, always_return_formatted=False, 
+                 return_format=u'%s.%s.%s/%s-%s', *args, **kwargs):
+        self.always_return_formatted = always_return_formatted
+        self.return_format = return_format
+        super(BRCNPJField, self).__init__(max_length=18, min_length=14, 
+                                          *args, **kwargs)    
 
     def clean(self, value):
         """
@@ -163,5 +196,10 @@
         value = value[:-1] + str(new_2dv)
         if value[-2:] != orig_dv:
             raise ValidationError(self.error_messages['invalid'])
+            
+        if self.always_return_formatted:
+            value = re.sub('[-/\.]', '', orig_value)
+            m = re.match(r'(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})', value)
+            return self.return_format % tuple(m.groups())
 
         return orig_value
Index: tests/regressiontests/forms/localflavor/br.py
===================================================================
--- tests/regressiontests/forms/localflavor/br.py	(revision 10620)
+++ tests/regressiontests/forms/localflavor/br.py	(working copy)
@@ -85,11 +85,11 @@
 ...
 ValidationError: [u'Invalid CNPJ number.']
 >>> f.clean('64.132.916/0001-88')
-'64.132.916/0001-88'
+u'64.132.916/0001-88'
 >>> f.clean('64-132-916/0001-88')
-'64-132-916/0001-88'
+u'64-132-916/0001-88'
 >>> f.clean('64132916/0001-88')
-'64132916/0001-88'
+u'64132916/0001-88'
 >>> f.clean('64.132.916/0001-XX')
 Traceback (most recent call last):
 ...
@@ -97,6 +97,40 @@
 >>> f = BRCNPJField(required=False)
 >>> f.clean('')
 u''
+>>> f.clean('64.132.916/0001-8')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field requires at least 14 digits']
+>>> f.clean('6413291600018')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 14 characters (it has 13).']
+>>> f.clean('64.132.916/0001-889')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 18 characters (it has 19).']
+>>> f = BRCNPJField(required=True, always_return_formatted=True)
+>>> f.clean('12-345-678/9012-10')
+Traceback (most recent call last):
+...
+ValidationError: [u'Invalid CNPJ number.']
+>>> f.clean('64.132.916/0001-88')
+u'64.132.916/0001-88'
+>>> f.clean('64132916000188')
+u'64.132.916/0001-88'
+>>> f.clean('64132916/0001-88')
+u'64.132.916/0001-88'
+>>> f = BRCNPJField(required=True, always_return_formatted=True, return_format='%s%s%s%s%s')
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('64132916/0001-88')
+u'64132916000188'
+>>> f.clean('64132916000188')
+u'64132916000188'
+>>> f.clean('64.132.916/0001-88')
+u'64132916000188'
 
 # BRCPFField #################################################################
 
@@ -151,6 +185,20 @@
 u''
 >>> f.clean(None)
 u''
+>>> f = BRCPFField(always_return_formatted=True)
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('663.256.017-26')
+u'663.256.017-26'
+>>> f.clean('66325601726')
+u'663.256.017-26'
+>>> f = BRCPFField(always_return_formatted=True, return_format='%s%s%s%s')
+>>> f.clean('663.256.017-26')
+u'66325601726'
+>>> f.clean('66325601726')
+u'66325601726'
 
 # BRPhoneNumberField #########################################################
 
