|
DjangoFullSerializers
Documentation and examples for the Wad of Stuff Django Full Serializers
IntroductionThe wadofstuff.django.serializers python module extends Django's built-in serializers, adding 3 new capabilities inspired by the Ruby on Rails JSON serializer. These parameters allow the developer more control over how their models are serialized. The additional capabilities are:
Serialization FormatsThe module currently support serializing to JSON and Python only. SourceThe latest stable release for the serialization module can be obtained by:
The latest development source can be obtained here: ExamplesProject SettingsYou must add the following to your project's settings.py to be able to use the JSON serializer. SERIALIZATION_MODULES = {
'json': 'wadofstuff.django.serializers.json'
}Backwards CompatibilityThe Wad of Stuff serializers are 100% compatible with the Django serializers when serializing a model. When deserializing a data stream the the Deserializer class currently only works with serialized data returned by the standard Django serializers. >>> from django.contrib.auth.models import Group
>>> from django.core import serializers
>>> print serializers.serialize('json', Group.objects.all(), indent=4)
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session",
"permissions": [
19
]
}
}
]Excludes>>> print serializers.serialize('json', Group.objects.all(), indent=4, excludes=('permissions',))
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session"
}
}
]ExtrasThe extras option allows the developer to serialize properties of a model that are not fields. These properties may be almost any standard python attribute or method. The only limitation being that you may only serialize methods that do not require any arguments. For demonstration purposes in this example I monkey patch the Group model to have a get_absolute_url() method. >>> def get_absolute_url(self):
... return u'/group/%s' % self.name
...
>>> Group.get_absolute_url = get_absolute_url
>>> print serializers.serialize('json', Group.objects.all(), indent=4, extras=('__unicode__','get_absolute_url'))
[
{
"pk": 2,
"model": "auth.group",
"extras": {
"get_absolute_url": "/group/session",
"__unicode__": "session"
},
"fields": {
"name": "session",
"permissions": [
19
]
}
}
]RelationsThe Wad of Stuff serializers allow you to follow related fields of a model to any depth you wish and serialize those as well. This is why it is considered a "full serializer" as opposed to Django's built-in serializers that only return the related fields primary key value. When using the relations argument to the serializer you may specify either a list of fields to be serialized or a dictionary of key/value pairs. The dictionary keys are the field names of the related fields to be serialized and the values are the arguments to pass to the serializer when processing that field. >>> print serializers.serialize('json', Group.objects.all(), indent=4, relations=('permissions',))
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session",
"permissions": [
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_session",
"name": "Can add session",
"content_type": 7
}
}
]
}
}
]Only serializing a particular field of a relation>>> print serializers.serialize('json', Group.objects.all(), indent=4, relations={'permissions':{'fields':('codename',)}})
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session",
"permissions": [
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_session"
}
}
]
}
}
]Serializing a relation of a relation>>> print serializers.serialize('json', Group.objects.all(), indent=4, relations={'permissions':{'relations':('content_type',)}})
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session",
"permissions": [
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_session",
"name": "Can add session",
"content_type": {
"pk": 7,
"model": "contenttypes.contenttype",
"fields": {
"model": "session",
"name": "session",
"app_label": "sessions"
}
}
}
}
]
}
}
]Excluding a field from a relation of a relation>>> print serializers.serialize('json', Group.objects.all(), indent=4, relations={'permissions':{'relations':{'content_type':{'excludes':('app_label',)}}}})
[
{
"pk": 2,
"model": "auth.group",
"fields": {
"name": "session",
"permissions": [
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_session",
"name": "Can add session",
"content_type": {
"pk": 7,
"model": "contenttypes.contenttype",
"fields": {
"model": "session",
"name": "session"
}
}
}
}
]
}
}
]
|
Sign in to add a comment
Extremely helpful - thank you.
Brilliant serializer, proven very useful. Thanks a lot
The 'extras' facility has just saved me heaps of time - I had no idea why it wasn't being serialized, and fortunately found your post.
many thanks! tone
I've passed on this link to the guys doing great work at the Washington Times <http://opensource.washingtontimes.com/> as they (Justin) have been working on a terrific django app called django-apibuilder which is a beautiful fit for this serializer.
yes, the wad is right now being used in the development branch of the django-apibuilder
Short question about the possibilities to serialize fields inherited by subclassing a django model. There's basically something like this:
from django.db import models class BaseModel(models.Model): name = models.CharField() class InheritModel(BaseModel): content = models.TextField() class OtherModel(BaseModel): date = models.DateTimeField()serializing either InheritModel? or OtherModel? does not yield serialization of the name field of BaseModel?, and I couldn't find how to make the link to the related field on a quick glance. Tried both of these options
serialize('json',InheritModel.objects.all(), relations = {'basemodel':{'fields':('name',)}}) serialize('json',InheritModel.objects.all(), relations = {'basemodel_ptr':{'fields':('name',)}}) # which is the fields name specified via InheritModel._metaAny suggestions on how to solve, or would it need to add some more code to the Serializer class?
Cheers
PS: BaseModel? is not an abstract = True class.
Well, looked a bit more into it and figured out, that django.db.models.fields.OneToOneField , which handles inheritance, is set to serialize = False on inheritance which skipped the serialization. I've added another loop which iterates over <obj>._meta.parents and updates self._fields with the values from the parent's object fields. You'll find the the svn diff in the issues. Hope I was able to enhance this awesome serializer. :)
Cheers,
How to i serialize infinite model Tree, like this:
class Item(models.Model):
thank you
You have to explicitly specify to depth you want to serialize to. e.g this will serial 3 relations deep.
>>> print serializers.serialize('json', Group.objects.all(), indent=4, relations={ 'parent_item':{ 'relations':{ 'parent_item':{ 'relations':('parent_item',) } } } })Brilliant serializer, using it in a few django apps. What is the best way to use it with the google app engine?
Thanks in advance.
Hi,
Sorry I haven't tried it with GAE. If you can get it working let me know and pass along any patches.
I am having little trouble when trying to serialize a model created by multi-table model inheritance.
I have tracked down the source to the fact that django marks the link from model to it's parent (OneToOneField?) with serialize=False. This results in not serializing the field by the serializer.
I need to serialize the fields from the parent as well.
Do you have some hint how to prevent Django from marking it up like this?
In the extras documentation you say: These properties may be almost any standard python attribute or method.
But it seems to me (from experimentation) that they can't be any attribute, they have to be a method that takes no arguments.
In addition if this method returns anything other than a string then the object is serialized as a string. I need to serialize a list of dictionaries and this is coming out as a string in the json.
This makes me a sad bunny as I then have to serialize it myself. :-(
Great work on the serializer, thank you very, very much!