콘텐츠로 건너뛰기

Odoo Reference Field 완전 정복 가이드

Odoo의 Reference 필드 완전 정복: 여러 모델을 연결하는 원리, 사용 시점, Studio와 Python으로 구현하는 방법
2026년 3월 6일 작성자
Odoo Reference Field 완전 정복 가이드
Dasolo
| 아직 댓글이 없습니다

소개


많은 Odoo 개발자는 레코드 연결이 필요할 때 기본적으로 Many2one을 사용합니다. 대부분의 상황에서 이 선택은 적절하지만, 연결 대상이 상황에 따라 여러 종류(판매주문, 구매주문, 제조오더 등)로 달라져야 할 때도 있습니다. 바로 이런 경우에 Reference 필드가 더 적합합니다.


Reference 필드는 Odoo ORM에서 유연하게 여러 모델을 가리킬 수 있게 설계된 필드입니다. 미리 정의한 모델 목록에서 먼저 문서 종류를 고르고, 그 다음에 구체적인 레코드를 선택하는 방식이라 한 필드로 여러 모델을 참조할 수 있는 다형성 링크를 제공합니다.


이 가이드는 Reference 필드가 내부적으로 무엇을 저장하는지, Odoo 데이터 모델에서 어떻게 동작하는지, Studio나 Python으로 어떻게 만들고 커스터마이징하는지 그리고 실제 업무에서 언제 유용한지를 다룹니다.

Odoo의 Reference 필드란 무엇인가


Odoo ORM에서 Reference 필드는 selection에 포함된 여러 모델 중 하나를 가리키는 링크를 저장하는 특별한 타입입니다. 즉, 항상 한 모델만을 가리키는 Many2one과 근본적으로 다릅니다.


데이터베이스에는 Reference 값이 model_name,record_id 형식의 문자열로 저장됩니다. 예를 들어 판매주문 42를 가리키면 sale.order,42로 저장됩니다. 직접 쿼리하거나 필터링할 때 이 저장 형식을 꼭 염두에 두어야 합니다.


UI에서는 Reference 필드가 두 단계 입력으로 보입니다. 먼저 드롭다운에서 문서 유형(예: 판매주문, 송장, 프로젝트 작업)을 선택하고, 그 모델의 레코드를 검색해 선택합니다. 사용자가 이 두 단계에 익숙해지면 인터페이스는 간단하고 직관적입니다.


아래는 Python에서 정의한 Reference 필드의 기본 형태 예시입니다.

from odoo import fields, models

class HelpDeskTicket(models.Model):
    _inherit = 'helpdesk.ticket'

    related_document = fields.Reference(
        selection=[
            ('sale.order', 'Sale Order'),
            ('purchase.order', 'Purchase Order'),
            ('account.move', 'Invoice'),
            ('project.task', 'Project Task'),
        ],
        string='Related Document',
    )

selection은 튜플 목록입니다. 각 튜플은 기술적 모델 이름(예: sale.order)과 사용자에게 보여질 레이블을 포함합니다. 이 목록을 통해 어떤 모델을 선택 가능하게 할지 정확히 제어합니다.


선택 목록을 런타임에 ir.model에서 동적으로 채우는 방식도 있습니다. 설치된 모든 모델을 노출할 수 있어 구성성이 높지만, 사용자에게 너무 많은 선택지를 주어 혼란을 일으킬 수 있으니 필터링이 필요합니다.


Odoo Studio에서는 필드 유형 패널에서 Reference로 표시되어 있으며, 코드 작성 없이 인터페이스에서 선택 가능한 모델 리스트를 설정할 수 있습니다. 따라서 비개발자도 비교적 쉽게 적용할 수 있는 고급 필드에 속합니다.

필드의 동작 방식


Reference 필드가 데이터를 어떻게 저장하고 불러오는지 이해하면 Odoo 개발에서 올바르게 활용할 수 있습니다.


데이터베이스 저장 방식

Many2one이 정수(외래키)만 저장하는 것과 달리 Reference는 모델명과 레코드 ID를 포함한 문자열을 저장합니다(예: sale.order,15)—PostgreSQL의 VARCHAR 컬럼에 보관됩니다. 이 때문에 데이터베이스 수준의 외래키 제약이 걸리지 않으며, 다형성 지원을 위한 의도된 설계입니다.


