Skip to main content

Django Nested Seed

A Django package for loading seed data from YAML files with support for nested relationships.

Before you use this package you should ask yourself the following questions:

  • Do I want the ability to programmatically create seed/fixture data?
  • Do I want the ability to generate random seed/fixture data?
  • Do I want the ability to keep my data in sync with what's in the database?
  • Do I care more about using these fixtures for unit testing?

If you answered Yes to any of the above questions, then you're probably looking for either Django Fixtures, Django Management Commands, Factory Boy or any of the excellent packages available on Django Packages' Fixture Generation Category

So when would you want to use this package?

  • You want bootstrap data for development or demonstration purposes
  • You prefer to have it declarative rather than programmatic
  • You want deeply nested relationships declarations instead of flat
  • Your workflow involves modifying the fixtures in the file and resetting the data, not exporting what you edited from your site.

If that's the case, then read on!

Installation

pip install django-nested-seed

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    'django_nested_seed',
]

Quick Start

Given a testapp django application with the following models

from django.db import models
from django.contrib.auth.models import User

class Person(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="people")
    pen_name = models.CharField(max_length=100)
    bio = models.TextField()

class Publisher(models.Model):
    name = models.CharField(max_length=200)
    country = models.CharField(max_length=100)

class Book(models.Model):
    STATUS_CHOICES = [
        ('DRAFT', 'Draft'),
        ('PUBLISHED', 'Published'),
        ('ARCHIVED', 'Archived'),
    ]

    title = models.CharField(max_length=200)
    person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="books")
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name="books")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='DRAFT')

Create a data.yaml file with the following content:

testapp:
  Author:
    - $ref: alice
      user:
        username: "alice"
        email: "alice@example.com"
      pen_name: "Alice Smith"
      bio: "Software engineer"

  Book:
    - title: "Python Patterns"
      author: "$alice"
      publisher:
        name: "Tech Books Inc"
        country: "UK"
      status: "PUBLISHED"

then load it via the following command:

python manage.py nested_seed data.yaml

The command will navigate through the hierarchy and create the corresponding records according to the rules specified in the YAML Structure below.

Another example with more features

auth:                                   # We can target any app
  User:
    - $ref: alice                       # $ref will assign an internal reference to the node
      username: "alice"
      email: "alice@example.com"

testapp:
  Technology:
    - $ref: python
      name: "Python"
      version: "3.11"
    - $ref: django
      name: "Django"
      version: "4.2"

  Organization:
    - name: "TechCorp"
      code: "TC"
      founded_date: "2020-01-01"
      configuration:                    # O2O or FK - inline declaration
        timezone: "UTC"
        currency: "USD"
      divisions:                        # FK's Reverse relationship "divisions"
        - name: "Engineering"
          location: "NYC"
          budget: "1000000.00"
          department_set:               # FK's Reverse relationship (default `_set`)
            - name: "Backend"
              code: "BE-01"
              manager: "$alice"         # "$alice" will point to the record with $ref
              project_set:              # another reverse declaration
                - name: "API Rewrite"
                  status: "IN_PROGRESS"
                  start_date: "2024-01-01"
                  technologies:         # ManyToMany works just as well
                    - "$python"
                    - "$django"
                  task_set:             # another reverse relationship
                    - title: "Design endpoints"
                      description: "Define REST API"
                      priority: "HIGH"
                      status: "DONE"
                      assigned_to: "$alice"
                      estimated_hours: 20
                    - title: "Implement auth"
                      description: "Add JWT support"
                      priority: "HIGH"
                      status: "IN_PROGRESS"
                      assigned_to: "$alice"
                      estimated_hours: 40

More Examples

See the examples/ directory for complete examples of each feature:

YAML Structure

