Django FactoryBoy-随机选择不适用于LazyFunction

时间:2019-03-12 16:10:54

标签: python django factory-boy

我正在为django应用程序构建许多测试,并且正在使用FactoryBoy

Profile模型具有一个gender字段,其定义如下:

class Profile(models.Model):

  GENDER_CHOICES = (
    (u'm', _(u'Male')),
    (u'f', _(u'Female')),
  ) 

 gender = models.CharField(
   max_length=2, choices=GENDER_CHOICES, verbose_name=_("Gender"),
   null=True, blank=True
 ) 

我想使用以下代码行将工厂男孩中的此字段的值随机化:

class ProfileFactory(factory.Factory):
   (...)
   gender = factory.LazyFunction(random.choice(['f', 'm']))

但是,这会引发TypeError: 'str' object is not callable错误 然后,我使用一个旧的博客文章尝试了以下可行的解决方案:

gender = factory.LazyAttribute(lambda x: random.choice(['f', 'm']))

这解决了问题,但是我不清楚为什么会这样。

factory.LazyFunction的{​​{3}}指出:

The LazyFunction is the simplest case where the value of an attribute
 does not depend on the object being built.

It takes as argument a method to call (function, lambda…); that method 
should not take any argument, though keyword arguments are safe but 
unused, and return a value.

据我了解,random.choice(['f', 'm'])构成了一个方法调用,因此应该可以按我预期的那样工作。

但是由于不是那样,所以我对LazyFunction的理解没有明显的缺陷,我希望有人可以在这里解释我做错了什么

1 个答案:

答案 0 :(得分:2)

两者之间的区别是

lambda x: random.choice(['f', 'm'])

返回一个函数,

random.choice(['f', 'm'])

计算该语句并返回字符串。

如果要在不使用lambda的情况下复制行为,则可以使用

def foo():
  return random.choice(['f', 'm'])

# ...
gender = factory.LazyFunction(foo)