235 | | ``ungettext`` takes three arguments: the singular translation string, the plural |
236 | | translation string and the number of objects (which is passed to the |
237 | | translation languages as the ``count`` variable). |
| 240 | This function is useful when your need you Django application to be localizable |
| 241 | to languages where the number and complexity of `plural forms |
| 242 | <http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is |
| 243 | greater than the two forms used in English ('object' for the singular and |
| 244 | 'objects' for all the cases where ``count`` is different from zero, irrespective |
| 245 | of its value.) |
| 246 | |
| 247 | In this example the number of objects is passed to the translation languages as |
| 248 | the ``count`` variable. |
| 249 | |
| 250 | Lets see a slightly more complex usage example:: |
| 251 | |
| 252 | from django.utils.translation import ungettext |
| 253 | |
| 254 | count = Report.objects.count() |
| 255 | if count == 1: |
| 256 | name = Report._meta.verbose_name |
| 257 | else: |
| 258 | name = Report._meta.verbose_name_plural |
| 259 | |
| 260 | text = ungettext( |
| 261 | 'There is %(count)d %(name)s available.', |
| 262 | 'There are %(count)d %(name)s available.', |
| 263 | count |
| 264 | ) % { |
| 265 | 'count': count, |
| 266 | 'name': name |
| 267 | } |
| 268 | |
| 269 | Here we reuse localizable, hopefully already translated literals (contained in |
| 270 | the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for |
| 271 | other parts of the sentence so all of it is consistently based on the |
| 272 | cardinality of the elements at play. |
| 273 | |
| 274 | .. _pluralization-var-notes: |
| 275 | |
| 276 | .. note:: |
| 277 | |
| 278 | When using this technique, make sure you use a single name for every |
| 279 | extrapolated variable included in the literal. In the example above note how |
| 280 | we used the ``name`` Python variable in both translation strings. This |
| 281 | example would fail:: |
| 282 | |
| 283 | from django.utils.translation import ungettext |
| 284 | from myapp.models import Report |
| 285 | |
| 286 | count = Report.objects.count() |
| 287 | if count == 1: |
| 288 | else: |
| 289 | d = { |
| 290 | 'count': count, |
| 291 | 'name': Report._meta.verbose_name |
| 292 | 'plural_name': Report._meta.verbose_name_plural |
| 293 | } |
| 294 | text = ungettext( |
| 295 | 'There is %(count)d %(name)s available.', |
| 296 | 'There are %(count)d %(plural_name)s available.', |
| 297 | count |
| 298 | ) % d |
| 299 | |
| 300 | You would get a ``a format specification for argument 'name', as in |
| 301 | 'msgstr[0]', doesn't exist in 'msgid'`` error when running |
| 302 | ``django-admin.py compilemessages`` or a Python ``KeyError`` exception at |
| 303 | runtime. |
291 | | Internally, all block and inline translations use the appropriate |
292 | | ``ugettext`` / ``ungettext`` call. |
| 359 | When you use the pluralization feature and bind additional values to local |
| 360 | variables apart from the counter value that selects the translated literal to be |
| 361 | used, have in mind that the ``blocktrans`` construct is internally converted |
| 362 | to an ``ungettext`` call. This means the same :ref:`notes |
| 363 | <pluralization-var-notes>` apply. |