Source code for openerp_proxy.experimental.relations

"""
This module contains functions and classes that could be used to get
information abour record relations
"""

from ..ext import sugar  # noqa
from ..orm.object import Object
from ..orm.record import (Record, RecordList)


[docs]class RelationsObject(Object):
def get_related_models(self, cache=None): """ Get related models for specified model return RecordList('ir.model') which contains models related to specified model """ if cache is None: cache = {} cache_key = 'related-models-for-%s-%s' % (id(self), self.name) related_models = cache.get(cache_key, None) if related_models is None: related_models = self.client._ir_model_fields( [('relation', '=', self.name)]).mapped('model_id') cache[cache_key] = related_models return related_models def get_related_model_fields(self, cache=None): """ Get a dictionary {<model>: RecordList('ir.model.fields')} which contains related models, and list of relational fields that points to specified model """ if cache is None: cache = {} cache_key = 'related-model-fields-for-%s-%s' % (id(self), self.name) related_models = self.get_related_models(cache) related_model_fields = cache.get(cache_key, None) if related_model_fields is None: related_model_fields = { model: model.field_id.filter(lambda x: x.relation == self.name) for model in related_models } cache[cache_key] = related_model_fields return related_model_fields
[docs]class RecordRelations(Record):
def get_rel_data_domain(self, field): if field.ttype == 'many2one': return [(field.name, '=', self.id)] elif field.ttype in ('one2many', 'many2many'): return [(field.name, 'in', [self.id])] else: return [] def find_related_objects(self, skip_models=None, cache=None): """ Find all links to this record """ cl = self._object.client skip_models = [] if skip_models is None else skip_models if cache is None: cache = {} # import pudb; pudb.set_trace() # XXX BREAKPOINT related_model_fields = self._object.get_related_model_fields(cache) model_fields = {} for model in related_model_fields: if model.model in skip_models: continue model_fields_data = {} model_cl = cl[model.model] for field in related_model_fields[model]: rel_data_domain = self.get_rel_data_domain(field) if model_cl.search(rel_data_domain, count=1): model_fields_data[field.name] = model_cl.search_records( rel_data_domain) if model_fields_data: model_fields[model.model] = model_fields_data return model_fields
[docs]class RecordListRelations(RecordList):
def find_related_objects_multi(self, skip_models, cache=None): """ Find all links to all records from other models """ cl = self.object.client model = self.object.name skip_models = [] if skip_models is None else skip_models if cache is None: cache = {} related_model_fields = self.object.get_related_model_fields(cache) model_fields_to_check = { model: [ field for field in fields if cl[model.model].search([(field.name, 'in', self.ids)], count=1) ] for model, fields in related_model_fields.items() if model.model not in skip_models } model_fields_to_check = { model: fields for model, fields in model_fields_to_check.items() if fields } res = { # <record>: {<model>: {<field>: <related_records}} } for record in self: record_data = {} # {<model>: {<field>: <related_records}} for model, fields in model_fields_to_check.items(): record_model_data = {} # {<field>: <related_records} for field in fields: field_data = cl[model.model]( record.get_rel_data_domain(field)) if field_data: record_model_data[field] = field_data if record_model_data: record_data[model] = record_model_data if record_data: res[record] = record_data return res