问题描述
我有以下ModelFactory:
class ProjectDataModelFactory(DjangoModelFactory):
project = factory.SubFactory("projects.factories.ProjectModelFactory")
version = "1"
content = {
"id": {"value": fuzzy.FuzzyText(length=7,chars=string.ascii_letters).fuzz().upper(),"type": "string"},"win_probability": {"value": fuzzy.FuzzyInteger(0,100).fuzz(),"type": "number"},"bid_value": {
"value": fuzzy.FuzzyInteger(0,10000000).fuzz(),"type": "number",},"status": {"value": random.choice(["Won","Lost"]),"sector": {
"value": random.choice(
["Construction","Technology","Finance","Consulting","Agriculture","Engineering"]
),"type": "string",}
在content["id"]
中,我希望value
成为project.external_id
而不是fuzzy.FuzzyText(length=7,chars=string.ascii_letters).fuzz().upper().
external_id
是ProjectModel.
的一部分,但是当我将project.external_id
放在模糊器的位置,会出现此错误:
AttributeError:'SubFactory'对象没有属性'external_id
这似乎仅是字典问题。在其他情况下使用它时,我们没有遇到任何问题。
我没有太多使用FactoryBoy的经验,因此很容易变得微不足道。有什么想法吗?
解决方法
您遇到的第一个问题是:导入类后,将评估您在random
字典中对.fuzz()
或content
的所有调用:每个实例将使用完全相同的值。
为了执行延迟评估,必须将它们包装在factory_boy
提供的声明中:
class ProjectDataModelFactory(DjangoModelFactory):
project = factory.SubFactory("projects.factories.ProjectModelFactory")
version = "1"
content = factory.Dict(
id=factory.Dict(
value=fuzzy.FuzzyText(length=7,chars=string.ascii_uppercase),type="string",),win_probability=factory.Dict(
value=fuzzy.FuzzyInteger(0,100),type="number",bid_value=factory.Dict(
value=fuzzy.FuzzyInteger(0,10_000_000),status=factory.Dict(
value=fuzzy.FuzzyChoice(["Won","Lost"]),sector=factory.Dict(
value=fuzzy.FuzzyChoice(
["Construction","Technology","Finance","Consulting","Agriculture","Engineering"],)
factory.Dict(**kwargs)
基本上是factory.SubFactory(DictFactory,**kwargs)
的别名;然后,您可以像使用简单的SubFactory
一样使用任何声明。
对于您的最初目标,现在可以轻松使用所有功能:
class ProjectDataModelFactory(DjangoModelFactory):
project = factory.SubFactory("projects.factories.ProjectModelFactory")
version = "1"
content = factory.Dict(
id=factory.Dict(
# . is the {"value": x,"type": "string"} dict;
# .. is {"id": {"value": x,...}} dict;
# ... is the ProjectData(content={"id": {...}}) object.
value=factory.SelfAttribute('...project.external_id'),# Other fields here
)