Odoo 11 필드 타입 2


관계형 타입



one2one

- one2one 필드는 두 객체간의 하나의 관계를 표현합니다. [사용되지 않습니다. many2one을 대신 사용합니다.] 


fields.one2one('other.object.name', 'Field Name')


 many2one

- 여러개를 하나에 연결한다는 의미입니다.


fields.many2one(
        'other.object.name',
        'Field Name',
        optional parameters)


Optional parameters


ondelete : 이 필드가 가리키는 자원이 삭제되면 어떻게 될 것인가.

미리 정의 된 값 : "cascade", "set null", "restrict", "no action", "default"

기본값 : "set null"


required : True


readonly : True


select : True - (외래 키 필드에 색인 생성)



예 )

'commercial': fields.many2one(
        'res.users',
        'Commercial',
        ondelete='cascade'),



one2many

 하나에 여러개를 연결한다는 의미입니다.


fields.one2many(
        'other.object.name',
        'Field relation id',
        'Fieldname',
        optional parameter)


Optional parameters


invisible: True / False


states:?


readonly: True / False



예 )

'address': fields.one2many(
        'res.partner.address',
        'partner_id',
        'Contacts'),



many2many

 여러개를 여러개에 연결한다는 의미입니다.


fields.many2many('other.object.name',
                 'relation object',
                 'actual.object.id',
                 'other.object.id',
                 'Field Name')


TIP


other.object.name은 관계에 속한 다른 객체입니다.


관계 객체는 링크를 만드는 테이블입니다.


actual.object.id 및 other.object.id는 관계 테이블에서 사용되는 필드의 이름입니다.



예 )

'category_ids':
   fields.many2many(
    'res.partner.category',
    'res_partner_category_rel',
    'partner_id',
    'category_id',
    'Categories'),


그것을 양방향으로 만들려면 => 다른 객체에 필드를 생성하십시오.


예 )

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()


예 )

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를 참조해야하는 경우 City 객체에서 아래와 같이 필드를 정의할 수 있습니다.


'country_id': fields.related(
    'state_id',
    'country_id',
    type="many2one",
    relation="res.country",
    string="Country",
    store=False)


TIP


other.object.name은 관계에 속한 다른 객체입니다.


관계 객체는 링크를 만드는 테이블입니다.


actual.object.id 및 other.object.id는 관계 테이블에서 사용되는 필드의 이름입니다.



Functional Fields

 함수 필드는 값이 함수에 의해 계산되는 필드 입니다. (데이터베이스에 저장되는것이 아닙니다.)


매개변수 종류 )

fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type="float", fnct_search=None, obj=None, method=False, store=False, multi=False



- fnct는 필드 값을 계산하는 함수 또는 메소드입니다. 기능 필드를 선언하기 전에 선언되어 있어야합니다.


fnct Prameter


method가 True이면 메소드의 서명은 다음과 같아야합니다.


def fnct(self, cr, uid, ids, field_name, arg, context):


그렇지 않으면 (전역 함수 인 경우) 서명은 다음과 같아야합니다.


def fnct(cr, table, ids, field_name, arg, context):


