| 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. |