zoukankan      html  css  js  c++  java
  • odoo child_of, parent_of 理解

    该操作符是用于多层继承结构的查询,和in不同,

    我们有如下表格product.category,parent_id 外键关联到自身的表格,可以设置记录之间的层级关系.

     id | parent_path |       name       |            complete_name             | parent_id |
    ----+-------------+------------------+--------------------------------------+-----------+
      1 | 1/          | All              | All                                  |           |
      2 | 1/2/        | Saleable         | All / Saleable                       |         1 |
      3 | 1/3/        | Expenses         | All / Expenses                       |         1 |
      4 | 1/4/        | Internal         | All / Internal                       |         1 |
      5 | 1/2/5/      | Services         | All / Saleable / Services            |         2 |
      6 | 1/2/5/6/    | Saleable         | All / Saleable / Services / Saleable |         5 |
      7 | 1/2/7/      | Software         | All / Saleable / Software            |         2 |
      8 | 1/2/8/      | Office Furniture | All / Saleable / Office Furniture    |         2 |
      9 | 1/9/        | Consumable       | All / Consumable                     |         1 |
    (9 行记录)
    

    假如我要查询id=2 的所有子记录(包含子记录的子记录),就可以使用child_of 操作符:

    categ = self.env.get('product.category').browse(2)
    categ.search([('id', 'child_of', categ.id)]).ids
    # [2, 8, 5, 6, 7]
    

    同理,也可以查询某一条记录的所有父记录,

    目前还明白算法是怎样实现的,但是算法的代码应该如下:

            def child_of_domain(left, ids, left_model, parent=None, prefix=''):
                """ Return a domain implementing the child_of operator for [(left,child_of,ids)],
                    either as a range using the parent_path tree lookup field
                    (when available), or as an expanded [(left,in,child_ids)] """
                if not ids:
                    return FALSE_DOMAIN
                if left_model._parent_store:
                    doms = OR([
                        [('parent_path', '=like', rec.parent_path + '%')]
                        for rec in left_model.browse(ids)
                    ])
                    if prefix:
                        return [(left, 'in', left_model.search(doms).ids)]
                    return doms
                else:
                    parent_name = parent or left_model._parent_name
                    child_ids = set(ids)
                    while ids:
                        ids = left_model.search([(parent_name, 'in', ids)]).ids
                        child_ids.update(ids)
                    return [(left, 'in', list(child_ids))]
    
            def parent_of_domain(left, ids, left_model, parent=None, prefix=''):
                """ Return a domain implementing the parent_of operator for [(left,parent_of,ids)],
                    either as a range using the parent_path tree lookup field
                    (when available), or as an expanded [(left,in,parent_ids)] """
                if left_model._parent_store:
                    parent_ids = [
                        int(label)
                        for rec in left_model.browse(ids)
                        for label in rec.parent_path.split('/')[:-1]
                    ]
                    if prefix:
                        return [(left, 'in', parent_ids)]
                    return [('id', 'in', parent_ids)]
                else:
                    parent_name = parent or left_model._parent_name
                    parent_ids = set()
                    for record in left_model.browse(ids):
                        while record:
                            parent_ids.add(record.id)
                            record = record[parent_name]
                    return [(left, 'in', list(parent_ids))]
    
  • 相关阅读:
    残缺的字符串
    [BZOJ3513: [MUTC2013]idiots]
    FFT感性瞎扯
    Quartz框架简介
    异常状态码总结
    【SSM】拦截器的原理、实现
    FastDFS实现文件上传下载实战
    分布式文件系统FastDFS设计原理(转)
    FastDFS简介
    【设计模式】观察者模式
  • 原文地址:https://www.cnblogs.com/qianxunman/p/12393259.html
Copyright © 2011-2022 走看看