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

Quickstart models

The comes with two sets of models that are useful for most projects.

The first is a custom users app with a User model. If you need to store custom data related to a user, you can put fields directly on this model. A custom user model is the recommended way to start a project according to the Django docs.

The second is a teams app, that includes the Team and TeamMembership models. Most projects inevitably need some type of "Team" concept, so it's one of the few places we like to provide a starting point. You can rename it if you like, or simply call it something else in your frontend HTML (ex. "Organization" or "Group"), but in general the Team is where you'll group users together and attach billing information. If you really don't intend to use it, you can delete it.


We include two modifications to what the Django AbstractUser provides:

  • The email for a user must be unique (helps with login and duplication)
  • The uuid field is added via UUIDModel (helps with identifying users without exposing the standard auto-incrementing ID)

When you need to store something directly on a user, go ahead and write your code in the User model:

# app/users/
class User(AbstractUser, UUIDModel):
    email = models.EmailField(unique=True)

    # Add your own fields and methods here!


The quickstart comes with all of the django.contrib.auth.urls enabled at the root (ex. ""). This includes:

  • login
  • logout
  • password changes
  • password resets

We also include a standard signup form to let users create an account using username, email address, and password.

# app/
urlpatterns = [
    # ...
    path("signup/", SignupView.as_view(), name="signup"),
    path("", include("django.contrib.auth.urls")),

Django signup form

When someone completes the signup form, they'll be redirected to log in using their new account. You can customize the SignupView to log them in immediately, show welcome messages, or start an email confirmation flow first.


When you're setting up the relationships in your project, most of the time you'll want to associate things with a "team" rather than a "user".

Whether you need teams right off the bat or plan to support them later, it's a good idea to tie "projects", billing, etc. to a Team even if that team is just a single User. Down the road, if you need to transfer a "project" from a user to their company team, you can effectively do a Team->Team transfer which is much simpler than changing the type of relationship from a User to a Team.

Likewise, if you plan to support subscriptions for individuals and businesses, you should consider both of those to be a Team on the backend which will simplify a lot of the billing logic.

Teams in Forge come with a few fields we think are useful, but you can customize is from there:

# app/teams/
class Team(TimestampModel, UUIDModel):
    name = models.CharField(max_length=255)
    members = models.ManyToManyField(

    # Add your own fields and methods here!

class TeamRoles(models.TextChoices):

class TeamMembership(TimestampModel, UUIDModel):


When you add people to teams, we also provide a role field with basic ADMIN or MEMBER options. You can add to these as needed, but if you aren't using roles right away then just make everyone a MEMBER so you can add admin-specific features later!

team = Team.objects.create("A new team")
team_member1 = TeamMembership.objects.create(


You can use any combination of the mixins when creating your models. Technically these are "abstract" models, so you don't actually need models.Model in your class definition if you use at least one of these.

# app/projects/
from django.db import models
from forge.models import TimestampModel, UUIDModel

class Project(TimestampModel, UUIDModel):
    name = models.CharField(max_length=255)


A TimestampModel includes two fields: created_at and updated_at.

In practice, you can use this on almost every model in your app unless you have a specific reason not to.

# app/projects/
from django.db import models
from forge.models import TimestampModel

class Project(TimestampModel):
    name = models.CharField(max_length=255)


A UUIDModel includes a unique uuid field. This is a standard way to identify objects in URLs and APIs where you'd rather not expose the auto-incrementing id field.

In URLs, this can often be an alternative to a user-managed SlugField, which can require a lot more effort to get right (uniqueness, edits/redirects, reserved names, etc.).

Note that our implementation does not replace the primary key of a model.

# app/projects/
from django.db import models
from forge.models import UUIDModel

class Project(UUIDModel):
    name = models.CharField(max_length=255)