Default language via settings not respected during testing

不羁的心 提交于 2019-12-30 18:50:09

问题


Using Django 1.3, Python 2.6

Having a particularly weird problem to track down related to internationalization, and RequestFactory vs. TestClient for testing views.

If I run:

./manage.py test 

All tests run (including the problematic ones) and pass successfully. If I run:

./manage.py test <appname> 

The app's tests will fail, throwing a template rendering exception for templates that use the language code because the language django thinks the request is asking for is not a language we've listed in settings.LANGUAGES. (In this case it has always been 'en-us', the closet matching language we support being 'en')

Here's an example of a test that will fail:

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
        )

This problem will not occur if django's TestClient is used to make a request to a url that calls a particular view. However if that same view is simply called with the result of RequestFactory's get or put methods, it will throw the error above.

It appears as though when using the RequestFactory method, the settings file is not being respected. Am I missing something simple here?

Additional Information

Applicable locale settings

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

Active middleware

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

回答1:


There are 2 possibilities :

a) You have 'django.middleware.locale.LocaleMiddleware' in settings.MIDDLEWARE_CLASSES.

In this case, the client use settings.LANGUAGE_CODE.

b) You don't.

In that case, you should set the language like that somewhere in your tests.py module:

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

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




回答2:


However if that same view is simply called with the result of RequestFactory's get or put methods, it will throw the error above.

I imagine you are doing something like:

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)

Then the URLs produced by the request have None instead of the language you wanted. You can try using a URL with a language prefix. You can try setting a language cookie in your request. You can try fiddling with the session. Nothing works.

The reason is does not work is because you are bypassing the entire middleware machinery. You are calling the view directly. Django won't intervene, take the request and pass it through the middlewares.

What you can do is call whatever middleware you need, or you can replicate what the middleware does. In order to get a request produced with RequestFactory to honor the language settings, I chose the latter and I did this:

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

This was enough for me to get the language prefix added to my URLs.



来源:https://stackoverflow.com/questions/9673842/default-language-via-settings-not-respected-during-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!