i18n django middleware to check for ugettext_lazy strings in byte strings

I'm internationalizing a Django project, which means putting gettext_lazy calls around all the strings. However you have to make sure to use them in a unicode cotext, not a byte string (or str), otherwise you don't get the translated string back, you get <django.utils.functional...>.

As the Django docs say:

If you ever see output that looks like "hello <django.utils.functional...>", you have tried to insert the result of ugettext_lazy() into a bytestring. That's a bug in your code.

I was bitten by this a few times, so I made this Django Middleware that will raise an exception if the string "<django.utils.functional.__proxy__ object" is in the response. If you add this middleware and then run all your tests (You do have tests, right?), and see any times this fails, then you will have found places where you use a _/ugettext_lazy in a byte string, and you'll have to fix it

class AssertNoGettextLazyInByteStringMiddleware(object): """ Raises an error if a response contains <django..., which occurs when you try to use _/ugettext_lazy in a bytestring. This prevents the text from being translated cf. http://docs.djangoproject.com/en/dev/topics/i18n/internationalization/#lazy-translation """ def process_response(self, request, response): assert '<django.utils.functional.__proxy__ object at 0' not in response.content, "Gettexted lazy string used in bytestring for url %s: content: %s" % (request.path, response.content) return response

This entry is tagged: