2017-04-12 58 views
0

我有一個與另一個模型(modelB)相關的one2many字段的模型(modelA),modelB中的一個字段是一個category字段,它是一個many2one字段。要求是爲每個類別顯示一個二十個字段。因此,如果有兩個類別分別命名爲'category1'和'category2',則modelA的表單視圖應該有2個one2many字段,其中一個顯示category1的記錄,另一個顯示category2的記錄(可能可以使用域)。動態顯示具有不同域的多個one2many字段?

例如,modelA和modelB具有以下結構。

class classA(models.Model): 
    _name = 'modelA' 

    modelA_one2manyfield = fields.One2many('modelB', 'modelB_many2onefield') 

class classB(models.Model): 
    _name = 'modelB' 

    name = fields.Char() 
    category = fields.Many2one('modelC') 
    modelB_many2onefield = fields.Many2one('modelA') 

我會如何實現用於MODELA一種形式的視圖,以便爲每個類別(其可以由用戶來添加,因此,可以有任意數量的類別中的)有一個單獨的one2many字段。

回答

1

你在問什麼需要很多時間來給出一個很好的答案我認爲你需要嘗試的方式之一是覆蓋fields_view_get,因爲這是檢索視圖的方法,在這裏你可以改變arch字段添加一個costum場看看這個教程:

Tutorial for dynamic view

,但我認爲你將有一個問題,因爲即使當你把域在XML的one2many場,odoo不會過濾 在視圖上發生加載時的記錄:

<!-- here all record are shown but the expected behavior is the one2many should be empty --> 
<field name="one2many_field_name" readonly="1" nolabel="1" domain="[('id', '=', False)]"> 

但是當我這個字段添加到蟒蛇聲明

# here no record will be shown on the view and that's what was expected 
one2many_field_name = fields.One2many(..., domain=[('id', '=', False)]) 

所以通過fields_view_get增加one2many場拱問題是容易的,但問題是filtring數據!

+0

但具有相同場一次以上的形式不會工作,對於相關領域,必須使用像'one2many_field_name_related = fields.One2many(相關=「one2many_field_name」)'。因此,在過濾fields_view_get方法的同時,我還需要創建與分類一樣多的相關字段。但是,是否有可能從一個方法內創建新的字段?如果可能的話,那麼這個問題就可以解決。 – diabolicfreak

1

這在技術上是不可能的。因爲在同一視圖中不能有兩次相同的字段。

但是你可以創建一個特定的小部件來顯示你想要的東西。您如何在時間表視圖中查看(我的當前時間表菜單)。

這是一個創建小部件的小教程。 https://www.odoo.com/documentation/10.0/howtos/web.html#widgets-basics

+0

我可以創建一個one2many相關視圖來顯示完全相同的one2many字段,但我需要創建儘可能多的相關領域,因爲有類別,如果它可能從一個方法創建一個新的領域,然後我可以重寫fields_view_get和創建新的二維相關字段,然後顯示這些字段。但問題是,有沒有辦法從odoo中的方法創建一個新的字段? – diabolicfreak

+0

您的字段是您的模型的屬性。而且不能爲每個類別創建一個新字段,因爲在模型中添加新字段時,需要更新模塊以實施新字段。這個領域有很多含義。很抱歉,如果您想在您的O2M中顯示您的記錄的特定視圖。您需要創建一個新的小部件。或者讓你的第一列成爲類別,然後按類別排列。 – jo541

1

這不是一個答案,但你能說動態視圖的教程示例: MODUL structur:

->dynamic_view 
    --> __ini__.py 
    --> models.py 
    --> views.xml 
    --> __manifest__.py 

__manifest__.py

# -*- coding: utf-8 -*- 
     { 
      'name' : 'Dynamic view', 
      'version' : '1.0', 
      'summary': 'Tutorial for Dynamic view', 
      'sequence': 30, 
      'description': """ 
      This Module is for showing that you can update the code of the view 
      when it's called and even create new field without having to use python 
      code at all 
      """, 
      'category': 'StackOverFlow', 
      'depends' : ['base_setup',], 
      'data': [ 
       'views.xml' 
      ], 
      'installable': True, 
      'application': True, 
      'auto_install': False, 
     } 

__init__.py

 # -*- coding: utf-8 -*- 
     from . import models 

models.py

