소개
제품 사진을 올리거나 회사 로고를 설정하거나 직원 프로필 사진을 등록해본 적이 있다면 이미 Image 필드를 사용해본 것입니다. Odoo 데이터 모델에서 가장 시각적으로 눈에 띄는 필드 유형 중 하나로, 생각보다 많은 화면과 워크플로우에 연결되어 있습니다.
일반 사용자 입장에서는 버튼을 눌러 파일을 올리면 끝나지만, 컨설턴트나 개발자가 직접 모델을 설계할 때는 내부 동작을 이해하는 것이 중요합니다. Image 필드는 저장 방식, 자동 리사이징 규칙, 그리고 접근제어 등 여러 세부 동작을 가지고 있어 커스텀 모델에 필드를 추가하기 전 미리 알아두면 유용합니다.
이 가이드는 Image 필드가 데이터를 어떻게 저장하는지, Odoo 프레임워크에서 어떤 식으로 동작하는지, Odoo Studio나 파이썬으로 필드를 추가하는 방법, 그리고 실제 업무 흐름에서의 활용 예시를 설명합니다.
Odoo에서 Image 필드란 무엇인가
Image 필드는 Odoo ORM에 도입된 전용 필드 타입으로, Odoo 13부터 fields.Image로 명확하게 정의되었습니다. 이전에는 fields.Binary와 이미지 위젯을 조합해 같은 기능을 구현하곤 했습니다. 현재는 Image 필드가 자체적으로 리사이징과 저장 라이프사이클을 관리합니다.
내부적으로 Image 필드는 base64로 인코딩된 바이너리 데이터를 저장합니다. PostgreSQL에서는 bytea로 저장될 수 있지만, 현대 Odoo 설치에서는 보통 레코드에 연결된 파일 첨부(ir.attachment) 형태로 관리하는 것이 일반적입니다. 첨부 기반 저장은 주요 테이블을 가볍게 유지하고, Odoo의 첨부 URL 시스템을 통해 효율적으로 이미지를 제공할 수 있게 합니다.
인터페이스에서의 표시 방식
폼 뷰에서는 Image 필드가 클릭 가능한 이미지 자리 표시자로 렌더링됩니다. 사용자는 로컬 파일을 업로드하거나 경우에 따라 URL을 붙여넣을 수 있고, 폼 상에서 바로 썸네일 미리보기가 표시되어 한눈에 확인하기 쉽습니다.
반면 목록(리스트) 뷰에는 이미지 컬럼을 잘 사용하지 않는데, 썸네일을 모두 불러오면 로딩 속도가 느려지기 때문입니다. 대신 카드형 레이아웃인 칸반(kanban) 뷰에서는 제품 사진이나 연락처 아바타 같은 시각적 표식이 유용해 자주 활용됩니다.
Odoo 필드 타입: Image와 Binary의 차이
중요한 구분은 Binary 필드는 모든 파일 형식을 저장할 수 있는 반면 Image 필드는 이미지 전용이라는 점입니다. Image 필드는 저장 시 자동 리사이징, 이미지 전용 유효성 검사, 이미지 위젯과의 기본 호환성 등을 제공합니다. 문서나 PDF를 저장하려면 Binary를, 사진·로고 등 이미지를 저장하려면 Image를 사용하세요.
필드의 동작 원리
사용자가 Image 필드에 이미지를 업로드하면, Odoo가 원본 그대로 저장하지 않고 내부적으로 처리를 거칩니다.
자동 리사이징
fields.Image 선언에는 max_width와 max_height 파라미터를 지정할 수 있습니다. 업로드한 이미지가 해당 크기를 초과하면 Odoo가 종횡비를 유지하면서 자동으로 크기를 줄여 저장합니다. 이 과정은 저장 시점에 투명하게 일어나 사용자 개입이 필요 없습니다.
표준 Image 필드의 기본 최대값은 긴 쪽이 1920픽셀입니다. 그래서 제품 템플릿이나 파트너 모델에서 흔히 image_1920 같은 필드명이 사용됩니다.
이미지 크기 변형(variants)
내장 모델에서는 보통 주 이미지와 함께 image_1920, image_1024, image_512, image_256, image_128 같은 관련 필드들이 보입니다. 이들은 기본 이미지를 참조하는 별도의 fields.Image 관련 필드로, 각기 다른 최대 크기가 설정되어 있습니다.
이 방식을 통해 상황에 맞는 해상도를 제공할 수 있습니다. 예: 목록 페이지에서는 가벼운 image_128을 불러와 페이지 속도를 유지하고, 상세 페이지에서는 고해상도 image_1920을 불러와 선명하게 표시합니다. 커스텀 모델에서는 실제 사용처를 생각해 멀티 사이즈 패턴 적용 여부를 결정하면 됩니다.
첨부 파일로서의 저장 방식
기본 설정으로 Image 필드는 Odoo의 파일 첨부 형태로 데이터를 저장합니다. 즉, 바이너리 콘텐츠는 레코드 테이블에 직접 저장되지 않고 ir.attachment 모델에 보관되며, 레코드는 해당 첨부를 가리키는 참조를 갖습니다.
이 방식은 주요 DB 테이블을 슬림하게 유지해 주고, /web/image/product.template/42/image_1920 같은 예측 가능한 URL로 이미지를 제공할 수 있게 합니다. 웹사이트, 이메일 템플릿, API 응답에서 이 패턴을 자주 사용합니다.
접근 제어
Image 필드는 해당 레코드의 일반 권한 규칙을 따릅니다. 사용자가 제품에 대한 읽기 권한이 없으면 이미지도 가져올 수 없습니다. 이 점은 퍼블릭 웹페이지나 고객 포털을 설계할 때 반드시 고려해야 할 보안 관련 포인트입니다.
비즈니스 활용 사례
Image 필드는 거의 모든 Odoo 모듈에서 쓰입니다. 다음은 대표적인 실제 활용처들입니다.
1. 제품 카탈로그(영업·재고)
제품 이미지는 Odoo에서 가장 눈에 띄는 사용 예입니다. 모든 product.template에는 image_1920이 있고, 이 이미지는 웹샵, 견적서 PDF, POS 화면, 모바일 피킹 화면 등 다양한 곳에 표시됩니다.
대규모 카탈로그를 운영하는 기업은 인터페이스로 일일이 올리는 대신 API를 통해 일괄 업로드하는 경우가 많습니다. Image 필드는 base64 인코딩된 바이너리를 받기 때문에 XML-RPC나 JSON-RPC로 프로그램 방식 업로드가 쉽습니다.
2. 고객·공급사 로고(CRM·구매)
res.partner 모델에는 연락처 사진이나 회사 로고용 Image 필드가 있습니다. 이 로고는 파트너 폼, 채터(chatter), CRM 칸반 카드에 표시되어 다수의 계정을 시각적으로 빠르게 식별하는 데 도움을 줍니다.
3. 직원 사진(HR)
hr.employee 모델은 직원 사진을 보관합니다. 이 사진은 직원 디렉터리, 일부 구성의 급여명세서, Odoo Discuss의 메시지 옆 아바타 등에 표시됩니다. HR팀은 대량 온보딩 시 이미지 일괄 업로드를 자주 활용합니다.
4. 장비·자산 사진(유지보수)
메인터넌스 모듈에서는 장비 레코드에 사진을 첨부할 수 있습니다. 현장 기술자들은 수리 전 해당 장비 사진을 확인해 올바른 기계를 작업 대상으로 삼았는지 빠르게 확인할 수 있어 유용합니다.
5. 점검·품질 확인용 커스텀 폼
품질 검사, 현장 점검, 배송 확인 등 커스텀 모델에 Image 필드를 추가하면 현장 인력이 증거 사진을 바로 레코드에 첨부할 수 있습니다. 이는 Odoo Studio로든 파이썬 코드로든 흔히 구현되는 커스터마이징 패턴입니다.
필드 생성 및 커스터마이징 방법
Image 필드를 모델에 추가하는 방법은 크게 두 가지입니다: 코드 없이 할 수 있는 Odoo Studio 방식과 개발자가 파이썬으로 직접 정의하는 방식입니다.
Odoo Studio 사용하기
Odoo Studio는 내장된 노코드 커스터마이징 툴입니다. Studio에서 원하는 앱을 열고 상단 메뉴에서 Studio를 활성화한 뒤, 필드를 넣을 폼 뷰로 이동하면 됩니다.
왼쪽 필드 패널에서 Image 필드를 폼으로 드래그하면 레이블을 묻는 창이 뜨고 모델에 기반 필드가 자동으로 생성됩니다. 개발자 도움 없이 필드를 만들고자 하는 비즈니스 사용자와 기능 컨설턴트에게 권장되는 방법입니다.
Studio로 생성된 필드는 관례상 x_studio_ 접두사가 붙습니다(예: x_studio_site_photo). 저장 및 표시 동작은 네이티브 Image 필드와 동일합니다.
파이썬으로 구현하기(개발자용)
기술적 커스터마이징이 필요하면 파이썬 모델 파일에서 직접 Image 필드를 정의합니다. 기본적인 예시는 다음과 같습니다.
from odoo import models, fields
class SiteInspection(models.Model):
_name = 'site.inspection'
_description = 'Site Inspection'
name = fields.Char(string='Reference', required=True)
photo = fields.Image(
string='Site Photo',
max_width=1920,
max_height=1920,
)
photo_128 = fields.Image(
related='photo',
max_width=128,
max_height=128,
store=True,
string='Thumbnail',
)
위 예제에서 max_width와 max_height는 저장 시 최대 크기를 1920 픽셀로 제한하도록 지시합니다. 두 번째 필드인 photo_128은 주 이미지를 참조하는 관련 필드로, 칸반 카드나 목록에서 사용할 소형 썸네일을 저장합니다. 하나의 레코드에서 여러 이미지 크기를 다루는 표준적인 패턴입니다.
뷰에 필드 추가하기
모델에 필드가 정의되면 해당 필드를 뷰에 추가해 인터페이스에서 보이도록 해야 합니다. 폼 뷰 XML에서는 widget="image" 속성을 사용해 Image 필드를 표시합니다.
<field name="photo" widget="image" class="oe_avatar"/>
oe_avatar 클래스를 쓰면 폼의 좌상단에 원형 아바타 형태로 배치되어 Odoo 표준 스타일과 맞습니다. 클래스를 빼고 인라인으로 배치할 수도 있습니다.
권장 관행
Image 필드를 사용할 때 고객에게 권장하는 실무 지침은 다음과 같습니다.
현실적인 크기 제한 설정
기본 1920픽셀 제한은 대부분의 경우 적절합니다. 인쇄용 고해상도 사진처럼 특별한 이유가 없다면 임의로 제한을 늘리지 마세요. 큰 이미지는 첨부 파일 용량 증가와 페이지 로드 속도 저하로 이어집니다.
목록·칸반용 썸네일 별도 생성
이미지를 리스트나 칸반에서 보여줘야 한다면 128 또는 256픽셀 수준의 작은 관련 필드를 따로 정의하세요. 모든 카드에 대해 1920픽셀 이미지를 불러오는 것보다 128픽셀 썸네일을 불러오는 편이 훨씬 빠릅니다.
대량 이미지 업로드는 API 사용
수백~수천 개 레코드의 이미지를 업로드할 때는 인터페이스로 수동 작업하지 마시고 XML-RPC나 JSON-RPC API로 base64 인코딩된 데이터를 일괄로 올리세요. 스크립트 자동화가 가능하고 처리 속도도 훨씬 빠릅니다.
업로드 전 이미지 압축 권장
Odoo가 자동 리사이징을 해주더라도 압축을 강하게 하지는 않을 수 있습니다. 예컨대 5MB짜리 JPEG를 1920픽셀로 줄여도 수백 KB가 남을 수 있으니, 업로드 전에 적절한 압축을 해두면 첨부 크기를 관리하는 데 도움이 됩니다.
자주 조회되는 리스트 뷰에는 Image 필드 사용 자제
리스트 뷰 컬럼에 Image 필드를 넣으면 화면에 보이는 모든 행의 바이너리 데이터를 가져와야 하므로 성능이 저하됩니다. 꼭 필요하지 않다면 폼 뷰에서만 전체 이미지를 사용하고, 리스트에서는 작은 썸네일만 쓰세요.
자주 발생하는 실수
팀들이 Image 필드를 다루다 자주 저지르는 실수는 다음과 같습니다.
Binary와 Image 필드 혼동
Binary 필드는 이미지 위젯을 지정하지 않으면 다운로드 버튼으로 표시됩니다. 이미지 미리보기를 원하면 fields.Image를 쓰거나 뷰에서 fields.Binary에 widget="image"를 명시해야 합니다. 이 점을 간과하면 특히 구버전에서 혼란이 생깁니다.
이미지 크기 변형을 초기에 계획하지 않음
처음엔 큰 Image 필드 하나만 만들기 쉽지만, 나중에 칸반이나 웹 목록에 작은 버전이 필요하다고 판단되면 커스텀 모듈에서는 DB 마이그레이션이 필요할 수 있습니다. 미리 사이즈 변형을 설계해 두면 나중에 골치 아픈 작업을 피할 수 있습니다.
첨부 대신 데이터베이스에 직접 이미지 저장
오래된 버전이나 잘못 설정된 인스턴스에서는 바이너리 데이터를 레코드 테이블에 직접 저장하는 경우가 있습니다. 이는 메인 테이블의 크기를 과도하게 불리고 다른 쿼리 성능을 떨어뜨립니다. 첨부 파일 저장이나 S3 호환 스토리지를 사용하도록 설정되어 있는지 확인하세요.
문서 저장용으로 Image 필드 오용
스캔한 문서나 멀티페이지 스크린샷을 Image 필드에 넣는 경우가 있는데, 기술적으로 가능하더라도 바람직하지 않습니다. 문서 관리는 Odoo Documents 모듈이나 파일 다운로드용 Binary 필드를 사용하세요. Image 필드는 사진·로고 등 시각 자료용입니다.
퍼블릭 페이지에서 접근 규칙을 잊음
퍼블릭 웹사이트나 포털에 이미지 URL을 표시하면서 underlying 레코드가 공개 접근이 아니면 이미지가 404를 반환할 수 있습니다. 웹페이지·포털 설계 시 해당 이미지 URL이 의도한 사용자에게 접근 가능한지 항상 확인하세요.
마무리
겉보기엔 Image 필드가 단순해 보이지만, 사전 계획 없이 사용하면 의외의 문제에 봉착할 수 있습니다. 리사이징 규칙, 첨부 저장 방식, 멀티 사이즈 패턴을 이해하면 모델 설계와 구성에서 시간을 크게 절약할 수 있습니다.
비즈니스 사용자는 이미지가 레코드에 안전하게 저장되고 예측 가능한 URL로 접근된다는 사실만 알아도 웹사이트나 포털 구성에 도움이 됩니다. 개발자라면 fields.Image와 관련 썸네일 필드를 조합하는 표준 패턴에 익숙해지는 것이 중요합니다.
제품 사진을 카탈로그에 올리든, 현장 점검 사진을 커스텀 모델에 첨부하든, 고객 포털에 기업 로고를 표시하든 Image 필드는 Odoo 데이터 모델 내에서 시각 정보를 깔끔하고 통합된 방식으로 다룰 수 있게 해줍니다.
Odoo 도입 지원이 필요하신가요?
Dasolo에서는 기업의 Odoo 도입, 커스터마이징, 최적화를 모든 모듈과 버전에서 지원합니다. 표준 모델의 필드 설정, 커스텀 모듈 개발, 레거시 시스템에서의 데이터 마이그레이션 등 실제 비즈니스에 맞게 Odoo를 운영하도록 현장에서 함께 작업합니다.
Odoo 설정에 관해 문의가 있거나 플랫폼에서 가능한 작업을 알아보고 싶다면, 문의해 주세요저희가 기꺼이 도와드리겠습니다.