-
Notifications
You must be signed in to change notification settings - Fork 1
/
fields.py
73 lines (59 loc) · 2.23 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
# -*- coding: utf-8 -*-
# copyright 2016 Camptocamp
# license agpl-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import json
from datetime import datetime, date
import dateutil
from odoo import fields, models
class JobSerialized(fields.Field):
""" Serialized fields provide the storage for sparse fields. """
type = 'job_serialized'
column_type = ('text', 'text')
def convert_to_column(self, value, record):
return json.dumps(value, cls=JobEncoder)
def convert_to_cache(self, value, record, validate=True):
# cache format: dict
value = value or {}
if isinstance(value, dict):
return value
else:
return json.loads(value, cls=JobDecoder, env=record.env)
class JobEncoder(json.JSONEncoder):
""" Encode Odoo recordsets so that we can later recompose them """
def default(self, obj):
if isinstance(obj, models.BaseModel):
return {'_type': 'odoo_recordset',
'model': obj._name,
'ids': obj.ids,
'uid': obj.env.uid,
}
elif isinstance(obj, datetime):
return {'_type': 'datetime_isoformat',
'value': obj.isoformat()}
elif isinstance(obj, date):
return {'_type': 'date_isoformat',
'value': obj.isoformat()}
return json.JSONEncoder.default(self, obj)
class JobDecoder(json.JSONDecoder):
""" Decode json, recomposing recordsets """
def __init__(self, *args, **kwargs):
env = kwargs.pop('env')
super(JobDecoder, self).__init__(
object_hook=self.object_hook, *args, **kwargs
)
assert env
self.env = env
def object_hook(self, obj):
if '_type' not in obj:
return obj
type_ = obj['_type']
if type_ == 'odoo_recordset':
model = self.env[obj['model']]
if obj.get('uid'):
model = model.sudo(obj['uid'])
return model.browse(obj['ids'])
elif type_ == 'datetime_isoformat':
return dateutil.parser.parse(obj['value'])
elif type_ == 'date_isoformat':
return dateutil.parser.parse(obj['value']).date()
return obj