我有一个模型(modelA),其中one2many字段与另一个模型(modelB)相关,而modelB中的一个字段是category字段,这是一个many2one字段。要求是为每个类别显示一个one2many字段。因此,如果有2个名为'category1'和'category2'的类别,modelA的表单视图应该有2个one2many字段,一个显示category1的记录,另一个显示category2的记录(可能使用domain)。
例如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字段。
答案 0 :(得分:1)
你所要求的是花费大量时间给出一个非常好的答案我认为你需要尝试的方法是覆盖fields_view_get
,因为这是一种可以检索视图的方法,你可以在这里更改arch
字段以添加costum字段,请查看本教程:
但我认为你会遇到问题,因为即使你把域放在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)]">
但是当我将此字段添加到python声明
时# 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
向one arch添加one2many字段的问题很简单,但问题是过滤数据!!
答案 1 :(得分:1)
技术上不可行。因为在同一视图中不能有相同字段的2倍。
但您可以创建一个特定的小部件来显示您想要的内容。如何在时间表视图中查看(我的当前时间表菜单)。
这是一个创建小部件的小教程。 https://www.odoo.com/documentation/10.0/howtos/web.html#widgets-basics
答案 2 :(得分:1)
这不是答案,但您可以说动态视图的教程示例: 模块结构:
->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
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>
我发现你可以使用ORM方法甚至计算字段创建字段。我认为创建一个小部件更好,但很高兴知道wen可以创建costum字段。
希望这有助于你
注意我没有为人员记录创建菜单,但如果新的one2many字段未显示只是刷新页面,则可以通过点击车窗体中的owner_id来查看视图。