Skip to main content

A model instances generator for Django

Project description

https://badge.fury.io/py/django-fakery.svg https://travis-ci.org/fcurella/django-fakery.svg?branch=master https://coveralls.io/repos/fcurella/django-fakery/badge.svg?branch=master&service=github

An easy-to-use implementation of Creation Methods (aka Object Factory) for Django, backed by Faker.

django_fakery will try to guess the field’s value based on the field’s name and type.

Installation

Install with:

$ pip install django-fakery

QuickStart

from django_fakery import factory
from myapp.models import MyModel

factory.m(MyModel)(field='value')

If you’re having issues with circular imports, you can also reference a model by using the M utility function:

from django_fakery import factory, M

factory.m(M("myapp.MyModel"))(field="value")

If you really don’t want to import things, you could also just reference a model by using the <app_label>.<ModelName> syntax. This is not encouraged, as it will likely break type-hinting:

from django_fakery import factory

factory.m("myapp.MyModel")(field="value")

If you use pytest, you can use the fakery fixture (requires pytest and pytest-django):

import pytest
from myapp.models import MyModel

@pytest.mark.django_db
def test_mymodel(fakery):
    fakery.m(MyModel)(field='value')

If you’d rather, you can use a more wordy API:

from django_fakery import factory
from myapp.models import MyModel

factory.make(
    MyModel,
    fields={
        'field': 'value',
    }
)

We will use the short API thorough the documentation.

The value of a field can be any python object, a callable, or a lambda:

from django.utils import timezone
from django_fakery import factory
from myapp.models import MyModel

factory.m(MyModel)(created=timezone.now)

When using a lambda, it will receive two arguments: n is the iteration number, and f is an instance of faker:

from django.contrib.auth.models import User

user = factory.m(User)(
    username=lambda n, f: 'user_{}'.format(n),
)

django-fakery includes some pre-built lambdas for common needs. See shortcuts for more info.

You can create multiple objects by using the quantity parameter:

from django_fakery import factory
from django.contrib.auth.models import User

factory.m(User, quantity=4)

For convenience, when the value of a field is a string, it will be interpolated with the iteration number:

from myapp.models import MyModel

user = factory.m(User, quantity=4)(
    username='user_{}',
)

Foreign keys

Non-nullable ForeignKey s create related objects automatically.

If you want to explicitly create a related object, you can pass a factory like any other value:

from django.contrib.auth.models import User
from food.models import Pizza

pizza = factory.m(Pizza)(
    chef=factory.m(User)(username='Gusteau'),
)

If you’d rather not create related objects and reuse the same value for a foreign key, you can use the special value django_fakery.rels.SELECT:

from django_fakery import factory, rels
from food.models import Pizza

pizza = factory.m(Pizza, quantity=5)(
    chef=rels.SELECT,
)

django-fakery will always use the first instance of the related model, creating one if necessary.

ManyToManies

Because ManyToManyField s are implicitly nullable (ie: they’re always allowed to have their .count() equal to 0), related objects on those fields are not automatically created for you.

If you want to explicitly create a related objects, you can pass a list as the field’s value:

from food.models import Pizza, Topping

pizza = factory.m(Pizza)(
    toppings=[
        factory.m(Topping)(name='Anchovies')
    ],
)

You can also pass a factory, to create multiple objects:

from food.models import Pizza, Topping

pizza = factory.m(Pizza)(
    toppings=factory.m(Topping, quantity=5),
)

Shortcuts

django-fakery includes some shortcut functions to generate commonly needed values.

future_datetime(end='+30d')

Returns a datetime object in the future (that is, 1 second from now) up to the specified end. end can be a string, anotther datetime, or a timedelta. If it’s a string, it must start with +, followed by and integer and a unit, Eg: '+30d'. Defaults to '+30d'

Valid units are:

  • 'years', 'y'

  • 'weeks', 'w'

  • 'days', 'd'

  • 'hours', 'hours'

  • 'minutes', 'm'

  • 'seconds', 's'

Example:

from django_fakery import factory, shortcuts
from myapp.models import MyModel

factory.m(MyModel)(field=shortcuts.future_datetime('+1w'))

future_date(end='+30d')

Returns a date object in the future (that is, 1 day from now) up to the specified end. end can be a string, another date, or a timedelta. If it’s a string, it must start with +, followed by and integer and a unit, Eg: '+30d'. Defaults to '+30d'

past_datetime(start='-30d')

Returns a datetime object in the past between 1 second ago and the specified start. start can be a string, another datetime, or a timedelta. If it’s a string, it must start with -, followed by and integer and a unit, Eg: '-30d'. Defaults to '-30d'

past_date(start='-30d')

Returns a date object in the past between 1 day ago and the specified start. start can be a string, another date, or a timedelta. If it’s a string, it must start with -, followed by and integer and a unit, Eg: '-30d'. Defaults to '-30d'

Lazies

