Django 프로젝트를 하다 보면 세션(session)에 특정 데이터를 저장해야 할 일이 생깁니다. 그런데 아래와 같은 에러 메시지를 본 적 있으신가요?
TypeError: Object of type Review is not JSON serializable
이 에러는 직렬화(Serialization)와 관련이 있습니다. 오늘은 이 에러의 의미와 원인, 그리고 해결 방법까지 함께 정리해보겠습니다.
1. 직렬화(Serialization)란?
직렬화는 객체를 파일 저장이나 네트워크 전송이 가능하도록 문자열 또는 바이트 형식으로 변환하는 과정입니다. 반대로 이를 다시 객체로 되돌리는 것은 역직렬화(Deserialization)라고 합니다.
💡 예시: 딕셔너리를 JSON으로 직렬화
import json
data = {"name": "Minjoo", "age": 25}
json_str = json.dumps(data)
print(json_str)
# 출력: {"name": "Minjoo", "age": 25}
2. Django 세션은 왜 직렬화를 사용할까?
Django의 세션은 기본적으로 데이터베이스(DB)나 쿠키 등에 저장됩니다. 이때 내부적으로 JSON 형식으로 데이터를 저장하게 되는데, 이 과정에서 저장하려는 객체가 JSON으로 변환 가능해야 합니다.
3. 에러 상황: 세션에 모델 객체 저장하기
예를 들어, 아래와 같이 Review라는 모델 객체를 세션에 저장하면 어떻게 될까요?
request.session["favorite_review"] = fav_review # ❌ 오류 발생
에러 메시지는 다음과 같이 뜹니다.
TypeError: Object of type Review is not JSON serializable
왜냐하면 Review는 Django 모델 객체이기 때문에 JSON으로 직렬화할 수 없습니다. JSON은 숫자, 문자열, 리스트, 딕셔너리와 같은 단순한 자료형만 지원하기 때문입니다.
4. 해결 방법: 객체 대신 기본 자료형을 저장하자!
가장 간단하고 안전한 방법은 모델의 ID와 같은 기본 자료형만 세션에 저장하고, 필요할 때 다시 DB에서 조회하는 방식입니다.
✅ 수정 전 (에러 발생)
request.session["favorite_review"] = fav_review
✅ 수정 후 (정상 작동)
request.session["favorite_review_id"] = fav_review.id
그리고 나중에 이 ID로 객체를 다시 가져올 수 있습니다.
review_id = request.session.get("favorite_review_id")
if review_id:
review = Review.objects.get(id=review_id)
5. 결론: 세션에는 직렬화 가능한 값만 저장하자
| 저장 가능 | 저장 불가능 |
| 문자열, 숫자, 리스트, 딕셔너리 | 모델 객체, 함수, 클래스 등 |
Django에서 세션을 쓸 때는 꼭 JSON으로 직렬화할 수 있는 값만 넣어야 한다는 걸 기억하세요. 만약 모델의 정보를 저장하고 싶다면, ID나 필요한 필드만 따로 저장하는 습관을 들이면 됩니다!
✅ 추가 팁
- Django Rest Framework에서는 ModelSerializer를 통해 모델을 JSON으로 직렬화할 수 있습니다. (API 개발 시 사용)
- 세션 외에도 캐시나 쿠키를 사용할 때도 마찬가지로 직렬화에 주의하세요.
이 글이 Django를 공부하는 데 도움이 되셨다면 공감과 댓글 부탁드립니다!
궁금한 점은 언제든지 질문 주세요 😊
'Programming > Django' 카테고리의 다른 글
| Django | 함수형 뷰 vs 클래스형 뷰(GET/POST 요청 처리 방식 비교) (2) | 2025.07.29 |
|---|---|
| Django 이미지가 보이지 않는 이유? static 태그와 |add 필터의 함정 (2) | 2025.07.29 |
| Django에서 세션(Session)을 다루는 방법 (1) | 2025.07.28 |
| [Django] Form 처리, 함수형 뷰에서 클래스 기반 뷰(CBV)로 리팩토링하기 (4) | 2025.07.24 |
| [Django] ModelForm으로 폼을 간단히! 그런데 레이블을 잃었다... (1) | 2025.07.24 |