odoo中一个动态视图的例子(在运行期间动态修改视图布局)

admin 2019-10-15 6267

1000 * 400 = 40万

This not an answer but you can say a tutorial example of dynamic view : 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 databas
      view_id.arch = new_arch


views.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>


I found out that you can create field using ORM method even compute field. i think creating a widget is better but good to know that wen can create costum fields .

Hope this helps you

Note i didn't create a menu for person record but you can see the view by clicking on the owner_id in the car form if the new one2many field not shown just refresh the page.


本文来源:

https://stackoverflow.com/questions/43367240/display-multiple-one2many-field-with-different-domain-dynamically


最新回复 (0)
返回