поля¶
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.
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