diff options
| author | Rudy Mutter <rudy@yetihq.com> | 2014-09-06 13:42:36 -0700 |
|---|---|---|
| committer | Loic Bistuer <loic.bistuer@gmail.com> | 2014-10-09 22:39:17 +0700 |
| commit | e31be40f163e7d478946530acb1068c6deadb845 (patch) | |
| tree | 33aa414c5789e46c1ddcb4d648d16297139ac04e /django/db | |
| parent | d8306650071369ee9d7cad71120d13c22e900a10 (diff) | |
[1.7.x] Fixed #23365 -- Added support for timezone-aware datetimes to migrations.
Backport of a407b846b4 from master
Diffstat (limited to 'django/db')
| -rw-r--r-- | django/db/migrations/questioner.py | 7 | ||||
| -rw-r--r-- | django/db/migrations/writer.py | 24 |
2 files changed, 23 insertions, 8 deletions
diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index 0476ba749f..3b31796cbc 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -5,7 +5,7 @@ import os import sys from django.apps import apps -from django.utils import datetime_safe, six +from django.utils import datetime_safe, six, timezone from django.utils.six.moves import input from .loader import MIGRATIONS_MODULE_NAME @@ -108,7 +108,8 @@ class InteractiveMigrationQuestioner(MigrationQuestioner): sys.exit(3) else: print("Please enter the default value now, as valid Python") - print("The datetime module is available, so you can do e.g. datetime.date.today()") + print("The datetime and django.utils.timezone modules are " + "available, so you can do e.g. timezone.now()") while True: if six.PY3: # Six does not correctly abstract over the fact that @@ -123,7 +124,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner): sys.exit(1) else: try: - return eval(code, {}, {"datetime": datetime_safe}) + return eval(code, {}, {"datetime": datetime_safe, "timezone": timezone}) except (SyntaxError, NameError) as e: print("Invalid input: %s" % e) return None diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index 82396c1033..894c6b3009 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -16,6 +16,7 @@ from django.db.migrations.loader import MigrationLoader from django.utils import datetime_safe, six from django.utils.encoding import force_text from django.utils.functional import Promise +from django.utils.timezone import utc COMPILED_REGEX_TYPE = type(re.compile('')) @@ -164,6 +165,20 @@ class MigrationWriter(object): return (MIGRATION_TEMPLATE % items).encode("utf8") + @staticmethod + def serialize_datetime(value): + """ + Returns a serialized version of a datetime object that is valid, + executable python code. It converts timezone-aware values to utc with + an 'executable' utc representation of tzinfo. + """ + if value.tzinfo is not None and value.tzinfo != utc: + value = value.astimezone(utc) + value_repr = repr(value).replace("<UTC>", "utc") + if isinstance(value, datetime_safe.datetime): + value_repr = "datetime.%s" % value_repr + return value_repr + @property def filename(self): return "%s.py" % self.migration.name @@ -267,12 +282,11 @@ class MigrationWriter(object): return "{%s}" % (", ".join("%s: %s" % (k, v) for k, v in strings)), imports # Datetimes elif isinstance(value, datetime.datetime): + value_repr = cls.serialize_datetime(value) + imports = ["import datetime"] if value.tzinfo is not None: - raise ValueError("Cannot serialize datetime values with timezones. Either use a callable value for default or remove the timezone.") - value_repr = repr(value) - if isinstance(value, datetime_safe.datetime): - value_repr = "datetime.%s" % value_repr - return value_repr, set(["import datetime"]) + imports.append("from django.utils.timezone import utc") + return value_repr, set(imports) # Dates elif isinstance(value, datetime.date): value_repr = repr(value) |
