diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 1b6ba07f24..dd50229461 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -127,6 +127,27 @@ class BaseDatabaseOperations(object):
         """
         raise NotImplementedError('Full-text search is not implemented for this database backend')
 
+    def last_executed_query(self, cursor, sql, params):
+        """
+        Returns a string of the query last executed by the given cursor, with
+        placeholders replaced with actual values.
+
+        `sql` is the raw query containing placeholders, and `params` is the
+        sequence of parameters. These are used by default, but this method
+        exists for database backends to provide a better implementation
+        according to their own quoting schemes.
+        """
+        from django.utils.encoding import smart_unicode, force_unicode
+
+        # Convert params to contain Unicode values.
+        to_unicode = lambda s: force_unicode(s, strings_only=True)
+        if isinstance(params, (list, tuple)):
+            u_params = tuple([to_unicode(val) for val in params])
+        else:
+            u_params = dict([(to_unicode(k), to_unicode(v)) for k, v in params.items()])
+
+        return smart_unicode(sql) % u_params
+
     def last_insert_id(self, cursor, table_name, pk_name):
         """
         Given a cursor object that has just performed an INSERT statement into
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index a7b080d505..d7b3558344 100644
--- a/django/db/backends/postgresql_psycopg2/base.py
+++ b/django/db/backends/postgresql_psycopg2/base.py
@@ -5,7 +5,7 @@ Requires psycopg 2: http://initd.org/projects/psycopg2
 """
 
 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures
-from django.db.backends.postgresql.operations import DatabaseOperations
+from django.db.backends.postgresql.operations import DatabaseOperations as PostgresqlDatabaseOperations
 try:
     import psycopg2 as Database
     import psycopg2.extensions
@@ -21,6 +21,13 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
 class DatabaseFeatures(BaseDatabaseFeatures):
     needs_datetime_string_cast = False
 
+class DatabaseOperations(PostgresqlDatabaseOperations):
+    def last_executed_query(self, cursor, sql, params):
+        # With psycopg2, cursor objects have a "query" attribute that is the
+        # exact query sent to the database. See docs here:
+        # http://www.initd.org/tracker/psycopg/wiki/psycopg2_documentation#postgresql-status-message-and-executed-query
+        return cursor.query
+
 class DatabaseWrapper(BaseDatabaseWrapper):
     features = DatabaseFeatures()
     ops = DatabaseOperations()
diff --git a/django/db/backends/util.py b/django/db/backends/util.py
index fa2df22927..ca4e90d6c2 100644
--- a/django/db/backends/util.py
+++ b/django/db/backends/util.py
@@ -1,7 +1,6 @@
 import datetime
 import md5
 from time import time
-from django.utils.encoding import smart_unicode, force_unicode
 
 try:
     import decimal
@@ -11,7 +10,7 @@ except ImportError:
 class CursorDebugWrapper(object):
     def __init__(self, cursor, db):
         self.cursor = cursor
-        self.db = db
+        self.db = db # Instance of a BaseDatabaseWrapper subclass
 
     def execute(self, sql, params=()):
         start = time()
@@ -19,8 +18,9 @@ class CursorDebugWrapper(object):
             return self.cursor.execute(sql, params)
         finally:
             stop = time()
+            sql = self.db.ops.last_executed_query(self.cursor, sql, params)
             self.db.queries.append({
-                'sql': smart_unicode(sql) % convert_args(params),
+                'sql': sql,
                 'time': "%.3f" % (stop - start),
             })
 
@@ -31,7 +31,7 @@ class CursorDebugWrapper(object):
         finally:
             stop = time()
             self.db.queries.append({
-                'sql': 'MANY: ' + sql + ' ' + smart_unicode(tuple(param_list)),
+                'sql': '%s times: %s' % (len(param_list), sql),
                 'time': "%.3f" % (stop - start),
             })
 
@@ -41,16 +41,6 @@ class CursorDebugWrapper(object):
         else:
             return getattr(self.cursor, attr)
 
-def convert_args(args):
-    """
-    Convert sequence or dictionary to contain unicode values.
-    """
-    to_unicode = lambda s: force_unicode(s, strings_only=True)
-    if isinstance(args, (list, tuple)):
-        return tuple([to_unicode(val) for val in args])
-    else:
-        return dict([(to_unicode(k), to_unicode(v)) for k, v in args.items()])
-
 ###############################################
 # Converters from database (string) to Python #
 ###############################################