Overview
FKApi uses Django ORM models to represent football kit data. The schema is designed to normalize data while maintaining query performance through strategic use of foreign keys, many-to-many relationships, and database indexes. All models are defined infkapi/core/models.py.
Entity Relationship Diagram
Core Models
Kit
The central model representing a football kit (jersey/uniform).Kit name (indexed for search performance)
URL-friendly identifier (unique). Allows special characters including Romanian characters (ăâîșț). Must match pattern:
[-a-zA-Z0-9_ăâîșțĂÂÎȘȚ]+Original ID from FootballKitArchive.com for URL construction
Club that owns this kit
Season this kit was used
Competitions this kit was used in
Type of kit (Home, Away, Third, etc.)
Manufacturer/brand of the kit
URL to main kit image
User rating (0.00-10.00)
Link to FootyHeadlines.com
Last update time from source website
Last update time in database (auto-updated)
Primary color of the kit
Secondary colors of the kit
Design description or pattern name
Indexes
Kit model has the following database indexes for query optimization:name(single field)team, season(composite)main_img_url(single field)web_updated(single field)last_updated(single field)rating(single field)
Club
Represents a football club/team.Original ID from footballkitarchive.com
Club name (indexed for search performance)
URL-friendly identifier (unique). Supports special characters like Romanian letters.
URL to club logo
URL to dark mode logo
Country where club is based
Indexes
namecountry
Season
Represents a football season. Supports both single-year (“2024”) and two-year (“2023-24”) formats.Full season identifier (unique). Examples: “2024”, “2023-24”, “1999-00”
First year of the season (4-digit year)
Second year of the season for two-year formats (4-digit year)
The scraper automatically handles various season format inputs including “23-24”, “2023-24”, “2023-2024” and normalizes them to the standard format.
Type_K
Represents the type of kit with categorization and ordering.Type name (e.g., “Home”, “Away”, “Third”, “GK Home”)
Category for organization. Choices:
match: Game kits (default)prematch: Pre-match, bench, warm-up, staffpreseason: Pre-season, temporarytraining: Trainingtravel: Travel, polojacket: Jackets (anthem, rain, windbreaker, track, vest)
Order of category (1-6):
- 1 = match
- 2 = prematch
- 3 = preseason
- 4 = training
- 5 = travel
- 6 = jacket
Priority within category (lower = first). Non-GK items come before GK items.
True if this is a goalkeeper kit (GK, Goalkeeper, Portero)
Ordering
Default ordering:['category_order', 'is_goalkeeper', 'order_priority', 'name']
This ensures:
- Match kits appear first
- Outfield kits before goalkeeper kits within each category
- Standard types (Home, Away, Third) before special types
Indexes
- Composite:
(category_order, is_goalkeeper, order_priority) - Composite:
(category, is_goalkeeper, order_priority)
Brand
Represents a kit manufacturer/brand.Brand name (indexed)
URL-friendly identifier (unique)
URL to brand logo
URL to dark mode logo
Index
name
Competition
Represents a football competition.Competition name (indexed)
URL-friendly identifier (unique)
URL to competition logo
URL to dark mode logo
Country where competition is based
Indexes
namecountry
Color
Represents a color used in kit designs.Name of the color (e.g., “Red”, “Blue”, “Navy”)
Hex color code (e.g., “#FF0000” for red)
Variation
Represents a color variation (shade) of a parent color.Name of the variation (e.g., “Light Blue”, “Dark Red”)
Parent color this variation belongs to
Hex color code for the variation
Red component (0-255)
Green component (0-255)
Blue component (0-255)
Relationships
One-to-Many Relationships
Club → Kit
One club has many kits
Season → Kit
One season has many kits
Brand → Kit
One brand has many kits
Type_K → Kit
One type has many kits
Color → Variation
One color has many variations
Many-to-Many Relationships
Kit ↔ Competition
Kits can be used in multiple competitions
Kit ↔ Color (secondary)
Kits can have multiple secondary colors
Query Optimization
select_related() vs prefetch_related()
Useselect_related() for foreign key relationships (SQL JOIN):
prefetch_related() for many-to-many and reverse foreign key relationships:
Combined Example
Custom Fields
ColorField
Provided bydjango-colorfield package:
- Stores hex color codes
- Includes color picker widget in admin
- Used in Color and Variation models
CountryField
Provided bydjango-countries package:
- Stores ISO 3166-1 country codes
- Provides country name display
- Used in Club and Competition models
Custom Slug Field
Both Kit and Club use custom slug validators that allow special characters:- Pattern:
[-a-zA-Z0-9_ăâîșțĂÂÎȘȚ]+ - Supports Romanian characters
- More permissive than Django’s default SlugField
Database Considerations
Indexes
Indexes
Strategic indexes improve query performance:
- Single-field indexes on frequently searched columns (name, slug)
- Composite indexes for common filter combinations (team+season)
- Category ordering indexes for Type_K sorting
Connection Pooling
Connection Pooling
PostgreSQL connection settings in
settings.py:CONN_MAX_AGE: 60 seconds- Keepalive settings for connection stability
- Reduces connection overhead
Transactions
Transactions
Scraping operations use atomic transactions: