|
板凳

楼主 |
发表于 2015-9-2 20:46:07
|
只看该作者
Example:
'category_ids':
fields.many2many(
'res.partner.category',
'res_partner_category_rel',
'partner_id',
'category_id',
'Categories'),
To make it bidirectional (= create a field in the other object):
class other_object_name2(osv.osv):
_inherit = 'other.object.name'
_columns = {
'other_fields': fields.many2many(
'actual.object.name',
'relation object',
'actual.object.id',
'other.object.id',
'Other Field Name'),
}
other_object_name2()
Example:
class res_partner_category2(osv.osv):
_inherit = 'res.partner.category'
_columns = {
'partner_ids': fields.many2many(
'res.partner',
'res_partner_category_rel',
'category_id',
'partner_id',
'Partners'),
}
res_partner_category2()
related:
有时候你需要考虑关联中的关联。例如,假设你有这样的对象:City -> State -> Country,你需要从一个城市名得到一个国家名,你可以在City对象中定义:
'country_id': fields.related(
'state_id',
'country_id',
type="many2one",
relation="res.country",
string="Country",
store=False)
Where:
The first set of parameters are the chain of reference fields to follow, with the desired field at the end.
:guilabel:type是期望字段的类型。
Use :guilabel:`relation` if the desired field is still some kind of reference. :guilabel:`relation` is the table to look up that reference in.
Functional Fields
功能字段是通过函数计算了值的字段。 (rather than being stored in the database).
Parameters:
fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type="float",
fnct_search=None, obj=None, method=False, store=False, multi=False
where
:guilabel:`fnct` is the function or method that will compute the field value. It must have been declared before declaring the functional field.
:guilabel:`fnct_inv` is the function or method that will allow writing values in that field.
:guilabel:`type` is the field type name returned by the function. It can be any field type name except function.
:guilabel:`fnct_search` allows you to define the searching behaviour on that field.
:guilabel:`method` whether the field is computed by a method (of an object) or a global function
:guilabel:`store` If you want to store field in database or not. Default is False.
:guilabel:`multi` is a group name. All fields with the same multi parameter will be calculated in a single function call.
fnct parameter
If method is True, the signature of the method must be:
def fnct(self, cr, uid, ids, field_name, arg, context):
otherwise (if it is a global function), its signature must be:
def fnct(cr, table, ids, field_name, arg, context):
不管哪种形式,它的返回值形式是: {id'_1_': value'_1_', id'_2_': value'_2_',...}.
返回值必须是之前定义的类型。
如果multi是set,则field_name将会被field_names代替:a list of the field names会被计算。Each value in the returned dictionary is also a dictionary from field name to value.例如,如果字段’name’和’age’都基于函数vital_statistics,那么该函数的返回值应该是这样(当ids是 [1,2,5])::
{
1: {'name': 'Bob', 'age': 23},
2: {'name': 'Sally', 'age', 19},
5: {'name': 'Ed', 'age': 62}
}
fnct_inv parameter
如果method是True,那么method声明是::
def fnct(self, cr, uid, ids, field_name, field_value, arg, context):
不然(如果是全局函数),声明是:
def fnct(cr, table, ids, field_name, field_value, arg, context):
fnct_search parameter
If method is true, the signature of the method must be:
def fnct(self, cr, uid, obj, name, args, context):
otherwise (if it is a global function), it should be:
def fnct(cr, uid, obj, name, args, context):
在查找函数中,返回值是三元祖的列表。
return [('id','in',[1,3,5])]
obj和self相同,name接受字段名。args是三元祖的列表,包含这个字段的查询规范,即使每个元祖分别调用该查询函数。
例子
我们创建这样一个contract对象:
class hr_contract(osv.osv):
_name = 'hr.contract'
_description = 'Contract'
_columns = {
'name' : fields.char('Contract Name', size=30, required=True),
'employee_id' : fields.many2one('hr.employee', 'Employee', required=True),
'function' : fields.many2one('res.partner.function', 'Function'),
}
hr_contract()
如果添加一个字段要通过看它的current contract来检索员工,我们使用functional field。对象hr_employee这样继承:
class hr_employee(osv.osv):
_name = "hr.employee"
_description = "Employee"
_inherit = "hr.employee"
_columns = {
'contract_ids' : fields.one2many('hr.contract', 'employee_id', 'Contracts'),
'function' : fields.function(
_get_cur_function_id,
type='many2one',
obj="res.partner.function",
method=True,
string='Contract Function'),
}
hr_employee()
def _get_cur_function_id(self, cr, uid, ids, field_name, arg, context):
for i in ids:
#get the id of the current function of the employee of identifier "i"
sql_req= """
SELECT f.id AS func_id
FROM hr_contract c
LEFT JOIN res_partner_function f ON (f.id = c.function)
WHERE
(c.employee_id = %d)
""" % (i,)
cr.execute(sql_req)
sql_res = cr.dictfetchone()
if sql_res: #The employee has one associated contract
res[i] = sql_res['func_id']
else:
#res[i] must be set to False and not to None because of XML:RPC
# "cannot marshal None unless allow_none is enabled"
res[i] = False
return res
在SQL query中使用函数的id来检索。如果这个查询没有结果返回,那么sql_res[‘func_id’]的值为None。我们必须将值设为False,因为XML:RPC不允许传送该值。
store Parameter
它会计算该字段的值,并且将结果存储在表中。当其他对象中相应该字段的值发生变化时会重新计算它。它使用一下句法:
store = {
'object_name': (
function_name,
['field_name1', 'field_name2'],
priority)
}
当对象object_name中列表['field1','field2']中的字段发生变化时,会调用函数function_name。函数声明如下:
def function_name(self, cr, uid, ids, context=None):
ids是其他对象表中记录的ids,这些对象有些字段值已被更改。这个函数在自己表中返回a list of ids of records 并且有些值已被更改。这个list作为main函数的参数字段。
|
|