Skip to content

Factory API

general_manager.factory.auto_factory.AutoFactory

Bases: DjangoModelFactory[modelsModel]

Factory that auto-populates model fields based on interface metadata.

The factory inspects the bound ORM interface, fills missing model fields with generated values or declared defaults, applies many-to-many relations after saved creation, and wraps created objects back into GeneralManager instances. Build strategy returns unsaved Django model instances and skips many-to-many assignment; create strategy returns manager wrappers. Subclasses are generated with an ORM interface that provides handle_custom_fields(), input_fields, format_identification(), and _parent_class for created-object wrapping.

__create_with_generate_func classmethod

__create_with_generate_func(use_creation_method, params)

Create or build model instance(s) using the configured adjustment method.

The adjustment method receives generated/default-filled kwargs after _adjust_kwargs() has stripped many-to-many entries and coerced foreign-key/one-to-one values. A returned list is processed in order and an empty list returns an empty list. Create-mode list processing is atomic, so later failures roll back earlier saves from the same adjustment-method result.

Parameters:

Name Type Description Default
use_creation_method bool

If True, created records are validated and saved; if False, unsaved instances are returned.

required
params FactoryParams

Keyword arguments forwarded to the adjustment method to produce record dict(s).

required

Returns:

Type Description
Model | list[Model]

models.Model | list[models.Model]: A single model instance or a list of instances — saved instances when use_creation_method is True, unsaved otherwise.

Raises:

Type Description
UndefinedAdjustmentMethodError

If no adjustment method has been configured on the factory.

AutoFactory is the generated factory base attached to ORM-backed managers as Manager.Factory. It fills missing fields from interface metadata, strips many-to-many values before model construction, applies many-to-many assignments after saved creation, and uses the interface's input_fields plus format_identification() to wrap saved objects back into manager instances. build() returns unsaved Django model instances; create() validates, saves, and returns GeneralManager wrappers. Batch calls keep the same distinction: build batches return model lists and create batches return manager lists. Factory relation reuse and sequence counters use the interface database alias when one is configured, so factories query and save against the same database.

The generation order is:

  1. _generate() validates Meta.model, asks the interface for custom-field metadata, and adds missing generated or declared defaults. Caller-supplied keyword arguments already present in the payload win over generated defaults. Missing foreign-key and one-to-one values use the configured related-factory mode.
  2. factory_boy dispatches to _build() or _create().
  3. _adjust_kwargs() removes many-to-many values from constructor kwargs and coerces foreign-key/one-to-one values.
  4. If _adjustmentMethod is configured, it receives those generated/default filled, many-to-many-stripped, relation-coerced kwargs and returns one or more record payloads. Otherwise the normalized kwargs are assigned directly.
  5. Create strategy calls full_clean() and save() for each record; build strategy only constructs unsaved model instances.
  6. _generate() applies many-to-many assignments to saved create-strategy model instances, then wraps those model instances into manager instances.

Call-time keyword arguments override generated defaults. Foreign-key and one-to-one values are normalized through the related model resolver, so callers may pass a Django model instance, a GeneralManager wrapper, or an identifier value that Django accepts.

Automatic relation defaults use reuse_existing mode unless configured otherwise. Foreign-key and one-to-one defaults prefer reusable existing related rows; one-to-one reuse excludes rows already linked through that one-to-one field. If no reusable row exists and the related model exposes a GeneralManager factory, AutoFactory creates a related row through that factory. Nullable relations and relations with a declared default of None keep their nullable behavior in default mode and may remain None even when related rows or factories are available. When the factory interface defines a database alias, existing-row lookup and one-to-one linked-row filtering use that alias.

Factories can change automatic relation generation with _related_factory_mode for all generated relations or _related_factory_modes for individual fields. "create" forces a new related object when a related factory exists and bypasses nullable/default-None relation short-circuiting. If no related factory exists, nullable relations may still resolve to None and required relations raise MissingFactoryOrInstancesError. "random" restores the legacy foreign-key behavior that may create through the related factory or reuse an existing related row.

Many-to-many keyword values are removed before instantiation and assigned after saved create() calls. A manager/queryset/list/tuple/set is expanded to a list; a scalar is treated as a one-item assignment. Values that cannot be resolved to Django model instances are passed through to Django's relation manager, so normal Django validation or assignment errors surface. Omitted blank many-to-many fields stay empty in default reuse_existing mode. A field-specific _related_factory_modes = {"field_name": "create"} entry can generate and assign many-to-many values after creation. build() returns unsaved model instances and skips many-to-many assignment.

