Ticket #7560: get_db_prep_refactor-4.patch
File get_db_prep_refactor-4.patch, 28.9 KB (added by , 16 years ago) |
---|
-
django/db/backends/__init__.py
diff -r 7dfb4f5c1bb0 django/db/backends/__init__.py
a b except ImportError: 4 4 except ImportError: 5 5 # Import copy of _thread_local.py from Python 2.4 6 6 from django.utils._threading_local import local 7 8 from django.db.backends import util 7 9 8 10 class BaseDatabaseWrapper(local): 9 11 """ … … class BaseDatabaseWrapper(local): 36 38 return cursor 37 39 38 40 def make_debug_cursor(self, cursor): 39 from django.db.backends import util40 41 return util.CursorDebugWrapper(cursor, self) 41 42 42 43 class BaseDatabaseFeatures(object): 43 44 allows_group_by_ordinal = True 44 45 inline_fk_references = True 45 needs_datetime_string_cast = True 46 needs_datetime_string_cast = True # uses 47 # django.db.backend.utils.typecast_timetamp 48 # on returned values from dates()? 46 49 supports_constraints = True 47 50 supports_tablespaces = False 48 51 uses_case_insensitive_names = False 49 52 uses_custom_query_class = False 50 53 empty_fetchmany_value = [] 51 54 update_can_self_select = True 52 supports_usecs = True53 time_field_needs_date = False54 55 interprets_empty_strings_as_nulls = False 55 date_field_supports_time_value = True56 56 57 57 class BaseDatabaseOperations(object): 58 58 """ … … class BaseDatabaseOperations(object): 272 272 """Prepares a value for use in a LIKE query.""" 273 273 from django.utils.encoding import smart_unicode 274 274 return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_") 275 276 def value_to_db_date(self, value): 277 """ 278 Transform a date value to an object compatible with what is expected 279 by the backend driver for date columns. 280 """ 281 if value is None: 282 return None 283 return value.strftime('%Y-%m-%d') 284 285 def value_to_db_datetime(self, value): 286 """ 287 Transform a datetime value to an object compatible with what is expected 288 by the backend driver for date columns. 289 """ 290 if value is None: 291 return None 292 return unicode(value) # XXX: Why not just str(value)? 293 294 def value_to_db_time(self, value): 295 """ 296 Transform a datetime value to an object compatible with what is expected 297 by the backend driver for date columns. 298 """ 299 if value is None: 300 return None 301 return unicode(value) # XXX: Why not just str(value)? 302 303 def value_to_db_decimal(self, value, max_digits, decimal_places): 304 """ 305 Transform a decimal.Decimal value to an object compatible with what is 306 expected by the backend driver for decimal (numeric) columns. 307 """ 308 if value is None: 309 return None 310 return util.format_number(value, max_digits, decimal_places) 311 312 def year_lookup_bounds(self, value): 313 """ 314 Returns a two-elements list with the lower and upper bound to be used 315 with a BETWEEN operator to query a field value using a year lookup 316 317 `value` is an int, containing the looked-up year. 318 """ 319 first = '%s-01-01 00:00:00' 320 second = '%s-12-31 23:59:59.999999' 321 return [first % value, second % value] 322 323 def year_lookup_bounds_for_date_field(self, value): 324 """ 325 Returns a two-elements list with the lower and upper bound to be used 326 with a BETWEEN operator to query a DateField value using a year lookup 327 328 `value` is an int, containing the looked-up year. 329 330 By default, it just calls `self.year_lookup_bounds`. Some backends need 331 this hook because on their DB date fields can't be compared to values 332 which include a time part. 333 """ 334 return self.year_lookup_bounds(value) 335 -
django/db/backends/mysql/base.py
diff -r 7dfb4f5c1bb0 django/db/backends/mysql/base.py
a b class DatabaseFeatures(BaseDatabaseFeatu 63 63 inline_fk_references = False 64 64 empty_fetchmany_value = () 65 65 update_can_self_select = False 66 supports_usecs = False67 66 68 67 class DatabaseOperations(BaseDatabaseOperations): 69 68 def date_extract_sql(self, lookup_type, field_name): … … class DatabaseOperations(BaseDatabaseOpe 130 129 return sql 131 130 else: 132 131 return [] 132 133 def value_to_db_datetime(self, value): 134 # MySQL doesn't support microseconds 135 if value is None: 136 return None 137 # XXX: Why not just str(value)? 138 return unicode(value.replace(microsecond=0)) 139 140 def value_to_db_time(self, value): 141 # MySQL doesn't support microseconds 142 if value is None: 143 return None 144 # XXX: Why not just str(value)? 145 return unicode(value.replace(microsecond=0)) 146 147 def year_lookup_bounds(self, value): 148 # Again, no microseconds 149 first = '%s-01-01 00:00:00' 150 second = '%s-12-31 23:59:59.99' 151 return [first % value, second % value] 133 152 134 153 class DatabaseWrapper(BaseDatabaseWrapper): 135 154 features = DatabaseFeatures() -
django/db/backends/mysql_old/base.py
diff -r 7dfb4f5c1bb0 django/db/backends/mysql_old/base.py
a b class DatabaseFeatures(BaseDatabaseFeatu 67 67 inline_fk_references = False 68 68 empty_fetchmany_value = () 69 69 update_can_self_select = False 70 supports_usecs = False71 70 72 71 class DatabaseOperations(BaseDatabaseOperations): 73 72 def date_extract_sql(self, lookup_type, field_name): … … class DatabaseOperations(BaseDatabaseOpe 134 133 return sql 135 134 else: 136 135 return [] 136 137 def value_to_db_datetime(self, value): 138 # MySQL doesn't support microseconds 139 if value is None: 140 return None 141 # XXX: Why not just str(value)? 142 return unicode(value.replace(microsecond=0)) 143 144 def value_to_db_time(self, value): 145 # MySQL doesn't support microseconds 146 if value is None: 147 return None 148 # XXX: Why not just str(value)? 149 return unicode(value.replace(microsecond=0)) 150 151 152 def year_lookup_bounds(self, value): 153 # Again, no microseconds 154 first = '%s-01-01 00:00:00' 155 second = '%s-12-31 23:59:59.99' 156 return [first % value, second % value] 157 137 158 138 159 class DatabaseWrapper(BaseDatabaseWrapper): 139 160 features = DatabaseFeatures() -
django/db/backends/oracle/base.py
diff -r 7dfb4f5c1bb0 django/db/backends/oracle/base.py
a b Requires cx_Oracle: http://www.python.ne 5 5 """ 6 6 7 7 import os 8 import datetime 9 import time 8 10 9 11 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util 10 12 from django.db.backends.oracle import query … … class DatabaseFeatures(BaseDatabaseFeatu 29 31 supports_tablespaces = True 30 32 uses_case_insensitive_names = True 31 33 uses_custom_query_class = True 32 time_field_needs_date = True33 34 interprets_empty_strings_as_nulls = True 34 date_field_supports_time_value = False35 35 36 36 class DatabaseOperations(BaseDatabaseOperations): 37 37 def autoinc_sql(self, table, column): … … class DatabaseOperations(BaseDatabaseOpe 185 185 186 186 def tablespace_sql(self, tablespace, inline=False): 187 187 return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), self.quote_name(tablespace)) 188 189 def value_to_db_time(self, value): 190 if value is None: 191 return None 192 if isinstance(value, basestring): 193 return datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6])) 194 return datetime.datetime(1900, 1, 1, value.hour, value.minute, 195 value.second, value.microsecond) 196 197 def year_lookup_bounds_for_date_field(self, value): 198 first = '%s-01-01' 199 second = '%s-12-31' 200 return [first % value, second % value] 201 202 188 203 189 204 class DatabaseWrapper(BaseDatabaseWrapper): 190 205 features = DatabaseFeatures() -
django/db/backends/sqlite3/base.py
diff -r 7dfb4f5c1bb0 django/db/backends/sqlite3/base.py
a b class DatabaseOperations(BaseDatabaseOpe 79 79 # sql_flush() implementations). Just return SQL at this point 80 80 return sql 81 81 82 def year_lookup_bounds(self, value): 83 first = '%s-01-01' 84 second = '%s-12-31 23:59:59.999999' 85 return [first % value, second % value] 86 87 82 88 class DatabaseWrapper(BaseDatabaseWrapper): 83 89 features = DatabaseFeatures() 84 90 ops = DatabaseOperations() … … def _sqlite_extract(lookup_type, dt): 151 157 dt = util.typecast_timestamp(dt) 152 158 except (ValueError, TypeError): 153 159 return None 154 return str(getattr(dt, lookup_type))160 return getattr(dt, lookup_type) 155 161 156 162 def _sqlite_date_trunc(lookup_type, dt): 157 163 try: -
django/db/backends/util.py
diff -r 7dfb4f5c1bb0 django/db/backends/util.py
a b def truncate_name(name, length=None): 117 117 hash = md5.md5(name).hexdigest()[:4] 118 118 119 119 return '%s%s' % (name[:length-4], hash) 120 121 def format_number(value, max_digits, decimal_places): 122 """ 123 Formats a number into a string with the requisite number of digits and 124 decimal places. 125 """ 126 return u"%.*f" % (decimal_places, value) -
django/db/models/base.py
diff -r 7dfb4f5c1bb0 django/db/models/base.py
a b class Model(object): 297 297 298 298 # If we are in a raw save, save the object exactly as presented. 299 299 # That means that we don't try to be smart about saving attributes 300 # that might have come from the parent class - we just save the 300 # that might have come from the parent class - we just save the 301 301 # attributes we have been given to the class we have been given. 302 302 if not raw: 303 303 for parent, field in meta.parents.items(): … … class Model(object): 305 305 setattr(self, field.attname, self._get_pk_val(parent._meta)) 306 306 307 307 non_pks = [f for f in meta.local_fields if not f.primary_key] 308 308 309 309 # First, try an UPDATE. If that doesn't update anything, do an INSERT. 310 310 pk_val = self._get_pk_val(meta) 311 311 # Note: the comparison with '' is required for compatibility with -
django/db/models/fields/__init__.py
diff -r 7dfb4f5c1bb0 django/db/models/fields/__init__.py
a b class Field(object): 252 252 value = int(value) 253 253 except ValueError: 254 254 raise ValueError("The __year lookup type requires an integer argument") 255 if settings.DATABASE_ENGINE == 'sqlite3': 256 first = '%s-01-01' 257 second = '%s-12-31 23:59:59.999999' 258 elif not connection.features.date_field_supports_time_value and self.get_internal_type() == 'DateField': 259 first = '%s-01-01' 260 second = '%s-12-31' 261 elif not connection.features.supports_usecs: 262 first = '%s-01-01 00:00:00' 263 second = '%s-12-31 23:59:59.99' 255 256 if self.get_internal_type() == 'DateField': 257 return connection.ops.year_lookup_bounds_for_date_field(value) 264 258 else: 265 first = '%s-01-01 00:00:00' 266 second = '%s-12-31 23:59:59.999999' 267 return [first % value, second % value] 259 return connection.ops.year_lookup_bounds(value) 260 268 261 raise TypeError("Field has invalid lookup: %s" % lookup_type) 269 262 270 263 def has_default(self): … … class AutoField(Field): 453 446 except (TypeError, ValueError): 454 447 raise validators.ValidationError, _("This value must be an integer.") 455 448 449 def get_db_prep_save(self, value): 450 if value is None: 451 return None 452 return int(value) 453 454 def get_db_prep_lookup(self, lookup_type, value): 455 if lookup_type == 'range': 456 value = [int(v) for v in value] 457 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 458 value = int(value) 459 return Field.get_db_prep_lookup(self, lookup_type, value) 460 456 461 def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True): 457 462 if not rel: 458 463 return [] # Don't add a FormField unless it's in a related context. … … class BooleanField(Field): 491 496 if value in ('t', 'True', '1'): return True 492 497 if value in ('f', 'False', '0'): return False 493 498 raise validators.ValidationError, _("This value must be either True or False.") 499 500 def get_db_prep_save(self, value): 501 if value is None: 502 return None 503 return bool(value) 504 505 def get_db_prep_lookup(self, lookup_type, value): 506 if lookup_type == 'exact' and value is not None: 507 value = bool(value) 508 return Field.get_db_prep_lookup(self, lookup_type, value) 494 509 495 510 def get_manipulator_field_objs(self): 496 511 return [oldforms.CheckboxField] … … class DateField(Field): 554 569 raise validators.ValidationError, _('Enter a valid date in YYYY-MM-DD format.') 555 570 556 571 def get_db_prep_lookup(self, lookup_type, value): 572 value_to_db_date = connection.ops.value_to_db_date 557 573 if lookup_type == 'range': 558 value = [smart_unicode(v) for v in value] 559 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'): 560 value = value.strftime('%Y-%m-%d') 561 else: 562 value = smart_unicode(value) 574 value = [value_to_db_date(self.to_python(v)) for v in value] 575 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 576 # Lookups with a date argument 577 value = value_to_db_date(self.to_python(value)) 563 578 return Field.get_db_prep_lookup(self, lookup_type, value) 564 579 565 580 def pre_save(self, model_instance, add): … … class DateField(Field): 586 601 return self.editable or self.auto_now or self.auto_now_add 587 602 588 603 def get_db_prep_save(self, value): 589 # Casts dates into string format for entry into database. 590 if value is not None: 591 try: 592 value = value.strftime('%Y-%m-%d') 593 except AttributeError: 594 # If value is already a string it won't have a strftime method, 595 # so we'll just let it pass through. 596 pass 597 return Field.get_db_prep_save(self, value) 604 # Casts dates into the format expected by the backend 605 return connection.ops.value_to_db_date(self.to_python(value)) 598 606 599 607 def get_manipulator_field_objs(self): 600 608 return [oldforms.DateField] … … class DateTimeField(DateField): 619 627 return value 620 628 if isinstance(value, datetime.date): 621 629 return datetime.datetime(value.year, value.month, value.day) 630 631 # Attempt to parse a datetime: 632 value = smart_str(value) 633 # split usecs, because they are not recognized by strptime. 634 if '.' in value: 635 try: 636 value, usecs = value.split('.') 637 usecs = int(usecs) 638 except ValueError: 639 raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format.') 640 else: 641 usecs = 0 642 kwargs = {'microsecond': usecs} 622 643 try: # Seconds are optional, so try converting seconds first. 623 return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6]) 644 return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6], 645 **kwargs) 646 624 647 except ValueError: 625 648 try: # Try without seconds. 626 return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5]) 649 return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5], 650 **kwargs) 627 651 except ValueError: # Try without hour/minutes/seconds. 628 652 try: 629 return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3]) 653 return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3], 654 **kwargs) 630 655 except ValueError: 631 raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM format.')656 raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format.') 632 657 633 658 def get_db_prep_save(self, value): 634 # Casts dates into string format for entry into database. 635 if value is not None: 636 # MySQL will throw a warning if microseconds are given, because it 637 # doesn't support microseconds. 638 if not connection.features.supports_usecs and hasattr(value, 'microsecond'): 639 value = value.replace(microsecond=0) 640 value = smart_unicode(value) 641 return Field.get_db_prep_save(self, value) 659 # Casts dates into the format expected by the backend 660 return connection.ops.value_to_db_datetime(self.to_python(value)) 642 661 643 662 def get_db_prep_lookup(self, lookup_type, value): 663 value_to_db_datetime = connection.ops.value_to_db_datetime 644 664 if lookup_type == 'range': 645 value = [ smart_unicode(v) for v in value]646 el se:647 value = smart_unicode(value)665 value = [value_to_db_datetime(self.to_python(v)) for v in value] 666 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 667 value = value_to_db_datetime(self.to_python(value)) 648 668 return Field.get_db_prep_lookup(self, lookup_type, value) 649 669 650 670 def get_manipulator_field_objs(self): … … class DecimalField(Field): 705 725 Formats a number into a string with the requisite number of digits and 706 726 decimal places. 707 727 """ 708 num_chars = self.max_digits 709 # Allow for a decimal point 710 if self.decimal_places > 0: 711 num_chars += 1 712 # Allow for a minus sign 713 if value < 0: 714 num_chars += 1 715 716 return u"%.*f" % (self.decimal_places, value) 728 # Method moved to django.db.backends.util. 729 # 730 # It is preserved because it is used by the oracle backend 731 # (django.db.backends.oracle.query), and also for 732 # backwards-compatibility with any external code which may have used 733 # this method. 734 from django.db.backends import util 735 return util.format_number(value, self.max_digits, self.decimal_places) 717 736 718 737 def get_db_prep_save(self, value): 719 value = self._format(value)720 return super(DecimalField, self).get_db_prep_save(value)738 return connection.ops.value_to_db_decimal(value, self.max_digits, 739 self.decimal_places) 721 740 722 741 def get_db_prep_lookup(self, lookup_type, value): 742 value_to_db_decimal = connection.ops.value_to_db_decimal 723 743 if lookup_type == 'range': 724 value = [self._format(v) for v in value] 744 value = [value_to_db_decimal(v, self.max_digits, 745 self.decimal_places) 746 for v in value] 725 747 else: 726 value = self._format(value) 748 value = value_to_db_decimal(value, self.max_digits, 749 self.decimal_places) 727 750 return super(DecimalField, self).get_db_prep_lookup(lookup_type, value) 728 751 729 752 def get_manipulator_field_objs(self): … … class FloatField(Field): 898 921 class FloatField(Field): 899 922 empty_strings_allowed = False 900 923 924 def get_db_prep_save(self, value): 925 if value is None: 926 return None 927 return float(value) 928 929 def get_db_prep_lookup(self, lookup_type, value): 930 if lookup_type == 'range': 931 value = [float(v) for v in value] 932 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 933 value = float(value) 934 return Field.get_db_prep_lookup(self, lookup_type, value) 935 901 936 def get_manipulator_field_objs(self): 902 937 return [oldforms.FloatField] 903 938 … … class ImageField(FileField): 948 983 949 984 class IntegerField(Field): 950 985 empty_strings_allowed = False 986 def get_db_prep_save(self, value): 987 if value is None: 988 return None 989 return int(value) 990 991 def get_db_prep_lookup(self, lookup_type, value): 992 if lookup_type == 'range': 993 value = [int(v) for v in value] 994 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 995 value = int(value) 996 return Field.get_db_prep_lookup(self, lookup_type, value) 997 951 998 def get_manipulator_field_objs(self): 952 999 return [oldforms.IntegerField] 953 1000 … … class NullBooleanField(Field): 995 1042 if value in ('f', 'False', '0'): return False 996 1043 raise validators.ValidationError, _("This value must be either None, True or False.") 997 1044 1045 def get_db_prep_save(self, value): 1046 if value is None: 1047 return None 1048 return bool(value) 1049 1050 def get_db_prep_lookup(self, lookup_type, value): 1051 if lookup_type == 'exact' and value is not None: 1052 value = bool(value) 1053 return Field.get_db_prep_lookup(self, lookup_type, value) 1054 1055 998 1056 def get_manipulator_field_objs(self): 999 1057 return [oldforms.NullBooleanField] 1000 1058 … … class NullBooleanField(Field): 1003 1061 defaults.update(kwargs) 1004 1062 return super(NullBooleanField, self).formfield(**defaults) 1005 1063 1006 class PhoneNumberField( IntegerField):1064 class PhoneNumberField(Field): 1007 1065 def get_manipulator_field_objs(self): 1008 1066 return [oldforms.PhoneNumberField] 1009 1067 … … class TimeField(Field): 1085 1143 def get_internal_type(self): 1086 1144 return "TimeField" 1087 1145 1146 def to_python(self, value): 1147 if value is None: 1148 return None 1149 if isinstance(value, datetime.time): 1150 return value 1151 1152 # Attempt to parse a datetime: 1153 value = smart_str(value) 1154 # split usecs, because they are not recognized by strptime. 1155 if '.' in value: 1156 try: 1157 value, usecs = value.split('.') 1158 usecs = int(usecs) 1159 except ValueError: 1160 raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.') 1161 else: 1162 usecs = 0 1163 kwargs = {'microsecond': usecs} 1164 1165 try: # Seconds are optional, so try converting seconds first. 1166 return datetime.time(*time.strptime(value, '%H:%M:%S')[3:6], 1167 **kwargs) 1168 except ValueError: 1169 try: # Try without seconds. 1170 return datetime.datetime(*time.strptime(value, '%H:%M')[:5], 1171 **kwargs) 1172 except ValueError: 1173 raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.') 1174 1088 1175 def get_db_prep_lookup(self, lookup_type, value): 1089 if connection.features.time_field_needs_date: 1090 # Oracle requires a date in order to parse. 1091 def prep(value): 1092 if isinstance(value, datetime.time): 1093 value = datetime.datetime.combine(datetime.date(1900, 1, 1), value) 1094 return smart_unicode(value) 1095 else: 1096 prep = smart_unicode 1176 value_to_db_time = connection.ops.value_to_db_time 1097 1177 if lookup_type == 'range': 1098 value = [ prep(v) for v in value]1099 el se:1100 value = prep(value)1178 value = [value_to_db_time(self.to_python(v)) for v in value] 1179 elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'): 1180 value = value_to_db_time(self.to_python(value)) 1101 1181 return Field.get_db_prep_lookup(self, lookup_type, value) 1102 1182 1103 1183 def pre_save(self, model_instance, add): … … class TimeField(Field): 1109 1189 return super(TimeField, self).pre_save(model_instance, add) 1110 1190 1111 1191 def get_db_prep_save(self, value): 1112 # Casts dates into string format for entry into database. 1113 if value is not None: 1114 # MySQL will throw a warning if microseconds are given, because it 1115 # doesn't support microseconds. 1116 if not connection.features.supports_usecs and hasattr(value, 'microsecond'): 1117 value = value.replace(microsecond=0) 1118 if connection.features.time_field_needs_date: 1119 # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field. 1120 if isinstance(value, datetime.time): 1121 value = datetime.datetime(1900, 1, 1, value.hour, value.minute, 1122 value.second, value.microsecond) 1123 elif isinstance(value, basestring): 1124 value = datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6])) 1125 else: 1126 value = smart_unicode(value) 1127 return Field.get_db_prep_save(self, value) 1192 # Casts times into the format expected by the backend 1193 return connection.ops.value_to_db_time(self.to_python(value)) 1128 1194 1129 1195 def get_manipulator_field_objs(self): 1130 1196 return [oldforms.TimeField] -
tests/modeltests/custom_methods/models.py
diff -r 7dfb4f5c1bb0 tests/modeltests/custom_methods/models.py
a b class Article(models.Model): 31 31 SELECT id, headline, pub_date 32 32 FROM custom_methods_article 33 33 WHERE pub_date = %s 34 AND id != %s""", [str(self.pub_date), self.id]) 34 AND id != %s""", [connection.ops.value_to_db_date(self.pub_date), 35 self.id]) 35 36 # The asterisk in "(*row)" tells Python to expand the list into 36 37 # positional arguments to Article(). 37 38 return [self.__class__(*row) for row in cursor.fetchall()] -
tests/regressiontests/model_fields/tests.py
diff -r 7dfb4f5c1bb0 tests/regressiontests/model_fields/tests.py
a b ValidationError: [u'This value must be a 20 20 >>> x = f.to_python(2) 21 21 >>> y = f.to_python('2.6') 22 22 23 >>> f. get_db_prep_save(x)23 >>> f._format(x) 24 24 u'2.0' 25 >>> f. get_db_prep_save(y)25 >>> f._format(y) 26 26 u'2.6' 27 >>> f.get_db_prep_save(None) 28 >>> f.get_db_prep_lookup('exact', x) 29 [u'2.0'] 30 >>> f.get_db_prep_lookup('exact', y) 31 [u'2.6'] 27 >>> f._format(None) 32 28 >>> f.get_db_prep_lookup('exact', None) 33 29 [None] 34 30 31 # DateTimeField and TimeField to_python should support usecs: 32 >>> f = DateTimeField() 33 >>> f.to_python('2001-01-02 03:04:05.000006') 34 datetime.datetime(2001, 1, 2, 3, 4, 5, 6) 35 >>> f.to_python('2001-01-02 03:04:05.999999') 36 datetime.datetime(2001, 1, 2, 3, 4, 5, 999999) 37 38 >>> f = TimeField() 39 >>> f.to_python('01:02:03.000004') 40 datetime.time(1, 2, 3, 4) 41 >>> f.to_python('01:02:03.999999') 42 datetime.time(1, 2, 3, 999999) 43 44 35 45 """ -
tests/regressiontests/model_regress/models.py
diff -r 7dfb4f5c1bb0 tests/regressiontests/model_regress/models.py
a b class Movie(models.Model): 28 28 29 29 class Party(models.Model): 30 30 when = models.DateField() 31 32 class Event(models.Model): 33 when = models.DateTimeField() 31 34 32 35 __test__ = {'API_TESTS': """ 33 36 (NOTE: Part of the regression test here is merely parsing the model … … 5000 68 71 >>> [p.when for p in Party.objects.filter(when__year = 1998)] 69 72 [datetime.date(1998, 12, 31)] 70 73 74 # Check that get_next_by_FIELD and get_previous_by_FIELD don't crash when we 75 # have usecs values stored on the database 76 # 77 # [It crashed after the Field.get_db_prep_* refactor, because on most backends 78 # DateTimeFields supports usecs, but DateTimeField.to_python didn't recognize 79 # them. (Note that Model._get_next_or_previous_by_FIELD coerces values to 80 # strings)] 81 # 82 >>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 16, 0, 0, 500)) 83 >>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 6, 0, 0, 400)) 84 >>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 13, 0, 0, 990)) 85 >>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 12, 0, 20, 24)) 86 >>> e.get_next_by_when().when 87 datetime.datetime(2000, 1, 1, 13, 0, 0, 990) 88 >>> e.get_previous_by_when().when 89 datetime.datetime(2000, 1, 1, 6, 0, 0, 400) 71 90 """ 72 91 }