| | 298 | |
|---|
| | 299 | Working with lazy translation objects |
|---|
| | 300 | ===================================== |
|---|
| | 301 | |
|---|
| | 302 | Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models |
|---|
| | 303 | and utility functions is a common operation. When you are working with these |
|---|
| | 304 | objects elsewhere in your code, you should ensure that you don't accidentally |
|---|
| | 305 | convert them to strings, because they should be converted as late as possible |
|---|
| | 306 | (so that the correct locale is in effect). This necessitates the use of a |
|---|
| | 307 | couple of helper functions. |
|---|
| | 308 | |
|---|
| | 309 | Joining strings: string_concat() |
|---|
| | 310 | -------------------------------- |
|---|
| | 311 | |
|---|
| | 312 | Standard Python string joins (``''.join([...])``) will not work on lists |
|---|
| | 313 | containing lazy translation objects. Instead, you can use |
|---|
| | 314 | ``django.utils.translation.string_concat()``, which creates a lazy object that |
|---|
| | 315 | concatenates its contents *and* converts them to strings only when the result |
|---|
| | 316 | is included in a string. For example:: |
|---|
| | 317 | |
|---|
| | 318 | from django.utils.translation import string_concat |
|---|
| | 319 | ... |
|---|
| | 320 | name = ugettext_lazy(u'John Lennon') |
|---|
| | 321 | instrument = ugettext_lazy(u'guitar') |
|---|
| | 322 | result = string_concat([name, ': ', instrument]) |
|---|
| | 323 | |
|---|
| | 324 | In this case, the lazy translations in ``result`` will only be converted to |
|---|
| | 325 | strings when ``result`` itself is used in a string (usually at template |
|---|
| | 326 | rendering time). |
|---|
| | 327 | |
|---|
| | 328 | The allow_lazy() decorator |
|---|
| | 329 | -------------------------- |
|---|
| | 330 | |
|---|
| | 331 | There are a lot of useful utility functions in Django (particularly in |
|---|
| | 332 | ``django.utils``) that take a string as their first argument and do something |
|---|
| | 333 | to that string. These functions are used by template filters as well as |
|---|
| | 334 | directly in other code. |
|---|
| | 335 | |
|---|
| | 336 | If you write your own similar functions, you will rapidly come across the |
|---|
| | 337 | problem of what to do when the first argument is a lazy translation object. |
|---|
| | 338 | You don't want to convert it to a string immediately, because you may be using |
|---|
| | 339 | this function outside of a view (and hence the current thread's locale setting |
|---|
| | 340 | will not be correct). For cases like this, the |
|---|
| | 341 | ``django.utils.functional.allow_lazy()`` decorator will be useful. It modifies |
|---|
| | 342 | the function so that *if* it is called with a lazy translation as the first |
|---|
| | 343 | argument, the function evaluation is delayed until it needs to be converted to |
|---|
| | 344 | a string. |
|---|
| | 345 | |
|---|
| | 346 | For example:: |
|---|
| | 347 | |
|---|
| | 348 | from django.utils.functional import allow_lazy |
|---|
| | 349 | |
|---|
| | 350 | def fancy_utility_function(s, ...): |
|---|
| | 351 | # Do some conversion on string 's' |
|---|
| | 352 | ... |
|---|
| | 353 | fancy_utility_function = allow_lazy(fancy_utility_function, unicode) |
|---|
| | 354 | |
|---|
| | 355 | The ``allow_lazy()`` decorator takes, in addition to the function to decorate, |
|---|
| | 356 | a number of extra arguments specifying the type(s) that the original function |
|---|
| | 357 | can return. Usually, it will be enough to just include ``unicode`` here and |
|---|
| | 358 | ensure that your function returns Unicode strings. |
|---|
| | 359 | |
|---|
| | 360 | Using this decorator means you can write your function and assume that the |
|---|
| | 361 | input is a proper string, then add support for lazy translation objects at the |
|---|
| | 362 | end. |
|---|