
1. Odoo API Decorator의 개념과 역할
데코레이터는 파이썬 함수나 메서드 위에 @ 기호와 함께 작성하여 해당 로직의 트리거 조건과 실행 방식을 지정하는 파이썬 표준 문법입니다. Odoo ORM은 이를 확장하여 화면 조작, 필드 값 변화, 데이터 저장 직전 등 비즈니스 프로세스 단계별로 적절한 시점에 메서드가 자동 호출되도록 제어합니다.
| 데코레이터 | 역할 요약 | 핵심 트리거 및 실행 시점 |
| @api.depends | Calculate (재계산) | 의존 필드의 값이 변경될 때 계산 필드(computed field) 재계산 실행 |
| @api.onchange | React in UI (화면 반응) | 폼 뷰(Form view)에서 사용자가 필드 값을 변경하는 즉시 UI 갱신 |
| @api.constrains | Validate (저장 검증) | 레코드가 DB에 저장(생성/수정)되기 직전 데이터 유효성 검사 수행 |
👉 [이전 글: Odoo Recordset 완벽 가이드: 필수 가공 메서드 3종과 self 다루기 바로가기]
2. 실무 필수 API 데코레이터 3종 완벽 분석
① @api.depends: 계산 필드(Computed Field)의 재계산 선언
compute 속성을 가진 계산 필드와 함께 사용되며, 어떤 필드가 변경되었을 때 해당 연산 로직을 다시 실행해야 하는지 Odoo에게 지정합니다.
Python
from odoo import api, fields, models
class OrderLine(models.Model):
_name = "x.order.line"
quantity = fields.Float()
price = fields.Float()
total = fields.Float(compute="_compute_total")
@api.depends("quantity", "price")
def _compute_total(self):
for rec in self:
rec.total = rec.quantity * rec.price
- total = fields.Float(compute="_compute_total") : 사용자가 직접 입력하지 않고 _compute_total 메서드의 연산 결과가 반영되는 계산 필드입니다.
- @api.depends("quantity", "price") : 수량(quantity)이나 단가(price) 중 어느 하나라도 변경되면 자동으로 _compute_total 메서드를 호출합니다.
- for rec in self : Odoo ORM에서 self는 단일 레코드가 아닌 여러 레코드가 포함된 레코드셋일 수 있으므로 반드시 반복 순회 패턴으로 안전하게 처리합니다.
② @api.onchange: UI 폼 뷰에서의 즉각적인 사용자 반응
웹 브라우저의 폼 뷰(Form View)에서 사용자가 특정 입력값을 수정하는 즉시 트리거되어 화면의 다른 필드 값을 채워 넣는 UI 전용 데코레이터입니다.
Python
from odoo import api, fields, models
class PartnerInfo(models.Model):
_name = "x.partner.info"
partner_id = fields.Many2one("res.partner")
phone = fields.Char()
@api.onchange("partner_id")
def _onchange_partner(self):
self.phone = self.partner_id.phone
- 실행 타이밍 : 데이터베이스에 최종 저장(Save) 버튼을 누르기 전, 화면상에서 파트너(partner_id)를 선택하는 순간 실행되어 전화번호(phone)를 자동 완성합니다.
- 엔지니어링 주의점 : @api.onchange는 오직 웹 폼 화면을 통한 인터랙션에서만 동작합니다. 백엔드 파이썬 코드(create, write)나 외부 API 연동 시에는 실행되지 않으므로, 절대 필수 비즈니스 로직이나 보안 검증 목적으로 사용해서는 안 됩니다.
③ @api.constrains: DB 커밋 직전 엄격한 데이터 유효성 검증
레코드가 데이터베이스(PostgreSQL)에 영구 저장(INSERT/UPDATE)되기 직전에 실행되어 잘못된 데이터 저장을 방지하는 백엔드 유효성 검사기입니다.
Python
from odoo import api, fields, models
from odoo.exceptions import ValidationError
class Product(models.Model):
_name = "x.product"
quantity = fields.Float()
@api.constrains("quantity")
def _check_quantity(self):
for rec in self:
if rec.quantity < 0:
raise ValidationError("Quantity cannot be negative.")
- ValidationError 발생 : 지정한 조건(예: 수량이 음수인 경우)을 위반하면 Odoo가 ValidationError 예외를 발생시켜 트랜잭션을 롤백하고 저장을 차단하며 사용자에게 경고 팝업을 표시합니다.
- 보안 및 무결성 보장 : UI를 통한 저장은 물론, 백엔드 배치 스크립트, 외부 API 호출, ORM 메서드 호출 등 모든 경로의 레코드 변경 시 항상 검사가 수행됩니다.
3. 데코레이터 3종 비교 및 실무 선택 기준
| 구분 | @api.depends | @api.onchange | @api.constrains |
| 핵심 목적 | 필드 값 연산 및 데이터 갱신 | 폼 화면 편의성 및 필드 자동 입력 | 데이터 무결성 검증 및 저장 방어 |
| 실행 위치 | 서버 백엔드 (ORM/DB 연동) | 클라이언트 웹 브라우저 (Form View 한정) | 서버 백엔드 (DB 트랜잭션 커밋 직전) |
| DB 저장 여부 | 연산 결과 저장 가능 (store=True 지원) | 미저장 (화면 임시 표시 상태) | 조건 위반 시 DB 저장을 즉각 차단 |
| 백엔드 코드 실행 시 | 정상 실행 | 미실행 (UI 전용) | 항상 실행 (무결성 보장) |
- UI 편의성은 onchange, 필수 무결성은 constrains : 화면에서 기본값을 빠르게 채워주는 것은 @api.onchange를 사용하되, "음수 재고 불가", "종료일이 시작일보다 앞설 수 없음"과 같은 엄격한 규칙은 반드시 @api.constrains로 방어해야 합니다.
'4. Odoo 기술 & 개발(Tech, Architecture) > 커스텀 모듈 개발 & API' 카테고리의 다른 글
| Odoo Recordset 완벽 가이드: 개념부터 필수 가공 메서드 3종과 self 다루기 (0) | 2026.09.05 |
|---|---|
| Odoo Model Inheritance 완벽 가이드: 3가지 모델 상속 방식과 실무 아키텍처 (0) | 2026.08.30 |
| Odoo Views & XML 구조 완벽 가이드: 5가지 핵심 뷰와 UI 렌더링 원리 (0) | 2026.08.30 |
| Odoo 개발의 시작: Model 정의와 Field 타입(기본·관계형) 완벽 가이드 (0) | 2026.08.29 |
| SQL 없이 데이터 다루는 Odoo ORM 기초: 실무 핵심 메서드 7가지 완벽 정리 (0) | 2026.08.29 |