You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何在字典内用Factory Boy关联子工厂属性?

I've run into this exact issue before with Factory Boy—let's break down what's happening and how to fix it.

Why the Error Happens

When you define the content dictionary directly in your factory class, it gets evaluated when the class is loaded, not when an instance is created. At that point, project is still a SubFactory object (not an actual Project model instance), so it doesn't have an external_id attribute. That's why you're getting the AttributeError.

Fix: Use factory.lazy_attribute

Factory Boy provides lazy_attribute to defer the creation of an attribute until the instance is being built. This way, the related project object will already exist, and you can safely access its external_id.

Here's how to modify your factory:

import factory
from factory.django import DjangoModelFactory
import fuzzy
import random
import string

class ProjectDataModelFactory(DjangoModelFactory):
    project = factory.SubFactory("projects.factories.ProjectModelFactory")
    version = "1"

    @factory.lazy_attribute
    def content(self):
        # Now self.project is a fully instantiated Project model instance
        return {
            "id": {"value": self.project.external_id, "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"]), "type": "string"},
            "sector": {
                "value": random.choice(
                    ["Construction", "Technology", "Finance", "Consulting", "Agriculture", "Engineering"]
                ), "type": "string",
            },
        }

Alternative: Lambda Syntax with factory.LazyAttribute

If you prefer a more concise inline approach, you can use the lambda version:

class ProjectDataModelFactory(DjangoModelFactory):
    project = factory.SubFactory("projects.factories.ProjectModelFactory")
    version = "1"

    content = factory.LazyAttribute(lambda obj: {
        "id": {"value": obj.project.external_id, "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"]), "type": "string"},
        "sector": {
            "value": random.choice(
                ["Construction", "Technology", "Finance", "Consulting", "Agriculture", "Engineering"]
            ), "type": "string",
        },
    })

Key Takeaway

Any time you need to reference a related model's attributes in your factory, use lazy evaluation (like lazy_attribute). This ensures that all dependent objects are fully created before you try to access their properties.

内容的提问来源于stack exchange,提问作者Matthew Gaiser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:02:54