Django is a hugely powerful web framework, and parts of this comes from its large ecosystem of ready-to-use applications and packages, which allows you to build your webapp on top of well maintained code, and save you from rewriting the boring stuff and concentrating on the scope of your website.

But to tap into this potential, you have to go through the installation and configuration of these packages. Most of the time is pretty straightforward:

  • pip install
  • add applicatiom to INSTALLED_APPS

and you are done.

Or not?

Oftentimes, steps above are not enough. You might also need to add something in the urlconf, or maybe a middleware, or maybe… And then, you end up spending minutes (if all goes well) settings everything right, just to have the project back in running shape.

And this is boring and wasteful.

Why can’t we have nice things?

Achieving a much bettere developer experience is something every ecosystem should strive.

Developers Developers Developers

We can, actually.

We have at our disposal two really powerful tools:

  • Django which provides an opinionated environment and a powerful configuration system
  • Python it’s great at introspecting itself, and has a really nice and powerful ast module (and some higher level packages based on it), which can help us alot in achieving a self configuring environment.

Entering django-app-enabler

Django configuration is made of python files, if we have a list of settings and changes to apply to a project, we can envision to use ast to apply them and, voilร !, the application is ready for use!

django-app-enabler, though in its infancy, does exactly this.

Sample usage

A typical django-app-enabler workflow involve few steps:

  1. Install django-app-enabler: pip install django-app-enabler (if not installed already)

  2. Install the application you need: pip install djangocms-blog

  3. Run app-enabler django-enabler enable djangocms-blog

  4. Profit!

    djangocms-blog application is now available ๐Ÿšข!

Of course you will be able to manually edit the settings file to further customize your installation.

As you see, in step 2 we manually installed the desired package: even if django-app-enabler can install packages, it’s not an installer, and it will never be. There already are excellent package managers for python, and adding another one would be a very bad choice: django-app-enabler itโ€™s just a tool to setup the initial configuration of a package.

You can replace steps 2. and 3. with django-enabler install djangocms-blog, but with a lot of limitations.

Action!

The sample project

To see it in action, let’s just use an empty project created with djangocms-installer:

1
2
3
4
$ mkdir new-project && cd new-project
$ python -mvenv env
$ pip install djangocms-installer
$ djangocms mysite

You will get an output similar to the one below:

Creating the project
Please wait while I install dependencies
If I am stuck for a long time, please check for connectivity / PyPi issues
Dependencies installed
Creating the project
...
Creating admin user
All done!
Get into "
mysite" directory and type "python manage.py runserver" to start your project

Running the django project will greet us with the django CMS login to create our first page:

django CMS login splash page

We’re good: the project is working ๐ŸŽ‰!

Install djangocms-blog

With a single command we can install and configure djangocms-blog, a blogging application for django CMS.

1
$ django-enabler install "djangocms-blog~=1.2.3"
Installation completed, check documentation
https://djangocms-blog.readthedocs.io/en/latest/installation.html#modify-templates
for further information

That’s all ๐Ÿš€

Let’s apply migrations and run the server once again and visit http://localhost:8000:

1
2
$ python manage.py migrate
$ python manage.py runserver

Unimpressive as it is, we will be greeted with a “real” home page with a blog subpage

Sample project home page

And we can verify that everything is working by creating our first blog post:

Form to create a blog post

What has happened ?

With a single command we have been able to:

  1. Install the desired package (django-app-enabler just calls pip to install packages);
  2. The django project configuration has been patched according to the addon configuration shipped by djangocms-blog;
  3. When we hit the home page djangocms-apphook-setup created the home and blog page for us; this is also something that is determined by djangocms-blog (and it’s separated from django-app-enabler, but still contribute to the overall experience);

Message and manual configuration

Not everything can be configured automatically at this stage: the goal is to provide enough flexibility to application developers to ship a meaningful base configuration that users can further customize after the setup.

For this reason a message is available to application developers to provide information regarding the following steps (either required or optional).

In the example above djangocms-blog output direct the user to check documentation: Installation completed, check documentation https://djangocms-blog.readthedocs.io/en/latest/installation.html#modify-templates for further information.

Use enable command

In practice the usage of install command it’s not the preferred way to invoke django-app-enabler: there are a lot of great package managers for python out there (pip, poetry, pipenv, …) and definitely you don’t want a different one to try and use. install has been made available to allow quick testing and prototyping.

For normal usage django-enabler enable <package_name> is the one true way to invoke django-enabler (see sample usage).

See documentation for the command details

How it works?

django-app-enabler works by reading a dedicated configuration file shipped by the target application that lists all the settings and urlconf changes required to make the application works (at least at a minimal level).

The information provided by this file are used to patch inplace settings.py and urls.py files by using Python ast module.

See Automating Django application configuration: an in-depth view for the package internals, and addon configuration specs.

Limitations

django-app-enabler is currently a little more than a proof-of-concept and there is still work to be done for a proper fully functional release.

Many of the limitations listed below will be removed in a near future.

Major current limitations are:

  • Only single-file settings.py and urls.py are supported;
  • Complex settings manipulations are not supported:
    • you can’t insert items in a specifix position in list setting; for example add a middleware in the middle or at the top of the existing middlewares list, it’s always appended at the end;
    • merging dictionary type settings (LANGUAGE, TEMPLATES, DATABASES, …) is not supported;
  • No support for target applications extra_requirements;
  • Comments and code structure is lost when saving back the file;

Where from here?

The current (release 0.2) state of django-app-enabler make it already fairly usable to some of the applications we released at Nephila (namely: djangocms-blog, djangocms-page-meta, djangocms-page-sitemap), but leave others not supported (djangocms-redirect, for example).

So the big next steps toward a stable release is to remove such limitations to make it more generally useful.

Two other major goals are adding support to external addon configuration files which opens up the ecosystem and the use cases for this application a lot and integrate support for django-app-enabler in djangocms-installer: it will make the installer useful for experienced developers what wil be able to create a django CMS with all the required applications by using a single command