-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfields.py
76 lines (55 loc) · 2.03 KB
/
fields.py
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
import inspect
import re
import simplejson
from django.db import models
from django.core.serializers.json import DjangoJSONEncoder
class GenChoice:
hidden_pat = re.compile(r'__\w+__')
@classmethod
def choices(cls):
fn = lambda x: (isinstance(x[1], str) or\
isinstance(x[1], int) or\
isinstance(x[1], float))\
and (not GenChoice.hidden_pat.match(x[0]))
return filter(fn, inspect.getmembers(cls))
class ManyToManyJSONField(models.Field):
__metaclass__ = models.SubfieldBase
def __init__(self, model, *args, **kwargs):
self.Model = model
super(ManyToManyJSONField, self).__init__(*args, **kwargs)
def db_type(self, connection):
return 'longtext'
def get_prep_value(self, value):
ids = []
for v in value:
ids.append(v.id)
return simplejson.dumps(ids) if ids else None
def to_python(self, value='[]'):
if not value:
value = '[]'
ids = simplejson.loads(str(value))
return [self.Model.objects.get(id=id) for id in ids]
class JSONField(models.TextField):
"""
Serializes/deserializes JSON object into a text field in a SQLite database
"""
description = "A JSON object"
__metaclass__ = models.SubfieldBase
def to_python(self, value):
"""Convert our string value to JSON after we load it from the DB"""
if value == "":
return {}
try:
if isinstance(value, basestring):
return simplejson.loads(value)
except ValueError:
pass
return value
def get_db_prep_save(self, value, connection):
"""Convert our JSON object to a string before we save"""
if value == "":
return None
if isinstance(value, dict):
value = simplejson.dumps(value)
# TODO: If the value is a string, make sure it is valid JSON before saving it
return super(JSONField, self).get_db_prep_save(value, connection)