from collections import OrderedDict from django.forms.forms import DeclarativeFieldsMetaclass from django import forms from django.utils.encoding import force_unicode from django.utils.functional import Promise def obj_as_dict(o): if isinstance(o, DeclarativeFieldsMetaclass): o = FormSerializer(form=o).data if isinstance(o, forms.Field): o = FormFieldSerializer(field=o).data if isinstance(o, forms.Widget): o = FormWidgetSerializer(widget=o).data if isinstance(o, (list, tuple)): o = [obj_as_dict(x) for x in o] if isinstance(o, Promise): try: o = force_unicode(o) except: # Item could be a lazy tuple or list try: o = [obj_as_dict(x) for x in o] except: raise Exception('Unable to resolve lazy object %s' % o) if callable(o): o = o() if isinstance(o, dict): for k, v in o.items(): o[k] = obj_as_dict(v) return o class BaseSerializer(object): @property def data(self): raise NotImplementedError class FormWidgetSerializer(BaseSerializer): def __init__(self, widget, *args, **kwargs): self.widget = widget @property def data(self): widget_data = OrderedDict() widget_data["type"] = self.widget.__class__.__name__ return widget_data class FormFieldSerializer(BaseSerializer): def __init__(self, field, *args, **kwargs): self.field = field @property def data(self): field_data = OrderedDict() field_data["type"] = self.field.__class__.__name__ field_data["widget"] = self.field.widget field_data["is_required"] = self.field.required return field_data class FormSerializer(BaseSerializer): def __init__(self, form, *args, **kwargs): self.form = form @property def data(self): form_fields = [] for name, field in self.form.base_fields.items(): d = dict() d[name] = field form_fields.append(d) return form_fields #todo check "formfield_overrides" MODEL_ADMIN_CLASS_ATTRIBUTES = ( "raw_id_fields", "fields", "exclude", "fieldsets", "filter_vertical", "filter_horizontal", "radio_fields", "prepopulated_fields", "readonly_fields", "ordering", "view_on_site", "show_full_result_count", "list_display", "list_display_links", "list_filter", "list_per_page", "list_max_show_all", "list_editable", "search_fields", "date_hierarchy","save_as", "save_on_top") class ModelAdminSerializer(BaseSerializer): def __init__(self, model_admin, admin_form, *args, **kwargs): self.model_admin = model_admin self.admin_form = admin_form @property def data(self): data = OrderedDict() for attr in MODEL_ADMIN_CLASS_ATTRIBUTES: data[attr] = getattr(self.model_admin, attr, None) data["form"] = self.admin_form return obj_as_dict(data) def serialize_form(self): return FormSerializer(self.admin_form).data