On May 27, 2010, at 3:24 AM, Chris McDonough wrote:
> This is an area that I'm not 100% confident about yet, so I'm glad
> you're stressing it a bit.
> FTR, this definitely won't work:
> SchemaNode(Integer(), required=False, allow_empty=True)
> Because a SchemaNode does nothing with either the ``required`` nor the
> ``allow_empty`` arguments. Instead, you probably meant to be passing
> these kwargs to the data type constructor ("Integer()"). I just made
> a change to Colander that will cause it to throw a TypeError if bogus
> keyword arguments are fed to the SchemaNode constructor, hopefully
> preventing future confusion about this.
I was grasping at straws and misread the docs; thanks for the alert that will
keep me honest next time.
> That said, although the ``colander.String`` type accepts an
> ``allow_empty``, there isn't any data type constructor that accepts a
> ``required`` argument. The ``required`` attribute of a SchemaNode is
> a computed property, derived from whether or not the node was given a
> default value, but types themselves aren't required or not-required,
> and neither a SchemaNode nor any particular type (Integer, String,
> etc) takes ``required`` as a valid kw argument.
It feels a bit unnatural to me to link 'required' to 'default'. Currently
supplying a default implies not-required, and not supplying default implies
required. What if I wanted a required field but wanted a default (e.g. a
users' name, or today's date)? Or the opposite: in my current case I want
fields to be optional, but don't want to force in an unrealistic number (e.g.,
number of things in a box = 0 or 24 or something else random).
I think it would be helpful to decouple these.
> I don't think you want to change the type.
Yeah, I'd prefer to use an Integer() if it's numeric, and not fake it with a
String() and special validator.
> I think this might be a
> deficiency in Colander or Deform, but I'd like to understand a little
> better before I make any particular change. So I'll try to state the
> requirements and the current state of affairs to make sure I make the
> right change:
> You want to make a field in a form "not-required". This implies
> that you don't want a little red asterisk next to the field title
> when the form is rendered, and when the form is submitted, you don't
> want the form to be re-rendered with an error message if no value is
> placed into the field representing the value. Instead, you want the
> form submission to be considered valid, and the data returned from
> the ``validate`` method of the form to contain a placeholder
> (default) value for that particular field. The placeholder value
> returned by ``validate`` won't necessarily be the same natural type
> as the field data type. For instance, you might want the
> placeholder value to be ``None``, while the type is an Integer.
I'm not sure I agree with "data returned ... contain a placeholder (default)
value" for optionals. Does it make sense to allow using required= and default=
I think I maybe be not thinking clearly enough about the distinction between
the form processing and validation and marshalling to the appstruct, vs. the
way (say) Django conflates schema and form and DB storage where a Integer field
could be Null in their SQL DB. While I'd like to allow (say) an Integer field
to be optional, I understand the marshaller can't set a python int to None --
it doesn't know or care that the backend DB would like to store it as NULL for
SQL or omit the field for Mongo. I don't know if it makes sense for the
marshaller to set an field whose schema is Integer to None if the field's
marked optional and no value is supplied, or validate and marshal to an int if
it is supplied.
This seems it would be a common use case so perhaps I'm thinking of it wrong,
or need to create subclasses like NullableInteger but that seems like I'd be
reinventing the wheel a bit.
Perhaps I'm just using it wrong; how are other users handling optional
Repoze-dev mailing list