mirror of
https://github.com/django/django.git
synced 2025-07-22 10:39:13 +00:00
Fixed #18296 -- Created missing custom target directory for startproject and startapp.
This commit is contained in:
parent
3babda775d
commit
bc21bc4282
@ -46,7 +46,9 @@ class TemplateCommand(BaseCommand):
|
|||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
parser.add_argument("name", help="Name of the application or project.")
|
parser.add_argument("name", help="Name of the application or project.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"directory", nargs="?", help="Optional destination directory"
|
"directory",
|
||||||
|
nargs="?",
|
||||||
|
help="Optional destination directory, this will be created if needed.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--template", help="The path or URL to load the template from."
|
"--template", help="The path or URL to load the template from."
|
||||||
@ -105,10 +107,10 @@ class TemplateCommand(BaseCommand):
|
|||||||
if app_or_project == "app":
|
if app_or_project == "app":
|
||||||
self.validate_name(os.path.basename(top_dir), "directory")
|
self.validate_name(os.path.basename(top_dir), "directory")
|
||||||
if not os.path.exists(top_dir):
|
if not os.path.exists(top_dir):
|
||||||
raise CommandError(
|
try:
|
||||||
"Destination directory '%s' does not "
|
os.makedirs(top_dir)
|
||||||
"exist, please create it first." % top_dir
|
except OSError as e:
|
||||||
)
|
raise CommandError(e)
|
||||||
|
|
||||||
# Find formatters, which are external executables, before input
|
# Find formatters, which are external executables, before input
|
||||||
# from the templates can sneak into the path.
|
# from the templates can sneak into the path.
|
||||||
|
@ -45,21 +45,16 @@ including database configuration, Django-specific options and
|
|||||||
application-specific settings.
|
application-specific settings.
|
||||||
|
|
||||||
From the command line, ``cd`` into a directory where you'd like to store your
|
From the command line, ``cd`` into a directory where you'd like to store your
|
||||||
code and create a new directory named ``djangotutorial``. (This directory name
|
code and run the following command to bootstrap a new Django project:
|
||||||
doesn't matter to Django; you can rename it to anything you like.)
|
|
||||||
|
|
||||||
.. console::
|
|
||||||
|
|
||||||
$ mkdir djangotutorial
|
|
||||||
|
|
||||||
Then, run the following command to bootstrap a new Django project:
|
|
||||||
|
|
||||||
.. console::
|
.. console::
|
||||||
|
|
||||||
$ django-admin startproject mysite djangotutorial
|
$ django-admin startproject mysite djangotutorial
|
||||||
|
|
||||||
This will create a project called ``mysite`` inside the ``djangotutorial``
|
This will create a directory ``djangotutorial`` with a project called
|
||||||
directory. If it didn't work, see :ref:`troubleshooting-django-admin`.
|
``mysite`` inside. The directory name doesn't matter to Django; you can rename
|
||||||
|
it to anything you like. If it didn't work, see
|
||||||
|
:ref:`troubleshooting-django-admin`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -1266,9 +1266,13 @@ By default, :source:`the new directory <django/conf/app_template>` contains a
|
|||||||
``models.py`` file and other app template files. If only the app name is given,
|
``models.py`` file and other app template files. If only the app name is given,
|
||||||
the app directory will be created in the current working directory.
|
the app directory will be created in the current working directory.
|
||||||
|
|
||||||
If the optional destination is provided, Django will use that existing
|
If the optional destination is provided, Django will use that name instead. If
|
||||||
directory rather than creating a new one. You can use '.' to denote the current
|
the directory with the given name doesn't exist, it will be created. You can
|
||||||
working directory.
|
use '.' to denote the current working directory.
|
||||||
|
|
||||||
|
.. versionchanged:: 6.0
|
||||||
|
|
||||||
|
Automatic creation of the destination directory was added.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@ -1378,9 +1382,14 @@ If only the project name is given, both the project directory and project
|
|||||||
package will be named ``<projectname>`` and the project directory
|
package will be named ``<projectname>`` and the project directory
|
||||||
will be created in the current working directory.
|
will be created in the current working directory.
|
||||||
|
|
||||||
If the optional destination is provided, Django will use that existing
|
If the optional destination is provided, Django will use that name as the
|
||||||
directory as the project directory, and create ``manage.py`` and the project
|
project directory, and create ``manage.py`` and the project package within it.
|
||||||
package within it. Use '.' to denote the current working directory.
|
If the directory with the given name doesn't exist, it will be created. Use '.'
|
||||||
|
to denote the current working directory.
|
||||||
|
|
||||||
|
.. versionchanged:: 6.0
|
||||||
|
|
||||||
|
Automatic creation of the destination directory was added.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
@ -170,7 +170,8 @@ Logging
|
|||||||
Management Commands
|
Management Commands
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* The :djadmin:`startproject` and :djadmin:`startapp` commands now create the
|
||||||
|
custom target directory if it doesn't exist.
|
||||||
|
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
@ -2843,8 +2843,7 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
|||||||
|
|
||||||
def test_custom_project_destination_missing(self):
|
def test_custom_project_destination_missing(self):
|
||||||
"""
|
"""
|
||||||
Make sure an exception is raised when the provided
|
Create the directory when the provided destination directory doesn't exist.
|
||||||
destination directory doesn't exist
|
|
||||||
"""
|
"""
|
||||||
template_path = os.path.join(custom_templates_dir, "project_template")
|
template_path = os.path.join(custom_templates_dir, "project_template")
|
||||||
args = [
|
args = [
|
||||||
@ -2857,12 +2856,8 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
|||||||
testproject_dir = os.path.join(self.test_dir, "project_dir2")
|
testproject_dir = os.path.join(self.test_dir, "project_dir2")
|
||||||
out, err = self.run_django_admin(args)
|
out, err = self.run_django_admin(args)
|
||||||
self.assertNoOutput(out)
|
self.assertNoOutput(out)
|
||||||
self.assertOutput(
|
self.assertNoOutput(err)
|
||||||
err,
|
self.assertTrue(os.path.exists(testproject_dir))
|
||||||
"Destination directory '%s' does not exist, please create it first."
|
|
||||||
% testproject_dir,
|
|
||||||
)
|
|
||||||
self.assertFalse(os.path.exists(testproject_dir))
|
|
||||||
|
|
||||||
def test_custom_project_template_with_non_ascii_templates(self):
|
def test_custom_project_template_with_non_ascii_templates(self):
|
||||||
"""
|
"""
|
||||||
@ -3099,6 +3094,66 @@ class StartApp(AdminScriptTestCase):
|
|||||||
content,
|
content,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_creates_directory_when_custom_app_destination_missing(self):
|
||||||
|
args = [
|
||||||
|
"startapp",
|
||||||
|
"my_app",
|
||||||
|
"my_app",
|
||||||
|
]
|
||||||
|
testapp_dir = os.path.join(self.test_dir, "my_app")
|
||||||
|
out, err = self.run_django_admin(args)
|
||||||
|
self.assertNoOutput(out)
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertTrue(os.path.exists(testapp_dir))
|
||||||
|
|
||||||
|
def test_custom_app_destination_missing_with_nested_subdirectory(self):
|
||||||
|
args = [
|
||||||
|
"startapp",
|
||||||
|
"my_app",
|
||||||
|
"apps/my_app",
|
||||||
|
]
|
||||||
|
testapp_dir = os.path.join(self.test_dir, "apps", "my_app")
|
||||||
|
out, err = self.run_django_admin(args)
|
||||||
|
self.assertNoOutput(out)
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertTrue(os.path.exists(testapp_dir))
|
||||||
|
|
||||||
|
def test_custom_name_with_app_within_other_app(self):
|
||||||
|
parent_app_dir = os.path.join(self.test_dir, "parent")
|
||||||
|
self.run_django_admin(["startapp", "parent"])
|
||||||
|
self.assertTrue(os.path.exists(parent_app_dir))
|
||||||
|
|
||||||
|
nested_args = ["startapp", "child", "parent/child"]
|
||||||
|
child_app_dir = os.path.join(self.test_dir, "parent", "child")
|
||||||
|
out, err = self.run_django_admin(nested_args)
|
||||||
|
self.assertNoOutput(out)
|
||||||
|
self.assertNoOutput(err)
|
||||||
|
self.assertTrue(os.path.exists(child_app_dir))
|
||||||
|
|
||||||
|
@unittest.skipIf(
|
||||||
|
sys.platform == "win32",
|
||||||
|
"Windows only partially supports umasks and chmod.",
|
||||||
|
)
|
||||||
|
def test_custom_app_directory_creation_error_handling(self):
|
||||||
|
"""The error is displayed to the user in case of OSError."""
|
||||||
|
args = [
|
||||||
|
"startapp",
|
||||||
|
"my_app",
|
||||||
|
"project_dir/my_app",
|
||||||
|
]
|
||||||
|
# Create a read-only parent directory.
|
||||||
|
os.makedirs(
|
||||||
|
os.path.join(self.test_dir, "project_dir"), exist_ok=True, mode=0o200
|
||||||
|
)
|
||||||
|
testapp_dir = os.path.join(self.test_dir, "project_dir", "my_app")
|
||||||
|
out, err = self.run_django_admin(args)
|
||||||
|
self.assertNoOutput(out)
|
||||||
|
self.assertOutput(
|
||||||
|
err,
|
||||||
|
"Permission denied",
|
||||||
|
)
|
||||||
|
self.assertFalse(os.path.exists(testapp_dir))
|
||||||
|
|
||||||
|
|
||||||
class DiffSettings(AdminScriptTestCase):
|
class DiffSettings(AdminScriptTestCase):
|
||||||
"""Tests for diffsettings management command."""
|
"""Tests for diffsettings management command."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user