com um clique
advanced-fk-seeding
Advanced seeding patterns for linking specific foreign keys
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
Advanced seeding patterns for linking specific foreign keys
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional SOC
Best practices for writing Django tests (updated template)
GlueFetchHelper patterns for making AJAX calls in templates
Apply DjangoSpire app CSS variables in templates instead of inline styles
Django URL configuration patterns, namespaces, and nested structure conventions
Best practices for AI bots, prompts, and intel in scope_of_work
Examples on how we build our form views.
| name | advanced-fk-seeding |
| description | Advanced seeding patterns for linking specific foreign keys |
This skill covers the pattern for seeding models that require specific, deterministic foreign key relationships — where you need to control exactly which records link to which, rather than relying on random or cached FK assignment.
This pattern resolves cache conflicts that occur when using in_order with cache_seed=True, enabling clean re-seeding without turning off the cache.
When seeding related models together (e.g., bins + locations, fields + lots), the old approach used in_order via field overrides:
# OLD PATTERN - causes cache conflicts
def seed_with_location(cls, count: int = 5):
# Step 1: Seed locations
locations = LocationSeeder.seed_database(
count=count,
fields={'type': LocationTypeChoices.BIN, ...}
)
# Step 2: Seed bins with in_order FK (problem here)
location_ids = [loc.id for loc in locations]
return cls.seed_database(
count=count,
fields={
'location_id': ('custom', 'in_order', {'values': location_ids})
}
)
seed_database() with cache_seed=True caches the generated objects including IDsin_order gets cached with the original values, not the new onesUniqueViolation errors on re-runscache_seed=False to work around the issueUse seed() to generate objects without database insertion, then manually manage IDs through bulk_create():
from __future__ import annotations
from app.location import models as location_models
from app.location.bin import models
from app.location.choices import LocationTypeChoices
from app.location.seeding.seeder import LocationSeeder
class BinSeeder(DjangoModelSeeder):
model_class = models.Bin
cache_seed = True
@classmethod
def with_rows(cls, count: int = 5, rows_per_bin: int = 4):
# 1. Create bin location objects with field overrides
bin_locations = LocationSeeder.seed(
count=count,
fields={
'type': LocationTypeChoices.BIN,
'name': ('llm', 'Generate a name for a storage bin...'),
},
)
# 2. Bulk create locations and capture new IDs
location_models.Location.objects.bulk_create(bin_locations)
bin_location_ids = [loc.id for loc in bin_locations]
# 3. Create bin objects, link to locations, bulk create
bins = cls.seed(count=count)
for bin, loc_id in zip(bins, bin_location_ids):
bin.location_id = loc_id
models.Bin.objects.bulk_create(bins)
# 4. Create row child locations linked to bins
total_rows = count * rows_per_bin
row_names = [f'Row {i}' for i in range(1, total_rows + 1)]
bin_ids_expanded = [bin_id for bin_id in bin_location_ids for _ in range(rows_per_bin)]
rows = LocationSeeder.seed(
count=total_rows,
fields={
'type': LocationTypeChoices.ROW,
},
)
for row, parent_id, name in zip(rows, bin_ids_expanded, row_names):
row.parent_id = parent_id
row.name = name
location_models.Location.objects.bulk_create(rows)
return bins
Seeder.seed() with field overrides — generates objects with pk=NoneModel.objects.bulk_create() — inserts records and assigns real DB IDs[obj.id for obj in objects]seed() — generates child objectsfor child, parent_id in zip(children, parent_ids)child.parent_id = parent_idseed() returns objects with pk=None by defaultbulk_create() assigns real IDs after insertcache_seed=True on all seedersFor models like Warehouse that link directly to locations:
@classmethod
def with_locations(cls, count: int = 5):
warehouse_locations = LocationSeeder.seed(
count=count,
fields={
'type': LocationTypeChoices.WAREHOUSE,
'name': ('llm', 'Generate a name for a warehouse...'),
},
)
location_models.Location.objects.bulk_create(warehouse_locations)
warehouse_location_ids = [loc.id for loc in warehouse_locations]
warehouses = cls.seed(count=count)
for warehouse, loc_id in zip(warehouses, warehouse_location_ids):
warehouse.location_id = loc_id
models.Warehouse.objects.bulk_create(warehouses)
return warehouses
For models like Bin that have multiple row children per bin:
@classmethod
def with_rows(cls, count: int = 5, rows_per_bin: int = 4):
# ... create and save parent locations ...
# Create rows with expanded parent IDs
total_rows = count * rows_per_bin
row_names = [f'Row {i}' for i in range(1, total_rows + 1)]
bin_ids_expanded = [bin_id for bin_id in bin_location_ids for _ in range(rows_per_bin)]
rows = LocationSeeder.seed(count=total_rows)
for row, parent_id, name in zip(rows, bin_ids_expanded, row_names):
row.parent_id = parent_id
row.name = name
location_models.Location.objects.bulk_create(rows)
Some fields like type may not apply via field override due to caching. Set them explicitly:
lots = LocationSeeder.seed(
count=total_lots,
fields={
'type': LocationTypeChoices.LOT,
},
)
for lot, parent_id, name in zip(lots, field_ids_expanded, lot_names):
lot.type = LocationTypeChoices.LOT # Explicitly set, not from field override
lot.parent_id = parent_id
lot.name = name
location_models.Location.objects.bulk_create(lots)
from __future__ import annotations
from app.location.bin.seeding.seeder import BinSeeder
from app.location.field.seeding.seeder import FieldSeeder
from app.location.warehouse.seeding.seeder import WarehouseSeeder
# Seed bins with child rows
bins = BinSeeder.with_rows(count=5)
# Seed fields with child lots
fields = FieldSeeder.with_lots(count=5)
# Seed warehouses
warehouses = WarehouseSeeder.with_locations(count=5)
When reviewing advanced FK seeding code, verify the following:
seed() not seed_database() for initial object generationzip() to pair children with parent IDscache_seed=True is set on the seeder classtype in loop when field override doesn't applywith_locations, with_rows, with_lots)