from collections import OrderedDict from rest_framework.fields import empty from django.utils.functional import cached_property class Mixin(object): ordered = False def __init__(self, *args, **kwargs): self.ordered = kwargs.pop('ordered', self.ordered) super(Mixin, self).__init__(*args, **kwargs) def obj_to_representation(self, obj): data = [(f, getattr(obj, f.field_name)) for f in self.repr_fields] if self.ordered: return OrderedDict( [(f.field_name, f.to_representation(val) if val else None) for f, val in data]) else: return dict( [(f.field_name, f.to_representation(val) if val else None) for f, val in data]) def dict_to_representation(self, d): data = [(f, d.get(f.field_name, None)) for f in self.repr_fields] if self.ordered: return OrderedDict( [(f.field_name, f.to_representation(val) if val else None) for f, val in data]) else: return dict( [(f.field_name, f.to_representation(val) if val else None) for f, val in data]) @cached_property def repr_fields(self): return [field for field in self.fields.values() if (not field.read_only) or (field.default is not empty)] obj_to_representation = Mixin.obj_to_representation dict_to_representation = Mixin.dict_to_representation