Default language through settings not observed during testing

Using Django 1.3, Python 2.6

Having a particularly strange tracking issue related to internationalization and RequestFactory vs. TestClient for testing Views.

If I run:

./manage.py test 

All tests are performed (including problem tests) and pass successfully. If I run:

 ./manage.py test <appname> 

Application tests will fail, throwing an exception to the template for templates that use language code, because the django language thinks the request is asking, is not the language that we list in settings.LANGUAGES. (In this case, it was always "en-us", the cabinet-matching language with which we support "en")

Here is 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 does not occur if django TestClient is used to create a request URL that invokes a specific view. However, if this view is simply invoked with the result of the RequestFactory get or put methods, it will raise the error above.

It seems that using the RequestFactory method, the settings file is not respected. Did I miss 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', ) 
+5
django internationalization testing
source share
2 answers

There are 2 possibilities:

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

In this case, the client uses settings.LANGUAGE_CODE .

b) You do not.

In this case, you should set such a language somehow in your tests.py module:

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

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

+5
source share

However, if the same view is simply called with the result of the getFlow or RequestPactory method, it throws an error above.

I assume 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 generated by the request have None instead of the language you need. You can try using a URL with a language prefix. You can try setting the language cookie in your request. You can try a session. Nothing works.

The reason is not that you bypass the whole middleware mechanism . You call the view directly. Django will not intervene, accept the request and transmit it through intermediaries.

What you can do is invoke any middleware that you need, or you can replicate what the middleware does. To get the request received using RequestFactory to honor the language settings, I selected the latter and I did the following:

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

This was enough to add a language prefix to my URLs.

0
source share

All Articles