поля¶
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')
Типы полей¶
голец¶
Сохранить строку с переменной 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'
выбор¶
Сохраните текст в базе данных, но предложите виджет выбора. Это не вызывает никаких ограничений выбора в базе данных. Выбор должен быть установлен в виде списка кортежей или вызываемого элемента, который возвращает список кортежей:
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.
ondeleteprovides 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