On Mar 4, 9:59 am, "Diez B. Roggisch" <[EMAIL PROTECTED]>
wrote:
> > Before I get into my specific code, here's a quick contrived example
> > of how it currently works and how I think it should work:
>
> > @expose(template='.foo')
> > def test(self):
> > class TestObj(object):
> > def __init__(self):
> > self.testval='three:3'
>
> > class TestValidator:
> > def to_python(self, value, state=None):
> > log.info('Call to_python on value "%s"', value)
> > result = {'1':'one:1',
> > '2':'two:2',
> > '3':'three:3',
> > '4':'four:4',
> > '5':'five:5' }.get(value, None)
> > if result is None: raise Invalid('Bad Value', value,
> > state)
> > return result
> > def from_python(self, value, state=None):
> > log.info('Call from_python on value "%s"', value)
> > name, id = value.split(':')
> > return id
>
> > class TestFields(WidgetsList):
> > testval=SingleSelectField(
> > 'testval', label='Test Value',
> > options=[('1','one'), ('2','two'), ('3','three'),
> > ('4','four')],
> > validator=TestValidator())
>
> > test_form = TableForm('test', fields=TestFields())
>
> > return dict(form=test_form,
> > item=TestObj())
>
> > The template has the expected ${form.display(item)}. If I use the
> > widgets code as-is, I get the following log output:
>
> > ...
> > 2007-03-04 07:00:58,853 tutornet.controllers INFO Call to_python on
> > value "three:3"
> > 2007-03-04 07:00:58,982 tutornet.controllers INFO Call to_python on
> > value "three:3"
> > 2007-03-04 07:00:58,982 tutornet.controllers INFO Call to_python on
> > value "three:3"
> > 2007-03-04 07:00:58,983 tutornet.controllers INFO Call to_python on
> > value "three:3"
>
> > And of course, no option in the select field is ever selected. If I
> > switch the widgets code to call from_python, however, I get the
> > following log output:
>
> > ...
> > 2007-03-04 07:04:34,820 tutornet.controllers INFO Call from_python on
> > value "three:3"
> > 2007-03-04 07:04:34,822 tutornet.controllers INFO Call from_python on
> > value "three:3"
> > 2007-03-04 07:04:34,823 tutornet.controllers INFO Call from_python on
> > value "three:3"
> > 2007-03-04 07:04:34,825 tutornet.controllers INFO Call from_python on
> > value "three:3"
>
> > And the third option is correctly selected.
>
> To me it looks as if you reversed the to- and from-values - no wonder
> that you need to switch the calls.
Valid form values: '1', '2', '3', '4'
Valid Python values: 'one:1', 'two:2', 'three:3', 'four:4'
The validator correctly converts the "form" value '1' to the "Python"
value 'one:1' and back.
> Your option list is this:
>
> [('1','one'), ('2','two'), ('3','three'), ('4','four')]
>
> Which means that '1', '2', ... _are_ the *python* values we're talking
> here about.
No, it means that '1', '2', ... are the values that will be inserted
*without conversion* into the "value" attribute of the <option> tag in
the template.
> But in your validator's _to_python-call, you map '1' to 'one:1'.
Right. '1' is a form value, 'one:1' is a Python value.
> Now obviously '1' != 'one:1' and so forth, so that the selected item
> will never get displayed correctly.
>
> So either your option-list reads
>
> [('one:1','one'), ('two:2','two'), ('three:3','three'), ('four:4','four')]
Well, I tried that, and didn't have any more success.
> or your mapping has to work differently.
>
> Diez
Looking at the template for the SingleSelectField (and verified
through testing), the '1', '2', etc. are not treated as Python values
at all during the rendering of the template. Instead, whatever is
there is shoved into the "value" attribute of the <option> field
without any conversion done at all:
Quoth turbogears/widgets/forms.py:
<option py:for="value, desc, attrs in options"
value="${value}"
py:attrs="attrs"
py:content="desc"
/>
And, as I confirmed with testing, replacing the '1' with '1:one' also
does *not* select the correct value. I created a new test with an
explicit Python "options" list just to check your idea on the '1'
being a Python value:
@expose(template='tutornet.foo')
def test(self):
class TestValue(object):
def __init__(self, value):
self.value = value
class TestObj(object):
def __init__(self):
self.testval=TestValue(3)
class TestValidator:
def to_python(self, value, state=None):
log.info('Call to_python on value "%s"', value)
result = {'1':TestValue(1),
'2':TestValue(2),
'3':TestValue(3),
'4':TestValue(4),
'5':TestValue(5) }.get(value, None)
if result is None: raise Invalid('Bad Value', value,
state)
return result
def from_python(self, value, state=None):
log.info('Call from_python on value "%s"', value)
return str(value.value)
class TestFields(WidgetsList):
testval=SingleSelectField(
'testval', label='Test Value',
# Here I try putting the Python values into the
options list
options=[(TestValue(1),'one'), (TestValue(2),'two'),
(TestValue(3),'three'), (TestValue(4),
'four')],
validator=TestValidator())
test_form = TableForm('test', fields=TestFields())
return dict(form=test_form,
item=TestObj())
A snippet of the HTML code generated is below:
... <OPTION VALUE="<tutornet.controllers.root.TestValue object at
0x2aaaaad92250>">one</OPTION> ...
So you can see that the values in the options list are not converted
on display.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---