Database Architecture¶
The application uses PostgreSQL with Django ORM.
Core Models¶
Product Hierarchy¶
erDiagram
Category ||--o{ Product : contains
Product ||--o{ ProductVariant : has
Product ||--o{ ProductColorImage : has
ProductVariant }o--|| Color : uses
ProductVariant }o--|| Size : uses
ProductColorImage }o--|| Color : uses
Order Flow¶
erDiagram
User ||--o{ Order : places
User ||--o{ ShoppingCart : has
ShoppingCart ||--o{ CartItem : contains
Order ||--o{ OrderItem : contains
OrderItem }o--|| ProductVariant : references
OrderItem }o--o| CustomDesign : includes
Key Models¶
Product¶
class Product(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
base_price = models.DecimalField(max_digits=10, decimal_places=2)
is_active = models.BooleanField(default=True)
# Print area configuration
max_print_width = models.IntegerField()
max_print_height = models.IntegerField()
ProductVariant¶
class ProductVariant(models.Model):
product = models.ForeignKey(Product, related_name='variants')
color = models.ForeignKey(Color, on_delete=models.PROTECT)
size = models.ForeignKey(Size, on_delete=models.PROTECT)
sku = models.CharField(max_length=50, unique=True)
stock_quantity = models.IntegerField(default=0)
price_adjustment = models.DecimalField(default=0)
CustomDesign¶
class CustomDesign(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
color = models.ForeignKey(Color, on_delete=models.PROTECT)
# Fabric.js JSON data per view
design_data_front = models.JSONField(null=True)
design_data_back = models.JSONField(null=True)
# Preview images
preview_image_front = models.ImageField(null=True)
preview_image_back = models.ImageField(null=True)
Database Indexes¶
Key indexes for performance:
class Meta:
indexes = [
models.Index(fields=['slug']),
models.Index(fields=['is_active', 'category']),
models.Index(fields=['sku']),
]
Migrations¶
Always review migrations before applying: