상황 개요
Django 개발을 하다 보면 gettext_lazy
를 사용해서 다국어 지원을 할 때가 많습니다.
그런데, 평소 잘 쓰던 gettext_lazy
가 어느 순간 JSON 응답을 만들 때 오류를 발생시키는 경우가 있습니다.
이 글에서는 왜 gettext_lazy
가 JSON 직렬화에서 문제를 일으키는지 그리고 어떻게 해결할 수 있는지를 자세히 설명합니다.
정상 작동 vs 오류 발생: 상황 비교
케이스 | 정상 동작한 경우 | 오류가 난 경우 |
---|---|---|
LANGUAGE_MAP.get(...) 반환값 위치 |
딕셔너리의 value | 딕셔너리의 key |
직렬화 가능 여부 | 가능 (문제 없음) | 불가능 (__proxy__ key는 JSON 변환 불가) |
문제의 핵심: 왜 이런 차이가 생겼을까?
gettext_lazy
가 반환하는 객체는 __proxy__
타입입니다. 이 객체는 문자열처럼 보이지만 실제로는 진짜 문자열이 아닙니다.
Django의 JsonResponse
나 Python의 json.dumps()
는 다음 규칙을 따릅니다:
# ✅ 가능: value로는 lazy 객체를 쓸 수 있음 (자동 str 변환)
json.dumps({'language': _('English')})
# ❌ 실패: key로는 lazy 객체를 쓸 수 없음
json.dumps({_('English'): 'language'})
즉, 딕셔너리의 key로 사용되려면 반드시 진짜 문자열이어야 합니다.
__proxy__
객체는 key로 쓰일 때 자동 변환되지 않기 때문에 에러가 발생합니다.
왜 value로는 문제가 없고, key로는 문제가 될까?
gettext_lazy
객체는 딕셔너리의 value로 사용될 때는 문제가 되지 않습니다. Django나 Python이 JSON 직렬화 과정에서 value를 문자열로 자동 변환해주기 때문입니다.
하지만 key로 사용될 경우, JSON 표준은 key를 반드시 문자열이어야 한다고 강제합니다. 이때 gettext_lazy
객체는 자동 변환되지 않고, 직렬화 오류를 발생시키는 것입니다.
결론:
- value로 쓸 때는 내부적으로 str 변환이 되어 문제 없이 넘어간다.
- key로 쓸 때는 변환이 자동으로 이뤄지지 않아 에러가 발생한다.
해결 방법
방법 1: gettext
로 전환 (Lazy 사용 안 함)
가장 확실한 방법입니다. lazy를 쓰지 않고 바로 문자열로 변환된 값을 사용합니다.
from django.utils.translation import gettext as _ # lazy 아님!
LANGUAGE_MAP = {
"en": _("English"),
"ko": _("Korean"),
"ja": _("Japanese"),
}
- 장점: 추가 처리가 필요 없음
- 단점: 최초 import 시점에 번역이 결정되므로 일부 동적 번역 요구사항과는 다를 수 있음
방법 2: JSON 직렬화 직전에 강제 str() 적용
lazy 객체를 계속 쓰고 싶다면, JSON에 넣기 전에 key를 str()
로 변환합니다.
lang = str(LANGUAGE_MAP.get(lang_code, lang_code.upper()))
- 장점: 기존 코드를 거의 안 바꿔도 됨
- 단점: 매번 str 변환을 신경 써야 함
번외: 클라이언트에서 번역 처리하기
아예 서버에서 다국어 번역을 하지 않고, 프론트엔드에서 처리하는 방법도 있습니다.
- 서버는 언어 코드만 보내고
- 클라이언트 자바스크립트에서 번역 테이블을 관리합니다.
이 방법은 프로젝트에 따라 선택할 수 있습니다.
정리하자면
gettext_lazy
는 딕셔너리 key로는 절대 사용하지 말 것- JSON 직렬화 전에 반드시 문자열로 변환하기
- 가장 안전한 방법은
gettext
로 즉시 문자열 변환 - 기존 코드 유지가 필요하다면
str(...)
을 잊지 말기
Jesse의 코멘트
이 문제는 Django에서의 다국어 처리와 JSON 응답 처리의 아주 미묘한 경계에서 발생하는 흔한 실수입니다.
앞으로는 "예전엔 됐었는데 왜 안 되지?"가 아니라, "예전엔 운이 좋았던 것"이라고 생각하고 코드를 점검해보세요.
개발자의 실력이 쌓이는 순간은, 바로 이런 '미묘함'을 이해하게 될 때입니다. 이 원리를 알고 있으면, Django 다국어 처리와 JSON 응답 모두 훨씬 튼튼하게 만들 수 있습니다!
Add a New Comment