def update_from_form(instance, form_data=None):
mapper = inspect(instance.__class__)
cols = {c.key: c for c in mapper.columns if not c.foreign_keys}
setables = dict(pyinspect.getmembers(
instance.__class__, lambda p:
pyinspect.isdatadescriptor(p) and getattr(p, 'fset', None)))
relns = {r.key: r for r in mapper.relationships if not r.uselist and
len(r._calculated_foreign_keys) == 1 and iter(
r._calculated_foreign_keys).next().table == mapper.local_table
}
unknown = set(form_data.keys()) - (
set(cols.keys()).union(set(setables.keys())).union(set(relns.keys())))
if unknown:
raise HTTPBadRequest("Unknown keys: "+",".join(unknown))
params = dict(form_data)
# type checking
columns = {c.key: c for c in mapper.columns}
for key, value in params.items():
if key in relns and isinstance(value, string_types):
val_inst = relns[key].class_.get_instance(value)
if not val_inst:
raise HTTPBadRequest("Unknown instance: "+value)
params[key] = val_inst
elif key in columns and isinstance(columns[key].type, DeclEnumType) \
and isinstance(value, string_types):
val_det = columns[key].type.enum.from_string(value)
if not val_det:
raise HTTPBadRequest("Cannot interpret " + value)
params[key] = val_det
elif key in columns and columns[key].type.python_type == datetime.datetime \
and isinstance(value, string_types):
val_dt = datetime.datetime.strpstr(value)
if not val_dt:
raise HTTPBadRequest("Cannot interpret " + value)
params[key] = val_dt
elif key in columns and columns[key].type.python_type == int \
and isinstance(value, string_types):
try:
params[key] = int(value)
except ValueError:
raise HTTPBadRequest("Not a number: " + value)
elif key in columns and not isinstance(value, columns[key].type.python_type):
raise HTTPBadRequest("Value %s for key %s should be a %s" % (
value, key, columns[key].type.python_type))
try:
for key, value in params.items():
setattr(instance, key, value)
except:
raise HTTPBadRequest()
评论列表
文章目录