외래키 제약이 없으므로 참조 대상 레코드가 삭제되어도 Reference 필드 값은 자동으로 지워지지 않습니다. 삭제된 판매주문을 가리키는 Reference는 여전히 문자열 값을 유지하므로 이를 관리하는 로직이 필요합니다.


파이썬에서 연결된 레코드 접근하기

Python으로 Reference 값을 읽으면 Odoo는 참조된 모델의 실제 레코드 객체를 반환합니다. Many2one과 동일하게 그 객체의 필드에 직접 접근할 수 있으며, 값이 비어 있으면 False를 반환합니다.


ticket = self.env['helpdesk.ticket'].browse(1)
doc = ticket.related_document

if doc:
    print(doc._name)   # e.g. 'sale.order'
    print(doc.name)    # e.g. 'S00042'
    print(doc.id)      # e.g. 15

저장 형식은 문자열이지만 Odoo ORM은 이를 적절한 레코드 객체로 해석해 주므로 코드에서 다루기 편리한 점이 장점입니다.


주요 필드 속성

Reference 필드에서 자주 설정하는 속성은 다음과 같습니다.


  • selection: 선택 가능한 모델 목록(튜플 리스트)입니다. 또한 목록을 반환하는 메서드 이름(문자열)으로 지정해 동적 구성이 가능합니다.
  • string: UI에 표시될 필드 레이블입니다.
  • required: 필드를 필수로 만듭니다. 저장하려면 모델 타입과 레코드 모두 선택되어야 합니다.
  • readonly: UI에서 사용자가 값을 변경하지 못하게 합니다. 프로그램적으로 설정할 때 유용합니다.
  • help: 필드 라벨에 마우스를 올렸을 때 표시되는 툴팁입니다. 사용자가 어떤 값을 골라야 하는지 안내할 때 씁니다.
  • compute: 다른 필드처럼 Reference도 Python 메서드로 계산값을 채울 수 있습니다. 비즈니스 로직에 따라 자동으로 참조를 설정할 때 유용합니다.

검색과 필터링

값이 문자열로 저장되기 때문에 Reference 필드에 대한 도메인 검색은 문자열 기반으로 구성해야 합니다. 특정 문서를 가리키는 레코드를 찾으려면 전체 문자열을 직접 만들어야 합니다.


tickets = self.env['helpdesk.ticket'].search([
    ('related_document', '=', 'sale.order,15')
])

모델 타입별로만 필터링하려면 like 연산자를 사용할 수 있습니다.


tickets = self.env['helpdesk.ticket'].search([
    ('related_document', 'like', 'sale.order,')
])

보고서나 계산 필드 설계 시 Reference의 문자열 기반 필터링 특성을 고려해야 합니다. Many2one의 도메인과는 달리 동작합니다.

비즈니스 활용 사례


Reference 필드는 동일한 맥락 연결을 여러 문서 유형으로 유연하게 가리켜야 할 때 특히 유용합니다. 다음은 실제 업무 예시 다섯 가지입니다.


1. 헬프데스크 티켓에서 다양한 문서 연결

지원팀은 송장 분쟁, 배송 문제, 계약 문의, 불량품 등 서로 다른 문서와 관련된 티켓을 처리합니다. 각 문서 유형마다 별도 필드를 만드는 대신 티켓에 하나의 Reference 필드를 두면 상담원이 필요한 문서를 유형별로 선택하고 연결할 수 있어 깔끔합니다.


2. CRM 활동에 여러 출처 문서 연결

영업 활동은 리드, 견적, 계약, 지원 사례 등 다양한 출처에서 발생합니다. 커스텀 활동 또는 노트 모델에 Reference를 두면 영업 담당자가 발생 근원을 하나의 필드로 태깅할 수 있어 유연한 CRM 확장이 가능합니다.


3. 모듈 전반의 메모·주석 연결

회사에 따라 고객, 프로젝트 작업, 제조오더, 구매오더 등 여러 문서에 걸쳐 메모를 남기고 싶을 때가 있습니다. Reference를 사용하면 메모 모델을 문서 유형마다 복제할 필요 없이 하나의 레코드로 여러 객체에 붙일 수 있습니다.


4. 문서 승인 워크플로우

포괄적인 승인 프로세스를 구성할 때 승인 요청은 구매주문, 출장비, 휴가신청, 계약 등 다양한 문서를 가리켜야 합니다. 승인 모델에 Reference를 두면 동일한 승인 로직으로 여러 문서 유형을 처리할 수 있어 아키텍처가 단순해집니다.


