After a few days' consideration, I've got some more crystalized
details about my proposal.

Here are the target result if this proposal is implementated:

1. User could configure serialization for each model.

2. In fact, user could configure the serialization details down to
each field of each model. That means:

3. The key name of each field would be freely defined, the value would
be freely and dynamically defined.

4. Nested structure could be represented as either fk or get
serialized as substructures in the result.

5. The depth of serializaton can be defined, again, down to each
field.

6. Various bonuses. e.g. "sorters" for serialized result, values
that's not from the query set, etc.


First off, the current assumption on the structure of a Model, as far
as serialization is concerned, should be changed. I propose that we
look at the model as a flat key-value structure, that is, pk and model
name (and potentially other metadata) are no different to a user-
defined field.

That is the base of everything below. So from now on, I'll stop
distinguishing user-defined fields, pk and metadata in my discussion,
and call them "fields" instead.

I want to add APIs targeting two level of abstraction:

"class SerializedModel": used to customize how each model is
serialized.

"class SerializedField": used to customize how each field is
serialized.

They are to be subclassed by user, serving as configuration for
serialization. SerializedModel will be passed as options to the actual
serializaton module and be referenced to through out the process.

How to achieved those goals in my claim? Let's see what's in those
classes.

The meat of things lies in the SerializedField class, I want to
introduce the proposed attributes of this class one by one, along each
I'll try explain my reasoning behind it and it's relevance to my
goals.

Some "regular" parts of a field:

"key_name": the name to be used for this field, defaults to the field
name(pk, model, album). This allows user to represent the field in
whatever name they want.

"with_type": a boolean, this let user deside whether the type of this
field should be part of the result.

"value_format": default to string repr of the field value, but if the
user want, she can assign a function to value_format to twist the
value however she like and return. More on this attr below.

"belongs_to": where in the result does the field go, default to top
level. If we were to mimic the current serialization format, this
value for all the user-defined fields would be "field".

"as_tag": a boolean. This is here specifically for XMLSerializer. If
set false, it causes the field to be rendered as attrs. There's more
on this part below.

If the field references to other models, these addtional attrs for
SerializedField would be used:

"rel_name": similar to "key_name", but it is for the relation type, if
renderd. defaults to "rel", as it would be if we were to mimic current
XML format.

"rel_to_name": similar to "key_name" and "rel_name", the key in the
result whose value is the model this field points to.

"with_rel": boolean, determines whether the two fields above shoud be
part of the result.

"embed_level": an integer. This is my answer to the question "how to
handle nested objects?". And it deserves its own paragraph.

For a reference-typed field, the value of SerializedField.value_format
should be an instance of SerializedField. If "embed_level" is 0, then
only the foreign key will be rendered. If it is greater than 0, then
the serializer should go ahead and serialize whatever this field
points to according to the info contained in "value_format".
"embed_level" would be initialized each time an instance of
SerializedField is instantiated, which happens when the serializer
discovers embed_level > 0. Another related note is, when "embed_level"
> 0, "as_tag" would be forced to be True.


Compare to SerializedField, SerializedModel is much simpler. It's
function is no more than holding info about which field should be
included in the serialization, and mapping the wanted field to its
SerializedField instance. Inspired by contrib.admin.ModelAdmin,
SerializedModel has two attributes:

"exclude": a list of unwelcomed fields referenced by their str names.

"fields": a dict whose keys are str names of wanted fields, and the
values are SerializedField instances.

If nessacery, a "sorter" fields which accept a sorter function for the
result serialization might be included as well.

The new serialization framework would include default
SerializationField for all the "native" field types, so that users
don't have to create one for each fields.

Here's an illustration of how a simple use case looks like, taking the
models from the tutorial as an example:

class SerializedChoiceText(DefaultSerializedCharField):
    key_name = "choice_text"
    value_fmt = lambda x: x.lowercase()
    as_tag = True # default value
    belongs_to = "field"

class SerializedChoice(DefaultSerializedModel):
    exclude = ["votes"]
    fields = {
        'pk': DefaultSerialiazedPkField(),
        'classname': DefaultClassnameSeializedField(),
        'choice': SerializedChoiceText(),
        'poll': DefaultSerializedFkField(
            embed_level=1,
            value_fmt=DefaultSerializedModel()
        )
    }

data = serializer.serialize('xml', Choice.objects.all(),
SerializedChoice())

data would contain something similar to what the current XMLSerializer
yields except:

    1. No votes number.

    2. The tag for poll now contains a sublevel tag that has a
serialized poll object in it.

    3. The text of the choise is in lowercase.

And that roughly covers the API design in my proposal.

In implementation, the structure of the serializers should be somewhat
similar to the current ones, since the whole idea is to add more
configurations.

Yours,
DaNmarner

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to