使用factory-boy的FuzzyDateTime调用create_batch时日期始终相同
解决factory-boy批量创建时FuzzyDateTime返回相同日期的问题
问题现象
调用create_batch批量创建Django模型实例时,直接传入factory.fuzzy.FuzzyDateTime作为字段参数,所有实例的对应日期字段值会完全一致(仅毫秒数可能因创建顺序有微小差异)。
原因分析
factory-boy在处理create_batch的关键字参数时,会对传入的模糊器实例仅执行一次generate()方法生成值,随后将这个值复用给所有批量创建的实例,导致所有对象共享同一个日期值。
解决方案
方案一:用LazyAttribute动态生成模糊日期
通过factory.LazyAttribute包装模糊器的生成逻辑,确保每个实例创建时都会重新生成一个模糊日期:
import datetime import pytz import factory from . import models class FooFactory(factory.django.DjangoModelFactory): class Meta: model = models.Foo # 批量创建逻辑 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.LazyAttribute( lambda _: factory.fuzzy.FuzzyDateTime(start_dt=one_week_ago, end_dt=now).generate({}) ) )
方案二:用可调用函数生成模糊日期
定义一个返回模糊日期的函数,直接将函数传入字段参数,factory-boy会在每个实例创建时调用该函数:
import datetime import pytz import factory from . import models class FooFactory(factory.django.DjangoModelFactory): class Meta: model = models.Foo def generate_fuzzy_dt(): now = datetime.datetime.now(tz=pytz.timezone("America/New_York")) one_week_ago = now - datetime.timedelta(days=7) return factory.fuzzy.FuzzyDateTime(start_dt=one_week_ago, end_dt=now).generate({}) # 批量创建 FooFactory.create_batch(10, dt_field=generate_fuzzy_dt)
验证效果
执行上述代码后,查询所有Foo实例的dt_field,会得到不同的模糊日期值:
>>> [r.dt_field for r in models.Foo.objects.all()] >>> [datetime.datetime(2022, 12, 8, 15, 20, 10, tzinfo=<UTC>), datetime.datetime(2022, 12, 12, 9, 35, 40, tzinfo=<UTC>), ...]
内容的提问来源于stack exchange,提问作者mprat
相关产品推荐
相关产品推荐