5. 비용처리 시 프로젝트 또는 주문에 연결

회계 처리에서 비용 항목을 프로젝트에 연결할 수도 있고 판매주문과 연결할 수도 있습니다. project.projectsale.order를 모두 선택 목록에 넣은 Reference를 사용하면 회계 담당자가 상황에 따라 적절히 연결할 수 있어 전문 서비스나 컨설팅 업종에서 유용합니다.


Reference 필드 만들기와 커스터마이징


Odoo 모델에 Reference 필드를 추가하는 방법은 크게 두 가지입니다. 코드 없이 Studio를 쓰는 방법과 Python으로 직접 정의하는 개발 방법입니다.


Odoo Studio 사용하기

Odoo Studio에서는 코드 작성 없이도 폼에 Reference 필드를 추가할 수 있습니다. 확장하려는 모델에서 Studio를 열어 필드 패널에서 Reference 타입을 추가하면 됩니다. 표시할 모델을 인터페이스에서 선택하도록 안내하며, 생성된 필드는 x_ 접두사의 수동 필드로 저장됩니다.


이 방법은 빠른 커스터마이징이나 비개발자가 폼을 확장할 때 적합합니다. 다만 동적 선택 메서드나 계산값 같은 고급 설정은 제한될 수 있습니다.


파이썬에서의 기술적 구현

개발 관점에서는 Python 모델에 Reference 필드를 직접 정의하는 것이 더 강력합니다. 아래는 동적 selection 메서드를 사용하는 예시입니다.

from odoo import api, fields, models

class ApprovalRequest(models.Model):
    _name = 'approval.request'
    _description = 'Approval Request'

    name = fields.Char(string='Request Name', required=True)

    @api.model
    def _get_document_types(self):
        return [
            ('purchase.order', 'Purchase Order'),
            ('hr.expense.sheet', 'Expense Report'),
            ('hr.leave', 'Time Off Request'),
            ('sale.order', 'Sale Order'),
        ]

    document_ref = fields.Reference(
        selection='_get_document_types',
        string='Document',
        help='Select the document this approval relates to.',
    )

selection에 메서드 이름을 넘기면(문자열로) 선택 목록을 동적으로 구성할 수 있습니다. 설치된 모듈에 따라 항목을 걸러 내거나 구성 레코드로부터 목록을 만들 때 유용합니다.


XML-RPC API로 생성하기

원격 구성 과정에서 Reference 필드를 프로그래밍으로 생성하려면 Odoo XML-RPC API를 이용할 수 있습니다. 필드 타입은 reference이고 selection은 문자열화된 리스트로 전달합니다.


field_id = models.execute_kw(
    ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_related_document',
        'field_description': 'Related Document',
        'model_id': model_id,
        'ttype': 'reference',
        'selection': "[('sale.order', 'Sale Order'), ('purchase.order', 'Purchase Order')]",
        'state': 'manual',
    }]
)

API로 생성할 때 selection은 실제 리스트가 아니라 평가 가능한 파이썬 문자열로 전달된다는 점을 유의하세요. 이는 Odoo의 ir.model.fields 테이블에 저장되는 방식입니다.

모범 사례


Reference 필드를 다룰 때 따라야 할 유용한 지침들입니다.


  • 선택 목록은 짧고 의미 있게 유지하세요. 가능한 모든 모델을 넣지 마십시오. 사용 사례에 맞는 문서 유형으로 목록을 제한하면 사용자가 덜 혼란스러워하고 필드 활용도가 높아집니다.
  • 항상 동일한 모델만 참조한다면 Many2one을 사용하세요. Reference는 다형적 관계를 위해 설계되었습니다. 대상 모델이 고정이라면 Many2one이 쿼리 성능과 보고서 호환성 면에서 더 효율적입니다.
  • 계산 필드에서는 null 값을 항상 검사하세요. Reference가 비어 있으면 Python에서 False를 반환하므로 연결 레코드에 접근할 때는 먼저 존재 여부를 확인해야 오류를 피할 수 있습니다.
  • 자동화된 작업으로 고아 레퍼런스 처리 방안을 마련하세요. DB 제약이 없으므로 삭제된 레코드를 가리키는 오래된 문자열을 주기적으로 정리하는 스케줄 액션이나 자동화를 두는 것이 좋습니다.
  • 선택 목록의 레이블은 사용자 친화적으로 작성하세요. 튜플의 두 번째 요소가 드롭다운에 표시됩니다. 기술명 대신 ‘고객 송장’ 같은 비즈니스 용어를 쓰면 사용성이 좋아집니다.
  • 기술 명세서에 필드를 명확히 문서화하세요. Reference 필드는 Many2one과 다르게 동작하므로 왜 Reference를 선택했는지, 어떤 모델을 연결하도록 했는지 후속 개발자가 이해할 수 있게 설명해 두어야 합니다.

