Seed Data & Catalog Management¶
This guide covers managing seed data for development, staging, and production environments, including strategies for incremental catalog updates.
Overview¶
The seed data system allows you to version-control your complete webshop catalog and automatically deploy it across environments via CI/CD. This ensures consistency between development, staging, and production.
What Gets Exported/Imported¶
Database Models (21 Total)¶
| App | Model | Description |
|---|---|---|
| core | SiteSettings |
Store settings, VAT, shipping, footer info |
| core | Page |
Static pages (Terms, Privacy, FAQ, About, Returns) |
| products | Category |
Product categories (hierarchical with MPTT) |
| products | Brand |
Product brands with logos |
| products | Product |
Products with specifications |
| products | Color |
Available product colors |
| products | Size |
Available sizes (clothing, caps, accessories) |
| products | ProductColorImage |
Multi-view images per color |
| products | ProductVariant |
Size/color combinations with stock |
| pricing | DiscountCode |
Promotional discount codes |
| pricing | VolumeDiscount |
Bulk purchase discounts |
| pricing | VolumeDiscountTier |
Volume discount tiers |
| pricing | TeamDiscount |
Team order discounts |
| pricing | SpecialOffer |
Time-limited promotions |
| pricing | PricingRule |
Dynamic pricing rules |
| designs | Font |
Designer fonts (uploaded + Google) |
| designs | TextColor |
Designer text colors with pricing |
| designs | DesignTemplate |
Pre-made design templates |
| clipart | ClipartCategory |
Clipart categories |
| clipart | ClipartItem |
Individual clipart SVGs |
Media Files¶
| Directory | Contents |
|---|---|
products/ |
Product main images |
categories/ |
Category thumbnails |
brands/ |
Brand logos |
variants/ |
Variant-specific images |
fonts/ |
Uploaded font files (.ttf, .otf, .woff, .woff2) |
clipart/ |
SVG files and thumbnails |
templates/ |
Design template thumbnails |
What's NOT Included (Runtime Data)¶
- Orders, OrderItems, CartItems
- CustomDesigns (user-created)
- User accounts
- Payment transactions
Git-Tracked Seed Data (Recommended)¶
Seed data is stored in backend/fixtures/seed/ and version-controlled:
backend/fixtures/seed/
├── seed_data.json # All catalog data
├── metadata.json # Export metadata
└── media/ # Product images, fonts, clipart
├── products/
├── categories/
├── fonts/
└── clipart/
Commands¶
Export Seed Data¶
# Using helper script (recommended)
./scripts/export-seed-data.sh
# Direct Django command
cd backend
python manage.py export_seed_data
# Export without images (JSON only)
python manage.py export_seed_data --skip-images
# Export to custom location
python manage.py export_seed_data --output /tmp/my_export
Import Seed Data¶
# Standard import (merge mode - updates existing, creates new)
python manage.py import_seed_data
# Import new records only, skip existing
python manage.py import_seed_data --mode skip
# Import with detailed logging
python manage.py import_seed_data --mode overwrite
# Clear all catalog data before import (dangerous!)
python manage.py import_seed_data --clear --force
# Import from custom location
python manage.py import_seed_data --input /path/to/seed_data
Import Modes¶
| Mode | Behavior |
|---|---|
merge (default) |
Update existing records, create new ones |
skip |
Only create new records, skip existing |
overwrite |
Same as merge with detailed logging |
Selective Export (Specific Models)¶
For updating specific parts of the catalog without a full export:
# Export only products
./manage.sh update-catalog products
# Export specific product (by SKU)
./manage.sh update-catalog products 'sku=HOODIE-BLUE-001'
# Export only pricing rules
./manage.sh update-catalog 'discount_codes,volume_discounts'
# Export a category and its products
./manage.sh update-catalog 'categories,products' 'category__slug=hoodies'
Available models for selective export: products, categories, brands, colors, sizes, product_variants, product_color_images, discount_codes, volume_discounts, team_discounts, special_offers, pricing_rules, site_settings
Catalog Update Strategies¶
After the initial catalog import, use the appropriate strategy for ongoing updates.
Strategy 1: Merge Import (Multiple Updates)¶
Best for updating multiple products, refreshing pricing, or adding new products alongside existing ones.
The import command uses update_or_create() by default:
- Existing records (matched by primary key) are updated
- New records are created
- Existing records not in the import are preserved
# On development: Make changes in Django admin
# Export the catalog
./scripts/export-seed-data.sh
# On staging/production: Import (merges with existing)
python manage.py import_seed_data
Strategy 2: Selective Export (Specific Updates)¶
Best for updating a single product, specific pricing rules, or a specific category.
# Update single product description
./manage.sh update-catalog products 'sku=TSHIRT-BASIC-001'
# Update all discount codes
./manage.sh update-catalog 'discount_codes,volume_discounts,team_discounts'
# Add new color to existing product
./manage.sh update-catalog 'colors,products,product_color_images,product_variants' 'product__sku=HOODIE-001'
Tip
Use --include-related to automatically include related records, or explicitly list related models.
Strategy 3: Direct Django Admin (Single Changes)¶
Best for fixing a typo, adjusting one price, or toggling a flag. Make changes directly in the target environment's Django admin -- no export/import needed.
Comparison¶
| Strategy | Use Case | Speed | Safety | Complexity |
|---|---|---|---|---|
| Merge Import | Multiple updates, new products | Slow | High | Low |
| Selective Export | Specific products/models | Fast | High | Medium |
| Direct Admin | Single field changes | Instant | Medium | Low |
Workflow by Environment¶
Development¶
# Make catalog changes in Django admin
# Then export to version control
./scripts/export-seed-data.sh
git add backend/fixtures/seed/
git commit -m "feat(catalog): add new product line"
Staging (Automatic via CI/CD)¶
Seed data is automatically imported on every deployment to the main branch:
- CI/CD copies
backend/fixtures/seed/to staging server - After deployment, runs
import_seed_data --mode merge - Staging always reflects the latest catalog from git
Production¶
For production, use a hybrid approach:
# Initial setup: Import baseline catalog
python manage.py import_seed_data --mode skip --force
# Ongoing: Use Django admin for catalog changes
# Major updates: Export from staging, review, import to production
CI/CD Integration¶
Automatic Testing (ci.yml)¶
The CI pipeline tests seed data export/import on every push:
- Creates a minimal test fixture (1 product, 1 category, 1 color, 1 size, 1 variant)
- Exports to
/tmpwith--skip-images - Flushes database
- Imports and validates data integrity
- Tests git-tracked seed data import (if exists)
Staging Deployment (deploy-staging.yml)¶
# Seed data is automatically deployed:
- name: Copy seed data to server
# Copies backend/fixtures/seed/ to staging
- name: Import seed data (staging only)
# Runs: python manage.py import_seed_data --mode merge --force
Adding New Models to CI Testing¶
- Update
create_test_fixture.py-- add 1 instance of the new model - Update CI verification assertions in
.github/workflows/ci.yml - Test locally before committing
Best Practices¶
- Always export after admin changes -- Keep git-tracked seed data current
- Review before committing --
git diff fixtures/seed/seed_data.json - Test on staging first -- Staging auto-imports on deploy
- Production via admin -- Use Django admin for ongoing changes
- Version large updates -- Create git tags for major catalog changes
- Backup before importing -- Export production data before major catalog changes
- Use selective exports for efficiency -- For large catalogs (1000+ products), don't export/import everything for small changes
Troubleshooting¶
Import Fails with Foreign Key Error¶
Ensure full export is being imported. Dependencies are imported in order. If using selective export, include all related models:
# Wrong: Export only products
./manage.sh update-catalog products
# Right: Export products AND their dependencies
./manage.sh update-catalog 'categories,brands,products'
Images Not Showing¶
Check MEDIA_ROOT and MEDIA_URL settings. Ensure web server can serve media files. If using DigitalOcean Spaces, upload paths should be relative (e.g., products/image.png not media/products/image.png).
Import Overwrites Custom Production Changes¶
Production-specific changes (like stock levels) get overwritten. Solution: Use Django admin for those fields, or manage them via selective export excluding those fields.
Large Media Files¶
Product images and media files are stored on DigitalOcean Spaces (S3-compatible object storage). Seed data media files in backend/fixtures/seed/media/ are version-controlled in the repository. During import, files are uploaded to the configured storage backend (local filesystem in development, DigitalOcean Spaces in staging/production).
CI Test Failures¶
| Error | Cause | Solution |
|---|---|---|
| "Expected X records, got Y" | Fixture/import logic changed | Check create_test_fixture.py and CI assertions |
| "JSON serialization error" | New field type not handled | Update DecimalEncoder in export_seed_data.py |
| "Foreign key constraint" | Import order issue | Check import_order list in import_database_data() |
Technical Details¶
Security Features¶
- Model whitelist prevents importing unauthorized models
- Path traversal protection on image imports
- File size limits (100MB max)
- Symlink following disabled
Export Format¶
- Database: Django JSON serialization with natural foreign keys
- Images: Direct file copy preserving directory structure
- Metadata: Export timestamp and record counts