Skip to content

# `nautobot.apps.factory`

Nautobot classes and utilities for factory boy.

## `nautobot.apps.factory.BaseModelFactory`

Bases: `DjangoModelFactory`

Base class for all Nautobot model factories.

## `nautobot.apps.factory.NautobotBoolIterator`

Bases: `Iterator`

Factory iterator that returns a semi-random sampling of boolean values

Iterator that returns a random sampling of True and False values while limiting the number of repeated values in a given number of iterations. Used in factories when a data set must contain both True and False values.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`cycle` | `boolean` | If True, iterator will restart at the beginning when all values are exhausted. Otherwise raise a `StopIterator` exception when values are exhausted. Defaults to True. | `True`
`chance_of_getting_true` | `int` | Percentage (0-100) of the values in the returned iterable set to True. Defaults to 50. | `NAUTOBOT_BOOL_ITERATOR_DEFAULT_PROBABILITY`
`length` | `int` | Length of the returned iterable. Defaults to 8. | `NAUTOBOT_BOOL_ITERATOR_DEFAULT_LENGTH`

## `nautobot.apps.factory.NautobotFakerProvider`

Bases: `BaseProvider`

Faker provider to generate fake data specific to Nautobot or network automation use cases.

### `ipv6_network()`

Produce a random IPv6 network with a valid CIDR greater than 0

## `nautobot.apps.factory.OrganizationalModelFactory`

Bases: `BaseModelFactory`

Factory base class for OrganizationalModel subclasses.

## `nautobot.apps.factory.PrimaryModelFactory`

Bases: `BaseModelFactory`

Factory base class for PrimaryModel subclasses.

## `nautobot.apps.factory.UniqueFaker`

Bases: `Faker`

https://github.com/FactoryBoy/factory_boy/pull/820#issuecomment-1004802669

## `nautobot.apps.factory.get_random_instances(model_or_queryset_or_lambda, minimum=0, maximum=None)`

Factory helper - retrieve a random number of instances of the given model.

This is different from random_instance() in that it's not itself a lazy function generator, but should instead be called only from within a @lazy_attribute or @post_generation function.

This is not an evenly weighted distribution (all counts equally likely), because in most of our code, the relevant code paths distinguish between 0, 1, or >1 instances - there's not a functional difference between "2 instances" and "10 instances" in most cases. Therefore, this implementation provides: - 1/3 chance of no instances - 1/3 chance of 1 instance - 1/3 chance of (2 to n) instances, where each possibility is equally likely within this range

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`model_or_queryset_or_lambda` | `Union[BaseModel, QuerySet, func]` | Either a model class, a model queryset, or a lambda that returns one of those | required
`minimum` | `int` | Minimum number of objects to return | `0`
`maximum` | `int` | Maximum number of objects to return, or None for no limit | `None`

## `nautobot.apps.factory.random_instance(model_or_queryset_or_lambda, allow_null=True)`

Factory helper - construct a LazyFunction that gets a random instance of the given model or queryset when evaluated.

TODO: once we have factories for all mandatory foreign keys, change allow_null default to False

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`model_or_queryset_or_lambda` | `Union[BaseModel, QuerySet, func]` | Either a model class, a model queryset, or a lambda that returns one of those | required
`allow_null` | `bool` | If False, and the given queryset contains no objects, raise a RuntimeError. | `True`

Example

class ObjectFactory(DjangoModelFactory): class Meta: model = Object exclude = ("has_group,")

    # Required foreign key
    user = random_instance(User, allow_null=False)

    # Optional foreign key
    has_group = NautobotBoolIterator()
    group = factory.Maybe("has_group", random_instance(Group), None)

    # Foreign key selected from a filtered queryset
    tenant = random_instance(Tenant.objects.filter(group__isnull=False))

    # Foreign key selected from a queryset generated by a lambda
    # This needs to be done this way because .get_for_model() evaluates a ContentType queryset,
    # and we need to defer evaluation of that queryset as well.
    status = random_instance(lambda: Status.objects.get_for_model(Object), allow_null=False)