odoo 批量查询

功能说明:

在进行查询时,可以批量,多个产品编码使用逗号分割

限制:

查询的字符必须是全程,不能模糊查询


def remove_empty_from_list(lst):
    """移除空字符"""
    return [i for i in lst if i != '']


def domain_add_in(domain):
    """
    domain中添加in查询参数,根据传入的值来盘点是否需要改写domain
    如果查询的数值中带有',' 则进行切割查询
    :param domain:
    :return: domain
    """
    # domain1 = ['&', ('id', '=', 1), ('name', '=', '1,2,4'), ('age', '=', '1,2,34,5')]
    domain2 = deepcopy(domain)
    if domain:
        position = 0
        for index, item in enumerate(domain):
            if not isinstance(item, (list, tuple)):
                continue
            if item[1] in ('ilike',) and ',' in str(item[2]):
                # list_value = item[2].split(',')
                list_value = re.split(r'[\s,]', item[2])
                list_value = remove_empty_from_list(list_value)
                domain2.insert(index + position, (item[0], 'in', list_value))
                domain2.insert(index + position, '|')
                position += 2
    return domain2 or []


@api.model
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
    """
    Private implementation of search() method, allowing specifying the uid to use for the access right check.
    This is useful for example when filling in the selection list for a drop-down and avoiding access rights errors,
    by specifying ``access_rights_uid=1`` to bypass access rights check, but not ir.rules!
    This is ok at the security level because this method is private and not callable through XML-RPC.

    :param access_rights_uid: optional user ID to use when checking access rights
                              (not for ir.rules, this is only for ir.model.access)
    :return: a list of record ids or an integer (if count is True)
    """
    self.sudo(access_rights_uid or self._uid).check_access_rights('read')
    args = domain_add_in(args)
    if expression.is_false(self, args):
        # optimization: no need to query, as no record satisfies the domain
        return 0 if count else []

    query = self._where_calc(args)
    self._apply_ir_rules(query, 'read')
    order_by = self._generate_order_by(order, query)
    from_clause, where_clause, where_clause_params = query.get_sql()

    where_str = where_clause and (" WHERE %s" % where_clause) or ''

    if count:
        # Ignore order, limit and offset when just counting, they don't make sense and could
        # hurt performance
        query_str = 'SELECT count(1) FROM ' + from_clause + where_str
        self._cr.execute(query_str, where_clause_params)
        res = self._cr.fetchone()
        return res[0]

    limit_str = limit and ' limit %d' % limit or ''
    offset_str = offset and ' offset %d' % offset or ''
    query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str
    self._cr.execute(query_str, where_clause_params)
    res = self._cr.fetchall()

    # TDE note: with auto_join, we could have several lines about the same result
    # i.e. a lead with several unread messages; we uniquify the result using
    # a fast way to do it while preserving order (http://www.peterbe.com/plog/uniqifiers-benchmark)
    def _uniquify_list(seq):
        seen = set()
        return [x for x in seq if x not in seen and not seen.add(x)]

    return _uniquify_list([x[0] for x in res])


models.Model._search = _search
posted @ 2023-03-10 13:51  那时一个人  阅读(122)  评论(0)    收藏  举报