2017-04-12 59 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