Django

Code

Changeset 4194

Show
Ignore:
Timestamp:
12/11/06 23:55:39 (2 years ago)
Author:
adrian
Message:

Fixed #3132 -- Added prefix support for newforms. Thanks, jkocherhans

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/newforms/forms.py

    r4192 r4194  
    3737    __metaclass__ = DeclarativeFieldsMetaclass 
    3838 
    39     def __init__(self, data=None, auto_id='id_%s'): # TODO: prefix stuff 
     39    def __init__(self, data=None, auto_id='id_%s', prefix=None): 
    4040        self.ignore_errors = data is None 
    4141        self.data = data or {} 
    4242        self.auto_id = auto_id 
     43        self.prefix = prefix 
    4344        self.clean_data = None # Stores the data after clean() has been called. 
    4445        self.__errors = None # Stores the errors after clean() has been called. 
     
    7273        """ 
    7374        return not self.ignore_errors and not bool(self.errors) 
     75 
     76    def add_prefix(self, field_name): 
     77        """ 
     78        Returns the field name with a prefix appended, if this Form has a 
     79        prefix set. 
     80 
     81        Subclasses may wish to override. 
     82        """ 
     83        return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name 
    7484 
    7585    def _html_output(self, normal_row, error_row, row_ender, errors_on_separate_row): 
     
    133143            # Each widget type knows how to retrieve its own data, because some 
    134144            # widgets split data over several HTML fields. 
    135             value = field.widget.value_from_datadict(self.data, name
     145            value = field.widget.value_from_datadict(self.data, self.add_prefix(name)
    136146            try: 
    137147                value = field.clean(value) 
     
    164174        self.form = form 
    165175        self.field = field 
    166         self.name = name 
     176        self.name = form.add_prefix(name) 
    167177        self.label = self.field.label or pretty_name(name) 
    168178 
  • django/trunk/tests/regressiontests/forms/tests.py

    r4192 r4194  
    19251925<li>Password (again): <input type="password" name="password2" /></li> 
    19261926 
     1927# Forms with prefixes ######################################################### 
     1928 
     1929Sometimes it's necessary to have multiple forms display on the same HTML page, 
     1930or multiple copies of the same form. We can accomplish this with form prefixes. 
     1931Pass the keyword argument 'prefix' to the Form constructor to use this feature. 
     1932This value will be prepended to each HTML form field name. One way to think 
     1933about this is "namespaces for HTML forms". Notice that in the data argument, 
     1934each field's key has the prefix, in this case 'person1', prepended to the 
     1935actual field name. 
     1936>>> class Person(Form): 
     1937...     first_name = CharField() 
     1938...     last_name = CharField() 
     1939...     birthday = DateField() 
     1940>>> data = { 
     1941...     'person1-first_name': u'John', 
     1942...     'person1-last_name': u'Lennon', 
     1943...     'person1-birthday': u'1940-10-9' 
     1944... } 
     1945>>> p = Person(data, prefix='person1') 
     1946>>> print p.as_ul() 
     1947<li><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /></li> 
     1948<li><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /></li> 
     1949<li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li> 
     1950>>> print p['first_name'] 
     1951<input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /> 
     1952>>> print p['last_name'] 
     1953<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /> 
     1954>>> print p['birthday'] 
     1955<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /> 
     1956>>> p.errors 
     1957{} 
     1958>>> p.is_valid() 
     1959True 
     1960 
     1961This is pretty unremarkable in and of itself, but let's create some data that 
     1962contains info for two different people. 
     1963>>> data = { 
     1964...     'person1-first_name': u'John', 
     1965...     'person1-last_name': u'Lennon', 
     1966...     'person1-birthday': u'1940-10-9', 
     1967...     'person2-first_name': u'Jim', 
     1968...     'person2-last_name': u'Morrison', 
     1969...     'person2-birthday': u'1943-12-8' 
     1970... } 
     1971 
     1972If we use the correct prefix argument, we can create two different forms that 
     1973will only use and validate the data for fields with a matching prefix. 
     1974>>> p1 = Person(data, prefix='person1') 
     1975>>> p1.is_valid() 
     1976True 
     1977>>> p1.clean_data 
     1978{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} 
     1979 
     1980>>> p2 = Person(data, prefix='person2') 
     1981>>> p2.is_valid() 
     1982True 
     1983>>> p2.clean_data 
     1984{'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)} 
     1985 
     1986By default, forms append a hyphen between the prefix and the field name, but a 
     1987form can alter that behavior by implementing the add_prefix() method. This 
     1988method takes a field name and returns the prefixed field, according to 
     1989self.prefix. 
     1990>>> class Person(Form): 
     1991...     first_name = CharField() 
     1992...     last_name = CharField() 
     1993...     birthday = DateField() 
     1994...     def add_prefix(self, field_name): 
     1995...         return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name 
     1996>>> p = Person(prefix='foo') 
     1997>>> print p.as_ul() 
     1998<li><label for="id_foo-prefix-first_name">First name:</label> <input type="text" name="foo-prefix-first_name" id="id_foo-prefix-first_name" /></li> 
     1999<li><label for="id_foo-prefix-last_name">Last name:</label> <input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" /></li> 
     2000<li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li> 
     2001>>> data = { 
     2002...     'foo-prefix-first_name': u'John', 
     2003...     'foo-prefix-last_name': u'Lennon', 
     2004...     'foo-prefix-birthday': u'1940-10-9' 
     2005... } 
     2006>>> p = Person(data, prefix='foo') 
     2007>>> p.is_valid() 
     2008True 
     2009>>> p.clean_data 
     2010{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} 
     2011 
    19272012# Basic form processing in a view ############################################# 
    19282013