# All models use list format with Django app_label and ModelName
app_label:
  ModelName:
    # Basic object without reference
    - field_name: value
      other_field: value

    # Object with explicit reference key (for later use)
    - $ref: my_key      # Reference key for this object
      field_name: value

    # Auto-generated key (modelname_0, modelname_1, etc.)
    - field_name: value

    # ForeignKey - inline nested object
    - field_name: value
      related_field:
        nested_field: value

    # ForeignKey - reference to existing object (defined in YAML)
    - field_name: value
      related_field: "$my_key"    # Reference using $ref_key

    # ForeignKey - reference to existing database record
    - field_name: value
      related_field: "@pk:123"    # Lookup by primary key
    - field_name: value
      related_field: "@username:alice"    # Lookup by field
    - field_name: value
      related_field: "@{name:John,email:john@example.com}"    # Lookup by multiple fields

    # OneToOne - nested directly under parent
    - field_name: value
      one_to_one_field:
        nested_field: value

    # Reverse ForeignKey - nested collection
    - field_name: value
      reverse_relation_set:       # Django reverse accessor
        - child_field: value
        - child_field: value

    # ManyToMany - list of references
    - field_name: value
      many_to_many_field:
        - "$ref_key_1"            # Reference YAML object
        - "$ref_key_2"

    # ManyToMany - with database lookups
    - field_name: value
      many_to_many_field:
        - "@slug:python"          # Reference existing database record
        - "@pk:42"

    # ManyToMany - mixed references, lookups, and inline objects
    - field_name: value
      many_to_many_field:
        - "$ref_key"              # Reference YAML object
        - "@slug:existing"        # Reference database record
        - inline_field: value     # Create new object inline

    # ManyToMany with through model (extra fields)
    - field_name: value
      many_to_many_field:
        - related_object: "$ref_key"
          extra_field: value      # Through model field
          date_field: "2024-01-01"

# Reference keys must be unique across all models

Features

  • Zero configuration
  • Supports OneToOne, ForeignKey, and ManyToMany relationships
  • ManyToMany with custom through models (extra fields on intermediate table)
  • Mixed relation references and inline definitions
  • Database lookups - Reference existing database records
  • Transaction safety with automatic rollback on errors
  • Multiple files can be loaded together
  • Topological sorting handles dependencies automatically

Database Lookups

Reference existing database records using @lookup syntax instead of creating new ones:

Lookup by primary key:

author: "@pk:123"  # Lookup by primary key

Lookup by single field:

author: "@username:alice"  # Lookup by unique field
category: "@slug:python"   # Lookup by slug

Lookup by multiple fields:

publisher: "@{name:O'Reilly Media,country:USA}"  # Lookup by multiple fields

With Django's related field syntax:

author: "@user__username:alice"  # Lookup Author where user.username='alice'

In ManyToMany fields:

Book:
  - title: "Django Book"
    categories:
      - "$new_category"    # Reference YAML object
      - "@slug:existing"   # Reference database record

Features:

  • Results are cached to avoid redundant queries
  • Clear error messages if record not found
  • Works with ForeignKey, OneToOne, and ManyToMany fields
  • Can be mixed with $ref references in the same file

Configuration

Custom Reference Key

Change the reference key field name in settings.py:

NESTED_SEED_CONFIG = {
    'reference_key': 'rid',  # Use 'rid' instead of '$ref'
}

Then use it in your YAML:

app:
  Category:
    - rid: python  # Using custom reference key
      name: "Python"

Development

uv sync
uv run pytest

Requirements

  • Python 3.10+
  • Django 4.2+
  • PyYAML 6.0+

License

MIT

Metadata

Release files for django-nested-seed 0.1.3

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-nested-seed 0.1.3
File Size Uploaded
django_nested_seed-0.1.3.tar.gz 73.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-nested-seed 0.1.3
File Interpreter ABI Platform
django_nested_seed-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 105.4 kB

Release files / django_nested_seed-0.1.3.tar.gz

Download URL django_nested_seed-0.1.3.tar.gz
Size 73.3 kB
Tags Source
SHA-256 checksum
How to use checksums
cc610b700c304ab56464909cd7e734f797dd4af9be1ef369a2a715d702305f1a
BLAKE2b-256 checksum
How to use checksums
ce0f7ce3b5b857193ffd54301a3e84b9348520512a293b44259c9e8a136234fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 10, 2025.

Transparency log

Release files / django_nested_seed-0.1.3-py3-none-any.whl

Download URL django_nested_seed-0.1.3-py3-none-any.whl
Size 32.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
478b701aa5e413502dcf16903057b5d855b0570d8ea8756419126b52c9b77ce0
BLAKE2b-256 checksum
How to use checksums
e13789120424e157c18635af9fc06b2bf9c0d139287a4e00aec9e83e6ef7bfc7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Dec 10, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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