Mercurial > p > roundup > code
changeset 4877:2ba982dcdf2c
New Link / Multilink option "try_id_parsing"
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Fri, 28 Mar 2014 16:47:36 +0100 |
| parents | 74b24b14071a |
| children | f6e76a03b502 |
| files | CHANGES.txt roundup/hyperdb.py test/test_hyperdbvals.py |
| diffstat | 3 files changed, 30 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Fri Mar 28 15:14:29 2014 +0100 +++ b/CHANGES.txt Fri Mar 28 16:47:36 2014 +0100 @@ -26,6 +26,11 @@ much better to use timezone names. (Thomas Arendsen Hein) - issue2550793: Wrap messages with very long lines in the web interface. (Thomas Arendsen Hein) +- New Link / Multilink option "try_id_parsing": Sometimes the key of a + class can be numeric -- in that case roundup will try to parse the + value as an ID when evaluating form values -- not as a key. Specifying + try_id_parsing='no' for these Link/Multilink will skip the ID step, + default is 'yes'. Fixed:
--- a/roundup/hyperdb.py Fri Mar 28 15:14:29 2014 +0100 +++ b/roundup/hyperdb.py Fri Mar 28 16:47:36 2014 +0100 @@ -127,13 +127,19 @@ class _Pointer(_Type): """An object designating a Pointer property that links or multilinks to a node in a specified class.""" - def __init__(self, classname, do_journal='yes', required=False, - default_value = None): - """ Default is to journal link and unlink events + def __init__(self, classname, do_journal='yes', try_id_parsing='yes', + required=False, default_value=None): + """ Default is to journal link and unlink events. + When try_id_parsing is false, we don't allow IDs in input + fields (the key of the Link or Multilink property must be + given instead). This is useful when the name of a property + can be numeric. It will only work if the linked item has a + key property and is a questionable feature for multilinks. """ super(_Pointer, self).__init__(required, default_value) self.classname = classname self.do_journal = do_journal == 'yes' + self.try_id_parsing = try_id_parsing == 'yes' def __repr__(self): """more useful for dumps. But beware: This is also used in schema storage in SQL backends! @@ -145,10 +151,13 @@ """An object designating a Link property that links to a node in a specified class.""" def from_raw(self, value, db, propname, **kw): - if value == '-1' or not value: + if (self.try_id_parsing and value == '-1') or not value: value = None else: - value = convertLinkValue(db, propname, self, value) + if self.try_id_parsing: + value = convertLinkValue(db, propname, self, value) + else: + value = convertLinkValue(db, propname, self, value, None) return value def sort_repr (self, cls, val, name): if not val: @@ -213,7 +222,10 @@ do_set = 0 # look up the value - itemid = convertLinkValue(db, propname, self, item) + if self.try_id_parsing: + itemid = convertLinkValue(db, propname, self, item) + else: + itemid = convertLinkValue(db, propname, self, item, None) # perform the add/remove if remove: @@ -1356,7 +1368,7 @@ def convertLinkValue(db, propname, prop, value, idre=re.compile('^\d+$')): """ Convert the link value (may be id or key value) to an id value. """ linkcl = db.classes[prop.classname] - if not idre.match(value): + if not idre or not idre.match(value): if linkcl.getkey(): try: value = linkcl.lookup(value)
--- a/test/test_hyperdbvals.py Fri Mar 28 15:14:29 2014 +0100 +++ b/test/test_hyperdbvals.py Fri Mar 28 16:47:36 2014 +0100 @@ -23,6 +23,7 @@ 'date': hyperdb.Date(), 'interval': hyperdb.Interval(), 'link': hyperdb.Link('test'), + 'linkkeyonly': hyperdb.Link('test', try_id_parsing='no'), 'link2': hyperdb.Link('test2'), 'multilink': hyperdb.Multilink('test'), 'multilink2': hyperdb.Multilink('test2'), @@ -104,11 +105,15 @@ self.assertRaises(hyperdb.HyperdbValueError, self._test, 'interval', 'fubar') def testLink(self): - self.assertEqual(self._test('password', ''), None) self.assertEqual(self._test('link', '1'), '1') self.assertEqual(self._test('link', 'valid'), '1') + self.assertEqual(self._test('linkkeyonly', 'valid'), '1') self.assertRaises(hyperdb.HyperdbValueError, self._test, 'link', 'invalid') + self.assertRaises(hyperdb.HyperdbValueError, self._test, 'linkkeyonly', + '1') + self.assertRaises(hyperdb.HyperdbValueError, self._test, 'linkkeyonly', + 'invalid') def testMultilink(self): self.assertEqual(self._test('multilink', '', '1'), []) self.assertEqual(self._test('multilink', '1', '1'), ['1'])
