Skip to main content

Project Layout

Single-App Architecture

SpeedPy uses a single-app architecture with two Django apps:

  • mainapp — Primary application containing all business logic (models, views, forms, tasks)
  • usermodel — Dedicated app for the custom User model with email-based authentication

There is also a utility app:

  • speedpycom — Contains management commands and the BaseModel abstract model

Directory Structure

myproject/
├── project/ # Django project settings
│ ├── settings.py # All configuration
│ ├── urls.py # Root URL routing
│ ├── celeryapp.py # Celery configuration
│ ├── wsgi.py
│ └── context_processors.py
├── mainapp/ # Primary business logic app
│ ├── models/ # Models (one file per domain)
│ │ ├── __init__.py # Imports & __all__
│ │ ├── teams.py # Team, TeamMembership, TeamInvitation
│ │ └── otp_profile.py # OTP profile model
│ ├── views/ # Views (one file per feature)
│ │ ├── __init__.py
│ │ ├── dashboard.py
│ │ ├── teams.py
│ │ ├── team_members.py
│ │ ├── otp_views.py
│ │ └── welcome.py
│ ├── forms/ # Forms (one file per feature)
│ ├── tasks/ # Celery tasks
│ │ ├── __init__.py
│ │ └── teams.py
│ ├── urls.py # App-level URL routing
│ └── subscription_plans.py
├── usermodel/ # Custom User app
│ ├── models.py # User model
│ ├── managers.py # UserManager
│ ├── forms.py # Auth forms (signup, login, etc.)
│ ├── adapters.py # Allauth adapter with OTP support
│ └── views.py
├── speedpycom/ # Utility app
│ ├── models/
│ │ └── base.py # BaseModel (UUID + timestamps)
│ └── management/commands/
├── templates/ # All templates (organized by app)
│ ├── emails/ # Email templates
│ └── ...
├── static/ # Static files
│ └── mainapp/
│ ├── input.css # Tailwind source CSS
│ └── styles.css # Compiled Tailwind output
├── docker-compose.yml
├── Dockerfile
├── Makefile
├── requirements.txt
├── package.json
├── tailwind.config.js
├── release.sh # Deployment release script
├── .docker.env # Docker environment template
└── manage.py

Key Patterns

Package-Style Organization

Models, views, and forms are organized as Python packages (directories with __init__.py) rather than single files. Each domain or feature gets its own file:

# mainapp/models/__init__.py
from .teams import Team, TeamMembership, TeamInvitation

__all__ = ["Team", "TeamMembership", "TeamInvitation"]

BaseModel

All application models should inherit from BaseModel, which provides:

  • UUID primary keyid = UUIDField(primary_key=True, default=uuid.uuid4)
  • Timestampscreated_at (auto_now_add) and updated_at (auto_now)
from speedpycom.models import BaseModel

class MyModel(BaseModel):
name = models.CharField(max_length=255)

class Meta:
verbose_name = "My Model"

TeamModel

For multi-tenant models scoped to a team, inherit from TeamModel:

from mainapp.models.teams import TeamModel

class Project(TeamModel):
name = models.CharField(max_length=255)
# Automatically has: id, created_at, updated_at, team (FK)

Foreign Key References

Use string notation for foreign keys to avoid circular imports:

team = models.ForeignKey('mainapp.Team', on_delete=models.CASCADE)