поля

Based on: http://odoo-new-api-guide-line.readthedocs.io/en/latest/fields.html

Теперь поля являются свойством класса:

from openerp import models, fields


class AModel(models.Model):

    _name = 'a_name'

    name = fields.Char(
        string="Name",                   # Optional label of the field
        compute="_compute_name_custom",  # Transform the fields in computed fields
        store=True,                      # If computed it will store the result
        select=True,                     # Force index on field
        readonly=True,                   # Field will be readonly in views
        inverse="_write_name"            # On update trigger
        required=True,                   # Mandatory field
        translate=True,                  # Translation enable
        help='blabla',                   # Help tooltip text
        company_dependent=True,          # Transform columns to ir.property
        search='_search_function'        # Custom search function mainly used with compute
    )

   # The string key is not mandatory
   # by default it wil use the property name Capitalized

   name = fields.Char()  #  Valid definition

Полевое наследование

Одна из новых функций API - возможность изменять только один атрибут поля:

name = fields.Char(string='New Value')

Типы полей

логический

Поле логического типа:

abool = fields.Boolean()

голец

Сохранить строку с переменной len .:

achar = fields.Char()

Конкретные варианты:

  • размер: данные будут обрезаны до указанного размера
  • перевести: поле можно перевести

Текст

Используется для хранения длинного текста.

atext = fields.Text()

Конкретные варианты:

  • перевести: поле можно перевести

HTML

Используется для хранения HTML, предоставляет виджет HTML .:

anhtml = fields.Html()

Конкретные варианты:

  • перевести: поле можно перевести

целое число

Сохраните целочисленное значение. Нет поддержки значения NULL. Если значение не установлено, возвращается 0:

anint = fields.Integer()

терка

Хранить значение с плавающей запятой. Нет поддержки значения NULL. Если значение не установлено, возвращается 0.0. Если задана опция цифр, будет использоваться числовой тип:

afloat = fields.Float()
afloat = fields.Float(digits=(32, 32))
afloat = fields.Float(digits=lambda cr: (32, 32))

Конкретные варианты:

  • цифры: принудительное использование числового типа в базе данных. Параметр может быть кортежем (int len, float len) или вызываемым, который возвращает кортеж и принимает курсор в качестве параметра

Дата

Дата магазина. Поле предоставляет несколько помощников:

  • `` context_today`` возвращает строку даты текущего дня на основе tz
  • `` today`` возвращает строку текущей системной даты
  • `` from_string`` возвращает datetime.date () из строки
  • `` to_string`` возвращает строку даты из datetime.date

dummy literal

>>> from openerp import fields

>>> adate = fields.Date()
>>> fields.Date.today()
'2014-06-15'
>>> fields.Date.context_today(self)
'2014-06-15'
>>> fields.Date.context_today(self, timestamp=datetime.datetime.now())
'2014-06-15'
>>> fields.Date.from_string(fields.Date.today())
datetime.datetime(2014, 6, 15, 19, 32, 17)
>>> fields.Date.to_string(datetime.datetime.today())
'2014-06-15'

DateTime

Хранить дату и время Поле предоставляет некоторый помощник:

  • `` context_timestamp`` возвращает строку даты текущего дня на основе tz
  • `` now`` возвращает строку текущей системной даты
  • `` from_string`` возвращает datetime.date () из строки
  • `` to_string`` возвращает строку даты из datetime.date

dummy literal

>>> fields.Datetime.context_timestamp(self, timestamp=datetime.datetime.now())
datetime.datetime(2014, 6, 15, 21, 26, 1, 248354, tzinfo=<DstTzInfo 'Europe/Brussels' CEST+2:00:00 DST>)
>>> fields.Datetime.now()
'2014-06-15 19:26:13'
>>> fields.Datetime.from_string(fields.Datetime.now())
datetime.datetime(2014, 6, 15, 19, 32, 17)
>>> fields.Datetime.to_string(datetime.datetime.now())
'2014-06-15 19:26:13'

двоичный

Сохраните файл, закодированный в base64, в столбце bytea:

abin = fields.Binary()

выбор

Сохраните текст в базе данных, но предложите виджет выбора. Это не вызывает никаких ограничений выбора в базе данных. Выбор должен быть установлен в виде списка кортежей или вызываемого элемента, который возвращает список кортежей:

aselection = fields.Selection([('a', 'A')])
aselection = fields.Selection(selection=[('a', 'A')])
aselection = fields.Selection(selection='a_function_name')

Конкретные варианты:

  • selection: список кортежей или вызываемых имен, которые принимают набор записей в качестве входных данных
  • size: опция size = 1 обязательна при использовании целых индексов, а не строк

При расширении модели, если вы хотите добавить возможные значения в поле выбора, вы можете использовать аргумент ключевого слова selection_add

class SomeModel(models.Model):
    _inherits = 'some.model'
    type = fields.Selection(selection_add=[('b', 'B'), ('c', 'C')])

Since Odoo 14.0 you have to specify ondelete attribute.

