【问题标题】:Default language via settings not respected during testing测试期间不遵守设置的默认语言
【发布时间】:2012-03-12 19:51:41
【问题描述】:

使用 Django 1.3、Python 2.6

有一个特别奇怪的问题需要追踪 国际化,以及 RequestFactory 与 TestClient 进行测试 意见。

如果我跑:

./manage.py test 

所有测试都运行(包括有问题的测试)并成功通过。如果我跑:

./manage.py test <appname> 

应用程序的测试将失败,引发模板渲染异常 使用语言代码的模板,因为语言 django 认为请求所要求的不是我们列出的语言 设置.语言。 (在这种情况下,它一直是 'en-us',我们支持的壁橱匹配语言是 'en')

下面是一个失败的测试示例:

class TemplateServingTestCase(TestCase):
    def setUp(self):
        self.app_dir      = os.path.abspath(os.path.dirname(__file__))
        self.gallery_root = os.path.join(self.app_dir, 'test_gallery')
        self.gallery_url  = '/'
        self.request      = RequestFactory().get('/')

    def test_404_invalid_category(self):
        self.assertRaises(Http404, gallery_page,
            self.request,
            'bad-category',
            self.gallery_root,
            self.gallery_url
        )

如果用django的TestClient做一个就不会出现这个问题了 请求调用特定视图的 url。但是,如果相同 视图只是用 RequestFactory 的 get 或 put 的结果调用 方法,它会抛出上面的错误。

看起来好像在使用 RequestFactory 方法时, 设置文件不被尊重。我错过了一些简单的东西吗 在这里?

附加信息

适用的区域设置

LANGUAGE_CODE = 'en'
LANGUAGES = (
    ('en', 'English'),
    ('de', 'Deutsch'),
    ('es', 'Espanol'),
    ('fr', 'Francaise'),
    ('it', 'Italiano'),
    ('pt-br', 'Portugues (Brasil)'),
)

活动中间件

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'services.middleware.LegacyIntegrationMiddleware',
)

【问题讨论】:

    标签: django testing internationalization


    【解决方案1】:

    有两种可能:

    a) 您在 settings.MIDDLEWARE_CLASSES 中有'django.middleware.locale.LocaleMiddleware'。

    在这种情况下,客户端使用settings.LANGUAGE_CODE。

    b) 你没有。

    在这种情况下,你应该在你的 tests.py 模块中的某个地方设置这样的语言:

    from django.utils.translation import activate
    ...
    activate('fr-fr')
    

    https://code.djangoproject.com/ticket/15143

    【讨论】:

    • 参见上面的编辑,a) 在这种情况下没有按预期工作。 b)确实解决了问题,但仍然很好奇为什么 RequestFactory 不遵守设置文件。
    • 已测试 a) 并且适用于我使用相同版本的 Python 和 Django。小心中间件排序。
    • 您的LANGUAGE_CODE 设置看起来无效。 docs.djangoproject.com/en/1.3/ref/settings/#language-code
    • @kaptainlange 不知何故(a)似乎对我也不起作用。使用LocaleMiddleware 和LANGUAGE_CODE='en-us',当我使用reverse('my_name') 时,我得到http://testserver/en-us/...,而在服务器中它是http://127.0.0.1:8000/en/...。此外,client.get() 使用 reverse 返回 404,这与使用静态 URL 和 /en/ 形成对比。
    【解决方案2】:

    但是,如果使用 RequestFactory 的 get 或 put 方法的结果简单地调用相同的视图,则会抛出上述错误。

    我想你正在做类似的事情:

    from django.utils import translation
    from app.views import some_view
    
    # Using translation.activate is pretty well known, so I suppose you
    # also do this:
    translation.activate(<whatever language you want>)
    
    request_factory = RequestFactory()
    request = request_factory.get("/foo")
    
    response = some_view(request)
    

    然后请求生成的 URL 有 None 而不是你想要的语言。您可以尝试使用带有语言前缀的 URL。您可以尝试在请求中设置语言 cookie。您可以尝试摆弄会话。没有任何效果。

    原因是不起作用是因为你绕过了整个中间件机制。您正在直接调用视图。 Django 不会干预,接受请求并通过中间件传递。

    你可以做的是调用你需要的任何中间件,或者你可以复制中间件的作用。为了获得使用RequestFactory 生成的请求以遵守语言设置,我选择了后者并这样做了:

    translation.activate("en-us")
    request.LANGUAGE_CODE = "en-us"
    response = some_view(request)
    

    这足以让我将语言前缀添加到我的网址中。

    【讨论】:

      【解决方案3】:

      我正在使用behave-django 进行测试。以上解决方案都不适合我。

      正确的做法是调用:

      settings.MIDDLEWARE.remove('django.middleware.locale.LocaleMiddleware')
      

      在测试的夹具设置中。特别是对于行为,在 environment.py 中:

      def before_all(context):
          context.browser = Browser('chrome', headless=True)
          # The LocaleMiddleware can false tests
          settings.MIDDLEWARE.remove('django.middleware.locale.LocaleMiddleware')
          # enforce english language for testing
          settings.LANGUAGE_CODE = 'en' 
      

      【讨论】:

        猜你喜欢
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-07
        • 1970-01-01
        • 2016-07-06
        相关资源
        最近更新 更多