On Fri, Mar 25, 2011 at 6:03 PM, Vivek Narayanan <m...@vivekn.co.cc> wrote:
>> I think I see where you're going here. However, I'm not sure it
>> captures the entire problem.
>>
>> Part of the problem with the existing serializers is that they don't
>> account for the fact that there's actually two subproblems to
>> serialization:
>>
>>  1) How do I output the value of a specific field
>>  2) What is the gross structure of an object, which is a collection of
>> fields plus, plus metadata about an object, plus
>>
>> So, for a single object the JSON serializer currently outputs:
>>
>> {
>>     "pk": 1,
>>     "model": "myapp.mymodel",
>>     "fields": {
>>         "foo": "foo value",
>>         "bar": "bar value"
>>     }
>>
>> }
>>
>> Implicit in this format is a bunch of assumptions:
>>
>>  * That the primary key should be rendered in a different way to the
>> rest of the fields
>>  * That I actually want to include model metadata like the model name
>>  * That the list of fields is an embedded structure rather than a list
>> of top-level attributes.
>>  * That I want to include all the fields on the model
>>  * That I don't have any non-model or computed metadata that I want to 
>> include
>
> I believe that my model of using a recursive method and storing
> temporary data in 'levels' would address most of these concerns. The
> method for handling a model would consist of the following steps,
> roughly:
>
>   * Get the list of fields to be serialized.

For a suitably relaxed definition of "field". Remember, serialized
data doesn't necessarily have to come from the model -- it could come
from a related model, or be a constant, or be a computed field, or
many other options.

>> When you start dealing with foreign keys and m2m, you have an
>> additional set of assumptions --
>>
>>  * How far should I traverse relations?
>
> The user can specify a limit to the levels of nesting through
> variable ``max_nesting_depth``.

A simple "nesting depth" approach won't work. You really need to
handle this on a per-model basis; Mode

It might be possible to automate some of this with a simple nesting
depth definition, but there will always be a need to define the exact
rollout of a tree of serialization options.

This is also a case where being explicit makes your life easier. If
you stop looking at "depth" as a single number specified at the top of
the tree, it becomes a lot easier to handle recursive or

>>  * Do I traverse reverse relations?
>
> In my opinion, traversing reverse relations can get really ugly at
> times, especially when there are M2M fields, foreign keys or circular
> relations involved. But there are some scenarios where the data is in
> a relatively simpler format and serializing them would be useful. To
> support this, I thought of something like this:
>
> class Srz(Serializer):
>   ...
>   reverse_relations = [ (from_model_type, to_model_type), ... ]
>
> But this should be used with caution and avoided when possible.
>
>>  * How do I represent traversed objects? As FK values? As embedded objects?
>
> As embedded objects, if the nesting depth limit is reached, then as FK
> values.

My point is that this is a serialization option. You're dictating a
policy here, rather than allowing it to be a configuration option.

>>  * If they're embedded objects, how do I represent *their* traversed values?
>
> Their traversed values would be represented just as a normal model
> would be, with field-value mappings. The user can choose which fields
> to dump.

Again -- you're dictating a policy, not allowing the user to define one.

>>  * What happens with circular relations?
>
> For all model type objects, like the base model in the query set and
> all FK and M2M fields, some uniquely identifying data (like the
> primary key, content type) will be stored in a list as each one of
> them is processed. Before serializing a model, it would be checked if
> the model is already on the list or not. If it is there, it is a
> circular reference and that model would be ignored .
>
>>  * If I have two foreign keys on the same model, are they both
>> serialized the same way?
>
> Yes.

Why should this be the case? Again, you are dictating policy, not
allowing policy to be defined.

>> When you start dealing with the XML serializer, you have all these
>> problems and more (because you have the attribute/tag distinction for
>> each of these decisions, too -- for example, I may want some fields to
>> be rendered as attributes, and some as tags.
>>
>
> For XML, I thought of using an intermediary container for a node that
> would store all these details.
>
>> > ---------------------------------------------------------
>> > New features in the serialize() function
>> > ---------------------------------------------------------
>> > Apart from the changes I’ve proposed for the ``fields`` argument of
>> > serialize, I would like to add a couple of features:
>>
>> > • An exclude argument, which would be a list of fields to exclude from
>> > the model, this would also contain the fields to exclude in related
>> > models.
>>
>> > • An extras argument, which would allow properties and data returned
>> > by some methods to be serialized.
>>
>> For me, the goal should be to deprecate these sorts of arguments. The
>> decision to include (or exclude) a particular field is a feature of
>> serialization that is intimately tied to the serialization format, not
>> something that is an external argument.
>>
> Initially, I thought the goal was not to tie down a serializer to any
> model, I can integrate these features into the serializer class then.

My point is that it should be *possible* to define a "generic"
serialization strategy -- after all, that's what Django does right
now. If arguments like this do exist, they should essentially be
arguments used to instantiate a specific serialization strategy,
rather than something baked into the serialization API.

>> > -----------------------------------------------------------------
>> > Representing the existing serialization model
>> > -----------------------------------------------------------------
>> > Here is an implementation of the existing serialization format in
>> > JSON, this would be the ‘fixture’ mode that I’ve mentioned above.
>>
>> I think these examples demonstrate what I said earlier -- your
>> proposed framework allows me to customize the name given to a field in
>> XML, but doesn't allow me to change the parent of that field within
>> the broader XML structure.
>
> I'm not sure that I follow this, It would be great if you could give
> an example. As I mentioned earlier, there will be an option to
> 'flatten' the nested models , provide alternate names to the fields,
> and wrap fields into a group. Initially I had thought of adding this
> to the external ``fields`` argument in ``serialize()``, but I can add
> them to the specification object too.

The recurring theme in my comments is that you are dictating policy,
not allowing users to define policy. We already have the former; we
need the latter.

Heres an example of the problem as I see it. Consider the
serialization of a "book" model.

Option 1: Django's current serializer:

{
   "pk": 1
   "model": "library.book"
   "fields": {
       "authors": [3, 4]
       "editor": 5
       "title": "Django for Dummies"
   }
}

No real surprises here.

Option 2: the format required for a particular book publishing API

{
    "book details": {
        "book title": "Django for dummies"
        "authors": [
             "John Smith",
             "Bob Jones"
        ],
    }
    "author_count": 2,
    "editor": {
        "firstname": "Alice"
        "lastname":  Watson",
        "coworkers": [1, 5],
        "contact_phone": "98761234",
        "company": {
             "name": "Mega publishing corp",
             "founded": 2010
        }
    },
}

Notable features:
 * Authors and editor are both "Person" objects, but
     - We need to serialize editors in detail, including recursive calls
     - Authors are serialized using their combined first+last name
 * "book title" is a rename of the native model field
 * "author_count" isn't on the model at all.
 * "book details" doesn't reflect any aspect of model structure --
it's entirely decoration.

Now - show me how both of these serializers are defined using your
proposed API.

Yours,
Russ Magee %-)

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