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

Reply via email to