Introduction
The Django startapp
management command is a great tool to create new Django apps. By default you can create a new app with the following command:
python manage.py startapp myapp
This will create a new app, based on the internal default template, with the following structure:
myapp/
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
This is a good start, but this can be done better, especially when the project is going to use additional libraries such as Django Rest Framework or the development team agrees on a common structure for the models, views, urls, etc.
The startapp command also provides the --template
option. This option allows you to specify a custom template for the new app. The template can be a directory or a zip file, the zip file can also be provided via URL.
Examples:
# create a new app using a local template
python manage.py startapp --template=/Users/nezhar/django-app-template myapp
# create a new app using a remote template
python manage.py startapp --template=https://github.com/nezhar/django-app-template/archive/main.zip myapp
The problem
The problem with the startapp
command is that it is limited to the context parameters that are available in the template,
which currently are app_name
, app_directory
, camel_case_app_name
, docs_version
and django_version
.
This makes it impractical to use the command with advanced templates where additional parameters are required.
In my case, I required certain value configured in the Django settings. I also had use cases where it would have been useful to add parameters when calling the startapp
command.
Solution
It seems that there was a ticket to add a similar option in the past, but it was not accepted.
For now, this needs to be solved at application level by creating a custom management command that extends the startapp
command with additional parameters.
The implementation of the command can be found here
In our command we can now directly add keyword arguments to pass in options
(e.g. app_slug
) or additional parameters inside the add_arguments
method.
from django.core.management.templates import TemplateCommand
from django.conf import settings
class Command(TemplateCommand):
help = (
"Creates a Django app directory structure for the given app name in "
"the current directory or optionally in the given directory."
)
missing_args_message = "You must provide an application name."
def handle(self, **options):
app_name = options.pop("name")
target = options.pop("directory")
options.update({"app_slug": settings.APP_SLUG})
super().handle("app", app_name, target, **options)
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"--custom-option",
help="Custom option to be used in template context.",
)
You should use a different name for the command, e.g. startapp2
, createapp
, etc. to avoid conflicts with the default startapp
command.
Conclusion
The startapp
command is a great tool to create new Django apps. However, since inside the template you have limited access to the context parameters, you need to extend the command to add additional parameters.