Fixed #3139 -- newforms BoundField no longer returns empty errors when using a prefix. Thanks, jkocherhans

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4199 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-12-13 23:03:19 +00:00
parent 10edce12fc
commit d8a21981b7
2 changed files with 44 additions and 12 deletions

View File

@ -173,7 +173,8 @@ class BoundField(StrAndUnicode):
def __init__(self, form, field, name): def __init__(self, form, field, name):
self.form = form self.form = form
self.field = field self.field = field
self.name = form.add_prefix(name) self.name = name
self.html_name = form.add_prefix(name)
self.label = self.field.label or pretty_name(name) self.label = self.field.label or pretty_name(name)
def __unicode__(self): def __unicode__(self):
@ -201,7 +202,7 @@ class BoundField(StrAndUnicode):
auto_id = self.auto_id auto_id = self.auto_id
if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'):
attrs['id'] = auto_id attrs['id'] = auto_id
return widget.render(self.name, self.data, attrs=attrs) return widget.render(self.html_name, self.data, attrs=attrs)
def as_text(self, attrs=None): def as_text(self, attrs=None):
""" """
@ -222,8 +223,8 @@ class BoundField(StrAndUnicode):
def _data(self): def _data(self):
"Returns the data for this BoundField, or None if it wasn't given." "Returns the data for this BoundField, or None if it wasn't given."
if self.field.widget.requires_data_list and isinstance(self.form.data, MultiValueDict): if self.field.widget.requires_data_list and isinstance(self.form.data, MultiValueDict):
return self.form.data.getlist(self.name) return self.form.data.getlist(self.html_name)
return self.form.data.get(self.name, None) return self.form.data.get(self.html_name, None)
data = property(_data) data = property(_data)
def label_tag(self, contents=None): def label_tag(self, contents=None):
@ -251,8 +252,8 @@ class BoundField(StrAndUnicode):
""" """
auto_id = self.form.auto_id auto_id = self.form.auto_id
if auto_id and '%s' in str(auto_id): if auto_id and '%s' in str(auto_id):
return str(auto_id) % self.name return str(auto_id) % self.html_name
elif auto_id: elif auto_id:
return self.name return self.html_name
return '' return ''
auto_id = property(_auto_id) auto_id = property(_auto_id)

View File

@ -1332,6 +1332,11 @@ u''
<input type="text" name="last_name" value="Lennon" id="id_last_name" /> <input type="text" name="last_name" value="Lennon" id="id_last_name" />
>>> print p['birthday'] >>> print p['birthday']
<input type="text" name="birthday" value="1940-10-9" id="id_birthday" /> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
>>> print p['nonexistentfield']
Traceback (most recent call last):
...
KeyError: "Key 'nonexistentfield' not found in Form"
>>> for boundfield in p: >>> for boundfield in p:
... print boundfield ... print boundfield
<input type="text" name="first_name" value="John" id="id_first_name" /> <input type="text" name="first_name" value="John" id="id_first_name" />
@ -1974,9 +1979,39 @@ actual field name.
{} {}
>>> p.is_valid() >>> p.is_valid()
True True
>>> p.clean_data
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
This is pretty unremarkable in and of itself, but let's create some data that Let's try submitting some bad data to make sure form.errors and field.errors
contains info for two different people. work as expected.
>>> data = {
... 'person1-first_name': u'',
... 'person1-last_name': u'',
... 'person1-birthday': u''
... }
>>> p = Person(data, prefix='person1')
>>> p.errors
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
>>> p['first_name'].errors
[u'This field is required.']
>>> p['person1-first_name'].errors
Traceback (most recent call last):
...
KeyError: "Key 'person1-first_name' not found in Form"
In this example, the data doesn't have a prefix, but the form requires it, so
the form doesn't "see" the fields.
>>> data = {
... 'first_name': u'John',
... 'last_name': u'Lennon',
... 'birthday': u'1940-10-9'
... }
>>> p = Person(data, prefix='person1')
>>> p.errors
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
With prefixes, a single data dictionary can hold data for multiple instances
of the same form.
>>> data = { >>> data = {
... 'person1-first_name': u'John', ... 'person1-first_name': u'John',
... 'person1-last_name': u'Lennon', ... 'person1-last_name': u'Lennon',
@ -1985,15 +2020,11 @@ contains info for two different people.
... 'person2-last_name': u'Morrison', ... 'person2-last_name': u'Morrison',
... 'person2-birthday': u'1943-12-8' ... 'person2-birthday': u'1943-12-8'
... } ... }
If we use the correct prefix argument, we can create two different forms that
will only use and validate the data for fields with a matching prefix.
>>> p1 = Person(data, prefix='person1') >>> p1 = Person(data, prefix='person1')
>>> p1.is_valid() >>> p1.is_valid()
True True
>>> p1.clean_data >>> p1.clean_data
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} {'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
>>> p2 = Person(data, prefix='person2') >>> p2 = Person(data, prefix='person2')
>>> p2.is_valid() >>> p2.is_valid()
True True