Technology Stack
FootyCollect is built on a modern Python web stack:- Framework: Django 5.0+ - Python web framework with ORM, admin interface, and authentication
- Database: PostgreSQL - Primary relational database with support for complex queries and indexes
- Cache & Broker: Redis - Used for caching and as Celery message broker
- Task Queue: Celery - Asynchronous task processing for background jobs (image processing, etc.)
- API: Django REST Framework - RESTful API for programmatic access
- Image Processing: Pillow + ImageKit - Image optimization and format conversion (AVIF)
- Frontend: Django Templates with Bootstrap 5 and django-cotton components
Architecture Layers
The application follows a layered architecture pattern:Layer Responsibilities
Views Layer- Handle HTTP requests and responses
- Render templates or serialize JSON
- Request validation and form handling
- Minimal business logic
- Encapsulate complex business logic
- Coordinate multiple repositories
- Manage database transactions
- Integrate with external APIs
- Orchestrate async tasks
- Abstract database access patterns
- Encapsulate complex queries
- Provide a clean data access API
- Handle query optimization
- Define database schema via Django ORM
- Implement data validation
- Define model-level business rules
- Manage relationships
Key Design Patterns
Multi-Table Inheritance (MTI)
FootyCollect uses Django’s multi-table inheritance to model different item types (jerseys, shorts, outerwear, tracksuits) while sharing common attributes.- Clear separation of common and type-specific fields
- Type safety with distinct models
- Flexibility to query all items or specific types
- Easy extensibility for new item types
Service Layer Pattern
Complex business logic is encapsulated in service classes, keeping views thin and focused on HTTP concerns.- Reusable business logic across views, APIs, and tasks
- Easier unit testing without HTTP layer
- Clear transaction boundaries
- Better separation of concerns
Repository Pattern
Data access is abstracted through repository classes that encapsulate query logic.- Centralized query logic
- Easier to optimize queries
- Testable data access layer
- Flexibility to change data source
Service Registry Pattern
Services are accessed through a centralized registry for dependency injection and testing.Data Flow Example
Here’s how a typical request flows through the architecture:- User creates a jersey via web form
- View validates form and extracts data
- Service (
ItemService) coordinates the operation:- Starts database transaction
- Creates
BaseItemrecord - Creates
Jerseyrecord (linked to BaseItem) - Processes photo uploads via
PhotoService - Commits transaction
- Repository executes optimized database queries
- Models enforce data validation and relationships
- View redirects to item detail page
Database Design
The database schema uses:- Multi-table inheritance for item types
- Foreign keys for relationships (user, club, season, brand)
- Many-to-many for competitions and colors
- Generic foreign keys for flexible photo associations
- Indexes on common query patterns (user+type, club+season)
External Integrations
Football Kit Archive API
FootyCollect integrates with the Football Kit Archive API to:- Fetch kit metadata (team, season, type)
- Download official kit images
- Populate collection data automatically
Asynchronous Processing
Celery handles background tasks:- Image optimization: Convert uploaded images to AVIF format
- Photo processing: Resize and generate thumbnails
- External API calls: Fetch data without blocking requests
Security & Performance
Security Measures
- Authentication: Django Allauth with email verification
- Authorization: User-based ownership checks
- Content Security Policy: Configurable CSP headers
- Input validation: Form validation and model constraints
- File upload validation: Type and size limits for images
Performance Optimizations
- Database indexes: Composite indexes on common query patterns
- Query optimization:
select_related()andprefetch_related() - Caching: Redis for session storage and caching
- Image optimization: AVIF format for smaller file sizes
- Asynchronous processing: Celery for heavy operations