search()
根据domain查询满足条件的数据记录,默认查询active为true的记录。
def search(self, args, offset=0, limit=None, order=None, count=False):
""" search(args[, offset=0][, limit=None][, order=None][, count=False])
Searches for records based on the ``args``
:ref:`search domain <reference/orm/domains>`.
:param args: :搜索域,使用空列表来匹配所有记录.
:param int offset: 要忽略的结果数
:param int limit: 返回的最大记录数
:param str order: 排序字符串
:param bool count: 如果为True,则仅计算并返回匹配记录的数量
:returns: 最多符合搜索条件的``limit''条记录
:raise AccessError: * 如果用户尝试绕过访问规则以读取请求的对象.
"""
res = self._search(args, offset=offset, limit=limit, order=order, count=count)
return res if count else self.browse(res)
active字段的特殊用法,使用active_test=False.
_search():
search_read,name_search,都会调用。
search()方法的私有实现,允许指定用于访问权限检查的uid。
例如,在为下拉列表填写选择列表并避免访问权限错误时,这很有用,
通过指定``access_rights_uid = 1’'绕过访问权限检查,而不是ir.rules!
在安全级别上可以这样做,因为此方法是私有的,不能通过XML-RPC调用。
@api.model
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
model = self.with_user(access_rights_uid) if access_rights_uid else self
model.check_access_rights('read')
if expression.is_false(self, args):
return 0 if count else []
#刷新必须在_where_calc()之前完成,因为后者可以执行某些选择
self._flush_search(args, order=order)
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()
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])
search_read():
页面默认数据筛选,分组后点击展开明细,控制页面显示数据筛选
@api.model
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
"""
:param domain: 搜索域,请参阅search中的args参数。默认为一个空域,它将匹配所有记录.
:param fields: 要读取的字段列表,请参见read中的fields参数。 默认为所有字段。
:param int offset: 要跳过的记录数,请参阅search中的offset参数。 默认为0.
:param int limit: 要返回的最大记录数,请参阅search中的limit参数。默认为无限制.
:param 用于对结果进行排序的列,请参见search中的order参数。 默认为无排序。
:return: 包含要求字段的词典列表.
:rtype: list(dict).
"""
records = self.search(domain or [], offset=offset, limit=limit, order=order)
if not records:
return []
if fields and fields == ['id']:
# shortcut read if we only want the ids
return [{'id': record.id} for record in records]
# TODO: Move this to read() directly?
if 'active_test' in self._context:
context = dict(self._context)
del context['active_test']
records = records.with_context(context)
result = records.read(fields)
if len(result) <= 1:
return result
read_group():
点击分组和筛选,主要控制分组或筛选后的分组显示数量。
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
"""获取列表视图中按给定``groupby''字段分组的记录列表.
:param list domain: :搜索域,使用空列表来匹配所有记录。
:param list fields: 在对象上指定的列表视图中存在的字段列表。
:param list groupby:记录分组的分组依据描述列表。
:param int offset:跳过的可选记录数
:param int limit: 可选的最大返回记录数。
:param list orderby:,用于覆盖组的自然排序顺序。
:param bool lazy: 如果为true,则结果仅按第一个groupby分组,其余的groupbys放入__context键。 如果为false,则所有groupby均在一次调用中完成。
:return: 词典列表(每条记录一个词典)
"""
result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
groupby = [groupby] if isinstance(groupby, str) else list(OrderedSet(groupby))
dt = [
f for f in groupby
if self._fields[f.split(':')[0]].type in ('date', 'datetime')
]
for group in result:
for df in dt:
if group.get(df):
group[df] = group[df][1]
return result
name_search()
关联字段输入框搜索时调用,定义搜索条件。例如:按名称搜索:
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
return self._name_search(name, args, operator, limit=limit)
@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
args = list(args or [])
if not self._rec_name:
_logger.warning("Cannot execute name_search, no _rec_name defined on %s", self._name)
elif not (name == '' and operator == 'ilike'):
args += [(self._rec_name, operator, name)]
ids = self._search(args, limit=limit, access_rights_uid=name_get_uid)
recs = self.browse(ids)
return lazy_name_get(recs.with_user(name_get_uid))
name_get()
关联字段输入框搜索时调用,控制搜索时候的字段展示。例如:显示部门编号+部门名称:
def name_get(self):
"""
返回“ self”中记录的文本表示形式。默认情况下,这是“ display_name”字段的值。
:return: 每个记录({id,text_repr)的列表
:rtype: list(tuple)
"""
result = []
name = self._rec_name
if name in self._fields:
convert = self._fields[name].convert_to_display_name
for record in self:
result.append((record.id, convert(record[name], record)))
else:
for record in self:
result.append((record.id, "%s,%s" % (record._name, record.id)))
return result