흔한 실수와 주의점


Reference 필드를 처음 접할 때 흔히 하는 실수들입니다.


Many2one처럼 도메인 필터를 작성하기

개발자들이 종종 Reference에 대해 Many2one 도메인 문법(예: [('document_ref', '=', 15)])을 쓰곤 합니다. 그러나 Reference는 정수가 아니라 문자열(sale.order,15)을 저장하므로 전체 문자열을 구성해 검색해야 합니다.


삭제된 레코드가 고아 값을 남긴다는 점을 잊는 것

DB에 외래키 제약이 없으므로 참조 대상이 삭제되어도 Reference 값은 그대로 남습니다. 삭제된 레코드를 가리키는 Reference를 읽으면 Odoo는 False를 반환합니다. 참조가 유효하다고 가정한 채로 코드를 작성하면 예기치 않은 동작이 발생할 수 있습니다.


동적 전체 모델 선택을 남용하는 것

ir.model에서 설치된 모든 모델을 반환하도록 selection을 설정할 수 있지만, 사용자용 드롭다운에 수백 개 항목을 노출하는 것은 거의 항상 부적절합니다. 항상 의미 있는 문서 유형으로 목록을 제한하세요.


보고서에서 기본 그룹화 기능을 기대하는 실수

Reference는 DB에 문자열로 저장되므로 기본 Odoo의 group-by나 피벗 기능이 Many2one처럼 작동하지 않습니다. 문서 유형별 그룹화가 필요하면 모델명만 추출해 별도 선택 필드나 문자 필드로 계산해 두어야 합니다.


Odoo Studio에서 Reference와 Many2one을 혼동하는 것

Studio 사용자들이 두 필드를 혼동하는 일이 자주 발생합니다. Many2one은 생성 시에 단일 모델을 고정하는 반면 Reference는 레코드 입력 시마다 모델을 사용자가 선택할 수 있게 합니다. 잘못 생성했다면 필드를 새로 만들어야 하는 경우가 많습니다.

결론


Reference 필드는 Many2one이 다루기 어려운 유연한 링크 요구를 해결해 줍니다. 다양한 문서 유형을 상황에 따라 가리켜야 할 때 적절한 도구이며, Studio로 간단히 추가하거나 파이썬 모델에 통합해 기술적으로 확장할 수 있습니다.


중요한 점은 문자열 기반 저장 형식, 자동 외래키 정리 부재, ID가 아닌 '모델명,아이디' 형태로 필터링해야 한다는 점입니다. 이 차이만 이해하면 Reference는 예측 가능하고 안정적으로 동작합니다.


일반적인 승인 워크플로우를 구축하거나 지원 티켓을 여러 문서에 연결하거나 모듈 간에 통용되는 메모 시스템을 설계할 때 Reference는 중복 로직 없이 깔끔하고 유지보수 가능한 해결책을 제공합니다.

Odoo 도입이 필요하신가요?


Dasolo에서 우리는 기업이 실제 업무 흐름에 맞춰 Odoo를 구현·커스터마이즈·최적화할 수 있도록 돕습니다. 커스텀 필드 로직을 만들든, 데이터 모델을 설계하든, 기존 시스템에 기능을 추가하든 저희 팀이 기술적으로 정확하게 완성해 드립니다.


Odoo 프로젝트에서 필드 선택, 데이터 아키텍처, 개발 모범 사례에 관해 조언이 필요하시면 언제든 문의해 주세요. 상황을 함께 검토하고 최적의 접근법을 제안해 드립니다.

Dasolo에 연락하기

Odoo Reference Field 완전 정복 가이드
Dasolo 2026년 3월 6일
이 게시물 공유하기
로그인 의견을 남기기