OpenERP и related поля

В официальной документации очень мало написано про то, как использовать поля типа related.
Прототип в официальной документации и его описание:

Sometimes you need to refer to the relation of a relation. For example, supposing you have objects: City -> State -> Country, and you need to refer to the Country from a City, you can define a field as below in the City object:
'country_id': fields.related(
    'state_id',
    'country_id',
    type="many2one",
    relation="res.country",
    string="Country",
    store=False)

Where:
— The first set of parameters are the chain of reference fields to follow, with the desired field at the end.
— type is the type of that desired field.
— Use relation if the desired field is still some kind of reference. relation is the table to look up that reference in.

Но как показывает практика этого описания недостаточно.
Есть, например, два класса invoce и contract.

class invoice(osv.osv):
    _name = "invoice"
    _columns = {
        'name_invoice': fields.char('Name'),
        'date_invoice': fields.datetime('Date')
        #'invoice_line': fields.one2many(....)
        #..... Список других полей .....
    }

class contract(osv.osv):
    _name = "contract"
    _columns = {
        'name_contract': fields.char('Name'),
        'date_contract': fields.datetime('Date')
        #..... Список других полей .....
    }

Нам необходимо, что бы пи создании новой записи в invoice происходила запись полей date_invoice и name_invoice в поля date_contract и name_contract объекта contract.

Для этого описываем дополнительные поля в классе invoice:
'name_lnk': fields.related('name_invoice', 'name_contract', type="char", relation="contract", string="Name")
'date_lnk': fields.related('date_invoice', 'date_contract', type="datetime", relation="contract", string="Date")

Теперь автоматически при создании invoice будет делаться запись в contract.

Вообще, лучше описать прототип так:
'country_id': fields.related(
    <поле_источника>,
    <поле_приёмника>,
    type=<тип_поля>,
    relation=<модель_приёмника>,
    string=<строковое_описание>,
    store=False)


Аргумент store служит для сохранения значений в базе:
Если True — данные сохраняются в базе данных
Если False — то это просто поле-функция, без сохранения данных в БД

6 комментариев

avatar
Тема не раскрыта
avatar
аргумент store эффективнее и реалистичнее всего для реальных жизненных ситуаций работает в случае, здесь не описанном. Он может быть равен не только True или False но так же содержать в себе словарь. Собственно, об этом есть в документации: doc.odoo.com/trunk/server/03_module_dev_02/#store-parameter
avatar
В 7 версии столкнулся с проблемой при реализации похожей модели.
class invoice и class contract
не указано как они между собой связаны
type="char", relation="contract"
не беспечивает связи двух классов.
Работает только в случаях если одному из
fields.related
указать тип
many2one
,
или же если создать дополнительное поле связи в классе invoice
'contract': fields.many2one('contract','Contract'),
и тогда…
'name_lnk': fields.related('contract', 'name_contract', type="char", relation="contract", string="Name")
'date_lnk': fields.related('contract', 'date_contract', type="datetime", relation="contract", string="Date")
avatar
Проверил и все равно работает некорректно. При создании новой записи в поле many2one, запись создается в базе данных, а остальные введенные значения в поля не сохраняются, если выбрать из существующих записей работает нормально.
Параметр store = False или True не влияет никак.
У кого нибудь есть идеи как решить вопрос.
avatar
Взять и посмотреть любой пример с relation полями в стандартных модулях. Дело на 5 минут.
avatar
Смотрел, и очень много раз.
Вот пример
Не обновляет, проверял в работе. Пошел по указаной вами ссылке, почитал описание, нашел примеры.
В параметре store нужно указать функцию которая будет возвращять ID записи.
пробовал так
store = {'модуль': (
            lambda self, cr, uid, ids, c={}: ids,
            ['поле'], 10)}
не работает,
def _get_id(self, cr, uid, ids, context=None):
        this_record = self.browse(cr, uid, ids[0], context = context)
        return this_record.поле.id


пробовал так
store = {'модуль': (_get_id, ['поле'], 10)}
не работает
В обоих случаях сохраняется в текущей таблице, а в связанной нет.

Оставить комментарий