W dniu 06.05.2012 10:45, Russell Keith-Magee pisze:
- I'm not sure I follow how class_name would be used in practice. The
act of deserialization is to take a block of data, and process it to
populate an object.
In the simplest case, you could provide an empty instance (or factory)
that is then populated by deserialization. In this case, no class name
is required -- it's provided explicitly by the object you provide.
I have this functionality with class_name
serializers.deserialize("json", data,
deserializer=UserSerializer(class_name=User))
A more complex case is to use the data itself to determine the type of
object to create. This seems to be the reason you have "class_name",
but I'm not sure it's that simple. Consider a case where you're
deserializing a thing of objects; if the data has a "name" attribute,
create a "Person" object, otherwise create a "Thing" object. The
object required is well defined, but not neatly available in a field.
If we have homogeneous list of object there is no problem. We can use
same construction as above, or depends (by class_name) on some field in
object. But if list is heterogeneous and we havn't information about
type - it's difficult then. There is need for feature like that? My
first thought is to have method in Serializer class like:
get_class(self, data):
# data is object (dict?) produced by first phase of deserialization)
# user can search some field in it and return class for object creation
if 'name' in data:
return Person
return Thing
it can be more like internal API which can be default set to:
get_class(self, data):
if self._meta.class_name is not None:
if isinstance(self._meta.class_name, str):
return object_from_string(data['self._meta.class_name'])
else:
return self._meta.class_name
raise Exception('No class for deserialization provided')
So if someone has simple needs he can use simple functionality like
class_name=Profile, but if there is need to find class by duck typing
philosophy using overwriting get_class will be suitable.
There's also no requirement that deserialization into an object is
handled by a ModelSerializer. ModelSerializer should just be a
convenient factory for populating a Serializer based on attributes of
a model -- so anything you do with ModelSerializer should be possible
to do manually with a Serializer. If class_name is tied to
ModelSerializer, we lose this ability.
Yes, I make a mistake - where I wrote ModelSerializer options I should
wrote Serializer options because ModelSerializer is just Serializer
which understands difference about fields in object (m2m, fk ...)
- I'm not sure I see the purpose of "aliases" -- or, why this role
can't be played by other parts of the system. In particular, I see
Field() as a definition for how to fill out one 'piece' of a
serialised object. Why doesn't Field() contain the logic for how to
extract it's value from the underlying object?
Previously I used it with additional meaning -> if aliases[x] =
aliases[y] then x = [value[x], value[y]], but now it's only shortcut for
writing:
1) fname = Field(label=first_name)
2) aliases = {'fname' :'first_name'}
It's redundant but I think this can be helpful
- Why is preserve_field_ordering needed? Can't ordering be handled by
the explicit order of field definitions, or the ordering in the
"fields" attribute?
I agree, ordering in the 'fields' attribute (like in Forms) will be better.
* As a matter of style, serializer_field_value and
deserialize_field_value seem excessively long as names. Is there
something wrong with serialize and deserialize?
For now I want reserve serialize and deserialize names because I think
these names would be more appropriate for methods that will return
python native datatypes after first phase of serialization. If user
overwrite it he can do anything he want and must return native datatypes.
But sure, (de)serializer_field_value seems to be too long. Any other
propositions? Maybe get_value (because it must get value from object
field for serialization) and set_value (it sets value ob object field in
deserialization) ?
* I don't think getattr() works quite how you think it does. In
particular, I don't think:
getattr(instance, instance_field_name) = getattr(obj, field_name)
will do what you think it does. I think you're looking for setattr() here.
Oops :) Definitely setattr should be there.
* Can you elaborate some more on the XML attribute syntax in your
proposal? One of your original statements (that I agree with) is that
the "format" is independent of the syntax, and that a single set of
formatting rules should be able to be used for XML or for JSON. The
big difference between XML and JSON is that XML allows for values to
be packed as attributes. I can see that you've got an 'attribute'
argument on a Field, but it isn't clear to me how JSON would interpret
this, or how XML would interpret:
I consider this a lot. I have two ideas. JSON will drop fields with
attribute(True) or JSON will treat it like any other. Second is better
in my opinion.
- A Field that had multiple sub-Fields, all of which were attribute=True
- A Field that had multiple sub-Fields, several of which were attribute=False
- The difference between these two definitions by your formatting rules:
<key attr1="val1" attr2="val2">
<subkey>subval</subkey>
</key>
key = KeyField()
class KeyField(Field):
attr1 = A1Field(attribute=True)
attr2 = A2Field(attribute=True)
def field_name(self, obj, field_name):
return 'subkey'
def serialize_field_value(self. obj, field_name):
return 'subval'
Will work in xml and json.
<key attr1="val1" attr2="val2">main value</key>
class KeyField(Field):
attr1 = A1Field(attribute=True)
attr2 = A2Field(attribute=True)
def serialize_field_value(self. obj, field_name):
return 'main_value'
Work in xml but fail in json
key : {
attr1 : 'val1',
attr2 : 'val2',
? : 'main_value'
}
Must raise an exception
I don't know if this is acceptable - same Field will work in xml and
fail in json. This is not the fault of xml attribute. We can fix that by
drop attributes in JSON and ensure that
if subfields in field are declared (and attribute=False in at least one
of them) then there must be also field_name declared
In particular, why is the top level structure of the JSON serializer
handled with nested Serializers, but the structure of the XML
serializer is handled with nested Fields?
I don't understand you. XML serializer is also handled with Serializer:
class XMLDumpDataSerializer(YJDumpDataSerializer)
YJDumpDataSerialzier is JSON serializer and this is Serializer
Yours, Russ Magee %-)
--
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.