Ticket #12990: json_field.diff

File json_field.diff, 4.8 KB (added by paltman, 14 years ago)

JSON Field Patch

  • django/db/models/fields/__init__.py

     
    88from django.db import connection
    99from django.db.models.fields.subclassing import LegacyConnection
    1010from django.db.models.query_utils import QueryWrapper
     11from django.db.models import signals
    1112from django.conf import settings
    1213from django import forms
    1314from django.core import exceptions, validators
     
    1819from django.utils.translation import ugettext_lazy as _
    1920from django.utils.encoding import smart_unicode, force_unicode, smart_str
    2021from django.utils import datetime_safe
     22from django.utils import simplejson as json
    2123
     24
    2225class NOT_PROVIDED:
    2326    pass
    2427
     
    11291132        self.schema_path = schema_path
    11301133        Field.__init__(self, verbose_name, name, **kwargs)
    11311134
     1135
     1136class JSONDateEncoder(json.JSONEncoder):
     1137    def default(self, obj):
     1138        if isinstance(obj, datetime):
     1139            return obj.strftime('%Y-%m-%d %H:%M:%S')
     1140        elif isinstance(obj, datetime.date):
     1141            return obj.strftime('%Y-%m-%d')
     1142        elif isinstance(obj, datetime.time):
     1143            return obj.strftime('%H:%M:%S')
     1144        return json.JSONEncoder.default(self, obj)
     1145
     1146
     1147class JSONField(TextField):
     1148    description = _("Data that serializes and deserializes into and out of JSON.")
     1149
     1150    def _dumps(self, data):
     1151        return JSONDateEncoder().encode(data)
     1152
     1153    def _loads(self, str):
     1154        return json.loads(str, encoding=settings.DEFAULT_CHARSET)
     1155
     1156    def db_type(self):
     1157        return 'text'
     1158
     1159    def pre_save(self, model_instance, add):
     1160        value = getattr(model_instance, self.attname, None)
     1161        return self._dumps(value)
     1162
     1163    def contribute_to_class(self, cls, name):
     1164        self.class_name = cls
     1165        super(JSONField, self).contribute_to_class(cls, name)
     1166        signals.post_init.connect(self.post_init)
     1167
     1168        def get_json(model_instance):
     1169            return self._dumps(getattr(model_instance, self.attname, None))
     1170        setattr(cls, 'get_%s_json' % self.name, get_json)
     1171
     1172        def set_json(model_instance, json):
     1173            return setattr(model_instance, self.attname, self._loads(json))
     1174        setattr(cls, 'set_%s_json' % self.name, set_json)
     1175
     1176    def post_init(self, **kwargs):
     1177        if 'sender' in kwargs and 'instance' in kwargs:
     1178            if kwargs['sender'] == self.class_name and hasattr(kwargs['instance'], self.attname):
     1179                value = self.value_from_object(kwargs['instance'])
     1180                if (value):
     1181                    setattr(kwargs['instance'], self.attname, self._loads(value))
     1182                else:
     1183                    setattr(kwargs['instance'], self.attname, None)
  • tests/modeltests/field_subclassing/models.py

     
    1919class DataModel(models.Model):
    2020    data = JSONField()
    2121
     22class ArbitraryDataModel(models.Model):
     23    data = models.JSONField()
     24
     25
    2226__test__ = {'API_TESTS': ur"""
    2327# Creating a model with custom fields is done as per normal.
    2428>>> s = Small(1, 2)
     
    7074>>> for m in MyModel.objects.all(): print unicode(m.data)
    717512
    727623
     77
     78# Test the Real JSONField
     79>>> a1 = ArbitraryDataModel()
     80>>> a1.data = [{'name': 'PyCon', 'type': 'Conference'}, {'name': 'BarCamp', 'type': 'Unconference'}]
     81>>> a1.save()
     82>>> a2 = ArbitraryDataModel.objects.get(id=a1.id)
     83>>> print a2.data[1]['name']
     84BarCamp
    7385"""}
  • AUTHORS

     
    3535    Ahmad Alhashemi <trans@ahmadh.com>
    3636    Ahmad Al-Ibrahim
    3737    Antoni Aloy
     38    Patrick Altman <paltman@gmail.com>
    3839    Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
    3940    AgarFu <heaven@croasanaso.sytes.net>
    4041    Dagur Páll Ammendrup <dagurp@gmail.com>
  • docs/ref/models/fields.txt

     
    791791
    792792.. _RelaxNG: http://www.relaxng.org/
    793793
     794``JSONField``
     795-------------
     796
     797.. class:: JSONField([**options])
     798
     799.. versionadded:: 1.2
     800
     801A :class:`TextField` that stores serialized data in the form of JSON.  You can
     802set this field to be any Python data structure that contains data that can be
     803serialized by the ``simplejson`` serializer, in addition to DateTime objects,
     804which can be serialized even though upon deserialization they will remain
     805strings.
     806
     807
    794808Relationship fields
    795809===================
    796810
Back to Top