Skip to main content

Django-Modeler

Django-modeler generates ORM code from an object instance, optionally including foreign key dependencies.

Example

$ django-modeler myapp.testmodel
from myapp.models import TestModel
from django.contrib.auth.models import User
from decimal import Decimal
import datetime


user1, created = User.objects.get_or_create(
    id=1,
    username=u'mike',
    first_name=u'',
    last_name=u'',
    email=u'mike@localhost.com',
    password=u'sha1$911c9$614a16c3c074f2972e14efbe97f4fa92b266b93f',
    is_staff=True,
    is_active=True,
    is_superuser=True,
    last_login=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
    date_joined=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
)

testmodel1, created = TestModel.objects.get_or_create(
    id=1,
    user=user1,
)

As requested, modeler found the TestModel instances and generated ORM code to recreate it (if it doesn't already exist). Modeler also generated code for the User object since it was referenced by TestModel.

Why?

This is a much nicer way of including test data. You probably already have a working site and some data for production, but dumpdata will serialize the data for an entire app. That's too much just to write a quick test!

Many people end up with an old, out-of-date copy of their production data in their test fixtures that nobody dares to change. And because fixtures can be a pain to keep up to date with site changes, it's common place to see a bunch of tests depend on the same fixtures. Sometimes entire projects will depend on just one or two fixtures.

Unfortunately, if a refactor needs a fixture change due to model changes, changing the fixture could cause other tests to fail that are unrelated to the refactor. Worse, it's difficult to edit the json directly, cumbersome to load and modify it, and refactoring tools won't update fixtures.

Instead, it's better to have each test use it's own data unrelated to other apps in the project. Django-modeler makes this easier to handle by generating Django ORM code that can be included in tests (or for other purposes).

Install

To get this awesome for your very own, pip install django-modeler or python setup.py install from source.

USAGE

Modeler supports a few command line options:

Usage: manage.py modeler [options] <model [filter option] [filter option] ...>

Writes data to ORM code to the console

Options:
  -v VERBOSITY, --verbosity=VERBOSITY
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=all output
  --settings=SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath=PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Print traceback on exception
  -f FILTER, --filter=FILTER
                        Filter objects
  -e EXCLUDE, --exclude=EXCLUDE
                        Exclude objects
  -r RELATED, --related=RELATED
                        number of object relationship levels to pull (does not
                        resolve circular references).
  --exclude-related=EXCLUDE_RELATED
                        exclude a package or specific model when searching for
                        related objects (format: app_label or app_label.model)
  --exclude-field=EXCLUDE_FIELD
                        exclude field types from ever appearing in output
                        (format: app_label or app_label.model)
  --version             show program's version number and exit
  -h, --help            show this help message and exit

Most important is the name of the model to start with. Modeler works by starting at an object instance and building a dependency tree from that point. The tree can have many starting points, or it can start from a single instance. The easiest way to filter for a single object is by using the -f filter. For example:

$ django-modeler auth.user -f pk=1
from django.contrib.auth.models import User
from decimal import Decimal
import datetime

user1, created = User.objects.get_or_create(
    id=1,
    username=u'mike',
    first_name=u'',
    last_name=u'',
    email=u'mike@localhost.com',
    password=u'sha1$911c9$614a16c3c074f2972e14efbe97f4fa92b266b93f',
    is_staff=True,
    is_active=True,
    is_superuser=True,
    last_login=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
    date_joined=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
)

The -f filter and -e exclude options are fed directly to Django's ORM filter and exclude methods on QuerySet and support the same options.

With the -r related option, Modeler will attempt to also use ForeignKey references in it's output. In the example above, pulling the auth.user instance only found a single object to serialize. But given the same command with a related depth of 1, Modeler will find more objects that reference this particular user instance:

$ django-modeler auth.user -f pk=1 -r1
from django.contrib.auth.models import User
from myapp.models import TestModel
from decimal import Decimal
import datetime


user1, created = User.objects.get_or_create(
    id=1,
    username=u'mike',
    first_name=u'',
    last_name=u'',
    email=u'mike@localhost.com',
    password=u'sha1$911c9$614a16c3c074f2972e14efbe97f4fa92b266b93f',
    is_staff=True,
    is_active=True,
    is_superuser=True,
    last_login=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
    date_joined=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
)

testmodel1, created = TestModel.objects.get_or_create(
    id=1,
    user=user1,
)

With -r2 Modeler will find another object instance that depends on the TestModel in the above:

$ django-modeler auth.user -f pk=1 -r2
from myapp.models import RelatedToTestModel
from django.contrib.auth.models import User
from myapp.models import TestModel
from decimal import Decimal
import datetime


user1, created = User.objects.get_or_create(
    id=1,
    username=u'mike',
    first_name=u'',
    last_name=u'',
    email=u'mike@localhost.com',
    password=u'sha1$911c9$614a16c3c074f2972e14efbe97f4fa92b266b93f',
    is_staff=True,
    is_active=True,
    is_superuser=True,
    last_login=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
    date_joined=datetime.datetime(2011, 8, 18, 20, 39, 14, 352576),
)

testmodel1, created = TestModel.objects.get_or_create(
    id=1,
    user=user1,
)

relatedtotestmodel1, created = RelatedToTestModel.objects.get_or_create(
    id=1,
    test_model=testmodel1,
    name=u'related_one',
)

relatedtotestmodel2, created = RelatedToTestModel.objects.get_or_create(
    id=2,
    test_model=testmodel1,
    name=u'related_two',
)

Other options are --exclude-related and --exclude-field. These both require an app_label.model argument. Exclude related will ignore models found that match the app_label or model name when Modeler is searching foreign key relationships, like in the above example both TestModel and RelatedToTestModel were found during the related search.

Using --exclude-field prevents a model or app from ever showing up in the output, regardless of how it was found.

LIMITATIONS

At this time, Modeler does not attempt to resolve circular dependencies when using -r. It may be necessary to limit the depth that Modeler will travel in order to avoid an exception because of the model dependencies.

WHAT CAN I DO WITH IT?

The original use case was to create test data. Use Modeler to create a data.py file in a tests folder:

$ django-modeler auth.user -f pk=1 -r2 > tests/data.py

data.py probably needs a load() method. The tests are a good example of this style usage.

Next, in the test that requires this data, add a setupUp method to load and use the data:

def setUp(self):
    data.load()

SUPPORT

Please use Github.

Metadata

Release files for django-modeler 0.12

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-modeler 0.12
File Size Uploaded Provenance
django-modeler-0.12.tar.gz 11.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django-modeler 0.12
File Interpreter ABI Platform
django_modeler-0.12-py3-none-any.whl Python 3 none any Details

Total release size: 21.4 kB

Release files / django-modeler-0.12.tar.gz

Download URL django-modeler-0.12.tar.gz
Size 11.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b86a8cbe56ce62df2d811493244a4ae1ef4f771805d62df172078937a336e2c0
BLAKE2b-256 checksum
How to use checksums
7a378c0e5ac29f6c1b9942a690d6b7c508b7720bb5bcad99adcf7a481334017a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.2

Release files / django_modeler-0.12-py3-none-any.whl

Download URL django_modeler-0.12-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48bc5ad7004c639d38fdab14f512807520cd31594f375cfc04fc64957a5d2b9a
BLAKE2b-256 checksum
How to use checksums
c2ac3ca617ad34b9559aa268889d9e84697b4bee80d26942a7941ff0b0679c16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.2

Security for django-modeler 0.12

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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