Skip to main content

django-seedkit

Minimal test data seeding for Django — plain Python, no magic.

Auto-discovery • Idempotent • Atomic transactions • Zero configuration

Features

  • Simple: Seed files are plain Python — just use get_or_create() and imports
  • Auto-discovery: Automatically finds setup_*.py files in your apps' seeds/ directories
  • Idempotent: Safe to run multiple times; uses get_or_create() pattern
  • Atomic: All seeds run in a single database transaction (configurable)
  • Dependency management: Use Python imports to control execution order
  • No magic: No decorators, no registration — just import and run

Installation

pip install django-seedkit

Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "seedkit",
]

Quick Start

1. Create a seed file

Create a seeds/ directory in your app and add seed files:

# myapp/seeds/setup_users.py
from django.contrib.auth import get_user_model
from seedkit import log

User = get_user_model()

admin, created = User.objects.get_or_create(
    username="admin",
    defaults={
        "email": "admin@example.com",
        "is_staff": True,
        "is_superuser": True,
    }
)

if created:
    admin.set_password("admin")
    admin.save()
    log("Created admin user")

2. Run the seeds

python manage.py seeddata

That's it! Your seed file runs automatically.

Managing Dependencies

Seed files execute when imported. Control the order by importing dependencies:

# myapp/seeds/setup_posts.py
from django.contrib.auth import get_user_model

# Import user seeds first - this ensures users exist before posts
from myapp.seeds.setup_users import admin

from myapp.models import Post
from seedkit import log

post, created = Post.objects.get_or_create(
    slug="welcome",
    defaults={
        "title": "Welcome!",
        "author": admin,
        "content": "Hello world",
    }
)

if created:
    log("Created welcome post")

Python's import caching ensures each seed file runs only once, even if imported multiple times.

Commands

# Run all seeds
python manage.py seeddata

# List available seeds without running
python manage.py seeddata --list

# Run seeds for specific apps only
python manage.py seeddata --apps=myapp,otherapp

# Preview what would run (dry run)
python manage.py seeddata --dry-run

# Run without transaction wrapper
python manage.py seeddata --no-atomic

Configuration

Optional configuration via Django settings:

# settings.py
SEEDKIT = {
    # Directory name in each app (default: "seeds")
    "SEED_DIR": "seeds",

    # File pattern to match (default: "setup_*.py")
    "FILE_PATTERN": "setup_*.py",

    # Wrap all seeds in atomic transaction (default: True)
    "ATOMIC": True,

    # Apps to exclude from discovery
    "EXCLUDE_APPS": ["django.contrib.admin"],
}

Helper Functions

Seedkit provides utility functions for common seeding tasks:

from seedkit import log, make_slug, make_hash_id, placeholder_image

# Log messages during seeding
log("Created user")                    # "  Created user"
log("Warning!", level="warning")       # "  ⚠ Warning!"

# Create URL-safe slugs (handles Finnish, Swedish, German, etc.)
make_slug("Pekka Mäkinen")            # "pekka-makinen"
make_slug("Müller Straße")            # "muller-strasse"

# Generate stable hash IDs
make_hash_id("unique-identifier")      # "a1b2c3d4..."

# Placeholder images for development
placeholder_image("apartment-1", 1600, 1200)
# "https://picsum.photos/seed/apartment-1/1600/1200"

Best Practices

Use get_or_create() for Idempotency

# Good - can run multiple times safely
user, created = User.objects.get_or_create(
    username="admin",
    defaults={"email": "admin@example.com"}
)

# Avoid - will fail on second run
user = User.objects.create(username="admin")
user, created = User.objects.get_or_create(username="admin", ...)

if created:
    # Only create profile if user is new
    Profile.objects.create(user=user, bio="Admin user")
    log("Created admin with profile")

Export Objects for Dependencies

# myapp/seeds/setup_users.py
admin, _ = User.objects.get_or_create(username="admin", ...)
editor, _ = User.objects.get_or_create(username="editor", ...)

# Now other files can import:
# from myapp.seeds.setup_users import admin, editor

License

MIT

Metadata

Release files for django-seedkit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-seedkit 0.1.0
File Size Uploaded
django_seedkit-0.1.0.tar.gz 41.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-seedkit 0.1.0
File Interpreter ABI Platform
django_seedkit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.3 kB

Release files / django_seedkit-0.1.0.tar.gz

Download URL django_seedkit-0.1.0.tar.gz
Size 41.9 kB
Tags Source
SHA-256 checksum
How to use checksums
069fb5cd0278fdc2a6d2b2621f24d6c0c185631bf956e0d5a27c463405e44210
BLAKE2b-256 checksum
How to use checksums
eab377d35411ddd808bc6fa445855f7bae87ba6f698c0e3930ef8e336cdb6807
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.2

Release files / django_seedkit-0.1.0-py3-none-any.whl

Download URL django_seedkit-0.1.0-py3-none-any.whl
Size 11.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8a41af823d2ecc8bd1e4672aceacc6d61f84473ca6bed351d1ad80e7618f87f
BLAKE2b-256 checksum
How to use checksums
fd0409952faca0303c1920094f3110f04aa11f09ae50b0c9af3f7e82a25a842a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page