# -*- coding: utf-8 -*- 

     from odoo import models, fields, api 


     class Person(models.Model): 
      _name = "training.person" 

      name = fields.Char("Full name") 


     class Car(models.Model): 
      _name = "training.car" 
      name = fields.Char("Car name") 
      mark_id = fields.Many2one(comodel_name="training.mark", string="Mark") 
      owner_id = fields.Many2one(comodel_name="training.person", string="Owner") 


     person_view_id = "dynamic_view.dgapr_form_person" 
     # here default arch value body in the view contains only 
     # name field but as we create new mark we add others field 
     person_view_arch = """ 
       <group> 
        <field name="name"/> 
       </group> 
     """ 


     class Mark(models.Model): 

      _name = "training.mark" 

      name = fields.Char("Mark") 

      @api.model 
      def create(self, values): 
       """ 
        when we create a category we add one2many field to person view 
        TODO: when we unlink a category we need to remove the one2many 
         name of field is : x_mark_{id of deleted record} 
       """ 
       rec_id = super(Mark, self).create(values) 
       o2m_field = { 
        # fields created using orm method must start with x_ 
        "name": "x_mark_%s"% rec_id.id, 
        "field_description": "Mark %s" % rec_id.name, 
        "ttype": "one2many", 
        "relation": "training.car", 
        "relation_field": "owner_id", 
        "stored": True, 
        "domain": "[('mark_id','=', %s)]"%rec_id.id, 
        "model_id": self.env.ref("dynamic_view.model_training_person").id, 
       } 
       # add on2many field to ir.model.fields 
       self.env["ir.model.fields"].create(o2m_field) 
       self.update_arch() 
       return rec_id 

      def update_arch(self): 
       """ 
       when ever we create or delete a mark record 
       we need to update the the view to add new one2many field 
       if we want to hide the one2many field in view that don't have 
       any record we should create compute field to use attrs features 
       """ 
       view_id = self.env.ref(person_view_id) 
       o2m_fields_ids = self.env['ir.model.fields'].search(
        [ 
         ('model_id', '=', self.env.ref("dynamic_view.model_training_person").id), 
         ('ttype', 'like', 'one2many'), 
         ('relation_field', 'like', 'owner_id') 
        ]) 
       o2many_arch = "" 
       for o2m_id in o2m_fields_ids: 
        o2many_arch = o2many_arch + """ 

         <group col="1" string="%s"> 
          <field name="%s" noloable="1" /> 
         </group> 

         """ % (o2m_id.field_description, o2m_id.name,) 

       arch_begin = """ 
        <form> 
         <sheet> 
        """ 
       arch_close = """ 
         </sheet> 
        </form> 
        """ 
       arch_body = person_view_arch + o2many_arch 
       new_arch = arch_begin + arch_body + arch_close 

       # update the arch of the view in database 
       view_id.arch = new_arch 

意見。XML:

<?xml version="1.0" encoding="utf-8" ?> 
     <odoo> 
      <data> 

       <record id="dgapr_form_car" model="ir.ui.view"> 
        <field name="name">car.form</field> 
        <field name="model">training.car</field> 
        <field name="arch" type="xml"> 
         <form > 
          <sheet> 
           <group> 
            <field name="name"/> 
            <field name="mark_id"/> 
            <field name="owner_id"/> 
           </group> 
          </sheet> 
         </form> 
        </field> 
       </record> 

       <record id="dgapr_action_car" model="ir.actions.act_window"> 
        <field name="name">Cars</field> 
        <field name="res_model">training.car</field> 
        <field name="view_type">form</field> 
        <field name="view_mode">tree,form</field> 
       </record> 

       <menuitem id="menu_root_training" name="Training"/> 
       <menuitem id="menu_ch_car" name="Cars" parent="menu_root_training" action="dgapr_action_car"/> 


       <record id="dgapr_form_person" model="ir.ui.view"> 
        <field name="name">dgapr.form.person</field> 
        <field name="model">training.person</field> 
        <field name="arch" type="xml"> 
         <form> 
          <sheet> 
           <group> 
            <field name="name"/> 
           </group> 
          </sheet> 
         </form> 
        </field> 
       </record> 


      </data> 
     </odoo> 

我發現,您可以使用ORM方法甚至計算領域建立領域。我認爲創建一個小部件比較好,但是很高興知道文能夠創建成本領域。

希望這有助於你

注意我沒有爲個人記錄創建一個菜單,但你可以通過點擊在車上形式owner_id看風景,如果未顯示剛剛刷新的新one2many場頁。

Person Form after adding two category and 3 car to charif

+0

這是在odoo 10中,但我認爲使它在odoo 8中工作很容易 – Cherif