mirror of https://github.com/django/django.git
Fixed #29595 -- Allowed using timedelta in migrations questioner.
Refs #29600 -- Removed usage of django.utils.datetime_safe in migrations.
This commit is contained in:
parent
3af695eda2
commit
c72dde41e6
|
@ -1,10 +1,11 @@
|
||||||
|
import datetime
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.db.models.fields import NOT_PROVIDED
|
from django.db.models.fields import NOT_PROVIDED
|
||||||
from django.utils import datetime_safe, timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from .loader import MigrationLoader
|
from .loader import MigrationLoader
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
return eval(code, {}, {"datetime": datetime_safe, "timezone": timezone})
|
return eval(code, {}, {'datetime': datetime, 'timezone': timezone})
|
||||||
except (SyntaxError, NameError) as e:
|
except (SyntaxError, NameError) as e:
|
||||||
print("Invalid input: %s" % e)
|
print("Invalid input: %s" % e)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import uuid
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.migrations.operations.base import Operation
|
from django.db.migrations.operations.base import Operation
|
||||||
from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
|
from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
|
||||||
from django.utils import datetime_safe
|
|
||||||
from django.utils.functional import LazyObject, Promise
|
from django.utils.functional import LazyObject, Promise
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
from django.utils.version import get_docs_version
|
from django.utils.version import get_docs_version
|
||||||
|
@ -46,25 +45,21 @@ class BaseSimpleSerializer(BaseSerializer):
|
||||||
return repr(self.value), set()
|
return repr(self.value), set()
|
||||||
|
|
||||||
|
|
||||||
class DatetimeSerializer(BaseSerializer):
|
class DateTimeSerializer(BaseSerializer):
|
||||||
|
"""For datetime.*, except datetime.datetime."""
|
||||||
|
def serialize(self):
|
||||||
|
return repr(self.value), {'import datetime'}
|
||||||
|
|
||||||
|
|
||||||
|
class DatetimeDatetimeSerializer(BaseSerializer):
|
||||||
|
"""For datetime.datetime."""
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
if self.value.tzinfo is not None and self.value.tzinfo != utc:
|
if self.value.tzinfo is not None and self.value.tzinfo != utc:
|
||||||
self.value = self.value.astimezone(utc)
|
self.value = self.value.astimezone(utc)
|
||||||
value_repr = repr(self.value).replace("<UTC>", "utc")
|
|
||||||
if isinstance(self.value, datetime_safe.datetime):
|
|
||||||
value_repr = "datetime.%s" % value_repr
|
|
||||||
imports = ["import datetime"]
|
imports = ["import datetime"]
|
||||||
if self.value.tzinfo is not None:
|
if self.value.tzinfo is not None:
|
||||||
imports.append("from django.utils.timezone import utc")
|
imports.append("from django.utils.timezone import utc")
|
||||||
return value_repr, set(imports)
|
return repr(self.value).replace('<UTC>', 'utc'), set(imports)
|
||||||
|
|
||||||
|
|
||||||
class DateSerializer(BaseSerializer):
|
|
||||||
def serialize(self):
|
|
||||||
value_repr = repr(self.value)
|
|
||||||
if isinstance(self.value, datetime_safe.date):
|
|
||||||
value_repr = "datetime.%s" % value_repr
|
|
||||||
return value_repr, {"import datetime"}
|
|
||||||
|
|
||||||
|
|
||||||
class DecimalSerializer(BaseSerializer):
|
class DecimalSerializer(BaseSerializer):
|
||||||
|
@ -246,19 +241,6 @@ class SettingsReferenceSerializer(BaseSerializer):
|
||||||
return "settings.%s" % self.value.setting_name, {"from django.conf import settings"}
|
return "settings.%s" % self.value.setting_name, {"from django.conf import settings"}
|
||||||
|
|
||||||
|
|
||||||
class TimedeltaSerializer(BaseSerializer):
|
|
||||||
def serialize(self):
|
|
||||||
return repr(self.value), {"import datetime"}
|
|
||||||
|
|
||||||
|
|
||||||
class TimeSerializer(BaseSerializer):
|
|
||||||
def serialize(self):
|
|
||||||
value_repr = repr(self.value)
|
|
||||||
if isinstance(self.value, datetime_safe.time):
|
|
||||||
value_repr = "datetime.%s" % value_repr
|
|
||||||
return value_repr, {"import datetime"}
|
|
||||||
|
|
||||||
|
|
||||||
class TupleSerializer(BaseSequenceSerializer):
|
class TupleSerializer(BaseSequenceSerializer):
|
||||||
def _format(self):
|
def _format(self):
|
||||||
# When len(value)==0, the empty tuple should be serialized as "()",
|
# When len(value)==0, the empty tuple should be serialized as "()",
|
||||||
|
@ -322,13 +304,9 @@ def serializer_factory(value):
|
||||||
if isinstance(value, enum.Enum):
|
if isinstance(value, enum.Enum):
|
||||||
return EnumSerializer(value)
|
return EnumSerializer(value)
|
||||||
if isinstance(value, datetime.datetime):
|
if isinstance(value, datetime.datetime):
|
||||||
return DatetimeSerializer(value)
|
return DatetimeDatetimeSerializer(value)
|
||||||
if isinstance(value, datetime.date):
|
if isinstance(value, (datetime.date, datetime.timedelta, datetime.time)):
|
||||||
return DateSerializer(value)
|
return DateTimeSerializer(value)
|
||||||
if isinstance(value, datetime.time):
|
|
||||||
return TimeSerializer(value)
|
|
||||||
if isinstance(value, datetime.timedelta):
|
|
||||||
return TimedeltaSerializer(value)
|
|
||||||
if isinstance(value, SettingsReference):
|
if isinstance(value, SettingsReference):
|
||||||
return SettingsReferenceSerializer(value)
|
return SettingsReferenceSerializer(value)
|
||||||
if isinstance(value, float):
|
if isinstance(value, float):
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
from django.db.migrations.questioner import MigrationQuestioner
|
import datetime
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from django.db.migrations.questioner import (
|
||||||
|
InteractiveMigrationQuestioner, MigrationQuestioner,
|
||||||
|
)
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import captured_stdout, override_settings
|
||||||
|
|
||||||
|
|
||||||
class QuestionerTests(SimpleTestCase):
|
class QuestionerTests(SimpleTestCase):
|
||||||
|
@ -11,3 +16,10 @@ class QuestionerTests(SimpleTestCase):
|
||||||
def test_ask_initial_with_disabled_migrations(self):
|
def test_ask_initial_with_disabled_migrations(self):
|
||||||
questioner = MigrationQuestioner()
|
questioner = MigrationQuestioner()
|
||||||
self.assertIs(False, questioner.ask_initial('migrations'))
|
self.assertIs(False, questioner.ask_initial('migrations'))
|
||||||
|
|
||||||
|
@mock.patch('builtins.input', return_value='datetime.timedelta(days=1)')
|
||||||
|
def test_timedelta_default(self, mock):
|
||||||
|
questioner = InteractiveMigrationQuestioner()
|
||||||
|
with captured_stdout():
|
||||||
|
value = questioner._ask_default()
|
||||||
|
self.assertEqual(value, datetime.timedelta(days=1))
|
||||||
|
|
|
@ -19,7 +19,6 @@ from django.db.migrations.writer import (
|
||||||
MigrationWriter, OperationWriter, SettingsReference,
|
MigrationWriter, OperationWriter, SettingsReference,
|
||||||
)
|
)
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils import datetime_safe
|
|
||||||
from django.utils.deconstruct import deconstructible
|
from django.utils.deconstruct import deconstructible
|
||||||
from django.utils.functional import SimpleLazyObject
|
from django.utils.functional import SimpleLazyObject
|
||||||
from django.utils.timezone import get_default_timezone, get_fixed_timezone, utc
|
from django.utils.timezone import get_default_timezone, get_fixed_timezone, utc
|
||||||
|
@ -364,20 +363,6 @@ class WriterTests(SimpleTestCase):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_serialize_datetime_safe(self):
|
|
||||||
self.assertSerializedResultEqual(
|
|
||||||
datetime_safe.date(2014, 3, 31),
|
|
||||||
("datetime.date(2014, 3, 31)", {'import datetime'})
|
|
||||||
)
|
|
||||||
self.assertSerializedResultEqual(
|
|
||||||
datetime_safe.time(10, 25),
|
|
||||||
("datetime.time(10, 25)", {'import datetime'})
|
|
||||||
)
|
|
||||||
self.assertSerializedResultEqual(
|
|
||||||
datetime_safe.datetime(2014, 3, 31, 16, 4, 31),
|
|
||||||
("datetime.datetime(2014, 3, 31, 16, 4, 31)", {'import datetime'})
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_serialize_fields(self):
|
def test_serialize_fields(self):
|
||||||
self.assertSerializedFieldEqual(models.CharField(max_length=255))
|
self.assertSerializedFieldEqual(models.CharField(max_length=255))
|
||||||
self.assertSerializedResultEqual(
|
self.assertSerializedResultEqual(
|
||||||
|
|
Loading…
Reference in New Issue