- Author:
- alexey-boriskin
- Posted:
- July 14, 2009
- Language:
- Python
- Version:
- 1.0
- Score:
- 0 (after 0 ratings)
Custom serialization, the poor try to make something like django full serializers
Usage: you need two files, goodjson.py and goodpython.py, for example, in the root of application named "core". Then, add two lines into your settings.py:
SERIALIZATION_MODULES = {'goodjson' : 'core.goodjson',
'goodpython': 'core.goodpython'}
This thing does only serialization, not deserialization. You were warned.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | goodjson.py:
from django.core.serializers.json import DateTimeAwareJSONEncoder
from django.core import serializers
from django.db.models.query import QuerySet
from django.db.models import Model
from django.utils import simplejson
from django.core.serializers.python import Serializer as PythonSerializer#, Deserializer as PythonDeserializer
from django.utils.encoding import smart_unicode
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
class ModelAwareJSONEncoder(DateTimeAwareJSONEncoder):
def __init__(self,select_related=False,include_unicode=False,**options):
super(ModelAwareJSONEncoder,self).__init__(**options)
self.select_related = select_related
self.include_unicode = include_unicode
def default(self, o):
if self.select_related:
serializer_name = 'goodpython'
else:
serializer_name = 'python'
if isinstance(o, QuerySet):
serializer = serializers.get_serializer(serializer_name)()
serializer.include_unicode = self.include_unicode
return serializer.serialize(o)
if isinstance(o, Model):
serializer = serializers.get_serializer(serializer_name)()
serializer.include_unicode = self.include_unicode
return serializer.serialize([o])[0]
else:
return super(ModelAwareJSONEncoder, self).default(o)
class Serializer(PythonSerializer):
def serialize(self, object, **options):
return simplejson.dumps(object, cls=ModelAwareJSONEncoder, **options)
goodpython.py:
from django.core.serializers.json import DateTimeAwareJSONEncoder
from django.core import serializers
from django.db.models.query import QuerySet
from django.db.models import Model
from django.utils import simplejson
from django.core.serializers.python import Serializer as PythonSerializer#, Deserializer as PythonDeserializer
from django.utils.encoding import smart_unicode
from django.template.defaultfilters import force_escape, escapejs, mark_safe
from core.libs.htmlfield import HtmlField
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
class Serializer(PythonSerializer):
def end_object(self, obj):
fields = self._current
if hasattr(self,'include_unicode') and self.include_unicode:
fields.update({'__unicode__': unicode(obj)})
self.objects.append({
"model" : smart_unicode(obj._meta),
"pk" : smart_unicode(obj._get_pk_val(), strings_only=True),
"fields" : fields
})
self._current = None
def handle_fk_field(self, obj, field):
related = getattr(obj, field.name)
self._current[field.name] = self.serialize_related(related)
def handle_m2m_field(self, obj, field):
self._current[field.name] = [self.serialize_related(related) for related in getattr(obj, field.name).iterator()]
def handle_field(self, obj, field):
''' The std. serialization is not suitable for the fields containing HTML. If such JSON is being output inside an inline <script> tag, the javascript code become invalid. This is why we need escapejs function to be applied to the contents of such fields. But after that the result is being escaped one more time. So, you need to unescape the result in your javascript with unescapejs()
'''
if isinstance(field, HtmlField):
self._current[field.name] = smart_unicode(escapejs(getattr(obj, field.name) or ''), strings_only=True)
else:
self._current[field.name] = smart_unicode(getattr(obj, field.name), strings_only=True)
def serialize_related(self,related):
if hasattr(self, 'already_serialized') and related in self.already_serialized:
serializer = serializers.get_serializer('python')()
else:
if hasattr(self, 'already_serialized'):
self.already_serialized.add(related)
else:
self.already_serialized = set([related])
serializer = serializers.get_serializer('goodpython')()
serializer.already_serialized = self.already_serialized
value = None
serializer.include_unicode = self.include_unicode
if isinstance(related, QuerySet):
value = serializer.serialize(related,**self.options)
if isinstance(related, Model):
value = serializer.serialize([related],**self.options)[0]
return value
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
What is
HtmlField
that you are talking about line 54?#
Please login first before commenting.