šŸŽµ DJ Beat Drop: A Modern Django Project Starter

Hi Django community! Iā€™m excited to share a tool Iā€™ve been working on to help make Django even more welcoming to newcomers.

What is DJ Beat Drop?

DJ Beat Drop is a modern project initializer for Django that aims to provide a smoother getting-started experience. It was inspired by my experiences teaching Django and the project initialization patterns from other modern web frameworks.

Iā€™ve also written about it in detail here and you find the repository here.

Features

  • :file_folder: Intuitive project structure with dedicated config directory
  • :wrench: Built-in support for .env files
  • :rocket: Modern Python tooling support (like uv)
  • :zap: Smooth CLI experience

Try It Out!

pip install dj-beat-drop
# Reload your shell to make the command available.
beatdrop new example_project
2 Likes

The new folder structure for config is only documented in the demo movie. But it went past so fast that I couldnā€™t see it, and I couldnā€™t pause the movie. I had to take a screenshot to see it.

The resulting structure still uses the project name for configuration files:

This complaint is a bit weird. You put config as the module name. Donā€™t you think thatā€™s a bitā€¦presumptious? This will clash with config Ā· PyPI which is the package that has taken that name.

config.urls is pretty weird as the module name for your projectā€™s urls. Thereā€™s a reason itā€™s your_project.urls by default. I think you might just be unused to python, and think this is not ā€œbest practicesā€ when in fact it is.

The Django CLI experience has some rough edges - error messages arenā€™t consistently formatted, and simple issues like hyphens in project names result in errors rather than automatic conversion to underscores.

This I 100% agree with though. Iā€™ve hit that myself a few times.

Thank you for your feedback!

The new folder structure for config is only documented in the demo movie. But it went past so fast that I couldnā€™t see it, and I couldnā€™t pause the movie. I had to take a screenshot to see it.

I went ahead and added what the directory structure looks like after the command. Thank you for the suggestion.

This complaint is a bit weird. You put config as the module name. Donā€™t you think thatā€™s a bitā€¦ presumptuous? This will clash with config Ā· PyPI which is the package that has taken that name.

config.urls is pretty weird as the module name for your projectā€™s urls. Thereā€™s a reason itā€™s your_project.urls by default. I think you might just be unused to Python, and think this is not ā€œbest practicesā€ when in fact it is.

So another friend made some similar comments, and this was my response:

I appreciate the perspective on namespacing - itā€™s one of the things I love about Python. Let me share my thinking on this:

  1. I fully agree that namespacing is important. The question is whether the project configuration code needs to live in that namespace. Most modern frameworks separate configuration from application code while maintaining proper Python namespacing for the application modules.
  2. Project naming presents a practical challenge. In my experience, initial project names often change as requirements evolve. Having this name baked into the configuration structure can lead to technical debt when teams need to rename projects. Engineers usually hesitate to refactor this due to the risk and effort involved.
  3. A standardized config directory could improve tooling integration. Many tools (IDEs, deployment platforms like AppPack) could provide better default support without relying on DJANGO_SETTINGS_MODULE configuration.
  4. While Djangoā€™s current approach works, adopting common patterns from the broader web development ecosystem (Laravel, Rails) could lower the learning curve for developers who are new to Django.
  5. For application-level namespacing, Iā€™ve found that an apps directory with a base app (apps/base/) effectively provides the namespace benefits you mentioned. For example, our PEARS project has 39 apps cleanly organized under the apps directory. This maintains good namespacing while keeping the project root clean and configuration separate.

Regarding your specific comment about distribution on PyPI: I would say that I was thinking that DJ Beat Drop is more about creating new Django web applications, not a third-party open-source Django plugin package. For that, I would start by doing the following:

$ mkdir new-library
$ cd new-library
$ uv init --lib
$ tree
.
ā”œā”€ā”€ README.md
ā”œā”€ā”€ pyproject.toml
ā””ā”€ā”€ src
    ā””ā”€ā”€ new_library
        ā”œā”€ā”€ __init__.py
        ā””ā”€ā”€ py.typed

Thatā€™s not what I meant. I meant that a project that would want to install that package would get a namespace conflict.

I worked on a project once that had a module named ā€œuserā€. That was a bit of a disaster that I had to fix.

How would a user module or a config module conflict with other packages that have a user module (e.g., foo_package.user)? I understand how it could conflict if you wanted to publish it to PyPI, but again, that goes back to what I was saying: if I was going to distribute on PyPI, then I wouldnā€™t have my package called config. I would probably name my package according to its branding/name. However, I would probably still put my config code in a config directory. So, my layout would be something like the following if I used PyPI for distribution.

.
ā”œā”€ā”€ README.md
ā”œā”€ā”€ pyproject.toml
ā””ā”€ā”€ src
    ā””ā”€ā”€ example_project
        ā”œā”€ā”€ __init__.py
        ā”œā”€ā”€ config
        ā”‚   ā”œā”€ā”€ __init__.py
        ā”‚   ā”œā”€ā”€ asgi.py
        ā”‚   ā”œā”€ā”€ settings.py
        ā”‚   ā”œā”€ā”€ urls.py
        ā”‚   ā””ā”€ā”€ wsgi.py
        ā”œā”€ā”€ manage.py
        ā””ā”€ā”€ py.typed

