model_bakery fills a Django model with values you did not have to invent
Object factory for Django
At a glance
- What is it?
- model_bakery is a Django testing library that creates model instances with plausible random field values, so a test can call baker.make on a model with a dozen fields and get a valid object back. The package follows the Python and Django release cycles, supports Django 5.2 through 6.1 on Python 3.11 and later, and is built with uv, tested against Postgres and PostGIS, and licensed under Apache 2.0.
- Who is it for?
- model_bakery is the right tool when your test suite spends more time writing model instances than asserting on them, because one call replaces a constructor with a dozen arguments and the generated values are valid enough to satisfy a database constraint.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 19, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The test that needs an object, not a fixture file
The library is described as offering a smart way to create fixtures for testing in Django, with a simple and powerful API that lets you create many objects with a single line of code. The problem it solves is the one every Django project hits. A model has a name, an email, an age, a boolean, a text field, a date and a datetime, and a test that only cares about one of them still has to supply the rest, either by hand or by loading a fixture file that somebody has to keep in step with the model. The README's example makes the shape of the work concrete. The model is a Customer with those seven fields, and the test's setUp creates it with a single call, baker.make('shop.Customer'), and then prints the instance dictionary so you can see what came out. The values are generated but they are not random noise, they are values that pass a database, which is the part that matters.
What the generated object actually looks like
The printed dictionary is the most useful thing in the README, because it shows what the library does with each field type rather than describing it. The integer age comes out as 3841, which is a number that satisfies an integer field and nothing else, and the boolean is True, and the date is a real date, datetime.date(2019, 12, 3), and the datetime is a real datetime with microseconds, datetime.datetime(2019, 12, 3, 21, 42, 34, 77019). The email field becomes a syntactically valid address, [email protected], and the name is a random string, and the text field is a long random string. The id is 1, because it came from the database. Two properties follow from that output. The generated values are valid for the schema, so the object can be saved without a constraint error, and they are meaningless, so a test that depends on a particular value has to set it explicitly, which is the honest division of labour between the library and the test.
Following the Python and Django release cycle
The support policy is stated in one sentence and it is the kind of sentence that saves an upgrade. Model Bakery follows the Python and Django release and support cycles, and support for a Python or Django version is dropped when that version reaches end-of-life. The classifiers in the packaging metadata make the current window concrete, with Django 5.2, 6.0 and 6.1 listed, and Python 3.11 through 3.15, and the single runtime dependency is django>=5.2. The development status is Development Status 5, Production/Stable, and the operating system is independent. That combination of an explicit support window and a permissive licence is what makes the library safe to add to a project with a long life, since the question that matters in three years is not whether the newest Django works but whether the one you are on still does, and the policy says the answer is yes until the day your Django version itself is retired.
Installing it, and the packaging it ships with
The install is one command:
pip install model-bakeryThe distribution is built with uv, since the build system requires uv_build and the build backend is uv_build, and the project keeps a uv.lock file, so the pinned development environment is reproducible. The tool configuration is also modern, with an exclude-newer setting of 7 days under the uv configuration, and the optional dependency groups cover the development roles. There is a docs group with Sphinx, sphinx-rtd-theme and myst-parser, a tests group with coverage, pillow, pytest and pytest-django, a typing group with ty, and a lint group with black, ruff and pre-commit, plus a dev group that includes the others. The repository has a tox.ini for running the suite against different environments, a .pre-commit-config.yaml, a .readthedocs.yaml for the documentation build, a SECURITY.md, and the documentation itself under docs/ with the published site at model-bakery.readthedocs.io.
The Makefile is four targets and a lint chain
The developer workflow is small enough to read in one screen, and the Makefile at the root is the whole of it. The help target greps the Makefile for its own targets and prints them, which is a trick worth copying. The test target runs python -m pytest, and the release target builds a source distribution and a wheel with python setup.py sdist bdist_wheel and uploads them with twine upload dist/*. The lint target is the interesting one, because it runs three tools in sequence, black to format, ruff check to lint, and ty check model_bakery to type check the package. The type checker being a separate tool from the linter is the modern arrangement, and the fact that the type check is scoped to model_bakery rather than the whole tree suggests the tests are not yet typed to the same standard. The coverage badge in the README reads 97 percent, which is high for a library whose job is to touch every field type of every model, and it is the number to keep an eye on as new Django versions arrive.
Postgres and PostGIS get their own test path
The repository carries a postgis-tests.sh script and a postgres-docker directory, which is the part of the setup that tells you how seriously the project takes databases it does not develop against. A library that creates objects for a test suite is only correct if the objects it creates are correct for your database, and SQLite in memory and Postgres differ in how they treat types, so a suite that passes on one and not the other has found a real problem. The same reasoning applies more sharply to PostGIS, where a geometry field has a type system of its own and a generated value is either valid geometry or an error. The top-level entries also show a tests/ directory, a model_bakery/ package directory, a CHANGELOG.md and a MANIFEST.in, and the CI workflow is the one whose badge sits at the top of the README, alongside the coverage badge and the readthedocs status badge.
Where a random object factory is the wrong tool
The honest limit is that generated values are only neutral when the test does not care. A random age of 3841 will not break most tests, but a random birthday will quietly hide a bug in a date comparison, and a random email will hide a bug in a uniqueness check, and the more your model has constraints and relations, the more a test that depends on the values can pass for the wrong reason. The library's answer is that you override the fields that matter, and for most suites that is the right answer, but for a test suite that is about data rather than about wiring, a fixed fixture is a better record of the scenario you mean. The alternative approach is a hand-written fixture, which is explicit and version controlled, and the difference in approach is that a fixture says exactly what a scenario looks like while a factory says here is a plausible one, and a project with a lot of business rules in its tests usually needs both. The history is worth knowing too, since the project was originally created by Vanderson Mota as Model Mommy and was previously maintained in the berinhard/model_mommy repository before being renamed and moved, and the maintainers now listed are Bernardo Fontes, Rustem Saiargaliev and Tim Klein.
Editorial conclusion
model_bakery is the right tool when your test suite spends more time writing model instances than asserting on them, because one call replaces a constructor with a dozen arguments and the generated values are valid enough to satisfy a database constraint. It is the wrong tool when the value under test is the value, since a random birthday can hide a bug in date logic that a fixed date would expose, and it is a poor fit for a project that wants to keep its fixtures in version control as the record of a scenario. Before adopting it, decide which of your factories need fixed values and which are happy with generated ones, because that decision is per field and per model, and check the Postgres and PostGIS test path if you use those, since the repository ships a separate script for that and it is where the failures will appear.
Frequently asked questions
How do I install model_bakery?
With pip install model-bakery. The package requires Python 3.11 or newer and depends on django>=5.2, and the classifiers list support for Django 5.2, 6.0 and 6.1 and for Python 3.11 through 3.15.
What does baker.make do in a Django test?
It creates a model instance with generated values for every field, so a test can call baker.make('shop.Customer') instead of constructing the object by hand. The README's example prints the resulting instance dictionary, showing a valid date, datetime, email and boolean, and a random string for the text field.
Which Python and Django versions does model_bakery support?
It follows the Python and Django release and support cycles, dropping support for a version when it reaches end-of-life. The current window is Django 5.2, 6.0 and 6.1 on Python 3.11 through 3.15.
How do I run the model_bakery test suite and its linters?
The Makefile has a test target that runs python -m pytest and a lint target that runs black, then ruff check, then ty check model_bakery. There is also a tox.ini for running against different environments, and a postgis-tests.sh script with a postgres-docker directory for testing against Postgres and PostGIS.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/model-bakers-model-bakery)