def parse_nested(cls, instance, field, nested, datas):
if field.many_to_one or field.one_to_one:
datas = (datas, )
ps = []
# Fun caveat of throwing everything into JSON, it doesn't support datetimes. Everything gets sent back as iso8601 strings
# Make a list of all fields that should be datetimes and parse them ahead of time
dts = [i for i, f in enumerate(field.related_model._meta.concrete_fields) if isinstance(f, models.DateTimeField)]
for data in datas or []:
if data is None:
ps.append(None)
continue
data, nested_data = data[:-len(nested) or None], data[-len(nested):]
for i in dts:
data[i] = util.parse_datetime(data[i])
# from_db expects the final argument to be a tuple of fields in the order of concrete_fields
parsed = field.related_model.from_db(instance._state.db, None, data)
for (f, n), d in zip(nested.items(), nested_data):
cls.parse_nested(parsed, f, n, d)
if field.remote_field.concrete:
setattr(parsed, field.remote_field.get_cache_name(), instance)
ps.append(parsed)
if (field.many_to_one or field.one_to_one) and ps:
return setattr(instance, field.get_cache_name(), ps[0])
if not hasattr(instance, '_prefetched_objects_cache'):
instance._prefetched_objects_cache = {}
if hasattr(field, 'get_accessor_name'):
accessor_name = field.get_accessor_name()
else:
accessor_name = field.name
# get_queryset() sets a bunch of attributes for us and will respect any custom managers
instance._prefetched_objects_cache[field.name] = getattr(instance, accessor_name).get_queryset()
instance._prefetched_objects_cache[field.name]._result_cache = ps
instance._prefetched_objects_cache[field.name]._prefetch_done = True
评论列表
文章目录