python-ox/ox/django/fields.py

100 lines
3.3 KiB
Python
Raw Normal View History

2011-02-25 12:24:38 +00:00
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
2010-11-23 09:23:40 +00:00
import time
2011-02-24 23:55:07 +00:00
import datetime
2016-02-19 18:37:41 +00:00
import copy
2010-11-23 09:23:40 +00:00
from django.db import models
2013-06-28 14:57:31 +00:00
from django.utils import datetime_safe
2014-10-02 06:34:58 +00:00
from six import string_types
2013-06-28 14:57:31 +00:00
2010-11-23 10:26:14 +00:00
from ox.utils import json
2010-11-23 09:23:40 +00:00
def to_json(python_object):
2011-02-24 23:55:07 +00:00
if isinstance(python_object, datetime.datetime):
2013-07-02 12:44:18 +00:00
if python_object.year < 1900:
2013-07-02 13:00:27 +00:00
tt = python_object.timetuple()
2013-07-02 12:44:18 +00:00
value = '%d-%02d-%02dT%02d:%02d%02dZ' % tuple(list(tt)[:6])
else:
2013-07-02 13:00:27 +00:00
value = python_object.strftime('%Y-%m-%dT%H:%M:%SZ')
2013-06-28 14:57:31 +00:00
return {'__class__': 'datetime.datetime',
2013-07-02 12:44:18 +00:00
'__value__': value}
2013-06-28 14:57:31 +00:00
if isinstance(python_object, datetime_safe.datetime):
2011-02-24 23:55:07 +00:00
return {'__class__': 'datetime.datetime',
'__value__': python_object.strftime('%Y-%m-%dT%H:%M:%SZ')}
if isinstance(python_object, time.struct_time):
return {'__class__': 'time.asctime',
'__value__': time.asctime(python_object)}
2011-02-25 12:24:38 +00:00
try:
if isinstance(python_object, bytes):
return {'__class__': 'bytes',
'__value__': list(python_object)}
except:
pass
2010-11-23 09:23:40 +00:00
raise TypeError(repr(python_object) + ' is not JSON serializable')
2011-02-24 23:55:07 +00:00
def from_json(json_object):
if '__class__' in json_object:
2010-11-23 09:23:40 +00:00
if json_object['__class__'] == 'bytes':
2011-02-24 23:55:07 +00:00
return bytes(json_object['__value__'])
2013-06-28 14:57:31 +00:00
if json_object['__class__'] == 'datetime_safe.datetime' \
or json_object['__class__'] == 'datetime.datetime':
return datetime_safe.datetime.strptime(json_object['__value__'], '%Y-%m-%dT%H:%M:%SZ')
2011-02-24 23:55:07 +00:00
if json_object['__class__'] == 'time.asctime':
return time.strptime(json_object['__value__'])
2010-11-23 09:23:40 +00:00
return json_object
2011-02-24 23:55:07 +00:00
2010-11-23 09:23:40 +00:00
class DictField(models.TextField):
2016-02-19 13:30:53 +00:00
_type = dict
def loads(self, value):
return json.loads(value, object_hook=from_json)
def dumps(self, obj):
2016-02-19 18:37:41 +00:00
return json.dumps(obj, default=to_json, ensure_ascii=False)
2010-11-23 09:23:40 +00:00
2016-02-19 18:37:41 +00:00
def from_db_value(self, value, expression, connection, context):
2016-02-19 13:30:53 +00:00
if value is None:
2012-09-25 11:26:50 +00:00
return value
2016-02-19 13:30:53 +00:00
if isinstance(value, self._type):
2010-11-23 09:23:40 +00:00
return value
try:
2016-02-19 13:30:53 +00:00
value = self.loads(value)
except:
raise Exception('failed to parse value: %s' % value)
if value is not None:
assert isinstance(value, self._type)
2010-11-23 09:23:40 +00:00
return value
2016-02-19 13:30:53 +00:00
def get_prep_value(self, value):
if isinstance(value, self._type):
value = self.dumps(value)
if value is not None:
assert isinstance(value, string_types)
value = models.TextField.get_prep_value(self, value)
return value
2010-11-23 09:23:40 +00:00
2016-02-19 18:37:41 +00:00
def get_default(self):
if self.has_default():
if callable(self.default):
return self.default()
return copy.deepcopy(self.default)
return super(DictField, self).get_default()
2010-11-23 09:23:40 +00:00
2016-02-19 13:30:53 +00:00
class TupleField(DictField):
2016-02-19 18:37:41 +00:00
_type = (tuple, list)
2010-11-23 09:23:40 +00:00
2016-02-19 13:30:53 +00:00
def loads(self, value):
value = DictField.loads(self, value)
if isinstance(value, list):
value = tuple(value)
return value
2010-11-23 09:23:40 +00:00
try:
from south.modelsinspector import add_introspection_rules
2011-07-06 22:06:35 +00:00
add_introspection_rules([], ["^ox.django\.fields\.DictField"])
add_introspection_rules([], ["^ox.django\.fields\.TupleField"])
2010-11-23 09:23:40 +00:00
except:
pass