Commits

Michael Manfre  committed a67db15

Fix issues with custom date fields and converting to the proper values.

  • Participants
  • Parent commits 2e57c2f

Comments (0)

Files changed (6)

File sqlserver_ado/compiler.py

 from __future__ import absolute_import
 
+try:
+    from itertools import zip_longest
+except ImportError:
+    from itertools import izip_longest as zip_longest
+
 import django
 from django.db.models.sql import compiler
 import datetime
             row = row[1:]
         values = []
         index_extra_select = len(self.query.extra_select)
-        for value, field in map(None, row[index_extra_select:], fields):
+        for value, field in zip_longest(row[index_extra_select:], fields):
+            # print '\tfield=%s\tvalue=%s' % (repr(field), repr(value))
             if field:
-                value = self.connection.ops.convert_values(value, field)
+                try:
+                    value = self.connection.ops.convert_values(value, field)
+                except ValueError:
+                    pass
             values.append(value)
         return row[:index_extra_select] + tuple(values)
 

File sqlserver_ado/creation.py

         'GenericIPAddressField':        'nvarchar(39)',
         'IntegerField':                 'int',
         'IPAddressField':               'nvarchar(15)',
+        'LegacyDateField':              'datetime',
         'LegacyDateTimeField':          'datetime',
+        'LegacyTimeField':              'time',
         'NewDateField':                 'date',
         'NewDateTimeField':             'datetime2',
         'NewTimeField':                 'time',

File sqlserver_ado/fields.py

         return result
 
     def get_db_prep_value(self, value, connection, prepared=False):
-        val = super(DateTimeField, self).get_db_prep_value(value, connection, prepared)
-        return connection.ops._new_value_to_db_datetime(val)
+        if not prepared:
+            value = self.get_prep_value(value)
+        return connection.ops._new_value_to_db_datetime(value)
 
 class DateTimeOffsetField(models.DateTimeField):
     """
         return 'DateTimeOffsetField'
 
     def to_python(self, value):
-        return super(DateTimeField, self).to_python(convert_microsoft_date_to_isoformat(value))
+        return super(DateTimeOffsetField, self).to_python(convert_microsoft_date_to_isoformat(value))
 
     def get_db_prep_value(self, value, connection, prepared=False):
-        val = super(DateTimeOffsetField, self).get_db_prep_value(value, connection, prepared)
-        if val is None:
+        if not prepared:
+            value = self.get_prep_value(value)
+        if value is None:
             return None
-        return val.isoformat(' ')
+        return value.isoformat(' ')
 
 class TimeField(models.TimeField):
     """
         return super(TimeField, self).to_python(convert_microsoft_date_to_isoformat(value))
 
     def get_db_prep_value(self, value, connection, prepared=False):
-        val = super(TimeField, self).get_db_prep_value(value, connection, prepared)
-        return connection.ops._new_value_to_db_time(val)
+        if not prepared:
+            value = self.get_prep_value(value)
+        return connection.ops._new_value_to_db_time(value)
 
 class LegacyDateField(models.DateField):
     """
     A DateField that is backed by a 'datetime' database field.
     """
     def get_internal_type(self):
-        return 'LegacyDateTimeField'
+        return 'LegacyDateField'
 
     def to_python(self, value):
         val = super(LegacyDateField, self).to_python(convert_microsoft_date_to_isoformat(value))
         return super(LegacyDateTimeField, self).to_python(convert_microsoft_date_to_isoformat(value))
 
     def get_db_prep_value(self, value, connection, prepared=False):
-        val = super(LegacyDateTimeField, self).get_db_prep_value(value, connection, prepared)
-        return connection.ops._legacy_value_to_db_datetime(val)
+        if not prepared:
+            value = self.get_prep_value(value)
+        return connection.ops._legacy_value_to_db_datetime(value)
 
 class LegacyTimeField(models.TimeField):
     """
     A TimeField that is backed by a 'datetime' database field.
     """
     def get_internal_type(self):
-        return 'LegacyDateTimeField'
+        return 'LegacyTimeField'
 
     def to_python(self, value):
         val = super(LegacyTimeField, self).to_python(convert_microsoft_date_to_isoformat(value))
         return val
   
     def get_db_prep_value(self, value, connection, prepared=False):
-        val = super(LegacyTimeField, self).get_db_prep_value(value, connection, prepared)
-        return connection.ops._legacy_value_to_db_time(val)
+        if not prepared:
+            value = self.get_prep_value(value)
+        return connection.ops._legacy_value_to_db_time(value)

File sqlserver_ado/operations.py

         if value is None or isinstance(value, basestring):
             return value
 
-        if timezone.is_aware(value) and not self.connection.features.supports_timezones:
+        if timezone.is_aware(value):# and not self.connection.features.supports_timezones:
             if getattr(settings, 'USE_TZ', False):
                 value = value.astimezone(timezone.utc).replace(tzinfo=None)
             else:
         if value is None or isinstance(value, basestring):
             return value
             
-        if timezone.is_aware(value) and not self.connection.features.supports_timezones:
+        if timezone.is_aware(value):# and not self.connection.features.supports_timezones:
             if getattr(settings, 'USE_TZ', False):
                 value = value.astimezone(timezone.utc).replace(tzinfo=None)
             else:
         if value is None or isinstance(value, basestring):
             return value
 
-        if timezone.is_aware(value) and not self.connection.features.supports_timezones:
+        if timezone.is_aware(value):
             if not getattr(settings, 'USE_TZ', False) and hasattr(value, 'astimezone'):
-                value = value.astimezone(timezone.utc).replace(tzinfo=None)
-            raise ValueError("SQL Server backend does not support timezone-aware times.")
+                value = timezone.make_naive(value, timezone.utc)
+            else:
+                raise ValueError("SQL Server backend does not support timezone-aware times.")
 
         # MS SQL 2005 doesn't support microseconds
         #...but it also doesn't really suport bare times
         if value is None or isinstance(value, basestring):
             return value
 
-        if timezone.is_aware(value) and not self.connection.features.supports_timezones:
+        if timezone.is_aware(value):
             if not getattr(settings, 'USE_TZ', False) and hasattr(value, 'astimezone'):
-                value = value.astimezone(timezone.utc).replace(tzinfo=None)
-            raise ValueError("SQL Server backend does not support timezone-aware times.")
+                value = timezone.make_naive(value, timezone.utc)
+            else:
+                raise ValueError("SQL Server backend does not support timezone-aware times.")
         return value.isoformat()
 
     def value_to_db_decimal(self, value, max_digits, decimal_places):
         if field:
             internal_type = field.get_internal_type()
             if internal_type in self._convert_values_map:
-                return self._convert_values_map[internal_type].to_python(value)
-            return super(DatabaseOperations, self).convert_values(value, field)
+                value = self._convert_values_map[internal_type].to_python(value)
+            else:
+                value = super(DatabaseOperations, self).convert_values(value, field)
         return value
 
     def bulk_insert_sql(self, fields, num_values):

File tests/test_main/regressiontests/models.py

 class TimeTable(models.Model):
     val = TimeField()
 
-class DateTimeoffsetTable(models.Model):
+class DateTimeOffsetTable(models.Model):
     val = DateTimeOffsetField()

File tests/test_main/regressiontests/tests.py

 
     def test_datetimeoffset(self):
         from django.utils import timezone
-        val = timezone.make_aware(datetime.datetime.now(), timezone.get_default_timezone())
+        val = timezone.make_aware(datetime.datetime.now(), timezone.LocalTimezone())
         self._test(DateTimeOffsetTable, val)