def from_json(cls, json_str, created=False, *args, **kwargs):
"""
Decode from human-readable json.
Parameters:
json_str: JSON string that should be passed to the serialized
created: a parameter that is passed to cls._from_son.
*args, **kwargs: Any additional arguments that is passed to
json.loads.
"""
from .fields import FollowReferenceField
hook = generate_object_hook(cls)
if "object_hook" not in kwargs:
kwargs["object_hook"] = hook
dct = json.loads(json_str, *args, **kwargs)
for name, fld in cls._fields.items():
if any([
getattr(fld, "exclude_from_json", None),
getattr(fld, "exclude_json", None)
]):
dct.pop(name, None)
from_son_result = cls._from_son(SON(dct), created=created)
@singledispatch
def normalize_reference(ref_id, fld):
"""Normalize Reference."""
return ref_id and fld.to_python(ref_id) or None
@normalize_reference.register(dict)
def normalize_reference_dict(ref_id, fld):
"""Normalize Reference for dict."""
return fld.to_python(ref_id["id"])
@normalize_reference.register(list)
def normalize_reference_list(ref_id, fld):
"""Normalize Reference for list."""
return [
normalize_reference(ref.id, fld) for ref in ref_id
]
for fldname, fld in cls._fields.items():
target = fld.field if isinstance(fld, db.ListField) else fld
if not isinstance(target, db.ReferenceField) or \
isinstance(target, FollowReferenceField):
continue
value = dct.get(fldname)
setattr(
from_son_result, fldname,
normalize_reference(getattr(value, "id", value), target)
)
return from_son_result
评论列表
文章目录