2

我想将 FactoryBoy 与用户/配置文件模式一起使用,如其文档中所述。

class ProfileFactory(DjangoModelFactory):
    class Meta:
        model = Profile     
    first_name = lazy_attribute(lambda o: faker.first_name())
    user = SubFactory('profiles.tests.factories.UserFactory', profile=None)

class UserFactory(DjangoModelFactory):
    class Meta:
        model = settings.AUTH_USER_MODEL
    username = lazy_attribute(lambda o: faker.first_name())
    profile = RelatedFactory(ProfileFactory, 'user')

现在我希望能够通过仅提供用户名来创建用户

u = UserFactory(username='alice')

并自动获取用户名作为配置文件中的 first_name ( ='Alice')

或 first_name 之类的

u = UserFactory(profile__first_name='Bob')

='bob'并根据给定的 first_name获取用户名 ( )

或者,如果我很活泼,提供用户名和名字,当然保留两者

u = UserFactory(username='alice', profile__first_name='Bob')

到目前为止,我还没有找到实施这种行为的合适地点。我尝试了覆盖_generate(),但发现这不是正确的位置,因为此时我的惰性属性已经触发。我也无法覆盖__call__()__new__()在我的UserFactory.

也许这都是因为我对 python 还很陌生,所以我会感谢任何帮助我朝着正确方向前进的帮助。

4

1 回答 1

2

尽管我在这里回答自己的第一个问题感觉有点愚蠢,但我想我自己找到了答案:

看起来最好的重写方法是实现我想要的attributesBaseFactory因为所有构建/创建函数都调用它,我仍然得到'纯粹'kwargsextra摆弄它们。

也许有人还有更好的答案,但在那之前这是我的版本。

@classmethod
def attributes(cls, create=False, extra=None):
    if extra:
        if 'profile__first_name' in extra and 'username' not in extra:
            extra['username'] = extra['profile__first_name'].lower()
        elif 'username' in extra and 'profile__first_name' not in extra:
            extra['profile__first_name'] = extra['username'].title()

    return super().attributes(create, extra)
于 2016-02-20T09:12:59.100 回答