W dniu 03.04.2012 15:55, Tom Christie pisze:
It breaks the problem down into two very well defined tasks.
1. Convert native datatypes to/from data streams. (eg. Tastypie's
serializers
<https://github.com/toastdriven/django-tastypie/blob/master/tastypie/serializers.py>,
REST framework's renderers
<https://github.com/tomchristie/django-rest-framework/blob/master/djangorestframework/renderers.py>
& parsers
<https://github.com/tomchristie/django-rest-framework/blob/master/djangorestframework/parsers.py>)
2. Convert complex objects to/from native datatypes. (eg. Tastypie's
hydrate/dehydate, REST frameworks serializer
<https://github.com/tomchristie/django-rest-framework/blob/master/djangorestframework/serializer.py>,
form based deserialization
<https://github.com/tomchristie/django-rest-framework/blob/master/djangorestframework/resources.py>)
In your proposal you've understandably addressed model serialization
in detail, but I (personally) think it'd be worthwhile breaking things
down a little bit more.
For example, you might consider the following:
1. Define a base API for part (1). Is it handled by a single class
with instance methods for converting in each direction, or by
two separate classes?
I read your code from last year. We have different aproach to
serialization. Mayby I am wrong with my understanding of two phase
serialization. You in part (1) don't think about target format
(xml/json/...). I assumed you have API in part (2) to deal with it.
In my solution user should (but it is not reguired) think about format
in first phase:
e.g
In present django serialization we have:
For json
fields : {
first_field : ...
second_field : ...
}
But in xml:
<field name=first_field>...
<field name=second_field>..
I don't see how you do it in your proposal. You only specify 'fields' in
Meta.fields.
In my proposal there is need for two Serializers definition but it's
simple and one can inherite from other.
I specify JSONSerializer and XMLSerializer for backward compatibility.
In my solution I can provide one Serializer for all formats:
class PKField(Field):
def dehydrate__value__(self, field):
return smart_unicode(self.instance._get_pk_val(),
strings_only=True)
def hydrate__value__(self, field):
self.instance.set_pk_val(field)
class ModelField(Field):
def dehydrate__value__(self, field):
return smart_unicode(obj._meta)
class AllSerializer(ModelSerializer):
pk = PKField()
model = ModelField()
class Meta:
aliases = {'__fields__' : 'fields'}
relation_serializer = FlatSerializer
If we render it to json we get:
{
pk : ... ,
model : ...,
fields : {
}
}
It's what we want. But in xml:
<object>
<pk>...
<model>...
<fields>only_field_value</fields>
<fields>...
...
</object>
Ups :/
What about formats that are one direction only? (eg. You might
want to parse HTTP form data, but you're unlikely to want to render it.)
Are formats that are not fully reversible an issue? (eg. Some
formats [eg csv?] might not have native representations of all the
python datatypes, and only have string representations.)
Present django solution support only xml json and yaml, so far I
consider only these formats. If other format can be serialized from my
native types or deserialized to it, it can be handled.
If some information about object are losed in
serialization-deserialization then I try construct model only from what
I get. I won't save it. It's user problem. Mayby he wants to add some
other informations from request (you mention it in point 7)
Some things I was slightly confused by in your proposal as it stands...
* JSONSerializer subclassing Serializer. (and XMLSerializer
subclassing JSONSerializer.)
I'd have thought that if you're using a two phase approach you'd
keep the complex<->native and native<->data stream APIs totally decoupled.
JSON serialization doesn't itself have anything to do with how you
choose to structure the serialization of a complex object, so why
should it subclass the implementation of that part?
I hope it's clear now?
* "dehydrate__value__", "hydrate__value__" - what's with the double
underscore naming?
It should be __value__ - default value returns by field. It is
special method. If you do in field:
def some_name(...):
return "test"
Then you get field_name : { some_name : test}
But __value__ is special:
field_name : return_of__value__
or field_name : {
some_name : test,
return_of__name__ : return_of __value__
}
But this is theory. I have dehydrate__xxx for serialization xxx
value. So I should have dehydrate____value__. Ugly :/ So there is value__
It should be rewrite.
* I don't get the '@attribute' decorator. I think it'd be simpler to
just have 'fields', 'include', 'exclude'. If fields is None then use
the 'default set of fields' + 'include' - 'exclude'. If fields is not
None, use that and ignore include/exclude.
Attribute is for xml attribute <field name=someting>...</field>
* I wouldn't consider special casing for XML serialization in the
complex<->native stage. Sure, yeah, make sure there's an XML
implementation that can handle the current Django XML serialization
structure, but anything more than that and you're likely to end up
muddying the API for a special case of data format.
* 'relation_reserialize' - Why is that needed?
class Photo
sender = User
person_on_photo = User
If p.sender=p.person_on_photo - mayby we want to serialize this two
times or mayby we want ony sender : {serialized_sender}, person_on_photo
: 10
* 'object_name' - It's not obvious to me if that's necessary or not.
Now every serialized object in XML (in root) is <object>...</object>.
What if we want <obj></obj>. We use object_name="obj"
* "In what field of serialized input is stored model class name" -
What about when the class name isn't stored in the serialization data?
First problem is what type of object is in serialized input. There are
two way to find it. You can pass Model class as argument to
serialization.serialize or specify in Meta.model_name what field
contains information about type.
* "dehydrate__xxx redefining serialization for type xxx." I'm not
convinced about that - it's not very pythonic to rely on
type hierarchy in preference to duck typing.
Suppose our model has 10 DateTimeFields. And we want only to serialize
Date. We use dehydrate__datetime to do it.
Cheers,
Tom
Thanks for your reply.
--
Piotr Grabowski
--
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.