- Author:
- gabipurcaru
- Posted:
- November 29, 2010
- Language:
- Python
- Version:
- 1.2
- Score:
- 0 (after 0 ratings)
Painless serializing
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 105 106 107 108 109 110 111 112 113 | from types import NoneType
from django.db.models.manager import Manager
from django.db.models import Model
import datetime
def get_values(instance, go_into={}, exclude=(), extra=()):
"""
Transforms a django model instance into an object that can be used for
serialization. Also transforms datetimes into timestamps.
@param instance(django.db.models.Model) - the model in question
@param go_into(dict) - relations with other models that need expanding
@param exclude(tuple) - fields that will be ignored
@param extra(tuple) - additional functions/properties which are not fields
Usage:
get_values(MyModel.objects.get(pk=187),
{'user': {'go_into': ('clan',),
'exclude': ('crest_blob',),
'extra': ('get_crest_path',)}},
('image'))
"""
SIMPLE_TYPES = (int, long, str, list, dict, tuple, bool, float, bool,
unicode, NoneType)
if not isinstance(instance, Model):
raise TypeError("Argument is not a Model")
value = {
'pk': instance.pk,
}
# check for simple string instead of tuples
# and dicts; this is shorthand syntax
if isinstance(go_into, str):
go_into = {go_into: {}}
if isinstance(exclude, str):
exclude = (exclude,)
if isinstance(extra, str):
extra = (extra,)
# process the extra properties/function/whatever
for field in extra:
property = getattr(instance, field)
if callable(property):
property = property()
if isinstance(property, SIMPLE_TYPES):
value[field] = property
else:
value[field] = repr(property)
field_options = instance._meta.get_all_field_names()
for field in field_options:
try:
property = getattr(instance, field)
except:
continue
if field in exclude or field[0] == '_' or isinstance(property, Manager):
# if it's in the exclude tuple, ignore it
# if it's a "private" field, ignore it
# if it's an instance of manager (this means a more complicated
# relationship), ignore it
continue
elif go_into.has_key(field):
# if it's in the go_into dict, make a recursive call for that field
try:
field_go_into = go_into[field].get('go_into', {})
except AttributeError:
field_go_into = {}
try:
field_exclude = go_into[field].get('exclude', ())
except AttributeError:
field_exclude = ()
try:
field_extra = go_into[field].get('extra', ())
except AttributeError:
field_extra = ()
value[field] = get_values(property,
field_go_into,
field_exclude,
field_extra)
else:
if isinstance(property, Model):
# if it's a model, we need it's PK #
value[field] = property.pk
elif isinstance(property, (datetime.date,
datetime.time,
datetime.datetime)):
# if it's a date/time, we need it #
# in iso format for serialization #
value[field] = property.isoformat()
else:
# else, we just put the value #
if callable(property):
property = property()
if isinstance(property, SIMPLE_TYPES):
value[field] = property
else:
value[field] = repr(property)
return value
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 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
This is pure GOLD! It would be even better if you had a method to serialize a list of objects and also had 'include'.
#
Please login first before commenting.