2016-05-26 2 views
3

У меня есть эти модули:Odoo/Python: зависимости модулей не так?

base_module, module_1 base_module_extend, module_2.

Эти модули имеют такие зависимости:

  • module_1 зависит от base_module.
  • base_module_extend зависит от base_module.
  • module_2 зависит от base_module_extend.

Если module_1 и module_2 не установлены в то же самое время, то все работает нормально, но если они будут установлены, то зависимости изменения в порядке были установлены эти модули.

Так, например, если я установлю module_2, а затем module_1, когда я начать использовать module_2 при вызове super в этом модуле кода, он находит класс, который был определен в base_module вместо base_module_extend первого, а затем некоторые вещи ломаются, потому что она делает не найти некоторые атрибуты/аргументы, которые определены в base_module_extend.

А если установить в обратном порядке: сначала установить module_1 и module_2, то, когда я использую module_2, он отлично работает, так как он вызывает правильные классы от super.

Есть ли способ сделать эти модули правильными родительскими классами, если они установлены, не заботясь о том, как они были установлены?

Или это ограничение, и вы ничего не можете с этим поделать? ..

Update

Пример того, что будет нарушен, если установить в неправильном порядке (первый сценарий):

Это метод, определенный в base_module:

def export_data(self, export_time=fields.Datetime.now()): 
    """ 
    This method can be overridden to implement custom data exportation 
    """ 
    self.ensure_one() 
    res = [] 
    return res 

Это метод, который был изменен в module_1:

def export_data(self, export_time=fields.Datetime.now()): 
    res = super(SFTPImportExport, self).export_data(export_time) 
    if self.process == 'custom_qty_available': 
     res = self._export_qty_available(export_time) 
    elif self.process == 'custom_sale': 
     res = self._export_sale(export_time) 
    return res 

Это метод, который был изменен в base_module_extend:

def export_data(
     self, export_time=fields.Datetime.now(), external_data=False): 
    """ 
    Overrides export_data to be able to provide external_data that 
    is already generated and can be directly returned to be used in export 
    @param export_time: time of export 
    @param external_data: used to bypass specific export 
    method and directly use data provided 
    """ 
    res = super(SFTPImportExport, self).export_data(export_time) 

    return res 

И это тот же метод, который был изменен в module_2:

def export_data(self, export_time=fields.Datetime.now(), external_data=False): 
    """ 
    Adds support for custom_invoice process 
    """ 
    res = super(SFTPImportExport, self).export_data(export_time=export_time, external_data=external_data) 
    if self.process == 'custom_invoice': 
     res = external_data 
    return res 

Update2

Когда последний метод версии (тот, который определен в module_2), я получаю эту ошибку:

"/opt/odoo/projects/project/sftp_import_export_extend/models/sftp_import_export.py", line 47, in export_sftp 

    export_time=now, external_data=external_data) 

ValueError: "export_data() got an unexpected keyword argument 'external_data'" while evaluating 

u'invoice_validate()' 

Так это выглядит, как это получить неправильный родительский класс, тот, который не имеет такой именованный аргумента

+0

Я хотел бы прочитать код этих модулей, поскольку иногда это то, как функции перезаписываются, в ваших примерах, если в 4-х модулях есть функция, определенная с тем же именем, все 4 должны запускаться (на самом деле это может измените, если это on_change или что-то, что зависит от вида). – dccdany

+0

Я обновил свой вопрос методом. Этот метод не зависит от вида. – Andrius

+0

Довольно странный случай, мне не нравится это использование иерархии, поскольку external_data не входит в первые два модуля, так или иначе, он должен работать, попробуйте войти в module_2 super (SFTPImportExport, self), прежде чем вызывать функцию, чтобы увидеть, какой объект/модель это. – dccdany

ответ

0

супер() стремится выбрать неправильный (неожиданный) родитель в Python. В качестве альтернативы вы можете использовать прямой вызов функции Python из желаемого суперкласса, вместо того, чтобы использовать super(), это гораздо более надежный способ.

Я не знаю структуру каталогов и исходные имена файлов вашего модуля Odoo, поэтому я попытаюсь приблизительно догадаться о структуре и дать вам описание того, что должно быть сделано. Примените его к своему делу (чтобы иметь правильное имя модуля, имя исходного файла и т. Д.).

Если нужный класс питона, скажем, назван SFTPImportExport, который содержит желаемый export_data метод определяется в следующем исходном файле внутри base_module_extend Odoo модуля (относительный путь): base_module_extend/models/somefile.py чем, вместо того, чтобы использовать super(), вы можете назвать это непосредственно как:

  • импорт желаемого supercalss:

    from openerp.base_module_extend.models.somefile import SFTPImportExport as ParentSFTPImportExport 
    
  • и называют это метод непосредственно:

    ParentSFTPImportExport.export_data(self, export_time=export_time, external_data=external_data) 
    

В этом случае точная функция вы хотите будет называться, как вы непосредственно обращаться к нему. Я предлагаю сделать то же самое, т. Е. Напрямую вызвать желаемую функцию в обоих модулях, чтобы убедиться, что они никогда не смешивают свои целевые функции.

Смежные вопросы