model에서 DateTimeField 한국 시간으로 설정하기
# models/diary.py
class Diary(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
이렇게 model을 만들어 model의 instance를 만들게 되면 created_at
필드에는 기본적으로 UTC 시간이 들어가게 된다.
그래서 일단 settings
에서 TIME_ZONE
값만 바꾸어 보았다.
# internationalization.py
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_L10N = True
USE_TZ = True
하지만 $ python manage.py runserver
할 때의 시간만 한국 시간으로 나올 뿐 여전히 model의 created_at
에는 UTC 시간이 들어가였다.
하지만 내가 만들 일기 서비스에는 한국 시간이 들어가야 하므로 이 부분을 수정하기 위해 구글링을 하였다. 그 결과 pytz 문서를 참고하여 아래와 같이 한국 시간으로 반환해주는 별도의 property
를 추가함으로써 해결할 수 있었다.
# diary.py
from django.db import models
from django.conf import settings
from pytz import timezone
class Diary(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
@property
def created_at_korean_time(self):
korean_timezone = timezone(settings.TIME_ZONE)
return self.created_at.astimezone(korean_timezone)
그리고 다음의 test 코드를 통해 원하는 결과가 나옴을 확인할 수 있었다. test 코드를 짜는 데 한참 더 많은 시간이 걸렸다.
# test_models.py
from django.test import TestCase
from django.contrib.auth import get_user_model
from datetime import datetime
import pytz
from diaries.models import Diary
class DiaryModelTestCase(TestCase):
def setUp(self):
# Create a user
self.user = get_user_model().objects.create_user(
username="test_username",
password="test_password",
)
# Create a diary
self.diary = self.user.diary_set.create(
content="content",
)
# Diary was created at 2016/06/30 15:18:38,(tzinfo='UTC')
self.diary.created_at = datetime(2016, 6, 30, 15, 18, 38, tzinfo=pytz.utc)
def test_diary_model_should_have_created_at_korean_time(self):
# Korean time = UTC + 9 hours
self.assertEqual(
self.diary.created_at_korean_time.strftime("%Y-%m-%d %H:%M:%S"),
'2016-07-01 00:18:38',
)
아래부터는 진정한 해결법입니다. 위의 글 모두 무시하셔도 좋습니다.
하지만 안수찬 강사님 덕분에 내가 한 이 모든 것이 뻘짓이었다는 것을 알게 됐다. 그냥 간단히 아까 settings
에서 USE_TZ
를 False
로 바꿔주면 해결되었다...
장고 공식 문서에 보면 TIME_ZONE에 대해서 아래와 같이 나와있다.
When USE_TZ is False, this is the time zone in which Django will store all datetimes. When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
즉, USE_TZ가 True일 때는 templates, forms에서의 datetime에만 내가 설정한 TIME_ZONE이 적용된다. 따라서 models의 datetime에는 이 부분이 적용되지 않았기 때문에 원래의 default time zone인 'UTC' 값으로 계속 설정되었던 것이다.
나는 models에서도 내가 설정한 TIME_ZONE 값을 적용하고 싶기 때문에 이 부분을 False로 바꾸어 주었다.
# internationalization.py
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_L10N = True
USE_TZ = False