diff options
| author | Alex Gaynor <alex.gaynor@gmail.com> | 2010-06-07 17:52:53 +0000 |
|---|---|---|
| committer | Alex Gaynor <alex.gaynor@gmail.com> | 2010-06-07 17:52:53 +0000 |
| commit | a61b34b048d84b2a8af78a42a4e635371252bd3f (patch) | |
| tree | 6c0733ffe75a10b95719ac7b99bcd9b9abc6b578 /django | |
| parent | 9d3e6668d91af5ef442d07192b5508707d7e0a2a (diff) | |
[soc2010/query-refactor] Merged up to trunk r13328.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/query-refactor@13329 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/conf/locale/pl/formats.py | 4 | ||||
| -rw-r--r-- | django/core/handlers/base.py | 3 | ||||
| -rw-r--r-- | django/core/management/base.py | 18 | ||||
| -rw-r--r-- | django/core/management/commands/loaddata.py | 30 | ||||
| -rw-r--r-- | django/db/backends/__init__.py | 5 | ||||
| -rw-r--r-- | django/db/backends/postgresql/creation.py | 3 | ||||
| -rw-r--r-- | django/db/backends/postgresql/operations.py | 30 | ||||
| -rw-r--r-- | django/http/__init__.py | 4 | ||||
| -rw-r--r-- | django/test/testcases.py | 3 | ||||
| -rw-r--r-- | django/utils/hashcompat.py | 8 | ||||
| -rw-r--r-- | django/views/debug.py | 2 |
11 files changed, 65 insertions, 45 deletions
diff --git a/django/conf/locale/pl/formats.py b/django/conf/locale/pl/formats.py index a4a2961185..4520f7ce4e 100644 --- a/django/conf/locale/pl/formats.py +++ b/django/conf/locale/pl/formats.py @@ -28,5 +28,5 @@ DATETIME_INPUT_FORMATS = ( '%Y-%m-%d', # '2006-10-25' ) DECIMAL_SEPARATOR = ',' -THOUSAND_SEPARATOR = '.' -NUMBER_GROUPING = 3
\ No newline at end of file +THOUSAND_SEPARATOR = ' ' +NUMBER_GROUPING = 3 diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 79f6607214..b03c2fd71e 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -137,9 +137,8 @@ class BaseHandler(object): raise except: # Handle everything else, including SuspiciousOperation, etc. # Get the exception info now, in case another exception is thrown later. - exc_info = sys.exc_info() receivers = signals.got_request_exception.send(sender=self.__class__, request=request) - return self.handle_uncaught_exception(request, resolver, exc_info) + return self.handle_uncaught_exception(request, resolver, sys.exc_info()) finally: # Reset URLconf for this thread on the way out for complete # isolation of request.urlconf diff --git a/django/core/management/base.py b/django/core/management/base.py index 4016faaa7a..6761cb69bc 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -213,20 +213,24 @@ class BaseCommand(object): sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) sys.exit(1) try: + self.stdout = options.get('stdout', sys.stdout) + self.stderr = options.get('stderr', sys.stderr) if self.requires_model_validation: self.validate() output = self.handle(*args, **options) if output: if self.output_transaction: - # This needs to be imported here, because it relies on settings. - from django.db import connection + # This needs to be imported here, because it relies on + # settings. + from django.db import connections, DEFAULT_DB_ALIAS + connection = connections[options.get('database', DEFAULT_DB_ALIAS)] if connection.ops.start_transaction_sql(): - print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()) - print output + self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())) + self.stdout.write(output) if self.output_transaction: - print self.style.SQL_KEYWORD("COMMIT;") + self.stdout.write(self.style.SQL_KEYWORD("COMMIT;") + '\n') except CommandError, e: - sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) + self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) sys.exit(1) def validate(self, app=None, display_num_errors=False): @@ -248,7 +252,7 @@ class BaseCommand(object): error_text = s.read() raise CommandError("One or more models did not validate:\n%s" % error_text) if display_num_errors: - print "%s error%s found" % (num_errors, num_errors != 1 and 's' or '') + self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or '')) def handle(self, *args, **options): """ diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 6212d6151d..caf3b11b85 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -112,10 +112,10 @@ class Command(BaseCommand): if formats: if verbosity > 1: - print "Loading '%s' fixtures..." % fixture_name + self.stdout.write("Loading '%s' fixtures...\n" % fixture_name) else: sys.stderr.write( - self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." % + self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format.\n" % (fixture_name, format))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) @@ -128,7 +128,7 @@ class Command(BaseCommand): for fixture_dir in fixture_dirs: if verbosity > 1: - print "Checking %s for fixtures..." % humanize(fixture_dir) + self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir)) label_found = False for combo in product([using, None], formats, compression_formats): @@ -141,16 +141,16 @@ class Command(BaseCommand): ) if verbosity > 1: - print "Trying %s for %s fixture '%s'..." % \ - (humanize(fixture_dir), file_name, fixture_name) + self.stdout.write("Trying %s for %s fixture '%s'...\n" % \ + (humanize(fixture_dir), file_name, fixture_name)) full_path = os.path.join(fixture_dir, file_name) open_method = compression_types[compression_format] try: fixture = open_method(full_path, 'r') if label_found: fixture.close() - print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." % - (fixture_name, humanize(fixture_dir))) + self.stderr.write(self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting.\n" % + (fixture_name, humanize(fixture_dir)))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) return @@ -158,8 +158,8 @@ class Command(BaseCommand): fixture_count += 1 objects_in_fixture = 0 if verbosity > 0: - print "Installing %s fixture '%s' from %s." % \ - (format, fixture_name, humanize(fixture_dir)) + self.stdout.write("Installing %s fixture '%s' from %s.\n" % \ + (format, fixture_name, humanize(fixture_dir))) try: objects = serializers.deserialize(format, fixture, using=using) for obj in objects: @@ -190,7 +190,7 @@ class Command(BaseCommand): # error was encountered during fixture loading. if objects_in_fixture == 0: sys.stderr.write( - self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" % + self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)\n" % (fixture_name))) transaction.rollback(using=using) transaction.leave_transaction_management(using=using) @@ -198,8 +198,8 @@ class Command(BaseCommand): except Exception, e: if verbosity > 1: - print "No %s fixture '%s' in %s." % \ - (format, fixture_name, humanize(fixture_dir)) + self.stdout.write("No %s fixture '%s' in %s.\n" % \ + (format, fixture_name, humanize(fixture_dir))) # If we found even one object in a fixture, we need to reset the # database sequences. @@ -207,7 +207,7 @@ class Command(BaseCommand): sequence_sql = connection.ops.sequence_reset_sql(self.style, models) if sequence_sql: if verbosity > 1: - print "Resetting sequences" + self.stdout.write("Resetting sequences\n") for line in sequence_sql: cursor.execute(line) @@ -217,10 +217,10 @@ class Command(BaseCommand): if object_count == 0: if verbosity > 0: - print "No fixtures found." + self.stdout.write("No fixtures found.\n") else: if verbosity > 0: - print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count) + self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % (object_count, fixture_count)) # Close the DB connection. This is required as a workaround for an # edge case in MySQL: if the same connection is used to diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 5918935899..fe2c7c451b 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -353,6 +353,11 @@ class BaseDatabaseOperations(object): """ return "BEGIN;" + def end_transaction_sql(self, success=True): + if not success: + return "ROLLBACK;" + return "COMMIT;" + def tablespace_sql(self, tablespace, inline=False): """ Returns the SQL that will be appended to tables or rows to define diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py index af26d0b78f..e3587f0e37 100644 --- a/django/db/backends/postgresql/creation.py +++ b/django/db/backends/postgresql/creation.py @@ -1,4 +1,5 @@ from django.db.backends.creation import BaseDatabaseCreation +from django.db.backends.util import truncate_name class DatabaseCreation(BaseDatabaseCreation): # This dictionary maps Field objects to their associated PostgreSQL column @@ -51,7 +52,7 @@ class DatabaseCreation(BaseDatabaseCreation): def get_index_sql(index_name, opclass=''): return (style.SQL_KEYWORD('CREATE INDEX') + ' ' + - style.SQL_TABLE(qn(index_name)) + ' ' + + style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))) + ' ' + style.SQL_KEYWORD('ON') + ' ' + style.SQL_TABLE(qn(db_table)) + ' ' + "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) + diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 2951c33db9..76f25410fb 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -54,7 +54,9 @@ class DatabaseOperations(BaseDatabaseOperations): return '%s' def last_insert_id(self, cursor, table_name, pk_name): - cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) + # Use pg_get_serial_sequence to get the underlying sequence name + # from the table name and column name (available since PostgreSQL 8) + cursor.execute("SELECT CURRVAL(pg_get_serial_sequence('%s','%s'))" % (table_name, pk_name)) return cursor.fetchone()[0] def no_limit_value(self): @@ -90,13 +92,14 @@ class DatabaseOperations(BaseDatabaseOperations): for sequence_info in sequences: table_name = sequence_info['table'] column_name = sequence_info['column'] - if column_name and len(column_name) > 0: - sequence_name = '%s_%s_seq' % (table_name, column_name) - else: - sequence_name = '%s_id_seq' % table_name - sql.append("%s setval('%s', 1, false);" % \ + if not (column_name and len(column_name) > 0): + # This will be the case if it's an m2m using an autogenerated + # intermediate table (see BaseDatabaseIntrospection.sequence_list) + column_name = 'id' + sql.append("%s setval(pg_get_serial_sequence('%s','%s'), 1, false);" % \ (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(self.quote_name(sequence_name))) + style.SQL_TABLE(table_name), + style.SQL_FIELD(column_name)) ) return sql else: @@ -110,11 +113,15 @@ class DatabaseOperations(BaseDatabaseOperations): # Use `coalesce` to set the sequence for each model to the max pk value if there are records, # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true # if there are records (as the max pk value is already in use), otherwise set it to false. + # Use pg_get_serial_sequence to get the underlying sequence name from the table name + # and column name (available since PostgreSQL 8) + for f in model._meta.local_fields: if isinstance(f, models.AutoField): - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + output.append("%s setval(pg_get_serial_sequence('%s','%s'), coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(qn('%s_%s_seq' % (model._meta.db_table, f.column))), + style.SQL_TABLE(model._meta.db_table), + style.SQL_FIELD(f.column), style.SQL_FIELD(qn(f.column)), style.SQL_FIELD(qn(f.column)), style.SQL_KEYWORD('IS NOT'), @@ -123,9 +130,10 @@ class DatabaseOperations(BaseDatabaseOperations): break # Only one AutoField is allowed per model, so don't bother continuing. for f in model._meta.many_to_many: if not f.rel.through: - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + output.append("%s setval(pg_get_serial_sequence('%s','%s'), coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(qn('%s_id_seq' % f.m2m_db_table())), + style.SQL_TABLE(model._meta.db_table), + style.SQL_FIELD('id'), style.SQL_FIELD(qn('id')), style.SQL_FIELD(qn('id')), style.SQL_KEYWORD('IS NOT'), diff --git a/django/http/__init__.py b/django/http/__init__.py index 8756d046b5..c3917a16b2 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -177,14 +177,14 @@ class QueryDict(MultiValueDict): super(QueryDict, self).__delitem__(key) def __copy__(self): - result = self.__class__('', mutable=True) + result = self.__class__('', mutable=True, encoding=self.encoding) for key, value in dict.items(self): dict.__setitem__(result, key, value) return result def __deepcopy__(self, memo): import django.utils.copycompat as copy - result = self.__class__('', mutable=True) + result = self.__class__('', mutable=True, encoding=self.encoding) memo[id(self)] = result for key, value in dict.items(self): dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo)) diff --git a/django/test/testcases.py b/django/test/testcases.py index 2f8acad68c..276d1f3c41 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -466,6 +466,9 @@ class TransactionTestCase(unittest.TestCase): msg_prefix + "Template '%s' was used unexpectedly in rendering" " the response" % template_name) + def assertQuerysetEqual(self, qs, values, transform=repr): + return self.assertEqual(map(transform, qs), values) + def connections_support_transactions(): """ Returns True if all connections support transactions. This is messy diff --git a/django/utils/hashcompat.py b/django/utils/hashcompat.py index b1e6021890..4d9b76f3a6 100644 --- a/django/utils/hashcompat.py +++ b/django/utils/hashcompat.py @@ -1,17 +1,17 @@ """ The md5 and sha modules are deprecated since Python 2.5, replaced by the hashlib module containing both hash algorithms. Here, we provide a common -interface to the md5 and sha constructors, preferring the hashlib module when -available. +interface to the md5 and sha constructors, depending on system version. """ -try: +import sys +if sys.version_info >= (2, 5): import hashlib md5_constructor = hashlib.md5 md5_hmac = md5_constructor sha_constructor = hashlib.sha1 sha_hmac = sha_constructor -except ImportError: +else: import md5 md5_constructor = md5.new md5_hmac = md5 diff --git a/django/views/debug.py b/django/views/debug.py index 6604bd3dae..a396d36244 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -12,7 +12,7 @@ from django.utils.importlib import import_module from django.utils.encoding import smart_unicode, smart_str -HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD|PROFANITIES_LIST') +HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD|PROFANITIES_LIST|SIGNATURE') def linebreak_iter(template_source): yield 0 |
