@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.