One2many 一对多字段
上一章定义了 Many2one 字段,将 Bangumi 与 Category 相关联。
class Bangumi(models.Model):
    _name = 'bangumi.bangumi'
    _description = 'Bangumi'
    name = fields.Char(string='Name', required=True)
    total = fields.Integer(string='Total', required=True)
    already_seen = fields.Integer(string='Already seen', default=0)
    score = fields.Float(string='Score', required=True, default=0.0)
    category_id = fields.Many2one(
        'bangumi.category', string='Category', required=False
    )
我们先进入交互式命令行将之前创建的数据于类别关联起来,同样的启动时别忘了 -u bangumi 参数,因为模型变更了。
$ ./odoo-bin shell -c odoorc.ini -u bangumi
...
In [1]: anime = env['bangumi.category'].search([('name', '=', 'Anime')])        
In [2]: anime                                                                   
Out[2]: bangumi.category(2,)
In [3]: env['bangumi.bangumi'].search([]).write({'category_id': anime.id})      
Out[3]: True
In [4]: env.cr.commit()
访问一下 bangumi 的 category_id 字段看看关联是否成功了。
In [8]: bangumi = env['bangumi.bangumi'].search([], limit=1)
In [9]: bangumi.category_id.name                                                
Out[9]: 'Anime'
可以看到 category_id 字段已经成功关联了,那么我们怎么从 Anime 这个类别访问到它底下的所有 bangumi 呢?    
这时候就需要在 Category 模型下定义一个 One2Many 字段来反向关联到 Bangumi 模型。  
class Category(models.Model):
    _name = 'bangumi.category'
    _description = 'Bangumi category'
    @api.model
    def _get_current_uid(self):
        _logger.info("Category model call _get_current_uid(%s)" % self)
        return self.env.uid
    name = fields.Char(string='Name', required=True)
    user_id = fields.Many2one(
        'res.users', string='User', required=True,
        default=_get_current_uid
    )
    bangumi_ids = fields.One2many(
        'bangumi.bangumi', 'category_id',
        string='Category Bangumi Set'
    )
这个字段的第一个属性是反向关联的模型,也就是 bangumi.bangumi。第二个字段是当前模型在反向关联的模型中定义为哪个字段,我们定义的是 category_id 字段。  
⚠️ 这里依然要注意字段的命名,Odoo 中的 One2many 字段名称请以 _ids 结尾。  
再次进入命令行:
$ ./odoo-bin shell -c odoorc.ini -u bangumi
...
In [1]: anime = env['bangumi.category'].search([('name', '=', 'Anime')])
In [2]: anime.bangumi_ids                                                       
Out[2]: bangumi.bangumi(1, 2)