1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- # -*- coding: utf-8 -*-
- """
- JSONField automatically serializes most Python terms to JSON data.
- Creates a TEXT field with a default value of "{}". See test_json.py for
- more information.
- from django.db import models
- from django_extensions.db.fields import json
- class LOL(models.Model):
- extra = json.JSONField()
- """
- from __future__ import absolute_import
- import datetime
- from decimal import Decimal
- import json
- import six
- from django.conf import settings
- from mongoengine.fields import StringField
- class JSONEncoder(json.JSONEncoder):
- def default(self, obj):
- if isinstance(obj, Decimal):
- return str(obj)
- elif isinstance(obj, datetime.datetime):
- assert settings.TIME_ZONE == 'UTC'
- return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
- return json.JSONEncoder.default(self, obj)
- def dumps(value):
- assert isinstance(value, dict)
- return JSONEncoder().encode(value)
- def loads(txt):
- value = json.loads(txt, parse_float=Decimal)
- assert isinstance(value, dict)
- return value
- class JSONDict(dict):
- """
- Hack so repr() called by dumpdata will output JSON instead of
- Python formatted data. This way fixtures will work!
- """
- def __repr__(self):
- return dumps(self)
- class JSONField(StringField):
- """
- JSONField is a generic textfield that neatly serializes/unserializes
- JSON objects seamlessly. Main object must be a dict object.
- """
- def __init__(self, *args, **kwargs):
- if 'default' not in kwargs:
- kwargs['default'] = '{}'
- StringField.__init__(self, *args, **kwargs)
- def to_python(self, value):
- """ Convert our string value to JSON after we load it from the DB """
- if not value:
- return {}
- elif isinstance(value, six.string_types):
- res = loads(value)
- assert isinstance(res, dict)
- return JSONDict(**res)
- else:
- return value
- def get_db_prep_save(self, value):
- """ Convert our JSON object to a string before we save """
- if not value:
- return super().get_db_prep_save("")
- else:
- return super().get_db_prep_save(dumps(value))
|