如何在Factory Boy中使用lazy_attribute和Faker

时间:2017-07-12 22:34:56

标签: python django django-models faker factory-boy

上下文: 我有一个有两个日期的模型,我想对它们使用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)
  • factory-boy(2.8.1)
  • Faker(0.7.17)

1 个答案:

答案 0 :(得分:5)

当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({})