How would a user module or a config module conflict with other packages that have a user module (e.g., foo_package.user )?

They wouldnā€™t. Thatā€™s what ā€œfoo_package.ā€ is for. Your ā€œconfigā€ module does NOT have such a prefix, which is my objection.

(In Python 2, there was a standard library module called user, thatā€™s why that was a problem, you donā€™t want to have namespace collisions with the standard library!)

It seems like youā€™re not understanding me. If you look at the directory output above, what Iā€™m suggesting, there wouldnā€™t be a conflict because the package would be called, example_project.

Yea, but thatā€™s not the structure you reference Improving the New Django Developer Experience | Epicserve

I believe the structure Iā€™m proposing in my blog and what is created with DJ Beat Drop is still a better and more preferred way, especially for developers new to Django. I acknowledge that some, like yourself, might want to distribute their project using PyPI. I donā€™t have any data supporting it, but my guess is that isnā€™t how most people want to deploy their projects. It wouldnā€™t be practical to try to help someone new to Django or Python learn all the intricacies of Python packaging. If you want to do it that way, youā€™re probably more advanced and will want to manually set up your project. I would consider adding an argument like --use-pypi-structure that would create a structure similar to what I showed above if there was a demand for it.

I acknowledge that some, like yourself, might want to distribute their project using PyPI

Again, no. I am not talking about that. At all. Never did.

This complaint is a bit weird. You put config as the module name. Donā€™t you think thatā€™s a bitā€¦presumptious? This will clash with config Ā· PyPI which is the package that has taken that name.

PyPI has 579,524 projects as of today which means there are very few apps names that one could pick that wouldnā€™t clash. Especially one that hasnā€™t been updated in over three years.

config.urls is pretty weird as the module name for your projectā€™s urls. Thereā€™s a reason itā€™s your_project.urls by default. I think you might just be unused to python, and think this is not ā€œbest practicesā€ when in fact it is.

I have used config for years. I worked on dozens of projects a week and most use this convention. The few that donā€™t are harder to work with because your_project takes longer to scan for and find. Even when searching, it easier if a project name sorts closer to the top than the bottom.

Either way, this smells of bike shedding, and you should name your projectā€™s config folder whatever sparks joy.

Jeff Triplett (webology) writes:

The few that donā€™t are harder to work with because your_project takes
longer to scan for and find. Even when searching, it easier if a
project name sorts closer to the top than the bottom.

I also switched using config a long time ago for the same reasons.

2 Likes

I donā€™t understand that. Sorts closer to the top compared to what? In what list(s)?

Sure, a folder with dozens of apps in a file folder view or even an ls listing.

Hmm. I still donā€™t understand that. For common stuff I prefer ā€œbaseā€, but I namespace that under the project name. So for work now I have dryft.base for example, and dryft.planning for the planning app. You would have that as base and planning at the top level? Donā€™t you risk namespace conflicts a lot then? And making the imports everywhere quite hard to read as they donā€™t clearly delineate what is stdlib or 3rd party from the project?

Iā€™ve been using a config folder for configuration files and then an apps folder for all my projects apps for over 12 years or more and Iā€™ve never had a single namespace conflict.

then an apps folder for all my projects apps

That ā€œappsā€ namespace would be the reason for no conflicts. I just think that if you are doing apps.foo for app names, why not project_name.foo, and then logically project_name.config for the config. Itā€™s the config for the project after all.

In any case, the part I object to is the term ā€œbest practicesā€, and the idea of moving such cultural habits over from one culture to another and declaring it an improvement. Itā€™s not imo, itā€™s just different.

And I think as many others I got that from ā€œDjango for Beginnersā€ by
Will Vincent.

I hope itā€™s ok to quote from my copy here

let me try this again ā€¦ [1]

And I think as many others I got that from ā€œDjango for Beginnersā€ by
Will Vincent.

I hope itā€™s ok to quote from my copy here

ā€œChapter 1: Initial Set Upā€
[ā€¦]
Create a new Django project called config with the following command.
Donā€™t forget that period . at the end.

(django) $ django-admin startproject config .

[ā€¦] By running django-admin startproject config . with the period at
the end - which says, install in the current directory - the result is
instead this:

Layout
ā”œā”€ā”€ config
ā”‚ ā”œā”€ā”€ init.py
ā”‚ ā”œā”€ā”€ asgi.py
ā”‚ ā”œā”€ā”€ settings.py
ā”‚ ā”œā”€ā”€ urls.py
ā”‚ ā””ā”€ā”€ wsgi.py
ā””ā”€ā”€ manage.py

The takeaway is that it doesnā€™t really matter if you include the
period or not at the end of the command, but I prefer to include the
period and so thatā€™s how weā€™ll do it in this book. As you progress in
your journey learning Django, youā€™ll start to bump up more and more
into similar situations where there are different opinions within the
Django community on the correct best practice. Django is eminently
customizable, which is a great strength, however the tradeoff is that
this flexibility comes at the cost of seeming complexity. Generally
speaking, itā€™s a good idea to research any such issues that arise,
make a decision, and then stick with it!

[1] using the mail gateway to the forum

1 Like