4. Odoo 기술 & 개발(Tech, Architecture)/커스텀 모듈 개발 & API

Odoo API Decorators 완벽 가이드: @api.depends, @api.onchange, @api.constrains 핵심 3종 비교와 실무 활용법

wegosolution 2026. 9. 10. 11:14

odoo api decorators overview

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로 방어해야 합니다.