Django New Project Structure/Name

I don’t think it matters what it’s called. I picked config years ago because it bubbles up to the top of a list of folders/files, it’s not clever, and it’s mentally easier to remember in big projects than {app_name}_project like everything else I had worked with leading up to it.

One could argue that project is a better name because you create it with python manage.py startproject. I think calling your web app “project” would be more confusing for new people because most people don’t even know what a project is. Most IDEs have a completely different set of opinions and features for projects as well, which doesn’t help.

In a perfect world, I would rename/merge startproject and startapp into one command, and I would call my default app+config just app, but going against ~16 years of Django material, so that’s out.

If you work on more than one project, I recommend standardizing one config folder name for all of your web applications/projects. Bonus points for being sort friendly so that it’s easier to locate.

In the medium to long term, I think standardizing to one config/project naming scheme is better because it makes copying and pasting configs between projects less problematic for people.

When in doubt, use config until you can come up with a better name.

4 Likes

I keep my projects inside a single Python package these days, and the apps as submodules within that. For example, for a project called books with two apps called core and loans:

books/
    core/
    loans/
    __init__.py
    settings.py

I normally have only one app called core. But when splitting things out into multiple apps, core is a good place for “base functionality” e.g. custom user model, custom model subclasses, etc.

It’s also possible to have the “project” module also be its one and only app:

books/
    __init__.py
    models.py
    settings.py

I think this is pretty beginner friendly, it’s what you’d when expanding up from one file in smaller frameworks like Flask. It’s just harder to split into multiple apps later, but is that really needed most of the time?:man_shrugging:

2 Likes

I am actually a big fan of config (or core) and would say keep it. Just maybe a brief explanation in the books(if not there already) on directory structure and why it matters - and Django defaults v. Common Patterns.

I don’t think there is anything consistent in the wild, and config is a pretty reasonable pattern.

2 Likes

In my lat project I use:

my_project/
    app/
        app1
        app2
        ..
    config/ -> This is the Django Project directory
        base.py
        production.py
        development.py
    templates/
    tests/
    utils/ -> A directory for non-specific-app stuff
        helpers.py
        validators.py
        views.py
    activate -> a symbolic link to my venv activate file
    manage.py
    requirements.txt
   .gitignore
    ...

I am very happy with the layout.

2 Likes

Bumping: PR issued!

I’ve also settled on config over the years, and have issued a PR to make the startproject template follow this convention. I’ve taught Django to well over 100 newcomers, and it is alarmingly frequent how confusing have two directories with the same name can be:

  • my_project at the root
  • my_project/my_project for configuration.

I can’t tell you how many times I’ve said, “Okay switch into the ‘my_project’ directory - no, the other one! The one with manage.py / settings.py!”

I think config is the right choice. settings is already taken by settings.py in the default project, and conf isn’t as explicit an abbreviation as config (conf is often used for conference).

Ticket: #33650 (Update startproject template with config directory) – Django (djangoproject.com)
WIP PR: Refs #33650: Changes to the startproject template by FlipperPA · Pull Request #15609 · django/django (github.com)

If we are going to simplify, I think @adamchainz One Folder suggestion is the way to go. Ever increasingly enjoying this myself, plus thinking it fits the bill for most users better…

If I were to teach a beginner I would use startproject as-is but then add to INSTALLED_APPS and add the models.py, rather than startapp… — If we shipped the single-folder option, I could skip that.

It’s just harder to split into multiple apps later…

FWIW I don’t find that really: most of the project lives in the single-folder, with (if needed) extra apps along side… — but likely I’m not seeing exactly what Adam was referring to. :thinking:

I’m almost certainly in a minority but I think custom user models are a distraction (and swappable models in general TBH…) All folks ever wanted was a unique email field.

Realistically speaking, I think we could maybe/likely ship a single-file, and a single-folder template, in addition to the existing classic one, but getting consensus on a change to the classic template seems difficult. (I didn’t search the archives but this seems to come up frequently with no consensus…)

I thought the reason for having the configuration and settings in a separate folder was for security concerns. I’m not entirely sure what those security reasons are; maybe directory traversal?

Where do you place the projects urls.py, asgi.py and wsgi.py? Normally they are in the project dir next to settings.py.

1 Like

How do you exactly do this?

You start with: django-admin startproject conf
and then rename the project folder simply to something else?
And then create an app with the name you want?
So it looks like this?
Is renaming the project folder all i have to do, or do i have to change the name also somewhere else?

