自定义model_to_dict()方法,在model里面加上一个方法
def to_dict(self):
opts = self._meta
data = {}
for f in opts.concrete_fields:
value = f.value_from_object(self)
if isinstance(value, datetime):
value = value.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(f, FileField):
value = value.url if value else None
data[f.name] = value
return data
"""
Why is `__fields` in here?
it holds the list of fields except for the one ends with a suffix '__[field_name]'.
When converting a model object to a dictionary using this method,
You can use a suffix to point to the field of ManyToManyField in the model instance.
The suffix ends with '__[field_name]' like 'publications__name'
"""
__fields = list(map(lambda a: a.split('__')[0], fields or []))
for f in chain(opts.concrete_fields, opts.virtual_fields, opts.many_to_many):
is_edtiable = getattr(f, 'editable', False)
if fields and f.name not in __fields:
continue
if exclude and f.name in exclude:
continue
if isinstance(f, ManyToManyField):
if instance.pk is None:
data[f.name] = []
else:
qs = f.value_from_object(instance)
if qs._result_cache is not None:
data[f.name] = [item.pk for item in qs]
else:
try:
m2m_field = list(filter(lambda a: f.name in a and a.find('__') != -1, fields))[0]
key = m2m_field[len(f.name) + 2:]
data[f.name] = list(qs.values_list(key, flat=True))
except IndexError:
data[f.name] = list(qs.values_list('pk', flat=True))
elif isinstance(f, DateTimeField):
date = f.value_from_object(instance)
data[f.name] = date_to_strf(date) if date_to_strf else date_to_timestamp(date)
elif isinstance(f, ImageField):
image = f.value_from_object(instance)
data[f.name] = image.url if image else None
elif isinstance(f, FileField):
file = f.value_from_object(instance)
data[f.name] = file.url if file else None
elif is_edtiable:
data[f.name] = f.value_from_object(instance)
"""
Just call an instance's function or property from a string with the function name in `__fields` arguments.
"""
funcs = set(__fields) - set(list(data.keys()))
for func in funcs:
obj = getattr(instance, func)
if inspect.ismethod(obj):
data[func] = obj()
else:
data[func] = obj
return data
网友评论