diff --git a/ckanext/scheming/plugins.py b/ckanext/scheming/plugins.py index d7665c57..33edd395 100644 --- a/ckanext/scheming/plugins.py +++ b/ckanext/scheming/plugins.py @@ -40,6 +40,7 @@ scheming_isodatetime_tz, scheming_valid_json_object, scheming_load_json, + scheming_do_not_change_if_missing, ) from ckanext.scheming.logic import ( scheming_dataset_schema_list, @@ -140,6 +141,7 @@ def get_validators(self): 'scheming_isodatetime_tz': scheming_isodatetime_tz, 'scheming_valid_json_object': scheming_valid_json_object, 'scheming_load_json': scheming_load_json, + 'scheming_do_not_change_if_missing': scheming_do_not_change_if_missing, } @run_once_for_caller('_scheming_add_template_directory', lambda: None) diff --git a/ckanext/scheming/validation.py b/ckanext/scheming/validation.py index d8722e3a..738805a5 100644 --- a/ckanext/scheming/validation.py +++ b/ckanext/scheming/validation.py @@ -229,6 +229,32 @@ def validator(key, data, errors, context): return validator +@scheming_validator +def scheming_do_not_change_if_missing(field, schema): + """ + Do not change a value if key is missing. + Default behavior during package_update is to remove value. + """ + def validator(key, data, errors, context): + package = context.get('package') + if package: + original = package.extras.get(key[0], '') + value = data.get(key[0], '') + + # May require separate validator for read_only fields + # that are set programatically elsewhere. In which case + # there may not be a need to compare values, just revert + # to original always, not just when empty. + # if original != value: + # data[key] = original + + if not value: + # silently replace with the old value when none is sent + data[key] = original + + return validator + + def scheming_valid_json_object(value, context): """Store a JSON object as a serialized JSON string