列表子工厂元素内的随机模型值

发布于 2025-01-15 23:24:16 字数 895 浏览 2 评论 0原文

我找不到我的问题的答案。问题是我想生成一个用户工厂模型,其中内部将是一个带有地址的子工厂列表。每个地址元素必须具有不同/随机值(我的意思是每个元素都有不可重复的唯一值)。

在我当前的实现中,所有元素都具有相同的值(也许需要播种?)

实际代码:

from pydantic import BaseModel
from factory import Factory, List, Subfactory


class Address(BaseModel):
    Name: str


class User(BaseModel):
    Addresses: list[Address]


class AddressFactory(Factory):
    Name = fake.name()

    class Meta:
        model = Address


class UserFactory(Factory):
    Addresses = List([SubFactory(AddressFactory) for _ in range(3)])

    class Meta:
        model = User

实际输出:

> UserFactory()
> User(Addresses=[Address(Name='Isa Merkx'), Address(Name='Isa Merkx'), Address(Name='Isa Merkx')])

所需输出:

> UserFactory()
> User(Addresses=[Address(Name='Isa Merkx'), Address(Name='John Smith'), Address(Name='Elon Musk')])

I cannot find an answer to my question. The thing is that I want to generate an User factory model where inside will be a subfactory List with Addresses. Each Addresses element must have different/random values (I mean that each element has non-repeatable unique values).

In my current implementation, all of the elements have the same values (maybe seeding is necessary?)

Actual code:

from pydantic import BaseModel
from factory import Factory, List, Subfactory


class Address(BaseModel):
    Name: str


class User(BaseModel):
    Addresses: list[Address]


class AddressFactory(Factory):
    Name = fake.name()

    class Meta:
        model = Address


class UserFactory(Factory):
    Addresses = List([SubFactory(AddressFactory) for _ in range(3)])

    class Meta:
        model = User

Actual output:

> UserFactory()
> User(Addresses=[Address(Name='Isa Merkx'), Address(Name='Isa Merkx'), Address(Name='Isa Merkx')])

Desired Output:

> UserFactory()
> User(Addresses=[Address(Name='Isa Merkx'), Address(Name='John Smith'), Address(Name='Elon Musk')])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗梦空间 2025-01-22 23:24:16

您应该使用 LazyAttribute 每次获取不同的值。

from typing import List
from pydantic import BaseModel
import factory
from faker import Faker

fake = Faker('en_GB') # <-- missing from the original example


class Address(BaseModel):
    Street: str
    HouseNumber: str
    City: str
    Postcode: str


class AddressFactory(factory.Factory):
    Street = factory.LazyAttribute(lambda _: fake.street_name()) # <-- Lazy load the attribute values
    HouseNumber = factory.LazyAttribute(lambda _: fake.building_number())
    City = factory.LazyAttribute(lambda _: fake.city())
    Postcode = factory.LazyAttribute(lambda _: fake.postcode())

    class Meta:
        model = Address


class User(BaseModel):
    Addresses: List[Address]


class UserFactory(factory.Factory):
    Addresses = factory.List([factory.SubFactory(AddressFactory) for _ in range(3)])

    class Meta:
        model = User


user = UserFactory()
user

输出:

User(Addresses=[Address(Street='Jade rapids', HouseNumber='3', City='Vanessaville', Postcode='B6H 2XA'), Address(Street='Wendy grove', HouseNumber='76', City='West Patricia', Postcode='WR5 0GL'), Address(Street='Smith ramp', HouseNumber='3', City='New Leslie', Postcode='L6 6JF')])

You should use the LazyAttribute to get a different value each time.

from typing import List
from pydantic import BaseModel
import factory
from faker import Faker

fake = Faker('en_GB') # <-- missing from the original example


class Address(BaseModel):
    Street: str
    HouseNumber: str
    City: str
    Postcode: str


class AddressFactory(factory.Factory):
    Street = factory.LazyAttribute(lambda _: fake.street_name()) # <-- Lazy load the attribute values
    HouseNumber = factory.LazyAttribute(lambda _: fake.building_number())
    City = factory.LazyAttribute(lambda _: fake.city())
    Postcode = factory.LazyAttribute(lambda _: fake.postcode())

    class Meta:
        model = Address


class User(BaseModel):
    Addresses: List[Address]


class UserFactory(factory.Factory):
    Addresses = factory.List([factory.SubFactory(AddressFactory) for _ in range(3)])

    class Meta:
        model = User


user = UserFactory()
user

The output:

User(Addresses=[Address(Street='Jade rapids', HouseNumber='3', City='Vanessaville', Postcode='B6H 2XA'), Address(Street='Wendy grove', HouseNumber='76', City='West Patricia', Postcode='WR5 0GL'), Address(Street='Smith ramp', HouseNumber='3', City='New Leslie', Postcode='L6 6JF')])
不念旧人 2025-01-22 23:24:16

在您提供的代码中,您必须将 fake.name() 替换为 Faker("name"),其中 Faker 是从 < code>factory 在文件的开头。

事实上,fake.name() 仅在定义类时调用一次,而您希望每次实例化工厂时都调用一次。

您会找到问题的更详细答案 此处

In the code you provided, you have to replace fake.name() by Faker("name"), where Faker is imported from factory at the beginning of your file.

Indeed, fake.name() is called only once, when the class is defined, whereas you want it to happen each time you instantiate a factory.

You'll find a more detailed answer to your question here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文