Factory._adjustmentMethod, when defined, receives the normalized keyword arguments and returns either one dict[str, object] record payload or a list[dict[str, object]] for fan-out creation. AutoFactory does not validate that shape before using it: unsupported return values fail through normal Python unpacking, model assignment, full_clean(), save, or factory_boy errors. Lists are processed in order; an empty list returns an empty list. AutoFactory does not create a transaction around an adjustment-method list, so create-mode failures can leave earlier records saved. When create-strategy wrapping cannot find the parent manager class it raises MissingManagerClassError; when an identification value cannot be read from a generated model, it raises MissingIdentificationFieldError. Non-model factory outputs raise InvalidGeneratedObjectError, and invalid Meta.model configuration raises InvalidAutoFactoryModelError.

Created manager wrapping reads each key in interface.input_fields from the model instance, falling back to <name>_id; related model objects are converted to their primary keys. The mapping returned by interface.format_identification() must be accepted as keyword arguments by the parent manager constructor. Factory class attributes are used as declared defaults only when they are present and not callable, classmethod, or staticmethod. A declared value of None is treated the same as no declared default by the current generation path.

AutoFactory._setup_next_sequence() returns at least the target model's current row count, using interface._get_database_alias() when the interface provides a database alias. For example, if one row already exists, the first generated factory_boy sequence index is 1. Override _setup_next_sequence() in a custom factory when uniqueness depends on parsing existing field values, such as extracting numeric suffixes from names or codes, rather than on the simple row count.

general_manager.factory.factories contains lower-level generation helpers used by AutoFactory. They are importable for advanced factory customization, but application factory classes should prefer the exported lazy helpers below when a specific generated default is needed.

get_field_value(field) accepts a Django Field or relation descriptor and returns a factory_boy declaration, model instance, scalar default, or None that can be assigned to that field by factory_boy. It handles choices, measurement fields, common scalar fields, regex-backed CharFields, nullable fields, foreign keys, and one-to-one relations. It does not generate many-to-many assignment lists; if a many-to-many field is passed here it returns None, and callers should use get_many_to_many_field_value() for ManyToManyField values. Unsupported scalar or custom Django field classes also return None. Relation fields default to relation_generation="reuse_existing": nullable/default-None relations may return None, reusable existing rows are preferred, and a related GeneralManager factory is used only when no reusable row exists. relation_generation="create" forces related-factory creation when available; relation_generation="random" provides legacy foreign-key behavior that may create or reuse. The optional database_alias argument scopes existing related-row lookup to a specific Django database alias. Nullable foreign-key and one-to-one fields with no factory and no existing rows return None, while non-nullable relation fields in the same situation raise MissingFactoryOrInstancesError. Missing relation metadata raises MissingRelatedModelError; non-model relation targets and non-relational scalar fields passed to relation helpers raise InvalidRelatedModelTypeError.

get_many_to_many_field_value(field) accepts a Django ManyToManyField and returns related model instances for assignment after object creation. In default mode it samples existing related rows when any exist; if no existing rows are available, it creates rows through the related GeneralManager factory when one is registered. relation_generation="create" bypasses existing rows and uses the related factory. The optional database_alias argument scopes existing-row sampling to that alias. The helper raises MissingFactoryOrInstancesError when no related factory or existing rows are available. GeneralManager factory outputs are normalized to Django model instances; if a manager output cannot be resolved to its model row, UnableToResolveManagerInstanceError is raised. blank=True fields may generate an empty list; blank=False fields request at least one related instance.

The factory helper exception classes are stable by type. Their messages are diagnostic and are not a stable parsing contract.

general_manager.factory.factories.get_field_value

get_field_value(
    field,
    *,
    relation_generation="reuse_existing",
    database_alias=None
)

Generate a realistic sample value appropriate for the given Django model field or relation.

This returns a value suitable for assignment to the field: common scalar and text fields produce Faker-generated declarations; CharField respects max_length and RegexValidator; MeasurementField returns a LazyFunction that produces a Measurement in the field's base unit; and OneToOneField/ForeignKey values return model instances or LazyFunction wrappers that either create instances via a GeneralManager factory or select existing related instances. Unsupported scalar or custom field types return None. Many-to-many fields are not generated here; passing one returns None, and callers should use get_many_to_many_field_value() for many-to-many assignment values.

Nullable fields have a 10% chance to return None. Nullable relation fields whose declared default is None return None immediately. Nullable foreign-key or one-to-one fields with no factory and no existing rows return None; non-nullable relation fields in the same situation raise MissingFactoryOrInstancesError. blank does not change foreign-key or one-to-one generation behavior.

Parameters:

Name Type Description Default
field DjangoField | ForeignObjectRel

A Django scalar field, foreign-key field, one-to-one field, or relation descriptor to generate a value for. Many-to-many fields are accepted by the broad type shape but intentionally return None here; pass them to get_many_to_many_field_value() instead.

required
relation_generation RelationGenerationMode

Strategy for relation fields. Defaults to reusing existing related rows before creating new related rows.

'reuse_existing'
database_alias str | None

Optional Django database alias used when querying existing related rows.

None

Returns:

Type Description
object

A value suitable for assignment to the field (scalar, string, Measurement-producing LazyFunction, model instance, LazyFunction that yields a related instance, or None).

Raises:

Type Description
MissingFactoryOrInstancesError

When a related field's model has neither a registered factory nor any existing instances.

MissingRelatedModelError

When a relational field does not declare a related model.

InvalidRelatedModelTypeError

When a relational field's related value is not a Django model class.

general_manager.factory.factories.get_many_to_many_field_value

get_many_to_many_field_value(
    field,
    *,
    relation_generation="reuse_existing",
    database_alias=None
)

Generate a list of related model instances suitable for assigning to a ManyToManyField.

The function selects a random number of related objects (at least one when the field is not blank, up to 10). Default generation samples existing related rows when they are available and creates through the related model's factory only when no existing rows are available. Create mode bypasses existing rows and uses the related factory. blank=True allows an empty result; blank=False requires at least one related instance.

Parameters:

Name Type Description Default
field ManyToManyField

The ManyToMany field to generate values for.

required
relation_generation RelationGenerationMode

Strategy for relation values. Defaults to reusing existing related rows before creating new related rows.

'reuse_existing'
database_alias str | None

Optional Django database alias used when querying existing related rows.

None

Returns:

Type Description
list[Model]

list[models.Model]: A list of related model instances to assign to the field.

Raises:

Type Description
MissingFactoryOrInstancesError

If the related model provides neither a factory nor any existing instances.

MissingRelatedModelError

If the field does not declare a related model.

InvalidRelatedModelTypeError

If the resolved related model is not a Django model class.

UnableToResolveManagerInstanceError

If a related GeneralManager factory returns a manager instance that cannot be resolved to its Django model row.

get_related_model(field)

Resolve and return the Django model class referenced by a relational field.

If the field's declared related model is the string "self", this resolves it to the field's model before validation.

Parameters:

Name Type Description Default
field ForeignObjectRel | DjangoField | ManyToManyField[Model, Model]

Relational field or relation descriptor to inspect. Passing a non-relational scalar field is unsupported.

required

Returns:

Type Description
type[Model]

type[models.Model]: The related Django model class.

Raises:

Type Description
MissingRelatedModelError

If the field does not declare a related model.

InvalidRelatedModelTypeError

If the resolved related model is not a Django model class, including non-relational scalar fields whose related_model value is None or absent.

general_manager.factory.factories.MissingFactoryOrInstancesError

Bases: ValueError

Raised when a related model offers neither a factory nor existing instances.

Public callers should handle this by exception type; the message is diagnostic and not a stable parsing contract.

__init__

__init__(related_model)

Exception raised when a related model has neither a registered factory nor any existing instances.

Parameters:

Name Type Description Default
related_model type[Model]

The Django model class that lacks both a factory and existing instances.

required

general_manager.factory.factories.MissingRelatedModelError

Bases: ValueError

Raised when a relational field lacks a related model definition.

Public callers should handle this by exception type; the message is diagnostic and not a stable parsing contract.

__init__

__init__(field_name)

Initialize the exception for a field that does not declare a related model.

Parameters:

Name Type Description Default
field_name str

The name of the field missing a related model; included in the exception message.

required

general_manager.factory.factories.InvalidRelatedModelTypeError

Bases: TypeError

Raised when a relational field references an incompatible model type.

This also covers scalar/non-relational fields passed to relation helpers. Public callers should handle this by exception type; the message is diagnostic and not a stable parsing contract.

__init__

__init__(field_name, related)

Initialize the exception indicating a relational field references a non-model type.

Parameters:

Name Type Description Default
field_name str

Name of the relational field that declared an invalid related model.

required
related object

The value provided as the related model; its repr is included in the exception message.

required

general_manager.factory.factories.UnableToResolveManagerInstanceError

Bases: ValueError

Raised when a GeneralManager instance cannot be converted back into its model.

Public callers should handle this by exception type; the message is diagnostic and not a stable parsing contract.

__init__

__init__(manager)

Initialize with the offending factory output.

Parameters:

Name Type Description Default
manager object

The manager or factory output that could not be resolved.

required

general_manager.factory.factory_methods.lazy_measurement

lazy_measurement(min_value, max_value, unit)

Return a lazy declaration that evaluates to a Measurement.

The evaluated value is a general_manager.measurement.measurement.Measurement with a magnitude sampled uniformly between the supplied inclusive bounds. The sampled number is formatted as a six-decimal string before it is passed to Measurement, so the resulting Measurement.magnitude follows Measurement's normal Decimal conversion rules.

Parameters:

Name Type Description Default
min_value int | float

Lower bound for the sampled magnitude.

required
max_value int | float

Upper bound for the sampled magnitude.

required
unit str

Unit string passed directly to Measurement.

required

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration.

Raises:

Type Description
ValueError

If min_value > max_value.

Exception

Errors from Measurement can be raised during evaluation when the sampled magnitude or unit is not accepted by the measurement layer.

general_manager.factory.factory_methods.lazy_delta_date

lazy_delta_date(avg_delta_days, base_attribute)

Return a lazy declaration that offsets another generated date-like value.

During evaluation, the declaration reads base_attribute from the generated object. If the attribute is missing or falsey, date.today() is evaluated and used as the base. Truthy base values must support adding a datetime.timedelta, such as date or datetime; invalid truthy values raise their normal TypeError during evaluation.

Parameters:

Name Type Description Default
avg_delta_days int

Average number of days for the offset. The actual offset is an integer chosen uniformly between avg_delta_days // 2 and avg_delta_days * 3 // 2, inclusive.

required
base_attribute str

Name of the generated object's base date/datetime attribute.

required

Returns:

Type Description
LazyAttribute

A factory.declarations.LazyAttribute declaration. It evaluates to the

LazyAttribute

base value plus the random day offset.

Raises:

Type Description
ValueError

If avg_delta_days is negative.

general_manager.factory.factory_methods.lazy_project_name

lazy_project_name()

Return a lazy declaration that evaluates to a pseudo-random project name.

The value uses the module-level default-locale Faker instance plus a random suffix. No deterministic seed is set by this helper.

general_manager.factory.factory_methods.lazy_date_today

lazy_date_today()

Return a lazy declaration that evaluates to date.today().

The date is read from Python's local system date at declaration evaluation time, not when the helper is called.

general_manager.factory.factory_methods.lazy_date_between

lazy_date_between(start_date, end_date)

Return a lazy declaration that evaluates to a random date in a range.

The date is chosen uniformly at evaluation time from the inclusive day range. If start_date is after end_date, the endpoints are swapped before choosing the value.

Parameters:

Name Type Description Default
start_date date

Start of the inclusive date range.

required
end_date date

End of the inclusive date range.

required

Returns:

Type Description
LazyAttribute

A factory.declarations.LazyAttribute declaration that evaluates to a

LazyAttribute

date between the normalized endpoints, inclusive.

general_manager.factory.factory_methods.lazy_date_time_between

lazy_date_time_between(start, end)

Return a lazy declaration that evaluates to a random datetime in a range.

The datetime is chosen uniformly at evaluation time with whole-second granularity. If start is after end, the endpoints are swapped before choosing the value. Python's normal datetime subtraction rules apply, so mixed naive/aware inputs raise TypeError.

Parameters:

Name Type Description Default
start datetime

Start of the inclusive datetime range.

required
end datetime

End of the inclusive datetime range.

required

Returns:

Type Description
LazyAttribute

A factory.declarations.LazyAttribute declaration that evaluates to a

LazyAttribute

datetime between the normalized endpoints, inclusive.

general_manager.factory.factory_methods.lazy_integer

lazy_integer(min_value, max_value)

Return a lazy declaration that evaluates to a random integer.

Parameters:

Name Type Description Default
min_value int

Inclusive lower bound.

required
max_value int

Inclusive upper bound.

required

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration that evaluates to an

LazyFunction

integer selected uniformly between min_value and max_value,

LazyFunction

inclusive.

Raises:

Type Description
ValueError

If min_value > max_value.

general_manager.factory.factory_methods.lazy_decimal

lazy_decimal(min_value, max_value, precision=2)

Return a lazy declaration that evaluates to a random Decimal.

The sampled float is drawn uniformly between the supplied inclusive bounds, formatted with exactly precision decimal places, and then converted through Decimal(str_value).

Parameters:

Name Type Description Default
min_value float

Lower bound of the generated value.

required
max_value float

Upper bound of the generated value.

required
precision int

Number of decimal places in the formatted value.

2

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration that evaluates to a

LazyFunction

Decimal.

Raises:

Type Description
ValueError

If min_value > max_value.

ValueError

If precision is negative.

general_manager.factory.factory_methods.lazy_choice

lazy_choice(options)

Return a lazy declaration that evaluates to one random option.

The options are snapshotted as a tuple when this helper is called. Later mutations to the caller's sequence do not affect generated values.

Parameters:

Name Type Description Default
options Sequence[_ChoiceT]

Non-empty candidate values to choose from.

required

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration that evaluates to one

LazyFunction

element selected uniformly from the declaration-time options snapshot.

Raises:

Type Description
ValueError

If options is empty.

general_manager.factory.factory_methods.lazy_sequence

lazy_sequence(start=0, step=1)

Return a sequence declaration that evaluates to successive integers.

Each evaluated value equals start + index * step, where index is the zero-based factory_boy sequence counter for that attribute.

Parameters:

Name Type Description Default
start int

Initial value of the sequence.

0
step int

Increment between successive values.

1

Returns:

Type Description
LazyAttributeSequence

A factory.declarations.LazyAttributeSequence declaration.

general_manager.factory.factory_methods.lazy_boolean

lazy_boolean(trues_ratio=0.5)

Return a lazy declaration that evaluates to a random boolean.

Parameters:

Name Type Description Default
trues_ratio float

Probability that the generated value is True. Must be in the inclusive [0, 1] interval.

0.5

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration that evaluates to a

LazyFunction

boolean by comparing _RNG.random() < trues_ratio.

Raises:

Type Description
ValueError

If trues_ratio is outside the inclusive [0, 1] interval.

general_manager.factory.factory_methods.lazy_uuid

lazy_uuid()

Return a lazy declaration that evaluates to an RFC 4122 version 4 UUID string.

Returns:

Type Description
LazyFunction

A factory.declarations.LazyFunction declaration that evaluates to a

LazyFunction

UUID4 string in standard 36-character representation.

general_manager.factory.factory_methods.lazy_faker_name

lazy_faker_name()

Return a lazy declaration that evaluates to a Faker-generated name.

Uses the module-level default-locale Faker instance. No deterministic seed is set by this helper.

general_manager.factory.factory_methods.lazy_faker_email

lazy_faker_email(name=None, domain=None)

Return a lazy declaration that evaluates to an email address.

When neither override is supplied, Faker generates the full email address. When name or domain is supplied, missing pieces are generated once when this helper is called. The name part is converted by replacing spaces with underscores, and domain should be a hostname without a leading @.

general_manager.factory.factory_methods.lazy_faker_sentence

lazy_faker_sentence(number_of_words=6)

Return a lazy declaration that evaluates to a Faker-generated sentence.

Uses the module-level default-locale Faker instance and requests number_of_words words from Faker at evaluation time.

general_manager.factory.factory_methods.lazy_faker_address

lazy_faker_address()

Return a lazy declaration that evaluates to a Faker-generated postal address.

Uses the module-level default-locale Faker instance.

general_manager.factory.factory_methods.lazy_faker_url

lazy_faker_url()

Return a lazy declaration that evaluates to a Faker-generated URL.

Uses the module-level default-locale Faker instance.