ondelete provides a fallback mechanism for any overridden
field with a selection_add. It is a dict that maps every option from the selection_add to a fallback action. This fallback action will be applied to all records whose selection_add option maps to it. The actions can be any of the following:
  • 'set null' – the default, all records with this option will have their selection value set to False.

  • 'cascade' – all records with this option will be deleted along with the option itself.

  • 'set default' – all records with this option will be set to the default of the field definition

  • <callable> – a callable whose first and only argument will be the set of records containing the specified Selection option, for custom processing. e.g.:

    my_selection = fields.Selection(selection_add=[
         ('bacon', "Bacon"),
    ], ondelete={'bacon': lambda records: record.write({'my_selection': 'bar'})})
    

Ссылка

Сохраните произвольную ссылку на модель и строку:

aref = fields.Reference([('model_name', 'String')])
aref = fields.Reference(selection=[('model_name', 'String')])
aref = fields.Reference(selection='a_function_name')

Конкретные варианты:

  • selection: список кортежей или вызываемых имен, которые принимают набор записей в качестве входных данных

Many2one

Сохранить отношение к совместной модели:

arel_id = fields.Many2one('res.users')
arel_id = fields.Many2one(comodel_name='res.users')
an_other_rel_id = fields.Many2one(comodel_name='res.partner', delegate=True)

Конкретные варианты:

  • comodel_name: имя противоположной модели
  • делегат: установите его в `` True``, чтобы сделать поля целевой модели доступными из текущей модели (соответствует `` _inherits``)

One2many

Сохранить отношение ко многим строкам совместной модели:

arel_ids = fields.One2many('res.users', 'rel_id')
arel_ids = fields.One2many(comodel_name='res.users', inverse_name='rel_id')

Конкретные варианты:

  • comodel_name: имя противоположной модели
  • inverse_name: реляционный столбец противоположной модели

Many2many

Сохраните отношение ко многим многим строкам совместной модели:

arel_ids = fields.Many2many('res.users')
arel_ids = fields.Many2many(comodel_name='res.users',
                            relation='table_name',
                            column1='col_name',
                            column2='other_col_name')

Конкретные варианты:

  • comodel_name: имя противоположной модели
  • отношение: имя реляционной таблицы
  • columns1: имя левого столбца реляционной таблицы (ссылка на запись в текущей таблице)
  • columns2: имя правого столбца реляционной таблицы (ссылка на запись в таблице * comodel_name *)

Чтобы сделать два взаимных много-много-много полей в разных моделях, используйте в них одну и ту же таблицу отношений и обратные столбцы:

_name = 'model1'
model2_ids = fields.Many2many(
    'model2', 'model2_ids_model1_ids_rel', 'model2_id', 'model1_id',

_name = 'model2'
model1_ids = fields.Many2many(
    'model1', 'model2_ids_model1_ids_rel', 'model1_id', 'model2_id',

Конфликты имен

Примечание

поля и имя метода могут конфликтовать.

Когда вы называете запись диктовкой, она заставляет смотреть на столбцы.

Поля по умолчанию

По умолчанию теперь используется ключевое слово поля:

Вы можете приписать ему значение или функцию

name = fields.Char(default='A name')
# or
name = fields.Char(default=a_fun)

#...
def a_fun(self):
   return self.do_something()

Использование веселья заставит вас определить функцию перед определением полей.

Заметка. Значение по умолчанию не может зависеть от значений других полей записи, т. Е. Вы не можете читать другие поля через `` self`` в функции.

Вычисляемые поля

Больше нет прямого создания полей.

Вместо этого вы добавляете `` compute`` kwarg. Значение - это имя функции в виде строки или функции. Это позволяет иметь определение полей поверх класса:

class AModel(models.Model):
    _name = 'a_name'

    computed_total = fields.Float(compute='compute_total')

    def compute_total(self):
        ...
        self.computed_total = x

Функция может быть недействительной. Он должен изменить свойство записи для записи в кеш:

self.name = new_value

Имейте в виду, что это назначение приведет к записи в базу данных. Если вам нужно сделать массовое изменение или вы должны быть осторожны с производительностью, вы должны сделать классический вызов, чтобы написать

Чтобы обеспечить функцию поиска для несохраненного вычисляемого поля, вы должны добавить к полю `` search``. Значение - это имя функции в виде строки или ссылка на ранее определенный метод. Функция принимает второго и третьего члена доменного кортежа и возвращает сам домен:

def search_total(self, operator, operand):
    ...
    return domain  # e.g. [('id', 'in', ids)]

обратный

Обратный ключ позволяет вызвать вызов декорированной функции, когда поле написано / «создано»

Мульти поля

Чтобы иметь одну функцию, которая вычисляет несколько значений:

@api.multi
@api.depends('field.relation', 'an_otherfield.relation')
def _amount(self):
    for x in self:
        x.total = an_algo
        x.untaxed = an_algo

Поле собственности

В некоторых случаях значение поля должно меняться в зависимости от текущей компании.

Чтобы активировать такое поведение, теперь вы можете использовать опцию company_dependent.

Заметная эволюция в новом API заключается в том, что «поля свойств» теперь доступны для поиска.

WIP копируемая опция

Есть запущенный разработчик, который не позволит переопределить копию, просто установив параметр копирования в полях:

copy=False  # !! WIP to prevent redefine copy