{"id":9668,"library":"django-dynamic-fixture","title":"Django Dynamic Fixture","description":"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.","status":"active","version":"4.0.1","language":"en","source_language":"en","source_url":"https://github.com/paulocheque/django-dynamic-fixture","tags":["django","testing","fixtures","tdd","development","orm"],"install":[{"cmd":"pip install django-dynamic-fixture","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core dependency for a Django library to function. DDF v4.x requires Django >= 3.2.","package":"Django","optional":false},{"reason":"Provides more realistic and varied data for generated fields. Highly recommended for rich test data.","package":"Faker","optional":true}],"imports":[{"note":"The primary function to create and persist model instances.","symbol":"G","correct":"from ddf import G"},{"note":"Used to define dynamic or conditional values for fields, e.g., using callables or Faker.","symbol":"F","correct":"from ddf import F"},{"note":"Creates a non-persisted (unsaved) model instance.","symbol":"N","correct":"from ddf import N"},{"note":"The `Fixture` class was renamed to `F` in v4.0.0. Using `Fixture` will raise an AttributeError in newer versions.","wrong":"from ddf import Fixture","symbol":"Fixture","correct":"from ddf import F"}],"quickstart":{"code":"import os\nfrom django.conf import settings\nfrom django.apps import apps\nfrom django.db import models\nfrom ddf import G, F, N\nfrom faker import Faker\n\n# Minimal Django setup for the quickstart to be runnable without a full project\nif not apps.ready:\n    settings.configure(\n        DEBUG=True,\n        INSTALLED_APPS=[\n            'django.contrib.auth',\n            'django.contrib.contenttypes',\n        ],\n        DATABASES={\n            'default': {\n                'ENGINE': 'django.db.backends.sqlite3',\n                'NAME': ':memory:',\n            }\n        },\n        SECRET_KEY='not-a-secret',\n        USE_TZ=True,\n        # Define a dummy app_label for models in this ad-hoc setup\n        MIGRATION_MODULES={'myapp': None} # Prevent migrations check\n    )\n    import django\n    django.setup()\n\n# Define dummy models for the quickstart within a custom app_label\nclass Author(models.Model):\n    name = models.CharField(max_length=255)\n    email = models.EmailField(unique=True)\n    bio = models.TextField(blank=True)\n\n    class Meta:\n        app_label = 'myapp' # Required for models in minimal setup\n\n    def __str__(self):\n        return self.name\n\nclass Book(models.Model):\n    title = models.CharField(max_length=255)\n    author = models.ForeignKey(Author, on_delete=models.CASCADE)\n    pages = models.IntegerField(default=100)\n\n    class Meta:\n        app_label = 'myapp' # Required\n\n    def __str__():\n        return self.title\n\n\n# --- Actual django-dynamic-fixture usage ---\nfake = Faker()\n\nprint(\"--- Creating instances ---\")\n\n# 1. Create a single Author instance\nauthor1 = G(Author, name=fake.name(), email=fake.email(), bio=fake.paragraph())\nprint(f\"  Created Author: {author1.name} ({author1.email})\")\n\n# 2. Create a Book instance referencing an existing author\nbook1 = G(Book, author=author1, title=fake.sentence(nb_words=4))\nprint(f\"  Created Book: '{book1.title}' by {book1.author.name}\")\n\n# 3. Create multiple Books with dynamic values using F()\n# This will also create a new Author because 'author__name' is specified\nbooks_dynamic = G(Book, n=2, author__name=F(fake.name), author__email=F(fake.email),\n                 title=F(lambda: fake.sentence(nb_words=3)),\n                 pages=F(lambda: fake.random_int(min=50, max=500)))\nfor book_obj in books_dynamic:\n    print(f\"  Created Dynamic Book: '{book_obj.title}' by {book_obj.author.name} ({book_obj.pages} pages)\")\n\n# 4. Create a non-persisted instance (not saved to database)\ndraft_book = N(Book, title=\"Draft Idea\", author=author1, pages=20)\nprint(f\"  Created Draft Book (not persisted): '{draft_book.title}' by {draft_book.author.name}\")\n\n# You can verify it's not saved (requires django.db.models import and Django setup)\n# from django.db import connection\n# with connection.cursor() as cursor:\n#     cursor.execute(\"SELECT COUNT(*) FROM myapp_book\")\n#     print(f\"Total books in DB: {cursor.fetchone()[0]}\")","lang":"python","description":"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."},"warnings":[{"fix":"Update imports from `from ddf import Fixture` to `from ddf import F` and replace all `Fixture(...)` calls with `F(...)`.","message":"The `Fixture` class was renamed to `F` in version 4.0.0. Code using `from ddf import Fixture` or `ddf.Fixture(...)` will break.","severity":"breaking","affected_versions":"4.0.0+"},{"fix":"Ensure your project runs on Python 3.8+ and Django 3.2+ before upgrading to django-dynamic-fixture v4.x. If not possible, stick to django-dynamic-fixture v3.x.","message":"Version 4.0.0 dropped support for older Python and Django versions. Specifically, it requires Python >= 3.8 and Django >= 3.2.","severity":"breaking","affected_versions":"4.0.0+"},{"fix":"To create a related object and link it, use the `related_field__attribute=value` syntax (e.g., `G(Book, author__name='New Author')`). To link to an existing object, pass the object directly (e.g., `G(Book, author=my_author_instance)`).","message":"When using `ddf.G` for related fields (ForeignKey, ManyToManyField, OneToOneField), passing `F(...)` directly for the related object (e.g., `author=F(...)`) will not create the related object automatically. Instead, define nested attributes using double underscores (e.g., `author__name='...'`) or pass an existing object.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Change `Fixture` to `F`. Update import statements (`from ddf import Fixture` to `from ddf import F`) and usage (`Fixture(...)` to `F(...)`).","cause":"Attempting to use the old `Fixture` class name after upgrading to ddf v4.0.0 or later.","error":"AttributeError: module 'ddf' has no attribute 'Fixture'"},{"fix":"Ensure you are using `ddf.F(lambda: some_value)` for dynamic values or `ddf.F(some_callable)` when you intend to pass a callable function for a field value that should be evaluated later, especially in list/generator contexts.","cause":"This often occurs when passing an integer (or other literal) directly to a field that expects a callable or `ddf.F` when using certain DDF features, e.g., in a list comprehension or generator, or when using `ddf.F` incorrectly.","error":"TypeError: 'int' object is not callable"},{"fix":"Add `from ddf import G` at the top of your file.","cause":"Forgetting to import the `G` function from the `ddf` module.","error":"NameError: name 'G' is not defined"},{"fix":"Explicitly provide values for all non-nullable fields. For unique fields, ensure DDF can generate unique values (e.g., by using `Faker().unique.email()` or providing `F(lambda: unique_value_generator())`).","cause":"Occurs when a non-nullable field or a unique field without a default value is not provided by `ddf.G` (or `ddf.G` generates a non-unique value for a unique field).","error":"django.db.utils.IntegrityError: NOT NULL constraint failed: myapp_model.field_id"}]}