Comment 0 for bug 400477

Revision history for this message
Curtis Hovey (sinzui) wrote : FieldMarshallers do not honor a Field's set() rules

The FieldMarshaller do no use a field's rule to validate or normalize data. So while the UI may use a field (or the help of a widget) to correct data instead of raising an error, the API will accept bad input.

The direct solution would be to create a companion marshaller for each field, much like the UI may use a companion widget. The does not seem like a practical solution because specialized fields will will rarely be used except by the party that creates them; they are not valuable in lazr.restful.

I propose that Fields place rules in commonly named functions that FieldMarshallers can call when the exist. Maybe there should be an IFieldMarshallerFriend interface that defines common methods like normalize().

For example, StripedTextField and its descendent NoneableTextLine both want a normalized value. The rules can be moved from their widgets to the fields themsleves. SimpleFieldMarshaller._marshall_from_json_data() could use the method to clean the data. This approach reduces the number of widgets and marshallers required to manage data, and allows lazr.restful to work with any field that does-the-right-thing. Thus

class StrippedTextLine(TextLine):
    implements(IStrippedTextLine)

    def normalize(self, value):
        """Return the value striped of leading and trailing whitespace."""
        return value.strip()

class SimpleFieldMarshaller:
    implements(IFieldMarshaller)

    def _marshall_from_json_data(self, value):
        ....
        if safe_hasattr(self.field, 'normalize'):
            value = self.field.normalize(value)
        return value

This may relate to bug 373370, where the widget knows that '' should be converted to None.