#django #factory-boy
#django #factory-boy
Вопрос:
У меня есть следующий 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"]), "type": "string"},
"sector": {
"value": random.choice(
["Construction", "Technology", "Finance", "Consulting", "Agriculture", "Engineering"]
),
"type": "string",
},
}
В content["id"]
, я хотел бы иметь value
be project.external_id
вместо fuzzy.FuzzyText(length=7, chars=string.ascii_letters).fuzz().upper().
external_id
is часть ProjectModel.
, но когда я ставлю project.external_id
вместо fuzzer, я получаю эту ошибку:
AttributeError: объект ‘SubFactory’ не имеет атрибута ‘external_id
Это только кажется проблемой с dicts. У нас не было проблем с его использованием в других контекстах.
У меня нет большого опыта использования FactoryBoy, поэтому это может быть что-то тривиальное. Есть идеи?
Ответ №1:
У вас есть первая проблема: все вызовы random
or .fuzz()
, которые вы вводите в content
dict, оцениваются при импорте класса: каждый экземпляр будет использовать одни и те же значения.
Чтобы выполнить отложенную оценку, вы ДОЛЖНЫ обернуть их в some factory_boy
-provided объявление:
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),
type="number",
),
status=factory.Dict(
value=fuzzy.FuzzyChoice(["Won", "Lost"]),
type="string",
),
sector=factory.Dict(
value=fuzzy.FuzzyChoice(
["Construction", "Technology", "Finance", "Consulting", "Agriculture", "Engineering"],
),
type="string",
),
)
factory.Dict(**kwargs)
по сути, это псевдоним для factory.SubFactory(DictFactory, **kwargs)
; затем вы можете использовать любое объявление, как если бы использовали simple 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'),
type="string",
),
# Other fields here
)