Skip to content
This repository has been archived by the owner on Jan 3, 2019. It is now read-only.

Commit

Permalink
Add a custom 3 state boolean schema type.
Browse files Browse the repository at this point in the history
This corrects and issue where if the has_accepted value was None,
it would change the value to True.
  • Loading branch information
mmulich committed Dec 11, 2014
1 parent 9f20214 commit 4d71e37
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion cnxauthoring/schemata.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,66 @@ def deferred_datetime_missing(node, kw):
return dt


class TriStateBoolean(colander.SchemaType):
"""A type representing a boolean object with 3 states.
That is true, false and unknown. These are represented in Python
as True, False and None.
"""

def __init__(self, false_choices=('false', '0',),
true_choices=('true', '1',),
unknown_choices=('none', '',),
true_val=True, false_val=False, unknown_val=None):
self.true_val = true_val
self.false_val = false_val
self.unknown_val = unknown_val
self.false_choices = false_choices
self.true_choices = true_choices
self.unknown_choices = unknown_choices

def serialize(self, node, appstruct):
if appstruct is colander.null:
return colander.null

if appstruct is None:
return self.unknown_val
else:
return appstruct and self.true_val or self.false_val

def deserialize(self, node, cstruct):
_ = colander._
if cstruct is colander.null:
return colander.null
elif cstruct is None:
return None

try:
result = str(cstruct)
except:
raise colander.Invalid(
node,
_('${val} is not a string', mapping={'val':cstruct})
)
result = result.lower()

if result in self.unknown_choices:
state = None
elif result in self.false_choices:
state = False
elif result in self.true_choices:
state = True
else:
raise colander.Invalid(
node,
_('"${val}" is neither in (${false_choices}) '
'nor in (${true_choices})',
mapping={'val':cstruct,
'false_choices': self.false_reprs,
'true_choices': self.true_reprs })
)
return state


class LicenseSchema(colander.MappingSchema):
"""Schema for ``License``"""

Expand Down Expand Up @@ -74,7 +134,7 @@ def schema_type(self, **kw):

class RoleSchema(UserSchema):
has_accepted = colander.SchemaNode(
colander.Boolean(),
TriStateBoolean(),
missing=colander.drop,
)
requester = colander.SchemaNode(
Expand Down

0 comments on commit 4d71e37

Please sign in to comment.