You can refer to the created instance’s own attributes or method by using Lazy objects.

For example, if you’d like to create user with email as username, and have them always match, you could do:

from django_fakery import factory, Lazy
from django.contrib.auth.models import User

factory.m(auth.User)(
    username=Lazy('email'),
)

If you want to assign a value returned by a method on the instance, you can pass the method’s arguments to the Lazy object:

from django_fakery import factory, Lazy
from myapp.models import MyModel

factory.m(MyModel)(
    myfield=Lazy('model_method', 'argument', keyword='keyword value'),
)

Pre-save and Post-save hooks

You can define functions to be called right before the instance is saved or right after:

from django.contrib.auth.models import User
from django_fakery import factory

factory.m(
    User,
    pre_save=[
        lambda u: u.set_password('password')
    ],
)(username='username')

Since settings a user’s password is such a common case, we special-cased that scenario, so you can just pass it as a field:

from django.contrib.auth.models import User
from django_fakery import factory

factory.m(User)(
    username='username',
    password='password',
)

Get or Make

You can check for existance of a model instance and create it if necessary by using the g_m (short for get_or_make) method:

from myapp.models import MyModel

myinstance, created = factory.g_m(
    MyModel,
    lookup={
        'myfield': 'myvalue',
    }
)(myotherfield='somevalue')

If you’re looking for a more explicit API, you can use the .get_or_make() method:

from myapp.models import MyModel

myinstance, created = factory.get_or_make(
    MyModel,
    lookup={
        'myfield': 'myvalue',
    },
    fields={
        'myotherfield': 'somevalue',
    },
)

Get or Update

You can check for existence of a model instance and update it by using the g_u (short for get_or_update) method:

from myapp.models import MyModel

myinstance, created = factory.g_u(
    MyModel,
    lookup={
        'myfield': 'myvalue',
    }
)(myotherfield='somevalue')

If you’re looking for a more explicit API, you can use the .get_or_update() method:

from myapp.models import MyModel

myinstance, created = factory.get_or_update(
    MyModel,
    lookup={
        'myfield': 'myvalue',
    },
    fields={
        'myotherfield': 'somevalue',
    },
)

Non-persistent instances

You can build instances that are not saved to the database by using the .b() method, just like you’d use .m():

from django_fakery import factory
from myapp.models import MyModel

factory.b(MyModel)(
    field='value',
)

Note that since the instance is not saved to the database, .build() does not support ManyToManies or post-save hooks.

If you’re looking for a more explicit API, you can use the .build() method:

from django_fakery import factory
from myapp.models import MyModel

factory.build(
    MyModel,
    fields={
        'field': 'value',
    }
)

Blueprints

Use a blueprint:

from django.contrib.auth.models import User
from django_fakery import factory

user = factory.blueprint(User)

user.make(quantity=10)

Blueprints can refer other blueprints:

from food.models import Pizza

pizza = factory.blueprint(Pizza).fields(
        chef=user,
    )
)

You can also override the field values you previously specified:

from food.models import Pizza

pizza = factory.blueprint(Pizza).fields(
        chef=user,
        thickness=1
    )
)

pizza.m(quantity=10)(thickness=2)

Or, if you’d rather use the explicit api:

from food.models import Pizza

pizza = factory.blueprint(Pizza).fields(
        chef=user,
        thickness=1
    )
)

thicker_pizza = pizza.fields(thickness=2)
thicker_pizza.make(quantity=10)

Seeding the faker

from django.contrib.auth.models import User
from django_fakery import factory

factory.m(User, seed=1234, quantity=4)(
    username='regularuser_{}'
)

Credits

The API is heavily inspired by model_mommy.

License

This software is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-fakery-2.3.0.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

django_fakery-2.3.0-py2.py3-none-any.whl (16.9 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django-fakery-2.3.0.tar.gz.

File metadata

  • Download URL: django-fakery-2.3.0.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.41.0 CPython/3.8.1

File hashes

Hashes for django-fakery-2.3.0.tar.gz
Algorithm Hash digest
SHA256 e103468b90779a7bf25fa1507a06deb0b67afe2fa56e40a99ef44553cc835cf8
MD5 5bbad9ca9d7dff266acf7e2ea5a6c928
BLAKE2b-256 11e734ff1b0ba274578ca6bc4e7d9cdd1b320740d497c1a5dac6842b12003e4b

See more details on using hashes here.

Provenance

File details

Details for the file django_fakery-2.3.0-py2.py3-none-any.whl.

File metadata

  • Download URL: django_fakery-2.3.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 16.9 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.41.0 CPython/3.8.1

File hashes

Hashes for django_fakery-2.3.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 5563aa4d6d6750d30520fbf0ff851b1d3a0bbff128c2e842750339d1a4e0a092
MD5 97130023aa164327fdd69464f6fa1c11
BLAKE2b-256 4861ecd0dfd6718617096123032cf6fda10a20cefaea79b4879ee11f3f74fbdc

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page