Fixed "can't compare offset-naive and offset-aware datetimes" (#337)

* Fixed "can't compare offset-naive and offset-aware datetimes" when USE_TZ = True

* Fixed case when `USE_TZ = False`
This commit is contained in:
Dmitriy Tatarkin 2019-08-12 19:00:07 +03:00 committed by Camilo Nova
parent 98800c0671
commit 299b3b1996
6 changed files with 43 additions and 7 deletions

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ test.db
.tox
.coverage
docs/_build
.idea

View file

@ -39,3 +39,4 @@ saw2th <stephen@saw2th.co.uk>
trbs <trbs@trbs.net>
vl <1844144@gmail.com>
vl <vl@u64.(none)>
Dmitriy Tatarkin <mail@dtatarkin.ru>

View file

@ -3,11 +3,9 @@ from datetime import datetime, date, time, timedelta
from decimal import Decimal
from operator import itemgetter
import hashlib
import os
from django import forms, VERSION
from django import forms, VERSION, conf
from django.apps import apps
from django.conf import settings as django_settings
from django.conf.urls import url
from django.contrib import admin, messages
from django.contrib.admin import widgets
@ -17,7 +15,7 @@ from django.core.files.storage import default_storage
from django.forms import fields
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
from django.utils import six
from django.utils import six, timezone
from django.utils.encoding import smart_bytes
from django.utils.formats import localize
from django.utils.module_loading import import_string
@ -142,8 +140,14 @@ class ConstanceForm(forms.Form):
self.cleaned_data[file_field] = default_storage.save(file.name, file)
for name in settings.CONFIG:
if getattr(config, name) != self.cleaned_data[name]:
setattr(config, name, self.cleaned_data[name])
current = getattr(config, name)
new = self.cleaned_data[name]
if conf.settings.USE_TZ and isinstance(current, datetime) and not timezone.is_aware(current):
current = timezone.make_aware(current)
if current != new:
setattr(config, name, new)
def clean_version(self):
value = self.cleaned_data['version']

View file

@ -63,6 +63,8 @@ CONSTANCE_ADDITIONAL_FIELDS = {
'email': ('django.forms.fields.EmailField',),
}
USE_TZ = True
CONSTANCE_CONFIG = {
'INT_VALUE': (1, 'some int'),
'LONG_VALUE': (long_value, 'some looong int'),

View file

@ -1,3 +1,5 @@
from datetime import datetime
import mock
from django.contrib import admin
from django.contrib.auth.models import User, Permission
@ -99,6 +101,27 @@ class TestAdmin(TestCase):
response = self.options.changelist_view(request, {})
self.assertIsInstance(response, HttpResponseRedirect)
@mock.patch('constance.settings.CONFIG', {
'DATETIME_VALUE': (datetime(2019, 8, 7, 18, 40, 0), 'some naive datetime'),
})
@mock.patch('constance.settings.IGNORE_ADMIN_VERSION_CHECK', True)
@mock.patch('tests.redis_mockup.Connection.set', mock.MagicMock())
def test_submit_aware_datetime(self):
"""
Test that submitting the admin page results in an http redirect when
everything is in order.
"""
request = self.rf.post('/admin/constance/config/', data={
"DATETIME_VALUE_0": "2019-08-07",
"DATETIME_VALUE_1": "19:17:01",
"version": "123",
})
request.user = self.superuser
request._dont_enforce_csrf_checks = True
with mock.patch("django.contrib.messages.add_message"):
response = self.options.changelist_view(request, {})
self.assertIsInstance(response, HttpResponseRedirect)
@mock.patch('constance.settings.CONFIG_FIELDSETS', {
'Numbers': ('LONG_VALUE', 'INT_VALUE',),
'Text': ('STRING_VALUE', 'UNICODE_VALUE'),

View file

@ -3,8 +3,10 @@
from datetime import datetime
from textwrap import dedent
from django.conf import settings
from django.core.management import call_command, CommandError
from django.test import TransactionTestCase
from django.utils import timezone
from django.utils.encoding import smart_str
from django.utils.six import StringIO
@ -53,7 +55,10 @@ u""" BOOL_VALUE True
call_command('constance', *('set', 'DATETIME_VALUE', '2011-09-24', '12:30:25'), stdout=self.out)
self.assertEqual(config.DATETIME_VALUE, datetime(2011, 9, 24, 12, 30, 25))
expected = datetime(2011, 9, 24, 12, 30, 25)
if settings.USE_TZ:
expected = timezone.make_aware(expected)
self.assertEqual(config.DATETIME_VALUE, expected)
def test_get_invalid_name(self):
self.assertRaisesMessage(CommandError, "NOT_A_REAL_CONFIG is not defined in settings.CONSTANCE_CONFIG",