These docs are a work-in-progress and are currently undergoing a major rewrite!

Forge repo layout

The app directory

Your Django code is all inside the app directory. You might have used repos before where all of your Django code it at the root of the repo, but our preference is to isolate the Django/Python code from other "meta" files like .gitignore, .github/, pyproject.toml, Procfile, etc. because when you're working in your app, you don't need access to those files to be right next to your Python code.

Top-level urls.py, views.py, and settings.py

In Django you have a handful of top-level files that act as "entrypoints" to your app. But they're often buried an additional layer deep in your project (myproject/myproject/settings.py).

We think that mentally it is easier to reason about a project hierarchy when your settings.py and urls.py are located right at the top. Additionally, there are some views like the homepage that don't really belong in a particular app, so a top-level app/views.py can be handy for those as well as view mixins that are shared across the project.

app
├── settings.py
├── urls.py
└── views.py

The only downside to this is that you can't do relative imports in these files, so in urls.py for example:

# app/urls.py
# Does not work:
from . import views

# Works
import views

Top-level static and templates

Like the settings.py and other top-level files, we include a top-level static and templates directory.

The static will include your Tailwind CSS files and other project-wide assets like a logo.

The templates directory will include your base.html and other project-wide templates or pages like home.html.

app/static
├── dist
   └── tailwind.css
└── src
    └── tailwind.css
app/templates
├── 400.html
├── 403.html
├── 404.html
├── 500.html
├── base.html
├── home.html
└── registration
    ├── login.html
    ├── password_change_done.html
    ├── password_change_form.html
    ├── password_reset_complete.html
    ├── password_reset_confirm.html
    ├── password_reset_done.html
    ├── password_reset_form.html
    └── signup.html

A minimal settings.py

In Forge, your settings.py will be much shorter than what you'd get from a standard Django project. Because we know so much more about your project and how it runs, we set a number of default settings for you. You only need to add or customize beyond the Forge defaults:

from forge.default_settings import *

# Add to the default INSTALLED_APPS
INSTALLED_APPS = INSTALLED_APPS + [
    "projects",
    "teams",
    "users",
]

# Overwrite other Django settings
TIME_ZONE = "America/Chicago"

# And add your own settings
STRIPE_PRICE_ID = environ["STRIPE_PRICE_ID"]

In most Python code, import * is not a great idea. But in this particular case we think it's a good solution for extending settings.

Where's manage.py?!

We've completely removed the manage.py, wsgi.py, and asgi.py files from your repo. They are automatically loaded from Forge itself, because you rarely need to make any changes to them. If you do need to customize them, you can simply place a copy in your app directory.

The forge django <subcommand> is essentially an alias to python manage.py <subcommand>.