diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index e4c870c..ecd1070 100644
--- a/django/db/backends/creation.py
+++ b/django/db/backends/creation.py
@@ -6,6 +6,7 @@ import warnings
 from django.conf import settings
 from django.db.utils import load_backend
 from django.utils.encoding import force_bytes
+from django.utils.functional import cached_property
 from django.utils.six.moves import input
 
 from .utils import truncate_name
@@ -29,6 +30,24 @@ class BaseDatabaseCreation(object):
     def __init__(self, connection):
         self.connection = connection
 
+    @cached_property
+    def nodb_connection(self):
+        """
+        Alternative connection to be used when there is no need to access
+        the main database, specifically for test db creation/deletion.
+        This also prevents the production database from being exposed to
+        potential child threads while (or after) the test database is destroyed.
+        Refs #10868 and #17786.
+        """
+        settings_dict = self.connection.settings_dict.copy()
+        settings_dict['NAME'] = None
+        backend = load_backend(settings_dict['ENGINE'])
+        nodb_connection = backend.DatabaseWrapper(
+             settings_dict,
+             alias='__no_db__',
+             allow_thread_sharing=False)
+        return nodb_connection
+
     @classmethod
     def _digest(cls, *args):
         """
@@ -386,7 +405,7 @@ class BaseDatabaseCreation(object):
         qn = self.connection.ops.quote_name
 
         # Create the test database and connect to it.
-        cursor = self.connection.cursor()
+        cursor = self.nodb_connection.cursor()
         try:
             cursor.execute(
                 "CREATE DATABASE %s %s" % (qn(test_database_name), suffix))
@@ -431,18 +450,7 @@ class BaseDatabaseCreation(object):
             print("Destroying test database for alias '%s'%s..." % (
                 self.connection.alias, test_db_repr))
 
-        # Temporarily use a new connection and a copy of the settings dict.
-        # This prevents the production database from being exposed to potential
-        # child threads while (or after) the test database is destroyed.
-        # Refs #10868 and #17786.
-        settings_dict = self.connection.settings_dict.copy()
-        settings_dict['NAME'] = old_database_name
-        backend = load_backend(settings_dict['ENGINE'])
-        new_connection = backend.DatabaseWrapper(
-                             settings_dict,
-                             alias='__destroy_test_db__',
-                             allow_thread_sharing=False)
-        new_connection.creation._destroy_test_db(test_database_name, verbosity)
+        self._destroy_test_db(test_database_name, verbosity)
 
     def _destroy_test_db(self, test_database_name, verbosity):
         """
@@ -452,12 +460,11 @@ class BaseDatabaseCreation(object):
         # ourselves. Connect to the previous database (not the test database)
         # to do so, because it's not allowed to delete a database while being
         # connected to it.
-        cursor = self.connection.cursor()
+        cursor = self.nodb_connection.cursor()
         # Wait to avoid "database is being accessed by other users" errors.
         time.sleep(1)
         cursor.execute("DROP DATABASE %s"
                        % self.connection.ops.quote_name(test_database_name))
-        self.connection.close()
 
     def set_autocommit(self):
         """
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index b22c653..cb23c33 100644
--- a/django/db/backends/postgresql_psycopg2/base.py
+++ b/django/db/backends/postgresql_psycopg2/base.py
@@ -101,13 +101,14 @@ class DatabaseWrapper(BaseDatabaseWrapper):
 
     def get_connection_params(self):
         settings_dict = self.settings_dict
-        if not settings_dict['NAME']:
+        # None may be used to connect to the default 'postgres' db
+        if settings_dict['NAME'] == '':
             from django.core.exceptions import ImproperlyConfigured
             raise ImproperlyConfigured(
                 "settings.DATABASES is improperly configured. "
                 "Please supply the NAME value.")
         conn_params = {
-            'database': settings_dict['NAME'],
+            'database': settings_dict['NAME'] or 'postgres',
         }
         conn_params.update(settings_dict['OPTIONS'])
         if 'autocommit' in conn_params:
