I am using factory-boy for creating instances of a Django model, and I am always getting the same value returned when using factory.fuzzy.FuzzyDateTime
.
Minimal example:
# factory class
class FooFactory(DjangoModelFactory):
class Meta:
# models.Foo has a dt_field that is a DateTimeField
model = models.Foo
# creation of object, in unit tests
# I can't move the dt_field declaration
# into the factory definition since different
# unit tests use different start / end points
# for the datetime fuzzer
now = datetime.datetime.now(tz=pytz.timezone("America/New_York"))
one_week_ago = now - datetime.timedelta(days=7)
FooFactory.create_batch(
10,
dt_field=factory.fuzzy.FuzzyDateTime(
start_dt=one_week_ago, end_dt=now
)
)
When inspecting the Foo models after factory creation, the dt_field
has the same date:
>>> [r.dt_field for r in Foo.objects.all()]
>>> [datetime.datetime(2022, 12, 10, 20, 15, 31, 954301, tzinfo=<UTC>), datetime.datetime(2022, 12, 10, 20, 15, 31, 961147, tzinfo=<UTC>),
datetime.datetime(2022, 12, 10, 20, 15, 31, 967383, tzinfo=<UTC>), ...]
The core issue was that the model in my code had auto_now_add=True
in the model definition. This is a Django internal that always overrides the provided value and therefore can't be used with factory-boy.
Instead, the auto_now_add
field is removed in favor of default=timezone.now
, and the field can be fuzzed with factory-boy correctly.