@Sebastien: I got your point about using a dict as an intermediate structure and the use of recursion, and I looked at your implementation which is somewhat similar to what I have in mind.
Well, here is a list of deliverables for the project: • Investigate existing structure of the serializer, make changes, refactor to suit needs. (1 week) • Implement metadata methods, change the ``fields`` argument of serialize(), write unit tests. (2 weeks) • Implement structures and templates parsing for custom serialization, configurations for XML/JSON/YAML etc. Also, write tests for this. (2 weeks) • Handling of nested and related models. (1 week) • Investigate the changes to be made at deserialization side and implement them. (1 week) • More tests and write documentation. (2 weeks) This is a conservative estimate and am keeping 3 weeks as a cushion. On Mar 3, 7:15 pm, sebastien piquemal <[email protected]> wrote: > Ok ... I have to admit I was not very clear. Here is what I meant, > illustrated with some code examples : > > http://readthedocs.org/docs/django-serializers-draft/en/latest/index.... > > These are my "dream" django-serializers ! > > On Mar 1, 10:20 am, Vivek Narayanan <[email protected]> wrote: > > > @Sebastien, Thank you for your suggestions, that's exactly what I had > > considered. > > > As I've mentioned earlier, I would like to start with providing basic > > XML, JSON, YAML and text serializers, that would be built on the > > existing base structure with a few modifications, as building blocks. > > But before I start with the class structure, let me describe a feature > > that I would be adding for the purpose of metadata. > > > Metadata Methods > > --------------------------- > > The user can define methods beginning with “meta_” to add metadata > > about each field. And functions starting with “meta2_” can be used to > > add metadata at the model level. Here is an example: > > > class ExampleSerializer(serializers.Serializer): > > ... > > def meta_foo(self, field): > > ''' > > Extract some metadata from field and return it. > > It would be displayed with the attribute ``foo`` > > ''' > > > In JSON the metadata would be represented inside an object as > > "key": {"foo": "bar", "value": value} > > instead of > > "key": value > > > In XML, two options would be provided, to represent the metadata as > > individual tags or with tag attributes, through a field option in the > > class. > > metadata_display_mode = TAGS #or ATTRIBUTES > > > TAGS > > --------- > > <field> > > <metadata1>..</metadata1> > > ... > > <Value>Value</Value> > > </field> > > > ATTRIBUTES > > --------------------- > > <field name="" metadata1 = "" ... > Value </field> > > > To select which fields would have which metadata, the arguments should > > be passed in the ``serialize()`` method as > > data = ExampleSerializer.serialize(queryset, fields = ('field1', > > ('field2',['foo']) ) > > > Each field can be specified in two ways: > > > 1. As a string:-> no metadata will be added. > > > 2. As a 2-element tuple, with the first element a string representing > > field name and the second a list of strings representing the metadata > > attributes to be applied on that field. > > > Instead of manually specifying the attributes for each field, the user > > can add all metadata functions for all the fields using the > > ``use_all_metadata`` parameter in ``serialize()`` > > use_all_metadata = True > > > The existing implementation of ``model.name`` and ``model.pk`` can be > > described using “meta2_” functions. These will be provided as > > ``meta2_name`` and ``meta2_pk`` to facilitate loading and dumping of > > fixtures. > > > Basic Structure > > ------------------------ > > Now coming to the basic structure of the fields. This need not be > > specified for JSON/YAML as this will be handled by the libraries. > > > For text based serializers a custom template would be provided: > > > class TextSerializer(Serializer): > > mode = "text" > > field_format = "%(key)s :: { %(value)f, %(meta_d1)s, %(meta_d2)}" > > # Simple string template, meta_xxx would be replaced by > > meta_xxx(field) if meta_xxx is callable > > > #The three parameters below are required for text mode > > field_separator = ";" > > wrap_begin = "[[" # For external wrapping structure > > wrap_end = "]]" > > > indent = 4 #indent by 4 spaces, each level. Default is 0. Used for > > text and xml modes only > > > For markup based serializers, users can provide strings for the tag > > names of fields, field values and models. > > > class XMLSerializer(Serializer): > > mode = "xml" > > indent = 2 > > metadata_display_mode = TAGS > > > field_tag_name = "object" # Now all fields will be rendered as > > <object>...</object> > > model_tag_name = "model" > > value_tag_name = "value" # if metadata_display_mode is set to > > ``TAGS``, this sets the tag name of the value of the model field > > > A class field ``wrap_fields`` will be provided to wrap all fields of a > > model into a group, as it is done now. If ``wrap_fields`` is set as > > “all_fields” for example. Then all the fields would be serialized > > inside an object called “all_fields”. If ``wrap_fields`` is not set, > > there will be no grouping. > > > Nesting and Related Models > > ------------------------------------------ > > I will modify the current “start_object -> handle_object -> > > end_object” sequence with a single method for handling a model, so > > that related models can be handled easily using recursion. An option > > of ``nesting_depth`` would be provided to the user as a field > > variable. Default value would be 0, as it is currently. Serializing > > only specific fields of related models can be done by using the fields > > argument. A related model would be represented as > > “Model_name.field_name” instead of just “field_name”. > > > Datatypes and conversion > > ---------------------------------------- > > The user can specify the protected types (the types that will be > > passed “as is” without any conversion) as a field variable. > > > The unicode conversion functions for each type can be specified as > > methods - “unicode_xxx”, where 'xxx' represents the type name. If no > > method is provided for a type, a default conversion function will be > > used. > > > class Example(Serializer): > > ... > > protected_types = (int, str, NoneType, bool) > > ... > > def unicode_tuple(self, object): > > # Do something with the object > > > Representing the existing serialization format > > ------------------------------------------------------------------ > > Here is an implementation of the existing serialization format in > > JSON: > > > class JsonSerializer(Serializer): > > mode = "json" > > wrap_fields = "fields" > > nesting_depth = 0 > > > def meta2_pk(self, model): > > '''This method is not required to be overridden as a default > > method would be provided''' > > def meta2_model(self, model): > > ... > > > In XML > > > class XMLSerializer(Serializer): > > mode = "xml" > > wrap_fields = "fields" > > nesting_depth = 0 > > metadata_display_mode = ATTRIBUTES > > indent = 4 > > > field_tag_name = "field" > > model_tag_name = "object" > > > def meta2_pk(self, model): > > ... > > def meta2_model(self, model): > > ... > > def meta_type(self, field): > > ... > > > Sincerely, > > > Vivek Narayanan -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