renamed_project_name /
     config/
           settings.py
            urls.py
     app_you_created/
     manage.py
1 Like

:wave: I’d like to raise this again as “two mysite folders” is still an ongoing source of confusion for Django beginners.

About the changes to the base project template – I’ve pinged @django/steering-council on Tim’s PR to address whether a DEP is needed or not (not sure this is the right way to get their opinion but we’ll see).

In the meantime, @TheEpic-dev made the following excellent suggestion on Discord:

[…] it might be better to just add a note to the tutorial to use django-admin start project NAME . which prevents nesting.

I think this would solve the problem very neatly for all the beginners who are following the tutorial / Django docs. How do people here feel about changing the tutorial like this? And perhaps also having that as an example on startproject reference docs?

2 Likes

Hey @thibaudcolas :wave:

If there’s a better way forward here, we should go for it. It does keep coming up.

I think the effort of writing up a DEP is likely worth it, to clarify what change is needed, and make sure we didn’t just forget about the reasons folks have pushed back. (Not moving my cheese is still a legitimate concern, even if not overriding.)
It doesn’t have to be a massive thing, but spec-ing a change of a long-standing feature seems a reasonable ask. (Happy to comment on a draft!)

Obviously, if it’s just a one-line change to the tutorial then we don’t need that :sweat_smile: — but I have the feeling there’s more here…

Thanks for the hustle.

There’s more here if you want to start rocking boats because things quickly become opinionated.

But maybe there’s a way to come to a consensus on an MVP setup for the template that shows beginners what we otherwise don’t learn for too long. Because it telling a beginner they should have a custom User is great, but it needs to show them otherwise people aren’t going to understand what we’re talking about.

And adding the . information to the tutorial/docs for startproject is the best foot forward. As raised on discord, that’s how the django-girls tutorial gets people going; Your first Django project! · HonKit

Long time, didn’t see the replay.

Yes, I run manage.py startproject config and then I rename the folder to whatever my project is about i.e. mv config djangonews-git. Then that’s where my code and everything internally live that gets push to GitHub.

This is our default project structure. Very rare that our project need to grow beyond the single folder. If we really want a reusable apps, we put them in totally separate repo, make them a proper python packages.

There is also this related discussion: Updating the default startapp template

I wonder if one way forward on both of these is to have a simplified project structure similar to Adam’s suggestion, perhaps something like this:

myproject/
    __init__.py
    models.py
    settings.py
    urls.py
    views.py
manage.py

And then we update the tutorial to do work in this basic, non-app structure. I think this will help a lot for beginners. Then we can introduce them to apps in a later, more advanced tutorial (if not just the re-usable apps tutorial).

3 Likes

For people interested in this, based on replies on #15609 in GitHub, and in #contributor-discussion in Discord, it’s now clear this requires a DEP to move forward.

I won’t pursue this at this time, so if anyone else wants to step in please go for it. @FlipperPA and I briefly discussed this at DjangoCon. I’m not sure where exactly Tim stands, for me I don’t feel like I have the mental energy nor required technical knowledge to make a good DEP on this at this time.

1 Like

I continue to run into this issue with newcomers, but as we’ve seen, what solution to embrace gets opinionated very quickly. This is a shame, because I think everyone agrees the status quo is not an ideal solution. I haven’t had the cycles to revisit this since making the original P.R. When I teach folks now, I use the same solution as @jeff by renaming the parent directory after django-admin startproject config. This is also confusing, but cuts out the requirement of editing manage.py and the settings.py file.

I had initially suggested writing a DEP before creating a ticket and submitting a PR, but after talking about it, was encouraged to follow the ticket and PR route. Perhaps making Django more friendly to the newcomer needs to be a Working Group.

I wouldn’t say everyone. :wink: But not because I don’t think the other options aren’t good, but because I don’t think the current option is “bad”, or is significantly improved by making a change. My experience has been that this is a “one-time” issue easily explained - and then you move on.

1 Like

Ha, fair enough, I shouldn’t have used an absolute term. How about “most folks seem to agree there is room for improvement”? :blush:

1 Like

I’m not sure whether this belongs in the Github thread or here or somewhere else, but one possible compromise on something like this would be if there were handful of “official” startproject templates that were well-maintained and referred to in the docs. These could be maintained by Django or by third parties. But basically the idea being that we can at least recommend a few other options if there is not ever going to be enough momentum to improve on the default one.

1 Like