3
0
Fork 0

fix: correct "empty option" behavior for ObjectRef schema type

This commit is contained in:
Lance Edgar 2024-12-11 09:48:50 -06:00
parent 16ed125113
commit 74e2a4f0e2
5 changed files with 22 additions and 2 deletions

View file

@ -207,6 +207,11 @@ class ObjectRef(colander.SchemaType):
def serialize(self, node, appstruct): def serialize(self, node, appstruct):
""" """ """ """
# nb. normalize to empty option if no object ref, so that
# works as expected
if self.empty_option and not appstruct:
return self.empty_option[0]
if appstruct is colander.null: if appstruct is colander.null:
return colander.null return colander.null

View file

@ -102,7 +102,7 @@ class ObjectRefWidget(SelectWidget):
# add url, only if rendering readonly # add url, only if rendering readonly
readonly = kw.get('readonly', self.readonly) readonly = kw.get('readonly', self.readonly)
if readonly: if readonly:
if 'url' not in values and self.url and field.schema.model_instance: if 'url' not in values and self.url and hasattr(field.schema, 'model_instance'):
values['url'] = self.url(field.schema.model_instance) values['url'] = self.url(field.schema.model_instance)
return values return values

View file

@ -4,6 +4,6 @@
${str(field.schema.model_instance or '')} ${str(field.schema.model_instance or '')}
</a> </a>
<span tal:condition="not url"> <span tal:condition="not url">
${str(field.schema.model_instance or '')} ${str(getattr(field.schema, 'model_instance', None) or '')}
</span> </span>
</tal:omit> </tal:omit>

View file

@ -102,6 +102,11 @@ class TestObjectRef(DataTestCase):
value = typ.serialize(node, person) value = typ.serialize(node, person)
self.assertEqual(value, person.uuid.hex) self.assertEqual(value, person.uuid.hex)
# null w/ empty option
typ = mod.ObjectRef(self.request, empty_option=('bad', 'BAD'))
value = typ.serialize(node, colander.null)
self.assertEqual(value, 'bad')
def test_deserialize(self): def test_deserialize(self):
model = self.app.model model = self.app.model
node = colander.SchemaNode(colander.String()) node = colander.SchemaNode(colander.String())

View file

@ -61,6 +61,7 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
# standard
node = colander.SchemaNode(PersonRef(self.request, session=self.session)) node = colander.SchemaNode(PersonRef(self.request, session=self.session))
widget = self.make_widget() widget = self.make_widget()
field = self.make_field(node) field = self.make_field(node)
@ -68,6 +69,15 @@ class TestObjectRefWidget(WebTestCase):
self.assertIn('cstruct', values) self.assertIn('cstruct', values)
self.assertNotIn('url', values) self.assertNotIn('url', values)
# readonly w/ empty option
node = colander.SchemaNode(PersonRef(self.request, session=self.session,
empty_option=('_empty_', '(empty)')))
widget = self.make_widget(readonly=True, url=lambda obj: '/foo')
field = self.make_field(node)
values = widget.get_template_values(field, '_empty_', {})
self.assertIn('cstruct', values)
self.assertNotIn('url', values)
class TestFileDownloadWidget(WebTestCase): class TestFileDownloadWidget(WebTestCase):