[Django] json.dumps 사용 시 한글이 유니코드로 출력되는 현상 수정

David Im·2022년 4월 26일
0

본 글은 야간모드에 최적화 되어있습니다. 우측 상단에서 해 혹은 달모양을 클릭시어 velog 설정을 야간모드로 해주시면 더욱 편안하게 읽으실 수 있습니다.

오늘은 API 개발을 하다가 RDB를 사용하면서 NoSQL처럼 JSON형식으로 데이터를 저장해놓고 써야하는 경우가 생겼다.

하지만 json.dumps로 가져왔을 때 한글의 경우는 유니코드로 반영되는 현상이 나타났다.

처음보는 현상이어서 해결하고 찾아본 방법을 기억하기 위해 작성한다.

1. django 예시 model 및 상황 설명


에를 들어서 아래와 같이 User 모델이 있고, 그 User 모델의 guid를 FK로 갖는 학습기록이라는 테이블을 예로 들어서 설명해보겠다.

class User(AbstractBaseUser, PermissionsMixin, LifeCycleModel)::
    guid = models.CharField(max_length=200, null=False, blank=True, unique=True)
	user_id = models.CharField(max_length=200, null=False, blank=True, unique=True)
    nickname = models.CharField(max_length=200, null=True, blank=True, unique=True)
    username = models.CharField(max_length=200, null=False, blank=True)
    verification = models.CharField(max_length=50, null=True)


class UserLearningLog(AbstractBaseUser, PermissionsMixin, LifeCycleModel)::
    user = models.ForeignKey(User, on_delete=models.CASCADE, db_column=_('user_id'), null=False)
    learning_date = models.CharField(max_length=200, null=True, default='')
    learning_data = models.TextField(max_length=200, null=False, default='')

원래는 더 복잡한 형태가 되고 다양한 컬럼을 갖겠지만 설명을 위해 간략화 했다.

UserLearningLog 모델의 learning_data 컬럼에 JSON 형식을 text로 통째로 저장한다고 가정하고 그 부분에 활용할 때의 예이다.

user_guid_list = [a1,b2,c3,d4]

user_data = UserLearningLog.objects.filter(user__guid__in(user_id_list))

위와 같이 guid 리스트를 가지고서 그 guid를 가진 User의 학습 데이터를 뽑아서 사용한다고 가정한다.
그리고 해당 쿼리셋 데이터는 user_data라는 변수에 저장한다.

해당 데이터를 활용해서 user_data의 첫번째 요소의 learning_data에 새로운 학습데이터를 request에서 통째로 JSON으로 뽑아서 사용한다고 해보자.

그리고 그 JSON data에는 아래와 같이 한글 데이터가 포함되어있다.

{
  "user_guid":"a1",
  "learning_date":"2022-04-26",
  "learning_subject":"국어",
  "learning_score":92
}

그래서 이 JSON 데이터를 통째로 저장하려고 했을 때 json.dumps로 당연하게 하면 저장이 될 줄 알았으나...

한글이 정상적으로 저장되지 않고 아래처럼 유니코드 형식으로 /uni012/ 이런식으로 저장되는것이다.
(유니코드값은 예시로 든 것일 뿐 정확한 코드가 아님을 명시)

{
  "user_guid":"a1",
  "learning_date":"2022-04-26",
  "learning_subject":"/uni092/ /uni023/",
  "learning_score":92
}

그래서 찾아보니 json.dumps에 옵션이 추가로 더 있다는 사실을 알게 되었다.
기존에는 json.dump로 보통 key, value 값이 영어인 경우가 많다보니 그대로 json.dumps로만 사용하는 경우가 많아서 모르고 있었다.

2. 해결방법


아래와 같이 json 데이터를 받아서 사용할 때, 그냥 json.dumps만 사용하는 것이 아니라,
ensure_ascii = False 라는 옵션을 주게 되면 JSON 안에 한글이 포함 되어있어도, json.dumps 메소드에서 한글을 변환해서 예쁘게 저장해준다.

import json

# 1. 기존 JSON 형식의 데이터를 그대로 저장하는 방식
new_learning_data = request.data.get('new_data')
user_data[0].learning_data = json.dumps(new_learning_data)


# 2. JSON 데이터에 한글과 같은 유니코드 변환이 필요한 문자가 포함된 경우
new_learning_data = request.data.get('new_data')
user_data[0].learning_data = json.dumps(new_learning_data, ensure_ascii=False)
profile
코더보다 개발자로, 결과와 과정의 시너지를 만들어 가고 싶은 주니어 개발자

0개의 댓글