Django Dynamic Fixture

4.0.1 · active · verified Fri Apr 17

Django Dynamic Fixture (DDF) is a full library designed to create dynamic model instances primarily for testing purposes. It allows developers to generate complex Django model objects with sensible default data, reducing boilerplate in tests. As of version 4.0.1, it supports modern Django and Python versions. Releases typically follow major Django version compatibility updates, with minor bug fix releases in between.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `ddf.G` to create and persist model instances, `ddf.F` for dynamic field values (including using `Faker`), and `ddf.N` for non-persisted instances. It includes a minimal, self-contained Django setup to make the code runnable without a pre-existing Django project.

import os
from django.conf import settings
from django.apps import apps
from django.db import models
from ddf import G, F, N
from faker import Faker

# Minimal Django setup for the quickstart to be runnable without a full project
if not apps.ready:
    settings.configure(
        DEBUG=True,
        INSTALLED_APPS=[
            'django.contrib.auth',
            'django.contrib.contenttypes',
        ],
        DATABASES={
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': ':memory:',
            }
        },
        SECRET_KEY='not-a-secret',
        USE_TZ=True,
        # Define a dummy app_label for models in this ad-hoc setup
        MIGRATION_MODULES={'myapp': None} # Prevent migrations check
    )
    import django
    django.setup()

# Define dummy models for the quickstart within a custom app_label
class Author(models.Model):
    name = models.CharField(max_length=255)
    email = models.EmailField(unique=True)
    bio = models.TextField(blank=True)

    class Meta:
        app_label = 'myapp' # Required for models in minimal setup

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    pages = models.IntegerField(default=100)

    class Meta:
        app_label = 'myapp' # Required

    def __str__():
        return self.title


# --- Actual django-dynamic-fixture usage ---
fake = Faker()

print("--- Creating instances ---")

# 1. Create a single Author instance
author1 = G(Author, name=fake.name(), email=fake.email(), bio=fake.paragraph())
print(f"  Created Author: {author1.name} ({author1.email})")

# 2. Create a Book instance referencing an existing author
book1 = G(Book, author=author1, title=fake.sentence(nb_words=4))
print(f"  Created Book: '{book1.title}' by {book1.author.name}")

# 3. Create multiple Books with dynamic values using F()
# This will also create a new Author because 'author__name' is specified
books_dynamic = G(Book, n=2, author__name=F(fake.name), author__email=F(fake.email),
                 title=F(lambda: fake.sentence(nb_words=3)),
                 pages=F(lambda: fake.random_int(min=50, max=500)))
for book_obj in books_dynamic:
    print(f"  Created Dynamic Book: '{book_obj.title}' by {book_obj.author.name} ({book_obj.pages} pages)")

# 4. Create a non-persisted instance (not saved to database)
draft_book = N(Book, title="Draft Idea", author=author1, pages=20)
print(f"  Created Draft Book (not persisted): '{draft_book.title}' by {draft_book.author.name}")

# You can verify it's not saved (requires django.db.models import and Django setup)
# from django.db import connection
# with connection.cursor() as cursor:
#     cursor.execute("SELECT COUNT(*) FROM myapp_book")
#     print(f"Total books in DB: {cursor.fetchone()[0]}")

view raw JSON →