어느 쪽이든 {{id'_1_ ': value'_1_', id'_2_ ': value'_2 _', ...} 형식의 값 사전을 리턴해야합니다.


반환 된 딕셔너리의 값은 필드 선언의 type 인수로 지정된 유형이어야합니다.


multi가 설정된 경우 field_name은 field_names로 대체됩니다. 이것은 계산해야 할 필드 이름의 목록입니다. 

반환 된 사전의 각 값은 필드 이름에서 값까지의 사전이기도합니다.

예를 들어 'name'및 'age'필드가 모두 vital_statistics 함수를 기반으로하고 ids가 [1, 2, 5] 인 경우 vital_statistics의 반환 값은 다음과 같을 수 있습니다.


{
    1: {'name': 'Bob', 'age': 23},
    2: {'name': 'Sally', 'age', 19},
    5: {'name': 'Ed', 'age': 62}
}



- fnct_inv는 해당 필드에 값을 쓸 수있게 해주는 함수 또는 메서드입니다.


fnct_inv Prameter


method가 true 인 경우 메서드의 시그니처는 다음과 같아야합니다.


def fnct(self, cr, uid, ids, field_name, field_value, arg, context):


그렇지 않으면 (전역 함수 인 경우) 다음과 같아야합니다.


def fnct(cr, table, ids, field_name, field_value, arg, context):



- type은 함수가 반환 한 필드 유형 이름입니다. 함수를 제외하고 모든 필드 유형 이름이 될 수 있습니다.



- fnct_search를 사용하면 해당 필드에서 검색 동작을 정의 할 수 있습니다.


fnct_search Prameter


method가 true 인 경우 메서드의 시그니처는 다음과 같아야합니다.


def fnct(self, cr, uid, obj, name, args, context):


그렇지 않으면 (전역 함수 인 경우) 다음과 같아야합니다.


def fnct(cr, uid, obj, name, args, context):


반환 값은 검색 함수에 사용되는 3파트의 튜플을 포함하는 목록입니다.


return [('id','in',[1,3,5])]


obj는 self와 같고 name은 필드 이름을받습니다. 

args는 이 필드에 대한 검색 기준을 포함하는 3파트로 된 튜플 리스트입니다.

검색 함수는 각 튜플에 대해 개별적으로 호출 될 수 있습니다.


다음과 같은 계약 객체를 생성한다고 가정 해보십시오.

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()


현재 계약을 살펴봄으로써 직원의 기능을 검색하는 필드를 추가하려는 경우 기능 필드를 사용합니다. 

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()


TIP


함수 필드가 many2one 필드를 만들어야하기 때문에 type = 'many2one'입니다. 함수는 hr_contract에서도 many2one으로 선언됩니다.


obj = "res.partner.function"은 many2one 필드에 사용할 객체가 res.partner.function임을 지정하는 데 사용됩니다.


우리의 메소드는 _get_cur_function_id 메소드를 호출했습니다. 그 역할은 키가 직원 ID이고 해당 값이 해당 직원의 기능에 대한 ID 인 사전을 리턴하기 때문입니다. 

이 메소드의 코드는 다음과 같습니다.


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


함수의 ID는 SQL 조회를 사용하여 검색됩니다. 쿼리가 결과를 반환하지 않으면 sql_res [ 'func_id']의 값은 None이됩니다. 

XML : RPC (서버와 클라이언트 간의 통신)가이 값을 전송할 수 없기 때문에이 경우 False 값을 강제합니다.



- method가 (객체의) 메소드 또는 전역 함수에 의해 계산되는지 여부



- store 데이터베이스에 필드를 저장할지 여부. 기본값은 False입니다.


store Prameter


필드를 계산하고 테이블에 결과를 저장합니다. 특정 필드가 다른 오브젝트에서 변경되면 필드가 다시 계산됩니다. 

다음 구문을 사용합니다.


store = {
    'object_name': (
            function_name,
            ['field_name1', 'field_name2'],
            priority)
}


'[object1]'객체의 [field1 ','field2 '] 목록의 필드에 변경 사항이 기록되면 함수 function_name을 호출합니다. 

함수의 서명은 다음과 같습니다.


def function_name(self, cr, uid, ids, context=None):


ids는 감시 대상 필드에서 값이 변경된 다른 객체의 테이블에있는 레코드의 ID입니다. 

이 함수는 필드를 다시 계산해야하는 자체 테이블의 레코드 ID 목록을 반환해야합니다. 이 목록은 필드의 주요 기능에 대한 매개 변수로 전송됩니다.


다음은 회원 모듈의 예입니다.


'membership_state':
    fields.function(
        _membership_state,
        method=True,
        string='Current membership state',
        type='selection',
        selection=STATE,
        store={
            'account.invoice': (_get_invoice_partner, ['state'], 10),
            'membership.membership_line': (_get_partner_id,['state'], 10),
            'res.partner': (
                lambda self, cr, uid, ids, c={}: ids,
                ['free_member'],
                10)
        }),



- multi는 그룹 이름입니다. 동일한 다중 매개 변수가있는 모든 필드는 단일 함수 호출로 계산됩니다.



+ Recent posts