【问题标题】:Change default faker locale in factory_boy在 factory_boy 中更改默认的 faker 语言环境
【发布时间】:2017-08-19 16:40:03
【问题描述】:

如何在 Python 的 factory_boy 中为我的所有工厂设置默认语言环境?

在文档中说应该用factory.Faker.override_default_locale 设置它,但这对我的伪造者没有任何作用......

import factory
from app.models import Example
from custom_fakers import CustomFakers

# I use custom fakers, this indeed are added
factory.Faker.add_provider(CustomFakers)
# But not default locales
factory.Faker.override_default_locale('es_ES')

class ExampleFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Example

    name = factory.Faker('first_name')


>>> from example import ExampleFactory
>>> e1 = ExampleFactory()
>>> e1.name
>>> u'Chad'

【问题讨论】:

    标签: python django factory-boy


    【解决方案1】:

    Faker.override_default_locale() 是一个上下文管理器,尽管从文档中不是很清楚。

    因此,要更改部分测试的默认语言环境:

    with factory.Faker.override_default_locale('es_ES'):
        ExampleFactory()
    

    对于整个测试:

    @factory.Faker.override_default_locale('es_ES')
    def test_foo(self):
        user = ExampleFactory()
    

    对于所有测试(Django):

    # settings.py
    TEST_RUNNER = 'myproject.testing.MyTestRunner'
    
    # myproject/testing.py
    import factory
    from django.conf import settings
    from django.util import translation
    import django.test.runner
    
    class MyTestRunner(django.test.runner.DiscoverRunner):
        def run_tests(self, test_labels, extra_tests=None, **kwargs):
            with factory.Faker.override_default_locale(translation.to_locale(settings.LANGUAGE_CODE)):
                return super().run_tests(test_labels, extra_tests=extra_tests, **kwargs)
    

    更多信息here

    【讨论】:

      【解决方案2】:

      UPD 正如我所说,这个解决方案不是最理想的:

      • factory.Faker._DEFAULT_LOCALE 是私有字段
      • fake()faker() 使用私有接口
      • fake() 不起作用,因为 factory-boy==3.1.0
      • 如果我要使用faker,我会直接使用它,而不是通过factory-boy

      您通常应该更喜欢other answer。留给子孙后代。


      不是一个好的解决方案,但现在它已经足够好了。您可以更改保存该值的variable

      import factory
      factory.Faker._DEFAULT_LOCALE = 'xx_XX'
      

      此外,您可以创建这样的文件 (app/faker.py):

      import factory
      from faker.providers import BaseProvider
      
      factory.Faker._DEFAULT_LOCALE = 'xx_XX'
      
      def fake(name):
          return factory.Faker(name).generate({})
      
      def faker():
          return factory.Faker._get_faker()
      
      class MyProvider(BaseProvider):
          def category_name(self):
              return self.random_element(category_names)
          ...
      factory.Faker.add_provider(MyProvider)
      
      category_names = [...]
      

      然后,一旦您导入文件,区域设置就会改变。此外,您还可以获得您的供应商以及在工厂外使用factory_boy 的伪造者的简单方法:

      from app.faker import fake
      print(fake('random_int'))
      print(faker().random_int())
      

      【讨论】:

      • Faker 5.6.5(可能所有版本> 4.17.1)没有generate()但有evaluate(None, None, {"locale": None})
      • @frost-nzcr4 generate() 属于factory-boy,而不是faker,但由于factory-boy==3.1.0 属于interface changed。请参阅我的更新答案。
      【解决方案3】:

      我遇到了和你一样的问题。对于临时解决方案,请尝试在 factory.Faker 中传递语言环境。

      例如:

      name = factory.Faker('first_name', locale='es_ES')
      

      【讨论】:

      • 是的,我知道,但这不是我想做的:(该项目的开发人员现在也不是太敏感:(
      【解决方案4】:

      使用 Django,您只需在 <myproject>/settings.py 中插入以下行:

      import factory
      factory.Faker._DEFAULT_LOCALE = 'fr_FR'
      

      【讨论】:

      • 最好在runner中更改语言环境。
      • 确实,既然您更改了答案,我意识到您可以将上下文管理器应用于所有测试。但是,我仍然认为我的解决方案更简单,而且众所周知,“简单胜于复杂”。
      • 您显然正在使用界面的私有部分,有一天它可能会损坏。就像在another case 中所做的那样。我不得不更新答案,因为它停止使用最近的factory-boy
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      相关资源
      最近更新 更多