Недавно к меня возникла необходимость сделать модель, в которой данные должны браться не из PostgreSQL, а из произвольного хранилища, в моем случае это был кэш на Redis.
После небольших изысканий решение было найдено и им я бы хотел поделиться.
Определение методов для переопределения
Первым шагом я выяснил какой метод отвечает за вывод данных в интерфейс.
Для этого я посмотрел в консоли браузера какой метод вызывается в момент запроса:

Данным методом оказался search_read
.
Класс для работы с redis
Для взаимодействия с Redis нужно добавить параметры соединения в конфигурационный файл, а для операций определим новый класс:
from odoo.tools.config import config
import json
import redis
redis_engine = redis.Redis(host=config.get('redis'), db=0)
class RedisModel(object):
@api.model
def search_read(self, domain=None, fields=None, offset=0, limit=0, order=None):
data = [json.loads(redis_engine.lindex('odoo', i)) for i in range(0, redis_engine.llen('odoo'))]
if domain:
out = []
for key, cond, val in domain:
if cond == '=':
out.extend([row for row in data if row.get(key) == val])
data = out
return data
@api.model
def search_count(self, args):
return redis_engine.llen('odoo')
Как видно в данном примере бы переопределен метод для вывода данных в интерфейс и метод подсчета общего кол-ва строк.
Кроме того в search_read
проверяется наличие условия для поиска значения в Redis.
Mixin для модели
Теперь необходимо создать модель, которая будет наследоваться от нашей Redis модели и от модели Odoo
class Points(RedisModel, models.Model):
_name = "points"
client = fields.Integer("Client")
packet_id = fields.Integer("Packet id")
lat = fields.Float("Latitude")
lon = fields.Float("Longitude")
Из-за особенностей MRO в Python класс для взаимодействия с Redis должен идти первым.
Вывод
В статье был показан самый базовый пример, и переопределение может не ограничиться одним методом.