如何将 factory.LazyAttribute 与 Faker() 函数一起使用

How to use factory.LazyAttribute with Faker() functions

我正在使用 factory_boy 在 Django 中构建一些装置。

我想使用factory.LazyAttribute根据另一个属性的条件构建一个属性。

class MyFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel

    title = 'My Title' if random() < 0.5 else None
    description = factory.LazyAttribute(
        lambda a: factory.Faker(
            'paragraph', nb_sentences=1, variable_nb_sentences=False
        ) if a.title else None)

但是,这 returns 一个 string<factory.faker.Faker object at 0x000001B10597BB20> 而不是执行正确的段落生成。

我哪里错了?

factory.Faker是一个特殊的对象:当一个工厂实例化一个对象时,它会要求factory.Faker代理从faker那里得到一个随机值。

实现您要查找的内容的最简单方法是使用 factory.Maybe:

class MyFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel

    title = factory.fuzzy.FuzzyChoice(["My Title", None])
    description = factory.Maybe('title', factory.Faker('paragraph'))

请注意,在您共享的代码中,当 Python 解析文件时,title = "My title" if random() < 0.5 else None 只计算一次。我用过 factory.fuzzy.FuzzyChoice to have that random computation performed for each object. This function also uses factory_boy's randomness management features.

另一种选择是使用 parameters (class Params):

class MyFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel

    class Params:
        # Items here will be available to further declarations, but won't be
        # passed to the model constructor.
        description_contents = factory.Faker('paragraph')

    title = factory.fuzzy.FuzzyChoice(["My Title", None])
    description = factory.LazyAttribute(lambda a: a.description_contents if a.title else None)

或者如果您需要与 Faker 库进行更具体的交互:

from faker import Faker as RealFaker
real_faker = RealFaker()

工厂内部:

factory.LazyAttribute(lambda a: real_faker.email())