2015-10-09 3 views
3

В Odoo 8 существует ли предпочтительный метод стандартизации значений полей для создания или записи? Некоторые методы приходят на ум, но эта функциональность кажется, что она принадлежит API. По сути, я хочу создать поле, которое задает функцию стандартизации, несколько похожее на поле вычисления, которое задает только обратную функцию. Это уже существует где-то в API?Как стандартизировать значения полей для создания или записи в Odoo 8?

Способ 0: создать поле, которое задает функцию стандартизации.

Единственный недостаток, который я вижу с помощью этого метода, заключается в том, что API не существует.

import openerp 

class Model(openerp.models.Model): 

    _name = 'addon.model' 

    field = openerp.fields.Text(
    required=True, 
    standardize='_standardize_field', 
) 

    @openerp.api.one 
    def _standardize_field(self): 
    self.field = self.field.upper() 

Метод 1: Переопределение создания и записи методы, чтобы вставить вызов стандартизировать поле.

Это работает, но представляется довольно подробным для того, что можно сделать с помощью одной функции выше. Обратите внимание, что ограничение требуется, если required=True, и стандартизация может дать пустое поле.

import openerp 

class Model(openerp.models.Model): 

    _name = 'addon.model' 

    field = openerp.fields.Text(
    required=True, 
) 

    @openerp.api.one 
    @openerp.api.constrains('field') 
    def _constrains_field(self): 
    if len(self.field) == 0: 
     raise openerp.exceptions.ValidationError('Field must be valid.') 

    def _standardize(self, args): 
    if 'field' in args: 
     # Return standardized field or empty string. 
     args['field'] = args['field'].upper() 

    @openerp.api.model 
    def create(self, args): 
    self._standardize(args) 
    return super(Model, self).create(args) 

    @openerp.api.multi 
    def write(self, args): 
    self._standardize(args) 
    super(Model, self).write(args) 
    return True 

Способ 2: С помощью вычисляемого поля и немного магии.

Это работает, но чувствует себя немного надуманным. Кроме того, этот метод требует, чтобы функция стандартизации была детерминированной, или это может создать бесконечный цикл. Обратите внимание, что функция стандартизации может вызываться дважды, что может быть проблемой, если стандартизация является дорогостоящей операцией.

import openerp 

class Model(openerp.models.Model): 

    _name = 'addon.model' 

    field = openerp.fields.Text(
    compute=lambda x: x, 
    inverse='_inverse_field', 
    required=True, 
    store=True, 
) 

    @openerp.api.one 
    @openerp.api.constrains('field') 
    def _constrains_field(self): 
    if self._standardize_field() is None: 
     raise openerp.exceptions.ValidationError('Field must be valid.') 

    def _inverse_field(self): 
    field = self._standardize_field() 

    # If the field is updated during standardization, this function will 
    # run a second time, so use this check to prevent an infinite loop. 
    if self.field != field: 
     self.field = field 

    def _standardize_field(self): 
    # Return the standardized field. 
    return self.field.upper() 

Способ 3: Использование регулярного поля и вычисленное поля, только с вычисленным полем подвергаясь в представлении.

Флаг readonly и ограничения помогают защитить базовое поле, но я не уверен, что этот метод будет поддерживать целостность данных, и метод в целом чувствует себя надуманным.

import openerp 

class Model(openerp.models.Model): 

    _name = 'addon.model' 

    field = openerp.fields.Text(
    readonly=True, 
    required=True, 
) 

    field_for_view = openerp.fields.Text(
    compute='_compute_field_for_view', 
    inverse='_inverse_field_for_view', 
    required=True, 
) 

    @openerp.api.one 
    @openerp.api.depends('field') 
    def _compute_field_for_view(self): 
    self.field_for_view = self.field 

    @openerp.api.one 
    @openerp.api.constrains('field', 'field_for_view') 
    def _constrains_field(self): 
    if self._standardize_field() is None: 
     raise openerp.exceptions.ValidationError('Field must be valid.') 

    def _inverse_field(self): 
    self.field = self._standardize_field() 

    def _standardize_field(self): 
    # Return the standardized field. 
    return self.field_for_view.upper() 

ответ

0

Возможно, атрибут «по умолчанию» является реализацией вашего подхода №1? Вот пример, взятый из документации Odoo8 на https://www.odoo.com/documentation/8.0/reference/orm.html#creating-models

a_field = fields.Char(default=compute_default_value) 

def compute_default_value(self): 
    return self.get_value() 

Другой вариант переопределить метод write() в подклассе, чтобы добавить свой вызов следующим образом:

def write(self, vals): 

     for record in self: 
      # do the cleanup here for each record, storing the result in 
      # vals again 

     # call the super: 
     res = super(extendedProject, self).write(vals) 

     return res 

vals является словарем с модифицированным значения для хранения; self - это набор записей со всеми записями для хранения значений. Обратите внимание, что транзакция в Odoo может по-прежнему откатываться после возврата с вашего вызова до write.

+0

Когда поле не имеет значения, например, при создании новой записи, атрибут по умолчанию предлагает значение для этого поля. Затем значение может быть изменено и может быть сохранено или не сохранено. Напротив, я хочу стандартизировать значение поля всякий раз, когда он сохраняется. Например, когда введен почтовый адрес, я могу стандартизировать и проверять адрес при сохранении записи. В моем случае я хочу разрешить пользователю вводить HTML, не требуя, чтобы их HTML был совершенным, поэтому я очищаю HTML, когда запись сохраняется, используя метод 1 выше. –

+0

А, ок. тогда вы также можете просто переопределить метод 'write' и затем выполнить любую очистку. Я обновлю ответ, чтобы добавить этот параметр. – miw

+0

Вы видели метод 1 в вопросе? Я отмечаю, что при переопределении метода write() 'требуется несколько дополнительных шагов, так как также необходимо переопределить метод' create() ', а иногда также необходимо использовать декоратор' @ constrains'. –