Ticket #3376: 3376_immutable_clean_dict.diff

File 3376_immutable_clean_dict.diff, 4.8 KB (added by Adrian Holovaty, 17 years ago)

Implementation of immutable clean_dict

  • django/utils/datastructures.py

     
    4343                return True
    4444        return False
    4545
     46class ImmutableDict(dict):
     47    "A dictionary whose values cannot be modified."
     48    def __setitem__(self, key, value):
     49        raise TypeError('This dictionary is immutable')
     50
     51    def __delitem__(self, key):
     52        raise TypeError('This dictionary is immutable')
     53
     54    def update(self, d):
     55        raise TypeError('This dictionary is immutable')
     56
    4657class SortedDict(dict):
    4758    "A dictionary that keeps its keys in the order in which they're inserted."
    4859    def __init__(self, data=None):
  • django/newforms/forms.py

     
    22Form classes
    33"""
    44
    5 from django.utils.datastructures import SortedDict, MultiValueDict
     5from django.utils.datastructures import SortedDict, MultiValueDict, ImmutableDict
    66from django.utils.html import escape
    77from fields import Field
    88from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
     
    187187            errors[NON_FIELD_ERRORS] = e.messages
    188188        if errors:
    189189            delattr(self, 'clean_data')
     190        else:
     191            self.clean_data = ImmutableDict(self.clean_data) # Make it immutable.
    190192        self.__errors = errors
    191193
    192194    def clean(self):
  • tests/regressiontests/forms/tests.py

     
    7272>>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
    7373u'<input type="password" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
    7474
    75 The render_value argument lets you specify whether the widget should render
    76 its value. You may want to do this for security reasons.
    77 >>> w = PasswordInput(render_value=True)
    78 >>> w.render('email', 'secret')
    79 u'<input type="password" name="email" value="secret" />'
    80 >>> w = PasswordInput(render_value=False)
    81 >>> w.render('email', '')
    82 u'<input type="password" name="email" />'
    83 >>> w.render('email', None)
    84 u'<input type="password" name="email" />'
    85 >>> w.render('email', 'secret')
    86 u'<input type="password" name="email" />'
    87 >>> w = PasswordInput(attrs={'class': 'fun'}, render_value=False)
    88 >>> w.render('email', 'secret')
    89 u'<input type="password" class="fun" name="email" />'
    90 
    9175# HiddenInput Widget ############################################################
    9276
    9377>>> w = HiddenInput()
     
    17451729...
    17461730KeyError: "Key 'nonexistentfield' not found in Form"
    17471731
     1732The clean_data dictionary is immutable -- i.e., you cannot add to it, delete
     1733from it or change its values. Use the copy() method to get a new dictionary
     1734whose values you can edit.
     1735>>> p.clean_data['first_name'] = 'foo'
     1736Traceback (most recent call last):
     1737...
     1738TypeError: This dictionary is immutable
     1739>>> del p.clean_data['first_name']
     1740Traceback (most recent call last):
     1741...
     1742TypeError: This dictionary is immutable
     1743>>> p.clean_data['new_field_name'] = 'foo'
     1744Traceback (most recent call last):
     1745...
     1746TypeError: This dictionary is immutable
     1747>>> new_clean_data = p.clean_data.copy()
     1748>>> new_clean_data['new_field_name'] = 'foo'
     1749
    17481750>>> for boundfield in p:
    17491751...     print boundfield
    17501752<input type="text" name="first_name" value="John" id="id_first_name" />
  • docs/newforms.txt

     
    273273    >>> f.clean_data # Doesn't contain extra_field_1, etc.
    274274    {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
    275275
     276The ``clean_data`` dictionary is immutable -- you cannot add to it, delete from
     277it or change its values. Use the ``copy()`` method, or the ``dict()`` builtin
     278function, to get a new dictionary whose values you can edit::
     279
     280    >>> f.clean_data['subject'] = 'foo'
     281    Traceback (most recent call last):
     282    ...
     283    TypeError: This dictionary is immutable
     284    >>> del f.clean_data['subject']
     285    Traceback (most recent call last):
     286    ...
     287    TypeError: This dictionary is immutable
     288    >>> f.clean_data['new_field_name'] = 'foo'
     289    Traceback (most recent call last):
     290    ...
     291    TypeError: This dictionary is immutable
     292
     293    # Method one: copy()
     294    >>> new_clean_data = f.clean_data.copy()
     295    >>> new_clean_data['new_field_name'] = 'foo' # Now it's mutable.
     296
     297    # Method two: dict()
     298    >>> other_clean_data = dict(f.clean_data, new_field_name='foo')
     299
    276300Behavior of unbound forms
    277301~~~~~~~~~~~~~~~~~~~~~~~~~
    278302
Back to Top