Converts an instance to a dictionary form

        Args:


            attrs_to_serialize (list of str):  The columns which should
                be serialized as a part of the output dictionary

            key_modifications (dict of str,str): A dictionary used to map
                the display names of columns whose original name we want
                to be modified in the json

            rels_to_serialize (list of tuple of str):  A list of tuples. The
                first element of the tuple is the relationship
                that is to be serialized. The second element it the name of the
                attribute in the related model, the value of which is to be used
                as the representation

            rels_to_expand (list of str): A list of relationships to expand.
                You can specify nested relationships by placing dots.

            group_listrels_by (dict of str, list of str): A dictionary
                representing how to hierarchially group a list like relationship.
                The relationship fields are the keys and the list of the attributes
                based on which they are to be grouped are the values.

def todict(self, attrs_to_serialize=None,
               rels_to_expand=None,
               rels_to_serialize=None,
               group_listrels_by=None,
               key_modifications=None,
               dict_struct=None,
               dict_post_processors=None):

        """Converts an instance to a dictionary form

        Args:


            attrs_to_serialize (list of str):  The columns which should
                be serialized as a part of the output dictionary

            key_modifications (dict of str,str): A dictionary used to map
                the display names of columns whose original name we want
                to be modified in the json

            rels_to_serialize (list of tuple of str):  A list of tuples. The
                first element of the tuple is the relationship
                that is to be serialized. The second element it the name of the
                attribute in the related model, the value of which is to be used
                as the representation

            rels_to_expand (list of str): A list of relationships to expand.
                You can specify nested relationships by placing dots.

            group_listrels_by (dict of str, list of str): A dictionary
                representing how to hierarchially group a list like relationship.
                The relationship fields are the keys and the list of the attributes
                based on which they are to be grouped are the values.


        """

        # Never replace the following code by the (attrs = attrs or
        # self._attrs_) idiom. Python considers empty list as false. So
        # even if you pass an empty list, it will take self._x_ value. But
        # we don't want that as the empty list is what we use to end
        # the recursion
        dict_struct = (
            self._dict_struct_ if dict_struct is None
            else dict_struct)
        if dict_struct is None:
            dict_struct = self.autogenerated_dict_structure()
        if dict_struct is not None:
            return self.todict_using_struct(
                dict_struct=dict_struct,
                dict_post_processors=dict_post_processors)
        attrs_to_serialize = (
            self._attrs_to_serialize_ if attrs_to_serialize is None
            else attrs_to_serialize)
        rels_to_serialize = (
            self._rels_to_serialize_ if rels_to_serialize is None
            else rels_to_serialize)
        rels_to_expand = (
            self._rels_to_expand_ if rels_to_expand is None
            else rels_to_expand)
        key_modifications = (
            self._key_modifications_ if key_modifications is None
            else key_modifications)
        group_listrels_by = (
            self._group_listrels_by_ if group_listrels_by is None
            else group_listrels_by)
        # Convert rels_to_expand to a dictionary
        rels_to_expand_dict = {}
        for rel in rels_to_expand:
            partitioned_rels = rel.partition('.')
            if partitioned_rels[0] not in rels_to_expand_dict:
                rels_to_expand_dict[partitioned_rels[0]] = (
                    [partitioned_rels[-1]] if partitioned_rels[-1]
                    else [])
            else:
                if partitioned_rels[-1]:
                    rels_to_expand_dict[partitioned_rels[0]].append(
                        partitioned_rels[-1])

        # # Convert grouplistrelsby to a dict
        # group_listrels_dict = {}
        # for rel_to_group, grouping_keys in group_listrels_by.iteritems():
        #     partitioned_rel_to_group = rel_to_group.partition('.')
        #     if partitioned_rel_to_group[0] not in group_listrels_dict:
        #         group_listrels_dict[partitioned_rel_to_group[0]] = (
        #             {partitioned_rel_to_group[-1]: grouping_keys}
        #             if partitioned_rel_to_group[-1] else grouping_keys)
        #     else:
        #         if partitioned_rel_to_group[-1]:
        #             group_listrels_dict[
        #                 partitioned_rel_to_group[0]][
        #                     partitioned_rel_to_group[-1]] = grouping_keys

        # Serialize attrs
        result = self.serialize_attrs(*attrs_to_serialize)

        # Serialize rels
        if len(rels_to_serialize) > 0:
            for rel, id_attr in rels_to_serialize:
                rel_obj = getattr(self, rel) if hasattr(self, rel) else None
                if rel_obj is not None:
                    if is_list_like(rel_obj):
                        if (group_listrels_by is not None and
                                rel in group_listrels_by):
                            result[rel] = deep_group(
                                rel_obj,
                                attr_to_show=id_attr,
                                keys=group_listrels_by[rel]
                            )
                        else:
                            result[rel] = [getattr(item, id_attr)
                                           for item in rel_obj if hasattr(item, id_attr)]
                    elif is_dict_like(rel_obj):
                        result[rel] = {k: getattr(v, id_attr)
                                       for k, v in rel_obj.iteritems()
                                       if hasattr(v, id_attr)}
                    else:
                        result[rel] = getattr(rel_obj, id_attr) if hasattr(
                            rel_obj, id_attr) else None
                else:
                    result[rel] = None

        # Expand some rels
        for rel, child_rels in rels_to_expand_dict.iteritems():
            rel_obj = getattr(self, rel) if hasattr(self, rel) else None
            if rel_obj is not None:
                if is_list_like(rel_obj):
                    if (group_listrels_by is not None and
                            rel in group_listrels_by):
                        result[rel] = deep_group(
                            rel_obj,
                            keys=group_listrels_by[rel], serializer='todict',
                            serializer_kwargs={'rels_to_expand': child_rels}
                        )
                    else:
                        result[rel] = [i.todict(rels_to_expand=child_rels)
                                       if hasattr(i, 'todict') else i
                                       for i in rel_obj]
                        # result[rel] = serialized_list(
                        #     rel_obj, rels_to_expand=child_rels)
                elif is_dict_like(rel_obj):
                    result[rel] = {k: v.todict()
                                   if hasattr(v, 'todict') else v
                                   for k, v in rel_obj.iteritems()}
                else:
                    result[rel] = rel_obj.todict(
                        rels_to_expand=child_rels) if hasattr(
                        rel_obj, 'todict') else rel_obj

        for key, mod_key in key_modifications.items():
            if key in result:
                result[mod_key] = result.pop(key)

        if isinstance(dict_post_processors, list):
            for dict_post_processor in dict_post_processors:
                if callable(dict_post_processor):
                    result = dict_post_processor(result, self)

        return result