Files
tryton/trytond/model/fields/dict.py
T
Cédric Krier f9c0457416 Remove support for simplejson
On Python 3, simplejson has a different behaviour than the stdlib json,
especially for dumping bytes.

issue6010
review33601002
2016-11-05 19:54:12 +01:00

91 lines
2.9 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the toplevel of this
# repository contains the full copyright notices and license terms.
import json
from sql import Query, Expression
from .field import Field, SQLType
from ...protocols.jsonrpc import JSONDecoder, JSONEncoder
from ...pool import Pool
from ...tools import grouped_slice
class Dict(Field):
'Define dict field.'
_type = 'dict'
def __init__(self, schema_model, string='', help='', required=False,
readonly=False, domain=None, states=None, select=False,
on_change=None, on_change_with=None, depends=None,
context=None, loading='lazy'):
super(Dict, self).__init__(string, help, required, readonly, domain,
states, select, on_change, on_change_with, depends, context,
loading)
self.schema_model = schema_model
def get(self, ids, model, name, values=None):
dicts = dict((id, None) for id in ids)
for value in values or []:
if value[name]:
dicts[value['id']] = json.loads(value[name],
object_hook=JSONDecoder())
return dicts
@staticmethod
def sql_format(value):
if isinstance(value, (Query, Expression)):
return value
if value is None:
return None
assert isinstance(value, dict)
return json.dumps(value, cls=JSONEncoder)
def sql_type(self):
return SQLType('TEXT', 'TEXT')
def translated(self, name=None, type_='values'):
"Return a descriptor for the translated value of the field"
if name is None:
name = self.name
if name is None:
raise ValueError('Missing name argument')
return TranslatedDict(name, type_)
class TranslatedDict(object):
'A descriptor for translated values of Dict field'
def __init__(self, name, type_):
assert type_ in ['keys', 'values']
self.name = name
self.type_ = type_
def __get__(self, inst, cls):
if inst is None:
return self
pool = Pool()
schema_model = getattr(cls, self.name).schema_model
SchemaModel = pool.get(schema_model)
value = getattr(inst, self.name)
if not value:
return value
domain = []
if self.type_ == 'values':
domain = [('type_', '=', 'selection')]
records = []
for key_names in grouped_slice(value.keys()):
records += SchemaModel.search([
('name', 'in', key_names),
] + domain)
keys = SchemaModel.get_keys(records)
if self.type_ == 'keys':
return {k['name']: k['string'] for k in keys}
elif self.type_ == 'values':
trans = {k['name']: dict(k['selection']) for k in keys}
return {k: v if k not in trans else trans[k].get(v, v)
for k, v in value.iteritems()}