diff --git a/django/core/management/templates.py b/django/core/management/templates.py
index 3addb068f7..7c147a5231 100644
--- a/django/core/management/templates.py
+++ b/django/core/management/templates.py
@@ -208,14 +208,21 @@ class TemplateCommand(BaseCommand):
             raise CommandError("you must provide %s %s name" % (
                 "an" if app_or_project == "app" else "a", app_or_project))
         # If it's not a valid directory name.
-        if not re.search(r'^[_a-zA-Z]\w*$', name):
-            # Provide a smart error message, depending on the error.
-            if not re.search(r'^[_a-zA-Z]', name):
-                message = 'make sure the name begins with a letter or underscore'
-            else:
-                message = 'use only numbers, letters and underscores'
-            raise CommandError("%r is not a valid %s name. Please %s." %
-                               (name, app_or_project, message))
+        if six.PY2:
+            if not re.search(r'^[_a-zA-Z]\w*$', name):
+                # Provide a smart error message, depending on the error.
+                if not re.search(r'^[_a-zA-Z]', name):
+                    message = 'make sure the name begins with a letter or underscore'
+                else:
+                    message = 'use only numbers, letters and underscores'
+                raise CommandError("%r is not a valid %s name. Please %s." %
+                                   (name, app_or_project, message))
+        else:
+            if not name.isidentifier():
+                raise CommandError(
+                    "%r is not a valid %s name. Please make sure the name is "
+                    "a valid identifier." % (name, app_or_project)
+                )
 
     def download(self, url):
         """
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index 4e976d89fd..f2950f0ee6 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -31,7 +31,7 @@ from django.test import (
 from django.test.runner import DiscoverRunner
 from django.utils._os import npath, upath
 from django.utils.encoding import force_text
-from django.utils.six import PY3, StringIO
+from django.utils.six import PY2, PY3, StringIO
 
 custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates')
 
@@ -633,6 +633,20 @@ class DjangoAdminSettingsDirectory(AdminScriptTestCase):
         self.assertTrue(os.path.exists(app_path))
         self.assertTrue(os.path.exists(os.path.join(app_path, 'api.py')))
 
+    @unittest.skipIf(PY2, "Python 2 doesn't support Unicode package names.")
+    def test_startapp_unicode_name(self):
+        "directory: startapp creates the correct directory with unicode characters"
+        args = ['startapp', 'こんにちは']
+        app_path = os.path.join(self.test_dir, 'こんにちは')
+        out, err = self.run_django_admin(args, 'test_project.settings')
+        self.addCleanup(shutil.rmtree, app_path)
+        self.assertNoOutput(err)
+        self.assertTrue(os.path.exists(app_path))
+        with open(os.path.join(app_path, 'apps.py'), 'r') as f:
+            content = f.read()
+            self.assertIn("class こんにちはConfig(AppConfig)", content)
+            self.assertIn("name = 'こんにちは'", content)
+
     def test_builtin_command(self):
         "directory: django-admin builtin commands fail with an error when no settings provided"
         args = ['check', 'admin_scripts']
@@ -1887,8 +1901,18 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
             self.addCleanup(shutil.rmtree, testproject_dir, True)
 
             out, err = self.run_django_admin(args)
-            self.assertOutput(err, "Error: '%s' is not a valid project name. "
-                "Please make sure the name begins with a letter or underscore." % bad_name)
+            if PY2:
+                self.assertOutput(
+                    err,
+                    "Error: '%s' is not a valid project name. Please make "
+                    "sure the name begins with a letter or underscore." % bad_name
+                )
+            else:
+                self.assertOutput(
+                    err,
+                    "Error: '%s' is not a valid project name. Please make "
+                    "sure the name is a valid identifier." % bad_name
+                )
             self.assertFalse(os.path.exists(testproject_dir))
 
     def test_simple_project_different_directory(self):