如何在Factory Boy中与Faker一起使用lazy_attribute
作者:互联网
语境:
我有一个有两个日期的模型,我想使用factory.Faker两个,但第二个日期应该总是大于第一个日期.
我试过这个:
型号摘录:
class Event(models.Model):
execution_start_date = models.DateTimeField()
execution_end_date = models.DateTimeField()
厂:
class EventFactory(factory.DjangoModelFactory):
class Meta:
model = Event
strategy = factory.BUILD_STRATEGY
execution_start_date = factory.Faker('date_time_this_year', tzinfo=pytz.utc)
@factory.lazy_attribute
def execution_end_date(self):
return factory.Faker('date_time_between_dates',
datetime_start=self.execution_start_date,
datetime_end=now(),
tzinfo=pytz.utc)
但是当我尝试使用python shell中的工厂时,我得到了这个:
In [3]: e = EventFactory()
In [4]: e.execution_end_date
Out[4]: <factory.faker.Faker at 0x1103f51d0>
我设法使其工作的唯一方法是这样:
@factory.lazy_attribute
def execution_end_date(self):
# return factory.Faker('date_time_between_dates',
# datetime_start=self.execution_start_date,
# datetime_end=now(),
# tzinfo=pytz.utc)
faker = factory.Faker._get_faker()
return faker.date_time_between_dates(datetime_start=self.execution_start_date,
datetime_end=now(),
tzinfo=pytz.utc)
但老实说,我认为有更好的方法可以做到这一点.
我的依赖是:
> Django(1.8.18)
>工厂男孩(2.8.1)
> Faker(0.7.17)
解决方法:
当lazy_attribute发挥作用时,你已经掌握了生成的对象.所以你可以使用例如random和timedelta,如下所示:
@factory.lazy_attribute
def execution_end_date(self):
max_days = (now() - self.execution_start_date).days
return self.execution_start_date + timedelta(random.randint(1, max_days))
或者其他一些生成随机日期的方法.没有必要坚持使用factory_boy.Faker
编辑
在我第一次回答之后,我设法找到了一种方法来做你想做的事情,这很简单.你只需要用Faker中的空dict调用generate()方法:
@factory.lazy_attribute
def execution_end_date(self):
return factory.Faker('date_time_between_dates',
datetime_start=self.execution_start_date,
datetime_end=now(),
tzinfo=pytz.utc).generate({})
标签:python,django,django-models,faker,factory-boy 来源: https://codeday.me/bug/20190622/1264628.html