summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-05-21 23:24:06 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-05-21 23:24:06 +0000
commit6f23be4ee9f0b333a7ee2faf0d5fc78f7c70b86e (patch)
tree7d46e1da3c7fe00c382ae6ec7e984e54760cb1a3
parentf1091ec619195a610f8b2df49cf647110ca0890e (diff)
unicode: Merged from trunk up to [5308].
git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5310 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS5
-rw-r--r--django/conf/locale/ca/LC_MESSAGES/django.mobin31909 -> 48325 bytes
-rw-r--r--django/conf/locale/ca/LC_MESSAGES/django.po3373
-rw-r--r--django/conf/locale/ca/LC_MESSAGES/djangojs.mobin1520 -> 1556 bytes
-rw-r--r--django/conf/locale/ca/LC_MESSAGES/djangojs.po17
-rw-r--r--django/conf/locale/es_AR/LC_MESSAGES/django.mobin41308 -> 44251 bytes
-rw-r--r--django/conf/locale/es_AR/LC_MESSAGES/django.po752
-rw-r--r--django/conf/locale/ru/LC_MESSAGES/django.mobin42820 -> 56778 bytes
-rw-r--r--django/conf/locale/ru/LC_MESSAGES/django.po2715
-rw-r--r--django/conf/locale/te/LC_MESSAGES/django.mobin35037 -> 35163 bytes
-rw-r--r--django/conf/locale/te/LC_MESSAGES/django.po51
-rw-r--r--django/contrib/admin/templatetags/admin_list.py4
-rw-r--r--django/contrib/admin/views/doc.py3
-rw-r--r--django/contrib/formtools/preview.py2
-rw-r--r--django/contrib/markup/models.py (renamed from tests/regressiontests/markup/models.py)0
-rw-r--r--django/contrib/markup/tests.py (renamed from tests/regressiontests/markup/tests.py)0
-rw-r--r--django/contrib/sessions/middleware.py3
-rw-r--r--django/contrib/sessions/tests.py19
-rw-r--r--django/contrib/sitemaps/__init__.py4
-rw-r--r--django/contrib/webdesign/models.py (renamed from tests/regressiontests/markup/__init__.py)0
-rw-r--r--django/contrib/webdesign/tests.py17
-rw-r--r--django/core/management.py8
-rw-r--r--django/core/serializers/json.py42
-rw-r--r--django/core/validators.py28
-rw-r--r--django/db/backends/ado_mssql/creation.py3
-rw-r--r--django/db/backends/mysql/base.py4
-rw-r--r--django/db/backends/mysql/creation.py3
-rw-r--r--django/db/backends/mysql/introspection.py2
-rw-r--r--django/db/backends/mysql_old/base.py2
-rw-r--r--django/db/backends/mysql_old/creation.py3
-rw-r--r--django/db/backends/mysql_old/introspection.py2
-rw-r--r--django/db/backends/oracle/creation.py3
-rw-r--r--django/db/backends/oracle/introspection.py2
-rw-r--r--django/db/backends/postgresql/base.py1
-rw-r--r--django/db/backends/postgresql/creation.py3
-rw-r--r--django/db/backends/postgresql/introspection.py3
-rw-r--r--django/db/backends/postgresql_psycopg2/introspection.py3
-rw-r--r--django/db/backends/sqlite3/base.py7
-rw-r--r--django/db/backends/sqlite3/creation.py3
-rw-r--r--django/db/backends/util.py15
-rw-r--r--django/db/models/fields/__init__.py73
-rw-r--r--django/http/__init__.py7
-rw-r--r--django/newforms/fields.py68
-rw-r--r--django/newforms/util.py11
-rw-r--r--django/oldforms/__init__.py30
-rw-r--r--django/utils/_decimal.py3079
-rw-r--r--docs/forms.txt7
-rw-r--r--docs/install.txt4
-rw-r--r--docs/model-api.txt59
-rw-r--r--docs/newforms.txt104
-rw-r--r--docs/settings.txt2
-rw-r--r--docs/tutorial02.txt2
-rw-r--r--tests/modeltests/invalid_models/models.py10
-rw-r--r--tests/regressiontests/forms/tests.py140
-rw-r--r--tests/regressiontests/httpwrappers/tests.py3
-rw-r--r--tests/regressiontests/serializers_regress/models.py16
-rw-r--r--tests/regressiontests/serializers_regress/tests.py25
-rwxr-xr-xtests/runtests.py14
58 files changed, 8321 insertions, 2435 deletions
diff --git a/AUTHORS b/AUTHORS
index 7f8eecb0e7..0f0142ddea 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,7 +41,6 @@ And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --
people who have submitted patches, reported bugs, added translations, helped
answer newbie questions, and generally made Django that much better:
- adurdin@gmail.com
alang@bright-green.com
Marty Alchin <gulopine@gamemusic.org>
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
@@ -90,6 +89,7 @@ answer newbie questions, and generally made Django that much better:
dne@mayonnaise.net
Maximillian Dornseif <md@hudora.de>
Jeremy Dunck <http://dunck.us/>
+ Andrew Durdin <adurdin@gmail.com>
Andy Dustman <farcepest@gmail.com>
Clint Ecker
enlight
@@ -192,7 +192,7 @@ answer newbie questions, and generally made Django that much better:
polpak@yahoo.com
J. Rademaker
Michael Radziej <mir@noris.de>
- ramiro
+ Ramiro Morales <rm0@gmx.net>
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
Brian Ray <http://brianray.chipy.org/>
remco@diji.biz
@@ -211,6 +211,7 @@ answer newbie questions, and generally made Django that much better:
sopel
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
Georgi Stanojevski <glisha@gmail.com>
+ Vasiliy Stavenko <stavenko@gmail.com>
Thomas Steinacher <http://www.eggdrop.ch/>
nowell strite
Radek Švarz <http://www.svarz.cz/translate/>
diff --git a/django/conf/locale/ca/LC_MESSAGES/django.mo b/django/conf/locale/ca/LC_MESSAGES/django.mo
index 00cc135c2d..ca03991f2b 100644
--- a/django/conf/locale/ca/LC_MESSAGES/django.mo
+++ b/django/conf/locale/ca/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/ca/LC_MESSAGES/django.po b/django/conf/locale/ca/LC_MESSAGES/django.po
index 212ecda34a..ccef4f8e3b 100644
--- a/django/conf/locale/ca/LC_MESSAGES/django.po
+++ b/django/conf/locale/ca/LC_MESSAGES/django.po
@@ -2,277 +2,43 @@
# This file is distributed under the same license as the PACKAGE package.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
#
-# Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>, 2005.
-# Ricardo Javier Cardenes Medina <ricardo.cardenes@gmail.com>, 2005.
-# Marc Fargas <marc@fargas.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-02-15 11:05+1100\n"
-"PO-Revision-Date: 2007-01-19 10:23+0100\n"
+"POT-Creation-Date: 2007-05-20 18:25+0200\n"
+"PO-Revision-Date: 2007-05-20 18:24+0200\n"
"Last-Translator: Marc Fargas <marc@fargas.com>\n"
"Language-Team: <es@li.org>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: VIM 7.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: db/models/manipulators.py:305
-#, python-format
-msgid "%(object)s with this %(type)s already exists for the given %(field)s."
-msgstr "Ja existeix %(object)s amb aquest %(fieldname)s."
-
-#: db/models/manipulators.py:306 contrib/admin/views/main.py:335
-#: contrib/admin/views/main.py:337 contrib/admin/views/main.py:339
-msgid "and"
-msgstr "i"
-
-#: db/models/fields/related.py:53
-#, python-format
-msgid "Please enter a valid %s."
-msgstr "Si us plau, introdueixi un %s vàlid."
-
-#: db/models/fields/related.py:642
-msgid "Separate multiple IDs with commas."
-msgstr "Separi múltiples IDs amb comes."
-
-#: db/models/fields/related.py:644
-msgid ""
-"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr "Premi \"Control\" o \"Command\" en un Mac per escollir més d'un."
-
-#: db/models/fields/related.py:691
-#, python-format
-msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
-msgid_plural ""
-"Please enter valid %(self)s IDs. The values %(value)r are invalid."
-msgstr[0] ""
-"Si us plau, introdueixi IDs de %(self)s vàlids. El valor %(value)r és "
-"invàlid."
-msgstr[1] ""
-"Si us plau, introdueixi IDs de %(self)s vàlids. Els valors %(value)r són "
-"invàlids."
-
-#: db/models/fields/__init__.py:42
-#, python-format
-msgid "%(optname)s with this %(fieldname)s already exists."
-msgstr "Ja existeix %(optname)s amb auqest %(fieldname)s."
-
-#: db/models/fields/__init__.py:116 db/models/fields/__init__.py:273
-#: db/models/fields/__init__.py:605 db/models/fields/__init__.py:616
-#: oldforms/__init__.py:352 newforms/fields.py:78 newforms/fields.py:373
-#: newforms/fields.py:449 newforms/fields.py:460
-msgid "This field is required."
-msgstr "Aquest camp és obligatori."
-
-#: db/models/fields/__init__.py:366
-msgid "This value must be an integer."
-msgstr "Aquest valor ha de ser un enter."
-
-#: db/models/fields/__init__.py:401
-msgid "This value must be either True or False."
-msgstr "Aquest valor ha de ser True (Veritat) o False (Fals)"
-
-#: db/models/fields/__init__.py:422
-msgid "This field cannot be null."
-msgstr "Aquest camp no pot ser null (estar buit)."
-
-#: db/models/fields/__init__.py:454 core/validators.py:147
-msgid "Enter a valid date in YYYY-MM-DD format."
-msgstr "Introdueixi una data vàlida en el forma AAAA-MM-DD."
-
-#: db/models/fields/__init__.py:521 core/validators.py:156
-msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
-msgstr "Introdueixi un data/hora vàlida en format YYYY-MM-DD HH:MM."
-
-#: db/models/fields/__init__.py:625
-msgid "Enter a valid filename."
-msgstr "Introdueixi un nom de fitxer vàlid."
-
-#: conf/global_settings.py:39
-msgid "Arabic"
-msgstr ""
-
-#: conf/global_settings.py:40
-msgid "Bengali"
-msgstr "Bengalí"
-
-#: conf/global_settings.py:41
-#, fuzzy
-msgid "Catalan"
-msgstr "Italià"
-
-#: conf/global_settings.py:42
-msgid "Czech"
-msgstr "Chec"
-
-#: conf/global_settings.py:43
-msgid "Welsh"
-msgstr "Galès"
-
-#: conf/global_settings.py:44
-msgid "Danish"
-msgstr "Danès"
-
-#: conf/global_settings.py:45
-msgid "German"
-msgstr "Alemany"
-
-#: conf/global_settings.py:46
-msgid "Greek"
-msgstr "Grec"
-
-#: conf/global_settings.py:47
-msgid "English"
-msgstr "Anglès"
-
-#: conf/global_settings.py:48
-msgid "Spanish"
-msgstr "Espanyol"
-
-#: conf/global_settings.py:49
-msgid "Argentinean Spanish"
-msgstr ""
-
-#: conf/global_settings.py:50
-#, fuzzy
-msgid "Finnish"
-msgstr "Danès"
-
-#: conf/global_settings.py:51
-msgid "French"
-msgstr "Francés"
-
-#: conf/global_settings.py:52
-msgid "Galician"
-msgstr "Galleg"
-
-#: conf/global_settings.py:53
-msgid "Hungarian"
-msgstr "Húngar"
-
-#: conf/global_settings.py:54
-msgid "Hebrew"
-msgstr "Hebreu"
-
-#: conf/global_settings.py:55
-msgid "Icelandic"
-msgstr "Islandés"
-
-#: conf/global_settings.py:56
-msgid "Italian"
-msgstr "Italià"
-
-#: conf/global_settings.py:57
-msgid "Japanese"
-msgstr "Japonés"
-
-#: conf/global_settings.py:58
-msgid "Latvian"
-msgstr ""
-
-#: conf/global_settings.py:59
-msgid "Macedonian"
-msgstr ""
-
-#: conf/global_settings.py:60
-msgid "Dutch"
-msgstr "Holandés"
-
-#: conf/global_settings.py:61
-msgid "Norwegian"
-msgstr "Norueg"
-
-#: conf/global_settings.py:62
-#, fuzzy
-msgid "Polish"
-msgstr "Anglès"
-
-#: conf/global_settings.py:63
-msgid "Brazilian"
-msgstr "Brasileny"
+#: utils/dateformat.py:40
+msgid "p.m."
+msgstr "p.m."
-#: conf/global_settings.py:64
-msgid "Romanian"
-msgstr "Rumanés"
+#: utils/dateformat.py:41
+msgid "a.m."
+msgstr "a.m."
-#: conf/global_settings.py:65
-msgid "Russian"
-msgstr "Rús"
+#: utils/dateformat.py:46
+msgid "PM"
+msgstr "PM"
-#: conf/global_settings.py:66
-msgid "Slovak"
-msgstr "Eslovac"
+#: utils/dateformat.py:47
+msgid "AM"
+msgstr "AM"
-#: conf/global_settings.py:67
-msgid "Slovenian"
-msgstr "Esloveni"
+#: utils/dateformat.py:95
+msgid "midnight"
+msgstr "mitja nit"
-#: conf/global_settings.py:68
-msgid "Serbian"
-msgstr "Serbi"
-
-#: conf/global_settings.py:69
-msgid "Swedish"
-msgstr "Suec"
-
-#: conf/global_settings.py:70
-msgid "Tamil"
-msgstr ""
-
-#: conf/global_settings.py:71
-msgid "Turkish"
-msgstr ""
-
-#: conf/global_settings.py:72
-msgid "Ukrainian"
-msgstr "Ucranià"
-
-#: conf/global_settings.py:73
-msgid "Simplified Chinese"
-msgstr "Xinés simplificat"
-
-#: conf/global_settings.py:74
-msgid "Traditional Chinese"
-msgstr "Xinés tradicional"
-
-#: utils/timesince.py:12
-msgid "year"
-msgid_plural "years"
-msgstr[0] "any"
-msgstr[1] "anys"
-
-#: utils/timesince.py:13
-msgid "month"
-msgid_plural "months"
-msgstr[0] "mes"
-msgstr[1] "mesos"
-
-#: utils/timesince.py:14
-msgid "week"
-msgid_plural "weeks"
-msgstr[0] "setmana"
-msgstr[1] "setmanes"
-
-#: utils/timesince.py:15
-msgid "day"
-msgid_plural "days"
-msgstr[0] "dia"
-msgstr[1] "dies"
-
-#: utils/timesince.py:16
-msgid "hour"
-msgid_plural "hours"
-msgstr[0] "hora"
-msgstr[1] "hores"
-
-#: utils/timesince.py:17
-msgid "minute"
-msgid_plural "minutes"
-msgstr[0] "minut"
-msgstr[1] "minuts"
+#: utils/dateformat.py:97
+msgid "noon"
+msgstr "mig dia"
#: utils/dates.py:6
msgid "Monday"
@@ -312,7 +78,7 @@ msgstr "Febrer"
#: utils/dates.py:14 utils/dates.py:27
msgid "March"
-msgstr "Març"
+msgstr "Març"
#: utils/dates.py:14 utils/dates.py:27
msgid "April"
@@ -426,383 +192,110 @@ msgstr "Nov."
msgid "Dec."
msgstr "Des."
-#: utils/translation/trans_real.py:362
-msgid "DATE_FORMAT"
-msgstr "F j, Y"
-
-#: utils/translation/trans_real.py:363
-msgid "DATETIME_FORMAT"
-msgstr "F j, Y, H:i"
+#: utils/timesince.py:12
+msgid "year"
+msgid_plural "years"
+msgstr[0] "any"
+msgstr[1] "anys"
-#: utils/translation/trans_real.py:364
-msgid "TIME_FORMAT"
-msgstr "H:i"
+#: utils/timesince.py:13
+msgid "month"
+msgid_plural "months"
+msgstr[0] "mes"
+msgstr[1] "mesos"
-#: utils/translation/trans_real.py:380
-#, fuzzy
-msgid "YEAR_MONTH_FORMAT"
-msgstr "F j, Y"
+#: utils/timesince.py:14
+msgid "week"
+msgid_plural "weeks"
+msgstr[0] "setmana"
+msgstr[1] "setmanes"
-#: utils/translation/trans_real.py:381
-#, fuzzy
-msgid "MONTH_DAY_FORMAT"
-msgstr "F j, Y"
+#: utils/timesince.py:15
+msgid "day"
+msgid_plural "days"
+msgstr[0] "dia"
+msgstr[1] "dies"
-#: oldforms/__init__.py:387
-#, python-format
-msgid "Ensure your text is less than %s character."
-msgid_plural "Ensure your text is less than %s characters."
-msgstr[0] "Aseguris de que el seu texte té menys de %s caracter."
-msgstr[1] "Aseguris de que el seu texte té menys de %s caracters."
+#: utils/timesince.py:16
+msgid "hour"
+msgid_plural "hours"
+msgstr[0] "hora"
+msgstr[1] "hores"
-#: oldforms/__init__.py:392
-msgid "Line breaks are not allowed here."
-msgstr "No es permeten salts de linea."
+#: utils/timesince.py:17
+msgid "minute"
+msgid_plural "minutes"
+msgstr[0] "minut"
+msgstr[1] "minuts"
-#: oldforms/__init__.py:493 oldforms/__init__.py:566 oldforms/__init__.py:605
+#: utils/timesince.py:40
#, python-format
-msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
-msgstr "Esculli una opció vàlida; %(data)s' no està dintre de %(choices)s."
-
-#: oldforms/__init__.py:572 contrib/admin/filterspecs.py:150
-#: newforms/widgets.py:162
-msgid "Unknown"
-msgstr "Desconegut"
-
-#: oldforms/__init__.py:572 contrib/admin/filterspecs.py:143
-#: newforms/widgets.py:162
-msgid "Yes"
-msgstr "Si"
-
-#: oldforms/__init__.py:572 contrib/admin/filterspecs.py:143
-#: newforms/widgets.py:162
-msgid "No"
-msgstr "No"
+msgid "%d milliseconds"
+msgstr "%d milisegons"
-#: oldforms/__init__.py:667 core/validators.py:173 core/validators.py:442
-msgid "No file was submitted. Check the encoding type on the form."
-msgstr ""
-
-#: oldforms/__init__.py:669
-msgid "The submitted file is empty."
-msgstr "El fitxer enviat està buit."
-
-#: oldforms/__init__.py:725
-msgid "Enter a whole number between -32,768 and 32,767."
-msgstr "Introdueixi un número enter entre -32,768 i 32,767."
-
-#: oldforms/__init__.py:735
-msgid "Enter a positive number."
-msgstr "Introdueixi un número positiu."
-
-#: oldforms/__init__.py:745
-msgid "Enter a whole number between 0 and 32,767."
-msgstr "Introdueixi un número entre 0 i 32,767."
-
-#: contrib/sessions/models.py:51
-msgid "session key"
-msgstr "clau de la sessió"
-
-#: contrib/sessions/models.py:52
-msgid "session data"
-msgstr "dades de la sessió"
-
-#: contrib/sessions/models.py:53
-msgid "expire date"
-msgstr "data de caducitat"
-
-#: contrib/sessions/models.py:57
-msgid "session"
-msgstr "sessió"
-
-#: contrib/sessions/models.py:58
-msgid "sessions"
-msgstr "sessions"
-
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
-msgid "The two password fields didn't match."
-msgstr ""
-
-#: contrib/auth/forms.py:25
-#, fuzzy
-msgid "A user with that username already exists."
-msgstr "Ja existeix %(optname)s amb auqest %(fieldname)s."
-
-#: contrib/auth/forms.py:53
-msgid ""
-"Your Web browser doesn't appear to have cookies enabled. Cookies are "
-"required for logging in."
-msgstr ""
-"El seu navegador no sembla tenir les 'cookies' (galetes) activades. Aquestes "
-"són necessàries per iniciar la sessió."
-
-#: contrib/auth/forms.py:60 contrib/admin/views/decorators.py:10
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"Si us plau, introdueixi un nom d'usuari i contrasenya vàlids. Tingui en "
-"compte que tots dos camps son sensibles a majúscules i minúscules."
-
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr ""
-
-#: contrib/auth/forms.py:85
-msgid ""
-"That e-mail address doesn't have an associated user account. Are you sure "
-"you've registered?"
-msgstr ""
-
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr ""
-
-#: contrib/auth/forms.py:124
-msgid "Your old password was entered incorrectly. Please enter it again."
-msgstr ""
-
-#: contrib/auth/views.py:39
-#, fuzzy
-msgid "Logged out"
-msgstr "Finalitzar sessió"
-
-#: contrib/auth/models.py:38 contrib/auth/models.py:57
-msgid "name"
-msgstr "nom"
-
-#: contrib/auth/models.py:40
-msgid "codename"
-msgstr "nom en clau"
-
-#: contrib/auth/models.py:42
-msgid "permission"
-msgstr "permís"
-
-#: contrib/auth/models.py:43 contrib/auth/models.py:58
-msgid "permissions"
-msgstr "permissos"
-
-#: contrib/auth/models.py:60
-msgid "group"
-msgstr "grup"
-
-#: contrib/auth/models.py:61 contrib/auth/models.py:100
-msgid "groups"
-msgstr "grups"
-
-#: contrib/auth/models.py:90
-msgid "username"
-msgstr "nom d'usuari"
-
-#: contrib/auth/models.py:90
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr ""
-
-#: contrib/auth/models.py:91
-msgid "first name"
-msgstr "nom propi"
-
-#: contrib/auth/models.py:92
-msgid "last name"
-msgstr "cognoms"
-
-#: contrib/auth/models.py:93
-msgid "e-mail address"
-msgstr "adreça de correu electrònic"
-
-#: contrib/auth/models.py:94
-msgid "password"
-msgstr "contrasenya"
-
-#: contrib/auth/models.py:94
-msgid ""
-"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
-"password form</a>."
-msgstr ""
-
-#: contrib/auth/models.py:95
-msgid "staff status"
-msgstr "és membre del personal"
-
-#: contrib/auth/models.py:95
-msgid "Designates whether the user can log into this admin site."
-msgstr "Indica si l'usuari pot entrar en el lloc administratiu."
-
-#: contrib/auth/models.py:96
-msgid "active"
-msgstr "actiu"
-
-#: contrib/auth/models.py:96
-#, fuzzy
-msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
-"instead of deleting accounts."
-msgstr "Indica si l'usuari pot entrar en el lloc administratiu."
-
-#: contrib/auth/models.py:97
-msgid "superuser status"
-msgstr "estat de superusuari"
-
-#: contrib/auth/models.py:97
-msgid ""
-"Designates that this user has all permissions without explicitly assigning "
-"them."
-msgstr ""
-
-#: contrib/auth/models.py:98
-msgid "last login"
-msgstr "últim inici de sessió"
-
-#: contrib/auth/models.py:99
-msgid "date joined"
-msgstr "data de creació"
-
-#: contrib/auth/models.py:101
-msgid ""
-"In addition to the permissions manually assigned, this user will also get "
-"all permissions granted to each group he/she is in."
-msgstr ""
-"Junt amb els permissos asignats manualment, aquest usuari tindrà, també, els "
-"permissos dels grups dels que sigui membre."
-
-#: contrib/auth/models.py:102
-msgid "user permissions"
-msgstr "permissos de l'usuari"
-
-#: contrib/auth/models.py:105
-msgid "user"
-msgstr "usuari"
-
-#: contrib/auth/models.py:106
-msgid "users"
-msgstr "usuaris"
-
-#: contrib/auth/models.py:111
-msgid "Personal info"
-msgstr "Informaciò personal"
-
-#: contrib/auth/models.py:112
-msgid "Permissions"
-msgstr "permissos"
-
-#: contrib/auth/models.py:113
-msgid "Important dates"
-msgstr "Dates importants"
-
-#: contrib/auth/models.py:114
-msgid "Groups"
-msgstr "Grups"
-
-#: contrib/auth/models.py:258
-msgid "message"
-msgstr "missatge"
-
-#: contrib/contenttypes/models.py:26
-msgid "python model class name"
-msgstr "nom de la classe del model en python"
-
-#: contrib/contenttypes/models.py:29
-msgid "content type"
-msgstr "tipus de contingut"
-
-#: contrib/contenttypes/models.py:30
-msgid "content types"
-msgstr "tipus de continguts"
-
-#: contrib/redirects/models.py:7
-msgid "redirect from"
-msgstr "redirigir desde"
-
-#: contrib/redirects/models.py:8
-msgid ""
-"This should be an absolute path, excluding the domain name. Example: '/"
-"events/search/'."
-msgstr ""
-"Aquesta ruta hauria de ser el camí absolut, excluint el nom del domini. "
-"Exemple '/events/search/'."
-
-#: contrib/redirects/models.py:9
-msgid "redirect to"
-msgstr "redirigir a"
-
-#: contrib/redirects/models.py:10
-msgid ""
-"This can be either an absolute path (as above) or a full URL starting with "
-"'http://'."
-msgstr ""
-"Això pot ser bé una ruta absoluta (com abans) o una URL completa que comenci "
-"per http:// ."
-
-#: contrib/redirects/models.py:13
-msgid "redirect"
-msgstr "redirecció"
-
-#: contrib/redirects/models.py:14
-msgid "redirects"
-msgstr "redireccions"
+#: utils/timesince.py:41
+#, python-format
+msgid "%(number)d %(type)s"
+msgstr "%(number)d %(type)s"
-#: contrib/flatpages/models.py:7 contrib/admin/views/doc.py:315
-msgid "URL"
-msgstr "URL"
+#: utils/timesince.py:47
+#, python-format
+msgid ", %(number)d %(type)s"
+msgstr ", %(number)d %(type)s"
-#: contrib/flatpages/models.py:8
-msgid ""
-"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr ""
-"Exemple: '/about/contact/'. Asseguri's de posar les barres al principi i al "
-"final."
+#: utils/translation/trans_real.py:358
+msgid "DATE_FORMAT"
+msgstr "F j, Y"
-#: contrib/flatpages/models.py:9
-msgid "title"
-msgstr "tìtol"
+#: utils/translation/trans_real.py:359
+msgid "DATETIME_FORMAT"
+msgstr "F j, Y, H:i"
-#: contrib/flatpages/models.py:10
-msgid "content"
-msgstr "contingut"
+#: utils/translation/trans_real.py:360
+msgid "TIME_FORMAT"
+msgstr "H:i"
-#: contrib/flatpages/models.py:11
-msgid "enable comments"
-msgstr "habilitar comentaris"
+#: utils/translation/trans_real.py:376
+msgid "YEAR_MONTH_FORMAT"
+msgstr "j de/d' F del Y"
-#: contrib/flatpages/models.py:12
-msgid "template name"
-msgstr "nom de la plantilla"
+#: utils/translation/trans_real.py:377
+msgid "MONTH_DAY_FORMAT"
+msgstr "j de/d' F del Y"
-#: contrib/flatpages/models.py:13
-#, fuzzy
-msgid ""
-"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
-"will use 'flatpages/default.html'."
-msgstr ""
-"Exemple: 'flatpages/contact_page'. Si no el proporciona, el sistema "
-"utilitzarà 'flatpages/default'."
+#: template/defaultfilters.py:491
+msgid "yes,no,maybe"
+msgstr "si,no,potser"
-#: contrib/flatpages/models.py:14
-msgid "registration required"
-msgstr "ha de estar registrat"
+#: template/defaultfilters.py:520
+#, python-format
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] "%(size)d byte"
+msgstr[1] "%(size)d bytes"
-#: contrib/flatpages/models.py:14
-msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr "Si està marcat, només els usuaris registrats podran veure la pàgina."
+#: template/defaultfilters.py:522
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
-#: contrib/flatpages/models.py:18
-msgid "flat page"
-msgstr "pàgina estàtica"
+#: template/defaultfilters.py:524
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
-#: contrib/flatpages/models.py:19
-msgid "flat pages"
-msgstr "pàgines estàtiques"
+#: template/defaultfilters.py:525
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
#: contrib/comments/models.py:67 contrib/comments/models.py:166
msgid "object ID"
-msgstr "ID de l'objete"
+msgstr "ID de l'objecte"
#: contrib/comments/models.py:68
msgid "headline"
-msgstr "encapçalament"
+msgstr "encapçalament"
#: contrib/comments/models.py:69 contrib/comments/models.py:90
#: contrib/comments/models.py:167
@@ -811,39 +304,39 @@ msgstr "comentari"
#: contrib/comments/models.py:70
msgid "rating #1"
-msgstr "calificació 1"
+msgstr "qualificació #1"
#: contrib/comments/models.py:71
msgid "rating #2"
-msgstr "calificació 2"
+msgstr "qualificació #2"
#: contrib/comments/models.py:72
msgid "rating #3"
-msgstr "calificació 3"
+msgstr "qualificació #3"
#: contrib/comments/models.py:73
msgid "rating #4"
-msgstr "calificació 4"
+msgstr "qualificació #4"
#: contrib/comments/models.py:74
msgid "rating #5"
-msgstr "calificació 5"
+msgstr "qualificació #5"
#: contrib/comments/models.py:75
msgid "rating #6"
-msgstr "calificació 6"
+msgstr "qualificació #6"
#: contrib/comments/models.py:76
msgid "rating #7"
-msgstr "calificació 7"
+msgstr "qualificació #7"
#: contrib/comments/models.py:77
msgid "rating #8"
-msgstr "calificació 8"
+msgstr "qualificació #8"
#: contrib/comments/models.py:82
msgid "is valid rating"
-msgstr "es calificació vàlida"
+msgstr "és qualificació vàlida"
#: contrib/comments/models.py:83 contrib/comments/models.py:169
msgid "date/time submitted"
@@ -851,22 +344,22 @@ msgstr "data/hora d'enviament"
#: contrib/comments/models.py:84 contrib/comments/models.py:170
msgid "is public"
-msgstr "és públic"
+msgstr "és públic"
#: contrib/comments/models.py:85 contrib/admin/views/doc.py:304
msgid "IP address"
-msgstr "Adreça IP"
+msgstr "Adreça IP"
#: contrib/comments/models.py:86
msgid "is removed"
-msgstr "està eliminat"
+msgstr "està eliminat"
#: contrib/comments/models.py:86
msgid ""
"Check this box if the comment is inappropriate. A \"This comment has been "
"removed\" message will be displayed instead."
msgstr ""
-"Marqui aquesta caixa si el comentari és inapropiat. En lloc seu es mostrarà "
+"Marqui aquesta caixa si el comentari no és apropiat. En lloc seu es mostrarà "
"\"Aquest comentari ha estat eliminat\" "
#: contrib/comments/models.py:91
@@ -875,7 +368,7 @@ msgstr "comentaris"
#: contrib/comments/models.py:131 contrib/comments/models.py:207
msgid "Content object"
-msgstr "Objete Contingut"
+msgstr "Objecte Contingut"
#: contrib/comments/models.py:159
#, python-format
@@ -898,7 +391,7 @@ msgstr "nom de la persona"
#: contrib/comments/models.py:171
msgid "ip address"
-msgstr "adreça ip"
+msgstr "adreça ip"
#: contrib/comments/models.py:173
msgid "approved by staff"
@@ -914,15 +407,15 @@ msgstr "comentaris lliures"
#: contrib/comments/models.py:233
msgid "score"
-msgstr "puntuació"
+msgstr "puntuació"
#: contrib/comments/models.py:234
msgid "score date"
-msgstr "data de la puntuació"
+msgstr "data de la puntuació"
#: contrib/comments/models.py:237
msgid "karma score"
-msgstr "puntuació de karma"
+msgstr "puntuació de karma"
#: contrib/comments/models.py:238
msgid "karma scores"
@@ -931,7 +424,7 @@ msgstr "punts de karma"
#: contrib/comments/models.py:242
#, python-format
msgid "%(score)d rating by %(user)s"
-msgstr "%(score)d punt per %(user)s"
+msgstr "%(score)d punt/s per %(user)s"
#: contrib/comments/models.py:258
#, python-format
@@ -963,11 +456,11 @@ msgstr "Marca de %r"
#: contrib/comments/models.py:278
msgid "deletion date"
-msgstr "data d'eliminació"
+msgstr "data d'eliminació"
#: contrib/comments/models.py:280
msgid "moderator deletion"
-msgstr "eliminació del moderador"
+msgstr "eliminació del moderador"
#: contrib/comments/models.py:281
msgid "moderator deletions"
@@ -976,7 +469,89 @@ msgstr "eliminacions del moderador"
#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
-msgstr "eliminació del moderador per %r"
+msgstr "eliminació del moderador per %r"
+
+#: contrib/comments/views/comments.py:27
+msgid ""
+"This rating is required because you've entered at least one other rating."
+msgstr "Es precisa aquesta puntuació perquè has introduït almenys un altre."
+
+#: contrib/comments/views/comments.py:111
+#, python-format
+msgid ""
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comment:\n"
+"\n"
+"%(text)s"
+msgid_plural ""
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comments:\n"
+"\n"
+"%(text)s"
+msgstr[0] ""
+"Aquest comentari el va enviar un usuari que ha enviat menys de %(count)s "
+"comentari:\n"
+"\n"
+"%(text)s"
+msgstr[1] ""
+"Aquest comentari el va enviar un usuari que ha enviat menys de %(count)s "
+"comentaris:\n"
+"\n"
+"%(text)s"
+
+#: contrib/comments/views/comments.py:116
+#, python-format
+msgid ""
+"This comment was posted by a sketchy user:\n"
+"\n"
+"%(text)s"
+msgstr ""
+"Aquest comentari va ser publicat per un usuari incomplet\n"
+"\n"
+"%(text)s"
+
+#: contrib/comments/views/comments.py:188
+#: contrib/comments/views/comments.py:280
+msgid "Only POSTs are allowed"
+msgstr "Només s'admed POST"
+
+#: contrib/comments/views/comments.py:192
+#: contrib/comments/views/comments.py:284
+msgid "One or more of the required fields wasn't submitted"
+msgstr "Un o més dels caps requerits no ha estat sotmès"
+
+#: contrib/comments/views/comments.py:196
+#: contrib/comments/views/comments.py:286
+msgid "Somebody tampered with the comment form (security violation)"
+msgstr ""
+"Algú està jugant amb el formulari de comentaris (violació de seguretat)"
+
+#: contrib/comments/views/comments.py:206
+#: contrib/comments/views/comments.py:292
+msgid ""
+"The comment form had an invalid 'target' parameter -- the object ID was "
+"invalid"
+msgstr ""
+"El formulari de comentaris tenia un paràmetre 'target' invàlid -- el ID del "
+"objecte era invàlid"
+
+#: contrib/comments/views/comments.py:257
+#: contrib/comments/views/comments.py:321
+msgid "The comment form didn't provide either 'preview' or 'post'"
+msgstr ""
+"El formulari del comentari no ha proveït ni 'previsualitzar' ni 'enviar'"
+
+#: contrib/comments/views/karma.py:19
+msgid "Anonymous users cannot vote"
+msgstr "Els usuaris anònims no poden votar"
+
+#: contrib/comments/views/karma.py:23
+msgid "Invalid comment ID"
+msgstr "ID del comentari invàlid"
+
+#: contrib/comments/views/karma.py:25
+msgid "No voting for yourself"
+msgstr "No pots votar-te a tu mateix"
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
@@ -985,26 +560,26 @@ msgid "Username:"
msgstr "Usuari:"
#: contrib/comments/templates/comments/form.html:6
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
+#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/object_history.html:3
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/admin_doc/missing_docutils.html:4
+#: contrib/admin/templates/admin_doc/template_detail.html:4
#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_filter_index.html:5
#: contrib/admin/templates/admin_doc/view_index.html:5
+#: contrib/admin/templates/admin_doc/index.html:4
#: contrib/admin/templates/admin_doc/template_tag_index.html:5
-#: contrib/admin/templates/admin_doc/model_detail.html:3
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
#: contrib/admin/templates/admin_doc/model_index.html:5
-#: contrib/admin/templates/admin_doc/index.html:4
-#: contrib/admin/templates/admin_doc/template_detail.html:4
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
-#: contrib/admin/templates/admin/auth/user/change_password.html:9
+#: contrib/admin/templates/admin_doc/template_filter_index.html:5
+#: contrib/admin/templates/admin_doc/model_detail.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/registration/password_change_done.html:3
msgid "Log out"
-msgstr "Finalitzar sessió"
+msgstr "Finalitzar sessió"
#: contrib/comments/templates/comments/form.html:8
#: contrib/admin/templates/admin/login.html:20
@@ -1017,7 +592,7 @@ msgstr "Contrasenya oblidada?"
#: contrib/comments/templates/comments/form.html:12
msgid "Ratings"
-msgstr "Calificacions"
+msgstr "Qualificacions"
#: contrib/comments/templates/comments/form.html:12
#: contrib/comments/templates/comments/form.html:23
@@ -1047,103 +622,65 @@ msgstr "Previsualitzar comentari"
msgid "Your name:"
msgstr "El seu nom:"
-#: contrib/comments/views/karma.py:19
-msgid "Anonymous users cannot vote"
-msgstr "Els usuaris anònims no poden votar"
-
-#: contrib/comments/views/karma.py:23
-msgid "Invalid comment ID"
-msgstr "ID del comentari invàlid"
-
-#: contrib/comments/views/karma.py:25
-msgid "No voting for yourself"
-msgstr "No pots votar-te a tu mateix"
+#: contrib/redirects/models.py:7
+msgid "redirect from"
+msgstr "redreçar des de"
-#: contrib/comments/views/comments.py:27
+#: contrib/redirects/models.py:8
msgid ""
-"This rating is required because you've entered at least one other rating."
-msgstr "Es precisa aquesta puntuació perquè has introduit almenys un altre."
+"This should be an absolute path, excluding the domain name. Example: '/"
+"events/search/'."
+msgstr ""
+"Aquesta ruta hauria de ser el camí absolut, excloent-ne el nom del domini. "
+"Exemple '/events/search/'."
-#: contrib/comments/views/comments.py:111
-#, python-format
-msgid ""
-"This comment was posted by a user who has posted fewer than %(count)s "
-"comment:\n"
-"\n"
-"%(text)s"
-msgid_plural ""
-"This comment was posted by a user who has posted fewer than %(count)s "
-"comments:\n"
-"\n"
-"%(text)s"
-msgstr[0] ""
-"Aquest comentari el va enviar un usuari que ha enviat menys de %(count)s "
-"comentari:\n"
-"\n"
-"%(text)s"
-msgstr[1] ""
-"Aquest comentari el va enviar un usuari que ha enviat menys de %(count)s "
-"comentaris:\n"
-"\n"
-"%(text)s"
+#: contrib/redirects/models.py:9
+msgid "redirect to"
+msgstr "redreçar a"
-#: contrib/comments/views/comments.py:116
-#, python-format
+#: contrib/redirects/models.py:10
msgid ""
-"This comment was posted by a sketchy user:\n"
-"\n"
-"%(text)s"
+"This can be either an absolute path (as above) or a full URL starting with "
+"'http://'."
msgstr ""
-"Aquest comentari va ser publicat per un usuari incomplert\n"
-"\n"
-"%(text)s"
+"Això pot ser bé una ruta absoluta (com abans) o una URL completa que comenci "
+"per http:// ."
-#: contrib/comments/views/comments.py:188
-#: contrib/comments/views/comments.py:280
-msgid "Only POSTs are allowed"
-msgstr "Només s'admed POST"
+#: contrib/redirects/models.py:13
+msgid "redirect"
+msgstr "redreçament"
-#: contrib/comments/views/comments.py:192
-#: contrib/comments/views/comments.py:284
-msgid "One or more of the required fields wasn't submitted"
-msgstr "Un o més dels caps requerits no ha estat sotmés"
+#: contrib/redirects/models.py:14
+msgid "redirects"
+msgstr "redreçaments"
-#: contrib/comments/views/comments.py:196
-#: contrib/comments/views/comments.py:286
-msgid "Somebody tampered with the comment form (security violation)"
-msgstr ""
-"Algú està jugant amb el formulari de comentaris (violació de seguretat)"
+#: contrib/admin/models.py:16
+msgid "action time"
+msgstr "moment de l'acció"
-#: contrib/comments/views/comments.py:206
-#: contrib/comments/views/comments.py:292
-msgid ""
-"The comment form had an invalid 'target' parameter -- the object ID was "
-"invalid"
-msgstr ""
-"El formulari de comentaris tenia un paràmetre 'target' invàlid -- el ID del "
-"objecte era invàlid"
+#: contrib/admin/models.py:19
+msgid "object id"
+msgstr "id del objecte"
-#: contrib/comments/views/comments.py:257
-#: contrib/comments/views/comments.py:321
-msgid "The comment form didn't provide either 'preview' or 'post'"
-msgstr ""
-"El formulari del comentari no ha proveit ni 'previsualitzar' ni 'enviar'"
+#: contrib/admin/models.py:20
+msgid "object repr"
+msgstr "'repr' de l'objecte"
-#: contrib/sites/models.py:10
-msgid "domain name"
-msgstr "nom del domini"
+#: contrib/admin/models.py:21
+msgid "action flag"
+msgstr "marca de l'acció"
-#: contrib/sites/models.py:11
-msgid "display name"
-msgstr "nom per mostrar"
+#: contrib/admin/models.py:22
+msgid "change message"
+msgstr "missatge del canvi"
-#: contrib/sites/models.py:15
-msgid "site"
-msgstr "lloc"
+#: contrib/admin/models.py:25
+msgid "log entry"
+msgstr "entrada del registre"
-#: contrib/sites/models.py:16
-msgid "sites"
-msgstr "llocs"
+#: contrib/admin/models.py:26
+msgid "log entries"
+msgstr "entrades del registre"
#: contrib/admin/filterspecs.py:40
#, python-format
@@ -1161,7 +698,7 @@ msgstr "Tots"
#: contrib/admin/filterspecs.py:109
msgid "Any date"
-msgstr "Cualsevol data"
+msgstr "Qualsevol data"
#: contrib/admin/filterspecs.py:110
msgid "Today"
@@ -1169,7 +706,7 @@ msgstr "Avui"
#: contrib/admin/filterspecs.py:113
msgid "Past 7 days"
-msgstr "Últims 7 dies"
+msgstr "Últims 7 dies"
#: contrib/admin/filterspecs.py:115
msgid "This month"
@@ -1179,159 +716,407 @@ msgstr "Aquest mes"
msgid "This year"
msgstr "Aquest any"
-#: contrib/admin/models.py:16
-msgid "action time"
-msgstr "moment de l'acció"
+#: contrib/admin/filterspecs.py:143 newforms/widgets.py:182
+#: oldforms/__init__.py:577
+msgid "Yes"
+msgstr "Si"
-#: contrib/admin/models.py:19
-msgid "object id"
-msgstr "id del objecte"
+#: contrib/admin/filterspecs.py:143 newforms/widgets.py:182
+#: oldforms/__init__.py:577
+msgid "No"
+msgstr "No"
-#: contrib/admin/models.py:20
-msgid "object repr"
-msgstr "'repr' de l'objecte"
+#: contrib/admin/filterspecs.py:150 newforms/widgets.py:182
+#: oldforms/__init__.py:577
+msgid "Unknown"
+msgstr "Desconegut"
-#: contrib/admin/models.py:21
-msgid "action flag"
-msgstr "marca de l'acció"
+#: contrib/admin/templatetags/admin_list.py:247
+msgid "All dates"
+msgstr "Totes les dates"
-#: contrib/admin/models.py:22
-msgid "change message"
-msgstr "missatge del canvi"
+#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48
+#: contrib/admin/views/doc.py:50
+msgid "tag:"
+msgstr "etiqueta:"
-#: contrib/admin/models.py:25
-msgid "log entry"
-msgstr "entrada del registre"
+#: contrib/admin/views/doc.py:77 contrib/admin/views/doc.py:79
+#: contrib/admin/views/doc.py:81
+msgid "filter:"
+msgstr "filtre:"
-#: contrib/admin/models.py:26
-msgid "log entries"
-msgstr "entrades del registre"
+#: contrib/admin/views/doc.py:135 contrib/admin/views/doc.py:137
+#: contrib/admin/views/doc.py:139
+msgid "view:"
+msgstr "vista:"
-#: contrib/admin/templatetags/admin_list.py:238
-msgid "All dates"
-msgstr "Totes les dates"
+#: contrib/admin/views/doc.py:164
+#, python-format
+msgid "App %r not found"
+msgstr "La aplicació %r no s'ha pogut trobar"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:6
-#: contrib/admin/templates/admin/change_list.html:6
-#: contrib/admin/templates/admin/change_form.html:13
-#: contrib/admin/templates/admin/base.html:30
-#: contrib/admin/templates/admin/auth/user/change_password.html:12
-#: contrib/admin/templates/registration/logged_out.html:4
-#: contrib/admin/templates/registration/password_reset_done.html:4
-#: contrib/admin/templates/registration/password_change_form.html:4
-#: contrib/admin/templates/registration/password_change_done.html:4
-#: contrib/admin/templates/registration/password_reset_form.html:4
-msgid "Home"
-msgstr "Inici"
+#: contrib/admin/views/doc.py:171
+#, python-format
+msgid "Model %(name)r not found in app %(label)r"
+msgstr "El model %(name)r no s'ha trobat en la aplicació %(label)r"
+
+#: contrib/admin/views/doc.py:183
+#, python-format
+msgid "the related `%(label)s.%(type)s` object"
+msgstr "el objecte relacionat `%(label)s.%(type)s`"
+
+#: contrib/admin/views/doc.py:183 contrib/admin/views/doc.py:205
+#: contrib/admin/views/doc.py:219 contrib/admin/views/doc.py:224
+msgid "model:"
+msgstr "model:"
+
+#: contrib/admin/views/doc.py:214
+#, python-format
+msgid "related `%(label)s.%(name)s` objects"
+msgstr "objectes relacionats `%(label)s.%(name)s`"
+
+#: contrib/admin/views/doc.py:219
+#, python-format
+msgid "all %s"
+msgstr "tots %s"
+
+#: contrib/admin/views/doc.py:224
+#, python-format
+msgid "number of %s"
+msgstr "nombre de %s"
+
+#: contrib/admin/views/doc.py:229
+#, python-format
+msgid "Fields on %s objects"
+msgstr "Camps en objectes %s"
+
+#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:301
+#: contrib/admin/views/doc.py:303 contrib/admin/views/doc.py:309
+#: contrib/admin/views/doc.py:310 contrib/admin/views/doc.py:312
+msgid "Integer"
+msgstr "Enter"
+
+#: contrib/admin/views/doc.py:292
+msgid "Boolean (Either True or False)"
+msgstr "Booleà (Verdader o Fals)"
+
+#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:311
+#, python-format
+msgid "String (up to %(maxlength)s)"
+msgstr "Cadena (fins a %(maxlength)s)"
+
+#: contrib/admin/views/doc.py:294
+msgid "Comma-separated integers"
+msgstr "Enters separats per comes"
+
+#: contrib/admin/views/doc.py:295
+msgid "Date (without time)"
+msgstr "Data (sense hora)"
+
+#: contrib/admin/views/doc.py:296
+msgid "Date (with time)"
+msgstr "Data (amb hora)"
+
+#: contrib/admin/views/doc.py:297
+msgid "E-mail address"
+msgstr "Adreça de correu electrònic"
+
+#: contrib/admin/views/doc.py:298 contrib/admin/views/doc.py:299
+#: contrib/admin/views/doc.py:302
+msgid "File path"
+msgstr "Ruta del fitxer"
+
+#: contrib/admin/views/doc.py:300
+msgid "Decimal number"
+msgstr "Número decimal"
+
+#: contrib/admin/views/doc.py:306
+msgid "Boolean (Either True, False or None)"
+msgstr "Booleà (Verdader, Fals o 'None' (cap))"
+
+#: contrib/admin/views/doc.py:307
+msgid "Relation to parent model"
+msgstr "Relació amb el model pare"
+
+#: contrib/admin/views/doc.py:308
+msgid "Phone number"
+msgstr "Número de telèfon"
+
+#: contrib/admin/views/doc.py:313
+msgid "Text"
+msgstr "Texte"
+
+#: contrib/admin/views/doc.py:314
+msgid "Time"
+msgstr "Hora"
+
+#: contrib/admin/views/doc.py:315 contrib/flatpages/models.py:7
+msgid "URL"
+msgstr "URL"
+
+#: contrib/admin/views/doc.py:316
+msgid "U.S. state (two uppercase letters)"
+msgstr "Estat dels E.U.A. (dos lletres majúscules)"
+
+#: contrib/admin/views/doc.py:317
+msgid "XML text"
+msgstr "Texte XML"
+
+#: contrib/admin/views/doc.py:343
+#, python-format
+msgid "%s does not appear to be a urlpattern object"
+msgstr "%s no sembla ser un objecte 'urlpattern'"
+
+#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Si us plau, introdueixi un nom d'usuari i contrasenya vàlids. Tingui en "
+"compte que tots dos camps son sensibles a majúscules i minúscules."
+
+#: contrib/admin/views/decorators.py:24
+#: contrib/admin/templates/admin/login.html:25
+msgid "Log in"
+msgstr "Iniciar sessió"
+
+#: contrib/admin/views/decorators.py:62
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Si us plau, identifiquis de nou doncs la seva sessió ha expirat. No es "
+"preocupi, el seu enviament està emmagatzemat."
+
+#: contrib/admin/views/decorators.py:69
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Sembla ser que el seu navegador no està configurat per acceptar "
+"'cookies' (galetes). Si us plau, habiliti les 'cookies', recarregui aquesta "
+"pàgina i provi-ho de nou. "
+
+#: contrib/admin/views/decorators.py:83
+msgid "Usernames cannot contain the '@' character."
+msgstr "Els noms d'usuari no poden contenir el caracter '@'."
+
+#: contrib/admin/views/decorators.py:85
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr ""
+"La seva adreça de correu no és el seu nom d'usuari. Provi '%s' en tot cas."
+
+#: contrib/admin/views/auth.py:19 contrib/admin/views/main.py:257
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "El/la %(name)s \"%(obj)s\".ha estat agregat/da amb èxit."
+
+#: contrib/admin/views/auth.py:24 contrib/admin/views/main.py:261
+#: contrib/admin/views/main.py:347
+msgid "You may edit it again below."
+msgstr "Pot editar-lo de nou abaix."
+
+#: contrib/admin/views/auth.py:30
+msgid "Add user"
+msgstr "Agregar usuari"
+
+#: contrib/admin/views/auth.py:57
+msgid "Password changed successfully."
+msgstr "Canvi de clau exitós"
+
+#: contrib/admin/views/auth.py:64
+#, python-format
+msgid "Change password: %s"
+msgstr "Canviar clau: %s"
+
+#: contrib/admin/views/main.py:223
+msgid "Site administration"
+msgstr "Lloc administratiu"
+
+#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356
+#, python-format
+msgid "You may add another %s below."
+msgstr "Pot agregar un altre %s abaix."
+
+#: contrib/admin/views/main.py:289
+#, python-format
+msgid "Add %s"
+msgstr "Agregar %s"
+
+#: contrib/admin/views/main.py:335
+#, python-format
+msgid "Added %s."
+msgstr "Agregat %s."
+
+#: contrib/admin/views/main.py:335 contrib/admin/views/main.py:337
+#: contrib/admin/views/main.py:339 db/models/manipulators.py:308
+msgid "and"
+msgstr "i"
+
+#: contrib/admin/views/main.py:337
+#, python-format
+msgid "Changed %s."
+msgstr "Modificat %s."
+
+#: contrib/admin/views/main.py:339
+#, python-format
+msgid "Deleted %s."
+msgstr "Eliminat %s."
+
+#: contrib/admin/views/main.py:342
+msgid "No fields changed."
+msgstr "Cap camp canviat."
+
+#: contrib/admin/views/main.py:345
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "S'ha modificat amb èxist el/la %(name)s \"%(obj)s."
+
+#: contrib/admin/views/main.py:353
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"S'ha agregat amb èxit el/la %(name)s \"%(obj)s\". Pot editar-lo de nou abaix."
+
+#: contrib/admin/views/main.py:391
+#, python-format
+msgid "Change %s"
+msgstr "Modificar %s"
+
+#: contrib/admin/views/main.py:476
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Un o més %(fieldname)s en %(name)s: %(obj)s"
+
+#: contrib/admin/views/main.py:481
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Un o més %(fieldname)s en %(name)s:"
+
+#: contrib/admin/views/main.py:514
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "El/la %(name)s \"%(obj)s\".ha estat eliminat amb èxit."
+
+#: contrib/admin/views/main.py:517
+msgid "Are you sure?"
+msgstr "Està segur?"
+
+#: contrib/admin/views/main.py:539
+#, python-format
+msgid "Change history: %s"
+msgstr "Modificar històric: %s"
+
+#: contrib/admin/views/main.py:573
+#, python-format
+msgid "Select %s"
+msgstr "Seleccioni %s"
+
+#: contrib/admin/views/main.py:573
+#, python-format
+msgid "Select %s to change"
+msgstr "Seleccioni %s per modificar"
+
+#: contrib/admin/views/main.py:768
+msgid "Database error"
+msgstr "Error de/en la base de dades"
+
+#: contrib/admin/templates/admin/filter.html:2
+#, python-format
+msgid " By %(filter_title)s "
+msgstr "Per %(filter_title)s "
+
+#: contrib/admin/templates/admin/filters.html:4
+msgid "Filter"
+msgstr "Filtre"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_list.html:5
#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/auth/user/change_password.html:9
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/registration/password_change_done.html:3
msgid "Documentation"
-msgstr "Documentació"
-
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-msgid "Bookmarklets"
-msgstr "'Bookmarklets'"
+msgstr "Documentació"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
-#: contrib/admin/templates/admin_doc/missing_docutils.html:4
-#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_filter_index.html:5
-#: contrib/admin/templates/admin_doc/view_index.html:5
-#: contrib/admin/templates/admin_doc/template_tag_index.html:5
-#: contrib/admin/templates/admin_doc/model_detail.html:3
-#: contrib/admin/templates/admin_doc/model_index.html:5
-#: contrib/admin/templates/admin_doc/index.html:4
-#: contrib/admin/templates/admin_doc/template_detail.html:4
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_list.html:5
#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/admin/auth/user/change_password.html:15
#: contrib/admin/templates/admin/auth/user/change_password.html:46
+#: contrib/admin/templates/admin_doc/missing_docutils.html:4
+#: contrib/admin/templates/admin_doc/template_detail.html:4
+#: contrib/admin/templates/admin_doc/view_detail.html:4
+#: contrib/admin/templates/admin_doc/view_index.html:5
+#: contrib/admin/templates/admin_doc/index.html:4
+#: contrib/admin/templates/admin_doc/template_tag_index.html:5
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
+#: contrib/admin/templates/admin_doc/model_index.html:5
+#: contrib/admin/templates/admin_doc/template_filter_index.html:5
+#: contrib/admin/templates/admin_doc/model_detail.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/registration/password_change_done.html:3
msgid "Change password"
msgstr "Canviar clau"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:5
-msgid "Documentation bookmarklets"
-msgstr "'Bookmarklets' de documentació"
-
-#: contrib/admin/templates/admin_doc/bookmarklets.html:9
-msgid ""
-"\n"
-"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
-"toolbar, or right-click the link and add it to your bookmarks. Now you can\n"
-"select the bookmarklet from any page in the site. Note that some of these\n"
-"bookmarklets require you to be viewing the site from a computer designated\n"
-"as \"internal\" (talk to your system administrator if you aren't sure if\n"
-"your computer is \"internal\").</p>\n"
-msgstr ""
-"\n"
-"<p class=\"help\">Per a instalar 'bookmarklets', arrosegui l'enllaç a la "
-"seva barra de\n"
-"marcadors, o faci click amb el botò dret en l'enllaç i afegeixi'l als "
-"marcadors.\n"
-"Ara pot escollir el 'bookmarklet' desde cualsevol pàgina del lloc.\n"
-"Observi que alguns d'aquests 'bookmarklets' precisen que estigui veient\n"
-"el lloc desde un ordinador senyalat com a \"intern\" (parli\n"
-"amb el seu administrador de sistemes si no està segur de la condició del "
-"seu).</p>\n"
-
-#: contrib/admin/templates/admin_doc/bookmarklets.html:19
-msgid "Documentation for this page"
-msgstr "Documentació d'aquesta pàgina"
+#: contrib/admin/templates/admin/change_form.html:13
+#: contrib/admin/templates/admin/change_list.html:6
+#: contrib/admin/templates/admin/500.html:4
+#: contrib/admin/templates/admin/delete_confirmation.html:6
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/invalid_setup.html:4
+#: contrib/admin/templates/admin/auth/user/change_password.html:12
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+#: contrib/admin/templates/registration/password_reset_form.html:4
+#: contrib/admin/templates/registration/password_reset_done.html:4
+#: contrib/admin/templates/registration/password_change_form.html:4
+#: contrib/admin/templates/registration/password_change_done.html:4
+#: contrib/admin/templates/registration/logged_out.html:4
+msgid "Home"
+msgstr "Inici"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:20
-msgid ""
-"Jumps you from any page to the documentation for the view that generates "
-"that page."
-msgstr ""
-"El porta desde cualsevol pàgina de la documentació a la vista que la genera."
+#: contrib/admin/templates/admin/change_form.html:15
+#: contrib/admin/templates/admin/index.html:28
+msgid "Add"
+msgstr "Afegir"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:22
-msgid "Show object ID"
-msgstr "Mostra el ID de l'objecte"
+#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/object_history.html:5
+msgid "History"
+msgstr "Històric"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:23
-msgid ""
-"Shows the content-type and unique ID for pages that represent a single "
-"object."
-msgstr ""
-"Mostra el 'content-type' (tipus de contingut) i el ID inequívoc de les "
-"pàgines que representen un únic objecte."
+#: contrib/admin/templates/admin/change_form.html:22
+msgid "View on site"
+msgstr "Veure en el lloc"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:25
-msgid "Edit this object (current window)"
-msgstr "Editar aquest objecte (finestra actual)"
+#: contrib/admin/templates/admin/change_form.html:32
+#: contrib/admin/templates/admin/auth/user/change_password.html:24
+msgid "Please correct the error below."
+msgid_plural "Please correct the errors below."
+msgstr[0] "Si us plau, corregeixi l'error mostrat abaix."
+msgstr[1] "Si us plau, corregeixi els errors mostrats abaix."
-#: contrib/admin/templates/admin_doc/bookmarklets.html:26
-msgid "Jumps to the admin page for pages that represent a single object."
-msgstr ""
-"El porta a la pàgina d'administració de pàgines que representen un únic "
-"objecte."
+#: contrib/admin/templates/admin/change_form.html:50
+msgid "Ordering"
+msgstr "Ordre"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:28
-msgid "Edit this object (new window)"
-msgstr "Editar aquest objecte (nova finestra)"
+#: contrib/admin/templates/admin/change_form.html:53
+msgid "Order:"
+msgstr "Ordre:"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:29
-msgid "As above, but opens the admin page in a new window."
-msgstr "Com abans, però obre la pàgina d'administració en una nova finestra."
+#: contrib/admin/templates/admin/change_list.html:12
+#, python-format
+msgid "Add %(name)s"
+msgstr "Afegir %(name)s"
#: contrib/admin/templates/admin/submit_line.html:3
#: contrib/admin/templates/admin/delete_confirmation.html:9
@@ -1354,6 +1139,19 @@ msgstr "Desar i continuar editant"
msgid "Save"
msgstr "Desar"
+#: contrib/admin/templates/admin/404.html:4
+#: contrib/admin/templates/admin/404.html:8
+msgid "Page not found"
+msgstr "No s'ha pogut trobar la pàgina"
+
+#: contrib/admin/templates/admin/404.html:10
+msgid "We're sorry, but the requested page could not be found."
+msgstr "Ho sentim, però no s'ha pogut trobar la pàgina solicitada"
+
+#: contrib/admin/templates/admin/pagination.html:10
+msgid "Show all"
+msgstr "Mostrar tots"
+
#: contrib/admin/templates/admin/500.html:4
msgid "Server error"
msgstr "Error del servidor"
@@ -1372,23 +1170,15 @@ msgid ""
"mail and should be fixed shortly. Thanks for your patience."
msgstr ""
"Hi ha hagut un error. S'ha informat als administradors del lloc per correu "
-"electrònic y hauria d'arreglar-se en breu. Gràcies per la seva paciència."
-
-#: contrib/admin/templates/admin/filter.html:2
-#, fuzzy, python-format
-msgid " By %(filter_title)s "
-msgstr "Per %(title)s "
+"electrònic y hauria d'arreglar-se en breu. Gràcies per la seva paciència."
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr ""
+#: contrib/admin/templates/admin/base_site.html:4
+msgid "Django site admin"
+msgstr "Lloc administratiu de Django"
-#: contrib/admin/templates/admin/invalid_setup.html:8
-msgid ""
-"Something's wrong with your database installation. Make sure the appropriate "
-"database tables have been created, and make sure the database is readable by "
-"the appropriate user."
-msgstr ""
+#: contrib/admin/templates/admin/base_site.html:7
+msgid "Django administration"
+msgstr "Adminsitració de Django"
#: contrib/admin/templates/admin/search_form.html:8
msgid "Go"
@@ -1398,196 +1188,207 @@ msgstr "Cercar"
#, python-format
msgid "1 result"
msgid_plural "%(counter)s results"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "1 resultat"
+msgstr[1] "%(counter)s resultats"
#: contrib/admin/templates/admin/search_form.html:10
#, python-format
msgid "%(full_result_count)s total"
-msgstr ""
+msgstr "%(full_result_count)s en total"
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/change_form.html:21
-msgid "History"
-msgstr "Històric"
+#: contrib/admin/templates/admin/index.html:17
+#, python-format
+msgid "Models available in the %(name)s application."
+msgstr "Models disponibles en la aplicació %(name)s."
-#: contrib/admin/templates/admin/object_history.html:18
-msgid "Date/time"
-msgstr "Data/hora"
+#: contrib/admin/templates/admin/index.html:18
+#, python-format
+msgid "%(name)s"
+msgstr "%(name)s"
-#: contrib/admin/templates/admin/object_history.html:19
-msgid "User"
-msgstr "Usuari"
+#: contrib/admin/templates/admin/index.html:34
+msgid "Change"
+msgstr "Modificar"
-#: contrib/admin/templates/admin/object_history.html:20
-msgid "Action"
-msgstr "Acció"
+#: contrib/admin/templates/admin/index.html:44
+msgid "You don't have permission to edit anything."
+msgstr "No té permís per editar res."
-#: contrib/admin/templates/admin/object_history.html:26
-msgid "DATE_WITH_TIME_FULL"
-msgstr "F j, Y, H:i "
+#: contrib/admin/templates/admin/index.html:52
+msgid "Recent Actions"
+msgstr "Accions recents"
-#: contrib/admin/templates/admin/object_history.html:36
-msgid ""
-"This object doesn't have a change history. It probably wasn't added via this "
-"admin site."
-msgstr ""
-"Aquest objecte no te historial de canvis. Probablement no va ser afegit "
-"utilitzant aquest lloc administratiu."
+#: contrib/admin/templates/admin/index.html:53
+msgid "My Actions"
+msgstr "Les meves accions"
+
+#: contrib/admin/templates/admin/index.html:57
+msgid "None available"
+msgstr "Cap disponible"
#: contrib/admin/templates/admin/delete_confirmation.html:14
-#, fuzzy, python-format
+#, python-format
msgid ""
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
"related objects, but your account doesn't have permission to delete the "
"following types of objects:"
msgstr ""
-"Eliminar el/la %(object_name)s '%(object)s' provocaria l'eliminació "
-"d'objectes relacionats, però el seu compte no te permisos per a esborrar els "
-"tipus d'objecte següents:"
+"Eliminar el/la %(object_name)s '%(escaped_object)s' provocaria l'eliminació "
+"d'objectes relacionats, però el seu compte no te permisos per a esborrar els "
+"tipus d'objecte següents:"
#: contrib/admin/templates/admin/delete_confirmation.html:21
-#, fuzzy, python-format
+#, python-format
msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
"All of the following related items will be deleted:"
msgstr ""
-"Està segur voler esborrar els/les %(object_name)s \"%(object)s\"? "
-"S'esborraran els següents elements relacionats:"
+"Està segur de voler esborrar els/les %(object_name)s \"%(escaped_object)s\"? "
+"S'esborraran els següents elements relacionats:"
#: contrib/admin/templates/admin/delete_confirmation.html:26
msgid "Yes, I'm sure"
msgstr "Si, estic segur"
-#: contrib/admin/templates/admin/pagination.html:10
-msgid "Show all"
-msgstr ""
-
-#: contrib/admin/templates/admin/change_list.html:12
-#, python-format
-msgid "Add %(name)s"
-msgstr "Afegir %(name)s"
-
-#: contrib/admin/templates/admin/change_form.html:15
-#: contrib/admin/templates/admin/index.html:28
-msgid "Add"
-msgstr "Afegir"
+#: contrib/admin/templates/admin/object_history.html:18
+msgid "Date/time"
+msgstr "Data/hora"
-#: contrib/admin/templates/admin/change_form.html:22
-msgid "View on site"
-msgstr "Veure en el lloc"
+#: contrib/admin/templates/admin/object_history.html:19
+msgid "User"
+msgstr "Usuari"
-#: contrib/admin/templates/admin/change_form.html:32
-#: contrib/admin/templates/admin/auth/user/change_password.html:24
-msgid "Please correct the error below."
-msgid_plural "Please correct the errors below."
-msgstr[0] "Si us plau, corregeixi l'error mostrat abaix."
-msgstr[1] "Si us plau, corregeixi els errors mostrats abaix."
+#: contrib/admin/templates/admin/object_history.html:20
+msgid "Action"
+msgstr "Acció"
-#: contrib/admin/templates/admin/change_form.html:50
-msgid "Ordering"
-msgstr "Ordre"
+#: contrib/admin/templates/admin/object_history.html:26
+msgid "DATE_WITH_TIME_FULL"
+msgstr "F j, Y, H:i "
-#: contrib/admin/templates/admin/change_form.html:53
-msgid "Order:"
-msgstr "Ordre:"
+#: contrib/admin/templates/admin/object_history.html:36
+msgid ""
+"This object doesn't have a change history. It probably wasn't added via this "
+"admin site."
+msgstr ""
+"Aquest objecte no te historial de canvis. Probablement no va ser afegit "
+"utilitzant aquest lloc administratiu."
#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Benvingut,"
-#: contrib/admin/templates/admin/404.html:4
-#: contrib/admin/templates/admin/404.html:8
-msgid "Page not found"
-msgstr "No s'ha pogut trobar la pàgina"
-
-#: contrib/admin/templates/admin/404.html:10
-msgid "We're sorry, but the requested page could not be found."
-msgstr "Ho sentim, però no s'ha pogut trobar la pàgina solicitada"
-
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:24
-msgid "Log in"
-msgstr "Iniciar sessió"
+#: contrib/admin/templates/admin/invalid_setup.html:8
+msgid ""
+"Something's wrong with your database installation. Make sure the appropriate "
+"database tables have been created, and make sure the database is readable by "
+"the appropriate user."
+msgstr ""
+"Alguna cosa està malament en la instal·lació de la teva base de dades. "
+"Assegurat de que s'han creat les taules, i de que la base de dades és "
+"llegible per l'usuari apropiat."
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/auth/user/change_password.html:28
#, python-format
-msgid "Models available in the %(name)s application."
-msgstr "Models disponibles en la aplicació %(name)s."
-
-#: contrib/admin/templates/admin/index.html:18
-#, fuzzy, python-format
-msgid "%(name)s"
-msgstr "Afegir %(name)s"
-
-#: contrib/admin/templates/admin/index.html:34
-msgid "Change"
-msgstr "Modificar"
-
-#: contrib/admin/templates/admin/index.html:44
-msgid "You don't have permission to edit anything."
-msgstr "No té permís per editar res."
-
-#: contrib/admin/templates/admin/index.html:52
-msgid "Recent Actions"
-msgstr "Accions recents"
-
-#: contrib/admin/templates/admin/index.html:53
-msgid "My Actions"
-msgstr "Les meves accions"
+msgid "Enter a new password for the user <strong>%(username)s</strong>."
+msgstr "Introdueixi una contrasenya per l'usuari <strong>%(username)s</strong>"
-#: contrib/admin/templates/admin/index.html:57
-msgid "None available"
-msgstr "Cap disponible"
+#: contrib/admin/templates/admin/auth/user/change_password.html:34
+#: contrib/admin/templates/admin/auth/user/add_form.html:18
+msgid "Password"
+msgstr "Contrasenya"
-#: contrib/admin/templates/admin/base_site.html:4
-msgid "Django site admin"
-msgstr "Lloc administratiu de Django"
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:23
+msgid "Password (again)"
+msgstr "Contrasenya (de nou)"
-#: contrib/admin/templates/admin/base_site.html:7
-msgid "Django administration"
-msgstr "Adminsitració de Django"
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
+#: contrib/admin/templates/admin/auth/user/add_form.html:24
+msgid "Enter the same password as above, for verification."
+msgstr "Introdueixi la mateixa contrasenya que a sobre, per a verificació."
#: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid ""
"First, enter a username and password. Then, you'll be able to edit more user "
"options."
msgstr ""
+"Primer, entri un usuari i una contrasenya. Després podrà editar més opcions "
+"del usuari."
#: contrib/admin/templates/admin/auth/user/add_form.html:12
-#, fuzzy
msgid "Username"
-msgstr "Usuari:"
+msgstr "Usuari"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
-#: contrib/admin/templates/admin/auth/user/change_password.html:34
-#, fuzzy
-msgid "Password"
-msgstr "Contrasenya:"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+msgid "Bookmarklets"
+msgstr "'Bookmarklets'"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
-#, fuzzy
-msgid "Password (again)"
-msgstr "Canvi de clau"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:5
+msgid "Documentation bookmarklets"
+msgstr "'Bookmarklets' de documentació"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:40
-msgid "Enter the same password as above, for verification."
+#: contrib/admin/templates/admin_doc/bookmarklets.html:9
+msgid ""
+"\n"
+"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
+"toolbar, or right-click the link and add it to your bookmarks. Now you can\n"
+"select the bookmarklet from any page in the site. Note that some of these\n"
+"bookmarklets require you to be viewing the site from a computer designated\n"
+"as \"internal\" (talk to your system administrator if you aren't sure if\n"
+"your computer is \"internal\").</p>\n"
msgstr ""
+"\n"
+"<p class=\"help\">Per a instalar 'bookmarklets', arrosegui l'enllaç a la "
+"seva barra de\n"
+"marcadors, o faci click amb el botò dret en l'enllaç i afegeixi'l als "
+"marcadors.\n"
+"Ara pot escollir el 'bookmarklet' des de qualsevol pàgina del lloc.\n"
+"Observi que alguns d'aquests 'bookmarklets' precisen que estigui veient\n"
+"el lloc des de un ordinador senyalat com a \"intern\" (parli\n"
+"amb el seu administrador de sistemes si no està segur de la condició del "
+"seu).</p>\n"
-#: contrib/admin/templates/admin/auth/user/change_password.html:28
-#, python-format
-msgid "Enter a new password for the user <strong>%(username)s</strong>."
+#: contrib/admin/templates/admin_doc/bookmarklets.html:19
+msgid "Documentation for this page"
+msgstr "Documentació d'aquesta pàgina"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:20
+msgid ""
+"Jumps you from any page to the documentation for the view that generates "
+"that page."
msgstr ""
+"El porta des de qualsevol pàgina de la documentació a la vista que la genera."
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Actualment:"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:22
+msgid "Show object ID"
+msgstr "Mostra el ID de l'objecte"
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Modificar:"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:23
+msgid ""
+"Shows the content-type and unique ID for pages that represent a single "
+"object."
+msgstr ""
+"Mostra el 'content-type' (tipus de contingut) i el ID inequívoc de les "
+"pàgines que representen un únic objecte."
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:25
+msgid "Edit this object (current window)"
+msgstr "Editar aquest objecte (finestra actual)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:26
+msgid "Jumps to the admin page for pages that represent a single object."
+msgstr ""
+"El porta a la pàgina d'administració de pàgines que representen un únic "
+"objecte."
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:28
+msgid "Edit this object (new window)"
+msgstr "Editar aquest objecte (nova finestra)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:29
+msgid "As above, but opens the admin page in a new window."
+msgstr "Com abans, però obre la pàgina d'administració en una nova finestra."
#: contrib/admin/templates/widget/date_time.html:3
msgid "Date:"
@@ -1597,18 +1398,18 @@ msgstr "Data:"
msgid "Time:"
msgstr "Hora:"
-#: contrib/admin/templates/registration/logged_out.html:8
-msgid "Thanks for spending some quality time with the Web site today."
-msgstr "Gràcies per emprar algun temps de cualitat amb el lloc web avui."
+#: contrib/admin/templates/widget/file.html:2
+msgid "Currently:"
+msgstr "Actualment:"
-#: contrib/admin/templates/registration/logged_out.html:10
-msgid "Log in again"
-msgstr "Iniciar sessió de nou"
+#: contrib/admin/templates/widget/file.html:3
+msgid "Change:"
+msgstr "Modificar:"
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
msgstr ""
-"Està rebent aquest missatge degut a que va solicitar un restabliment de "
+"Està rebent aquest missatge degut a que va solicitar un restabliment de "
"contrasenya."
#: contrib/admin/templates/registration/password_reset_email.html:3
@@ -1619,11 +1420,11 @@ msgstr "del seu compte d'usuari a %(site_name)s."
#: contrib/admin/templates/registration/password_reset_email.html:5
#, python-format
msgid "Your new password is: %(new_password)s"
-msgstr "La seva nova contrasenya és: %(new_password)s"
+msgstr "La seva nova contrasenya és: %(new_password)s"
#: contrib/admin/templates/registration/password_reset_email.html:7
msgid "Feel free to change this password by going to this page:"
-msgstr "Sentis lliure de canviar-la en aquesta pàgina:"
+msgstr "Sentis lliure de canviar-la en aquesta pàgina:"
#: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Your username, in case you've forgotten:"
@@ -1631,31 +1432,47 @@ msgstr "El seu nom d'usuari, en cas d'haver-lo oblidat:"
#: contrib/admin/templates/registration/password_reset_email.html:13
msgid "Thanks for using our site!"
-msgstr "Gràcies per fer us del nostre lloc!"
+msgstr "Gràcies per fer us del nostre lloc!"
#: contrib/admin/templates/registration/password_reset_email.html:15
#, python-format
msgid "The %(site_name)s team"
msgstr "L'equip de %(site_name)s"
-#: contrib/admin/templates/registration/password_reset_done.html:4
#: contrib/admin/templates/registration/password_reset_form.html:4
#: contrib/admin/templates/registration/password_reset_form.html:6
#: contrib/admin/templates/registration/password_reset_form.html:10
+#: contrib/admin/templates/registration/password_reset_done.html:4
msgid "Password reset"
msgstr "Restablir contrasenya"
+#: contrib/admin/templates/registration/password_reset_form.html:12
+msgid ""
+"Forgotten your password? Enter your e-mail address below, and we'll reset "
+"your password and e-mail the new one to you."
+msgstr ""
+"Ha oblidat la seva contrasenya? Introdueixi la seva adreça de correu "
+"electrònic i crearem una nova que li enviarem per correu."
+
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "E-mail address:"
+msgstr "Adreça de correu electrònic:"
+
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "Reset my password"
+msgstr "Restablir la meva contrasenya"
+
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
-msgstr "Contrasenya restaber-ta amb èxit"
+msgstr "Contrasenya restaber-ta amb èxit"
#: contrib/admin/templates/registration/password_reset_done.html:12
msgid ""
"We've e-mailed a new password to the e-mail address you submitted. You "
"should be receiving it shortly."
msgstr ""
-"Li hem enviat una contrasenya nova a l'adreça de correu electrònic que ens "
+"Li hem enviat una contrasenya nova a l'adreça de correu electrònic que ens "
"ha indicat. L'hauria de rebre en breu."
#: contrib/admin/templates/registration/password_change_form.html:4
@@ -1693,426 +1510,1228 @@ msgstr "Canviar la meva clau:"
#: contrib/admin/templates/registration/password_change_done.html:6
#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
-msgstr "Canvi de clau exitò"
+msgstr "Canvi de clau exitò"
#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "La seva clau ha estat canviada."
-#: contrib/admin/templates/registration/password_reset_form.html:12
-msgid ""
-"Forgotten your password? Enter your e-mail address below, and we'll reset "
-"your password and e-mail the new one to you."
-msgstr ""
-"Ha oblidat la seva contrasenya? Introdueixi la seva adreça de correu "
-"electrònic i crearem una nova que li enviarem per correu."
+#: contrib/admin/templates/registration/logged_out.html:8
+msgid "Thanks for spending some quality time with the Web site today."
+msgstr "Gràcies per emprar algun temps de cualitat amb el lloc web avui."
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "E-mail address:"
-msgstr "Adreça de correu electrònic:"
+#: contrib/admin/templates/registration/logged_out.html:10
+msgid "Log in again"
+msgstr "Iniciar sessió de nou"
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "Reset my password"
-msgstr "Restablir la meva contrasenya"
+#: contrib/localflavor/fi/forms.py:14 contrib/localflavor/de/forms.py:16
+#: contrib/localflavor/fr/forms.py:17
+msgid "Enter a zip code in the format XXXXX."
+msgstr "Introdueixi un codi zip en el format XXXXX."
-#: contrib/admin/views/main.py:223
-msgid "Site administration"
-msgstr "Lloc administratiu"
+#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
+msgid "Enter a valid Finnish social security number."
+msgstr "Introdueixi un número vàlid de la seguretat social finlandesa."
-#: contrib/admin/views/main.py:257 contrib/admin/views/auth.py:19
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "El/la %(name)s \"%(obj)s\".ha estat agregat/da amb èxit."
+#: contrib/localflavor/jp/forms.py:21
+msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
+msgstr "Introdueixi un codi postal en el format XXXXXXX o XX-XXXX."
-#: contrib/admin/views/main.py:261 contrib/admin/views/main.py:347
-#: contrib/admin/views/auth.py:24
-msgid "You may edit it again below."
-msgstr "Pot editar-lo de nou abaix."
+#: contrib/localflavor/jp/jp_prefectures.py:4
+msgid "Hokkaido"
+msgstr "Hokkaido"
-#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356
-#, python-format
-msgid "You may add another %s below."
-msgstr "Pot agregar un altre %s abaix."
+#: contrib/localflavor/jp/jp_prefectures.py:5
+msgid "Aomori"
+msgstr "Aomori"
-#: contrib/admin/views/main.py:289
-#, python-format
-msgid "Add %s"
-msgstr "Agregar %s"
+#: contrib/localflavor/jp/jp_prefectures.py:6
+msgid "Iwate"
+msgstr "Iwate"
-#: contrib/admin/views/main.py:335
-#, python-format
-msgid "Added %s."
-msgstr "Agregat %s."
+#: contrib/localflavor/jp/jp_prefectures.py:7
+msgid "Miyagi"
+msgstr "Miyagi"
-#: contrib/admin/views/main.py:337
-#, python-format
-msgid "Changed %s."
-msgstr "Modificat %s."
+#: contrib/localflavor/jp/jp_prefectures.py:8
+msgid "Akita"
+msgstr "Akita"
-#: contrib/admin/views/main.py:339
-#, python-format
-msgid "Deleted %s."
-msgstr "Eliminat %s."
+#: contrib/localflavor/jp/jp_prefectures.py:9
+msgid "Yamagata"
+msgstr "Yamagata"
-#: contrib/admin/views/main.py:342
-msgid "No fields changed."
-msgstr "Cap camp canviat."
+#: contrib/localflavor/jp/jp_prefectures.py:10
+msgid "Fukushima"
+msgstr "Fukushima"
-#: contrib/admin/views/main.py:345
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "S'ha modificat amb èxist el/la %(name)s \"%(obj)s."
+#: contrib/localflavor/jp/jp_prefectures.py:11
+msgid "Ibaraki"
+msgstr "Ibaraki"
-#: contrib/admin/views/main.py:353
-#, python-format
+#: contrib/localflavor/jp/jp_prefectures.py:12
+msgid "Tochigi"
+msgstr "Tochigi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:13
+msgid "Gunma"
+msgstr "Gunma"
+
+#: contrib/localflavor/jp/jp_prefectures.py:14
+msgid "Saitama"
+msgstr "Saitama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:15
+msgid "Chiba"
+msgstr "Chiba"
+
+#: contrib/localflavor/jp/jp_prefectures.py:16
+msgid "Tokyo"
+msgstr "Tokyo"
+
+#: contrib/localflavor/jp/jp_prefectures.py:17
+msgid "Kanagawa"
+msgstr "Kanagawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:18
+msgid "Yamanashi"
+msgstr "Yamanashi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:19
+msgid "Nagano"
+msgstr "Nagano"
+
+#: contrib/localflavor/jp/jp_prefectures.py:20
+msgid "Niigata"
+msgstr "Niigata"
+
+#: contrib/localflavor/jp/jp_prefectures.py:21
+msgid "Toyama"
+msgstr "Toyama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:22
+msgid "Ishikawa"
+msgstr "Ishikawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:23
+msgid "Fukui"
+msgstr "Fukui"
+
+#: contrib/localflavor/jp/jp_prefectures.py:24
+msgid "Gifu"
+msgstr "Gifu"
+
+#: contrib/localflavor/jp/jp_prefectures.py:25
+msgid "Shizuoka"
+msgstr "Shizuoka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:26
+msgid "Aichi"
+msgstr "Aichi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:27
+msgid "Mie"
+msgstr "Mie"
+
+#: contrib/localflavor/jp/jp_prefectures.py:28
+msgid "Shiga"
+msgstr "Shiga"
+
+#: contrib/localflavor/jp/jp_prefectures.py:29
+msgid "Kyoto"
+msgstr "Kyoto"
+
+#: contrib/localflavor/jp/jp_prefectures.py:30
+msgid "Osaka"
+msgstr "Osaka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:31
+msgid "Hyogo"
+msgstr "Hyogo"
+
+#: contrib/localflavor/jp/jp_prefectures.py:32
+msgid "Nara"
+msgstr "Nara"
+
+#: contrib/localflavor/jp/jp_prefectures.py:33
+msgid "Wakayama"
+msgstr "Wakayama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:34
+msgid "Tottori"
+msgstr "Tottori"
+
+#: contrib/localflavor/jp/jp_prefectures.py:35
+msgid "Shimane"
+msgstr "Shimane"
+
+#: contrib/localflavor/jp/jp_prefectures.py:36
+msgid "Okayama"
+msgstr "Okayama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:37
+msgid "Hiroshima"
+msgstr "Hiroshima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:38
+msgid "Yamaguchi"
+msgstr "Yamaguchi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:39
+msgid "Tokushima"
+msgstr "Tokushima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:40
+msgid "Kagawa"
+msgstr "Kagawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:41
+msgid "Ehime"
+msgstr "Ehime"
+
+#: contrib/localflavor/jp/jp_prefectures.py:42
+msgid "Kochi"
+msgstr "Kochi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:43
+msgid "Fukuoka"
+msgstr "Fukuoka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:44
+msgid "Saga"
+msgstr "Saga"
+
+#: contrib/localflavor/jp/jp_prefectures.py:45
+msgid "Nagasaki"
+msgstr "Nagasaki"
+
+#: contrib/localflavor/jp/jp_prefectures.py:46
+msgid "Kumamoto"
+msgstr "Kumamoto"
+
+#: contrib/localflavor/jp/jp_prefectures.py:47
+msgid "Oita"
+msgstr "Oita"
+
+#: contrib/localflavor/jp/jp_prefectures.py:48
+msgid "Miyazaki"
+msgstr "Miyazaki"
+
+#: contrib/localflavor/jp/jp_prefectures.py:49
+msgid "Kagoshima"
+msgstr "Kagoshima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:50
+msgid "Okinawa"
+msgstr "Okinawa"
+
+#: contrib/localflavor/it/forms.py:16
+msgid "Enter a valid zip code."
+msgstr "Introdueixi un codi zip vàlid."
+
+#: contrib/localflavor/it/forms.py:41
+msgid "Enter a valid Social Security number."
+msgstr "Introdueixi un número valid de la Seguretat Social."
+
+#: contrib/localflavor/it/forms.py:68
+msgid "Enter a valid VAT number."
+msgstr "Introdueixi un número de IVA (VAT) vàlid."
+
+#: contrib/localflavor/de/forms.py:60
msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
msgstr ""
-"S'ha agregat amb èxit el/la %(name)s \"%(obj)s\". Pot editar-lo de nou abaix."
+"Introdueixi un número de tarjeta d'identificació alemany vàlid en el format "
+"XXXXXXXXXXX-XXXXXXX-XXXXXXX-X."
-#: contrib/admin/views/main.py:391
-#, python-format
-msgid "Change %s"
-msgstr "Modificar %s"
+#: contrib/localflavor/de/de_states.py:5
+msgid "Baden-Wuerttemberg"
+msgstr "Baden-Wuerttemberg"
-#: contrib/admin/views/main.py:473
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Un o més %(fieldname)s en %(name)s: %(obj)s"
+#: contrib/localflavor/de/de_states.py:6
+msgid "Bavaria"
+msgstr "Bavaria"
-#: contrib/admin/views/main.py:478
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Un o més %(fieldname)s en %(name)s:"
+#: contrib/localflavor/de/de_states.py:7
+msgid "Berlin"
+msgstr "Berlin"
-#: contrib/admin/views/main.py:511
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "El/la %(name)s \"%(obj)s\".ha estat eliminat amb èxit."
+#: contrib/localflavor/de/de_states.py:8
+msgid "Brandenburg"
+msgstr "Brandenburg"
-#: contrib/admin/views/main.py:514
-msgid "Are you sure?"
-msgstr "Està segur?"
+#: contrib/localflavor/de/de_states.py:9
+msgid "Bremen"
+msgstr "Bremen"
-#: contrib/admin/views/main.py:536
-#, python-format
-msgid "Change history: %s"
-msgstr "Modificar històric: %s"
+#: contrib/localflavor/de/de_states.py:10
+msgid "Hamburg"
+msgstr "Hamburg"
-#: contrib/admin/views/main.py:570
-#, python-format
-msgid "Select %s"
-msgstr "Seleccioni %s"
+#: contrib/localflavor/de/de_states.py:11
+msgid "Hessen"
+msgstr "Hessen"
-#: contrib/admin/views/main.py:570
-#, python-format
-msgid "Select %s to change"
-msgstr "Seleccioni %s per modificar"
+#: contrib/localflavor/de/de_states.py:12
+msgid "Mecklenburg-Western Pomerania"
+msgstr "Mecklenburg-Western Pomerania"
-#: contrib/admin/views/main.py:758
-msgid "Database error"
+#: contrib/localflavor/de/de_states.py:13
+msgid "Lower Saxony"
+msgstr "Lower Saxony"
+
+#: contrib/localflavor/de/de_states.py:14
+msgid "North Rhine-Westphalia"
+msgstr "North Rhine-Westphalia"
+
+#: contrib/localflavor/de/de_states.py:15
+msgid "Rhineland-Palatinate"
+msgstr "Rhineland-Palatinate"
+
+#: contrib/localflavor/de/de_states.py:16
+msgid "Saarland"
+msgstr "Saarland"
+
+#: contrib/localflavor/de/de_states.py:17
+msgid "Saxony"
+msgstr "Saxony"
+
+#: contrib/localflavor/de/de_states.py:18
+msgid "Saxony-Anhalt"
+msgstr "Saxony-Anhalt"
+
+#: contrib/localflavor/de/de_states.py:19
+msgid "Schleswig-Holstein"
+msgstr "Schleswig-Holstein"
+
+#: contrib/localflavor/de/de_states.py:20
+msgid "Thuringia"
+msgstr "Thuringia"
+
+#: contrib/localflavor/us/forms.py:18
+msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
+msgstr "Introdueixi un codi zip en el format XXXXX o XXXXX-XXXX."
+
+#: contrib/localflavor/us/forms.py:51
+msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
msgstr ""
+"Introdueixi un número vàlid de la Seguretat Social dels E.U.A. en el format "
+"XXX-XX-XXXX."
-#: contrib/admin/views/decorators.py:62
+#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:15
+msgid "Enter a zip code in the format XXXX."
+msgstr "Introdueixi un codi zip en el format XXXX."
+
+#: contrib/localflavor/ch/forms.py:90
msgid ""
-"Please log in again, because your session has expired. Don't worry: Your "
-"submission has been saved."
+"Enter a valid Swiss identity or passport card number in X1234567<0 or "
+"1234567890 format."
msgstr ""
-"Si us plau, identifiquis de nou doncs la seva sessió ha expirat. No es "
-"preocupi, el seu enviament està emmagatzemat."
+"Introdueixi un número de identificació o de passaport Suïssos en els formats "
+"1234567890 o X1234567<0."
-#: contrib/admin/views/decorators.py:69
+#: contrib/localflavor/ch/ch_states.py:5
+msgid "Aargau"
+msgstr "Argau"
+
+#: contrib/localflavor/ch/ch_states.py:6
+msgid "Appenzell Innerrhoden"
+msgstr "Appenzell Innerrhoden"
+
+#: contrib/localflavor/ch/ch_states.py:7
+msgid "Appenzell Ausserrhoden"
+msgstr "Appenzell Ausserrhoden"
+
+#: contrib/localflavor/ch/ch_states.py:8
+msgid "Basel-Stadt"
+msgstr "Basel-Stadt"
+
+#: contrib/localflavor/ch/ch_states.py:9
+msgid "Basel-Land"
+msgstr "Basel-Land"
+
+#: contrib/localflavor/ch/ch_states.py:10
+msgid "Berne"
+msgstr "Berne"
+
+#: contrib/localflavor/ch/ch_states.py:11
+msgid "Fribourg"
+msgstr "Fribourg"
+
+#: contrib/localflavor/ch/ch_states.py:12
+msgid "Geneva"
+msgstr "Geneva"
+
+#: contrib/localflavor/ch/ch_states.py:13
+msgid "Glarus"
+msgstr "Glarus"
+
+#: contrib/localflavor/ch/ch_states.py:14
+msgid "Graubuenden"
+msgstr "Graubuenden"
+
+#: contrib/localflavor/ch/ch_states.py:15
+msgid "Jura"
+msgstr "Jura"
+
+#: contrib/localflavor/ch/ch_states.py:16
+msgid "Lucerne"
+msgstr "Lucerne"
+
+#: contrib/localflavor/ch/ch_states.py:17
+msgid "Neuchatel"
+msgstr "Neuchatel"
+
+#: contrib/localflavor/ch/ch_states.py:18
+msgid "Nidwalden"
+msgstr "Nidwalden"
+
+#: contrib/localflavor/ch/ch_states.py:19
+msgid "Obwalden"
+msgstr "Obwalden"
+
+#: contrib/localflavor/ch/ch_states.py:20
+msgid "Schaffhausen"
+msgstr "Schaffhausen"
+
+#: contrib/localflavor/ch/ch_states.py:21
+msgid "Schwyz"
+msgstr "Schwyz"
+
+#: contrib/localflavor/ch/ch_states.py:22
+msgid "Solothurn"
+msgstr "Solothurn"
+
+#: contrib/localflavor/ch/ch_states.py:23
+msgid "St. Gallen"
+msgstr "St. Gallen"
+
+#: contrib/localflavor/ch/ch_states.py:24
+msgid "Thurgau"
+msgstr "Thurgau"
+
+#: contrib/localflavor/ch/ch_states.py:25
+msgid "Ticino"
+msgstr "Ticino"
+
+#: contrib/localflavor/ch/ch_states.py:26
+msgid "Uri"
+msgstr "Uri"
+
+#: contrib/localflavor/ch/ch_states.py:27
+msgid "Valais"
+msgstr "Valais"
+
+#: contrib/localflavor/ch/ch_states.py:28
+msgid "Vaud"
+msgstr "Vaud"
+
+#: contrib/localflavor/ch/ch_states.py:29
+msgid "Zug"
+msgstr "Zug"
+
+#: contrib/localflavor/ch/ch_states.py:30
+msgid "Zurich"
+msgstr "Zurich"
+
+#: contrib/localflavor/au/forms.py:18
+msgid "Enter a 4 digit post code."
+msgstr "Introdueixi un codi postal de 4 dígits."
+
+#: contrib/localflavor/is_/forms.py:16
msgid ""
-"Looks like your browser isn't configured to accept cookies. Please enable "
-"cookies, reload this page, and try again."
+"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
msgstr ""
-"Sembla ser que el seu navegador no està configurat per acceptar "
-"'cookies' (galetes). Si us plau, habiliti les 'cookies', recarregui aquesta "
-"pàgina i provi-ho de nou. "
+"Introdueixi un número de identificació d'Islàndia. El format és XXXXXX-XXXX."
-#: contrib/admin/views/decorators.py:83
-msgid "Usernames cannot contain the '@' character."
-msgstr "Els noms d'usuari no poden contenir el caracter '@'."
+#: contrib/localflavor/is_/forms.py:30
+msgid "The Icelandic identification number is not valid."
+msgstr "El número de identificació d'Islàndia no és vàlid."
-#: contrib/admin/views/decorators.py:85
-#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
+#: contrib/localflavor/br/forms.py:18
+msgid "Enter a zip code in the format XXXXX-XXX."
+msgstr "Introdueixi un codi zip en el format XXXXX-XXX."
+
+#: contrib/localflavor/br/forms.py:30
+msgid "Phone numbers must be in XX-XXXX-XXXX format."
+msgstr "El número de telèfon ha de ser en el format XX-XXXX-XXXX."
+
+#: contrib/localflavor/br/forms.py:72
+msgid "This field requires only numbers."
+msgstr "Aquest camps requereix només números."
+
+#: contrib/localflavor/br/forms.py:74
+msgid "This field requires at most 11 digits or 14 characters."
+msgstr "Aquest camp requereix com a màxim 11 dígits o 14 caracters."
+
+#: contrib/localflavor/br/forms.py:84
+msgid "Invalid CPF number."
+msgstr "Número CPF invàlid."
+
+#: contrib/localflavor/br/forms.py:106
+msgid "This field requires at least 14 digits"
+msgstr "Aquest camp requereix almenys 14 dígits."
+
+#: contrib/localflavor/br/forms.py:116
+msgid "Invalid CNPJ number."
+msgstr "Número CNPJ invàlid."
+
+#: contrib/localflavor/cl/forms.py:21
+msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
+msgstr "Introdueixi un RUT Xilè vàlid. El format és XX.XXX.XXX-X"
+
+#: contrib/localflavor/cl/forms.py:26
+msgid "Enter valid a Chilean RUT"
+msgstr "Introdueixi un RUT Xilè vàlid."
+
+#: contrib/localflavor/no/forms.py:36
+msgid "Enter a valid Norwegian social security number."
+msgstr "Introdueixi un número de la seguretat social Noruega vàlid."
+
+#: contrib/localflavor/uk/forms.py:18
+msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr ""
-"La seva adreça de correu no és el seu nom d'usuari. Provi '%s' en tot cas."
+"Introdueixi un codi postal. És necessari un espai entre les dues parts del "
+"codi postal."
-#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48
-#: contrib/admin/views/doc.py:50
-msgid "tag:"
+#: contrib/sessions/models.py:68
+msgid "session key"
+msgstr "clau de la sessió"
+
+#: contrib/sessions/models.py:69
+msgid "session data"
+msgstr "dades de la sessió"
+
+#: contrib/sessions/models.py:70
+msgid "expire date"
+msgstr "data de caducitat"
+
+#: contrib/sessions/models.py:74
+msgid "session"
+msgstr "sessió"
+
+#: contrib/sessions/models.py:75
+msgid "sessions"
+msgstr "sessions"
+
+#: contrib/flatpages/models.py:8
+msgid ""
+"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
+"Exemple: '/about/contact/'. Asseguri's de posar les barres al principi i al "
+"final."
-#: contrib/admin/views/doc.py:77 contrib/admin/views/doc.py:79
-#: contrib/admin/views/doc.py:81
-msgid "filter:"
+#: contrib/flatpages/models.py:9
+msgid "title"
+msgstr "tìtol"
+
+#: contrib/flatpages/models.py:10
+msgid "content"
+msgstr "contingut"
+
+#: contrib/flatpages/models.py:11
+msgid "enable comments"
+msgstr "habilitar comentaris"
+
+#: contrib/flatpages/models.py:12
+msgid "template name"
+msgstr "nom de la plantilla"
+
+#: contrib/flatpages/models.py:13
+msgid ""
+"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
+"will use 'flatpages/default.html'."
msgstr ""
+"Exemple: 'flatpages/contact_page.html'. Si no el proporciona, el sistema "
+"utilitzarà 'flatpages/defaula.htmlt'."
-#: contrib/admin/views/doc.py:135 contrib/admin/views/doc.py:137
-#: contrib/admin/views/doc.py:139
-msgid "view:"
+#: contrib/flatpages/models.py:14
+msgid "registration required"
+msgstr "s'ha de estar registrat"
+
+#: contrib/flatpages/models.py:14
+msgid "If this is checked, only logged-in users will be able to view the page."
+msgstr "Si està marcat, només els usuaris registrats podran veure la pàgina."
+
+#: contrib/flatpages/models.py:18
+msgid "flat page"
+msgstr "pàgina estàtica"
+
+#: contrib/flatpages/models.py:19
+msgid "flat pages"
+msgstr "pàgines estàtiques"
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "th"
msgstr ""
-#: contrib/admin/views/doc.py:164
-#, fuzzy, python-format
-msgid "App %r not found"
-msgstr "No s'ha pogut trobar la pàgina"
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "st"
+msgstr "r"
-#: contrib/admin/views/doc.py:171
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "nd"
+msgstr "n"
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "rd"
+msgstr "r"
+
+#: contrib/humanize/templatetags/humanize.py:47
#, python-format
-msgid "Model %r not found in app %r"
-msgstr ""
+msgid "%(value).1f million"
+msgid_plural "%(value).1f million"
+msgstr[0] "%(value).1f milió"
+msgstr[1] "%(value).1f milions"
-#: contrib/admin/views/doc.py:183
+#: contrib/humanize/templatetags/humanize.py:50
#, python-format
-msgid "the related `%s.%s` object"
-msgstr ""
+msgid "%(value).1f billion"
+msgid_plural "%(value).1f billion"
+msgstr[0] "%(value).1f bilió"
+msgstr[1] "%(value).1f bilions"
-#: contrib/admin/views/doc.py:183 contrib/admin/views/doc.py:205
-#: contrib/admin/views/doc.py:219 contrib/admin/views/doc.py:224
-msgid "model:"
+#: contrib/humanize/templatetags/humanize.py:53
+#, python-format
+msgid "%(value).1f trillion"
+msgid_plural "%(value).1f trillion"
+msgstr[0] "%(value).1f trilió"
+msgstr[1] "%(value).1f trilions"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "one"
+msgstr "un"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "two"
+msgstr "dos"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "three"
+msgstr "tres"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "four"
+msgstr "cuatre"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "five"
+msgstr "cinc"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "six"
+msgstr "sis"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "seven"
+msgstr "set"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "eight"
+msgstr "vuit"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "nine"
+msgstr "nou"
+
+#: contrib/contenttypes/models.py:36
+msgid "python model class name"
+msgstr "nom de la classe del model en python"
+
+#: contrib/contenttypes/models.py:39
+msgid "content type"
+msgstr "tipus de contingut"
+
+#: contrib/contenttypes/models.py:40
+msgid "content types"
+msgstr "tipus de continguts"
+
+#: contrib/sites/models.py:10
+msgid "domain name"
+msgstr "nom del domini"
+
+#: contrib/sites/models.py:11
+msgid "display name"
+msgstr "nom per mostrar"
+
+#: contrib/sites/models.py:15
+msgid "site"
+msgstr "lloc"
+
+#: contrib/sites/models.py:16
+msgid "sites"
+msgstr "llocs"
+
+#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+msgid "The two password fields didn't match."
+msgstr "Els dos camps de contrasenya no coincideixen."
+
+#: contrib/auth/forms.py:25
+msgid "A user with that username already exists."
+msgstr "Ja existeix un usuari amb aquest nom."
+
+#: contrib/auth/forms.py:53
+msgid ""
+"Your Web browser doesn't appear to have cookies enabled. Cookies are "
+"required for logging in."
msgstr ""
+"El seu navegador no sembla tenir les 'cookies' (galetes) activades. Aquestes "
+"són necessàries per iniciar la sessió."
-#: contrib/admin/views/doc.py:214
-#, python-format
-msgid "related `%s.%s` objects"
+#: contrib/auth/forms.py:62
+msgid "This account is inactive."
+msgstr "Aquest compte està inactiu"
+
+#: contrib/auth/forms.py:85
+msgid ""
+"That e-mail address doesn't have an associated user account. Are you sure "
+"you've registered?"
msgstr ""
-#: contrib/admin/views/doc.py:219
-#, python-format
-msgid "all %s"
+#: contrib/auth/forms.py:117
+msgid "The two 'new password' fields didn't match."
+msgstr "Els dos camps de nova contrasenya no coincideixen."
+
+#: contrib/auth/forms.py:124
+msgid "Your old password was entered incorrectly. Please enter it again."
msgstr ""
+"La seva antiga contrasenya no és correcte. Si el plau, introdueixi-la de nou."
-#: contrib/admin/views/doc.py:224
-#, python-format
-msgid "number of %s"
+#: contrib/auth/views.py:40
+msgid "Logged out"
+msgstr "Sessió finalitzada"
+
+#: contrib/auth/models.py:44 contrib/auth/models.py:64
+msgid "name"
+msgstr "nom"
+
+#: contrib/auth/models.py:46
+msgid "codename"
+msgstr "nom en clau"
+
+#: contrib/auth/models.py:49
+msgid "permission"
+msgstr "permís"
+
+#: contrib/auth/models.py:50 contrib/auth/models.py:65
+msgid "permissions"
+msgstr "permissos"
+
+#: contrib/auth/models.py:68
+msgid "group"
+msgstr "grup"
+
+#: contrib/auth/models.py:69 contrib/auth/models.py:109
+msgid "groups"
+msgstr "grups"
+
+#: contrib/auth/models.py:99
+msgid "username"
+msgstr "nom d'usuari"
+
+#: contrib/auth/models.py:99
+msgid ""
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
msgstr ""
+"Requerit. 30 o menys caracters. Només caracters alfanumèrics (lletres, "
+"dígits i guions baixos)."
-#: contrib/admin/views/doc.py:229
-#, python-format
-msgid "Fields on %s objects"
+#: contrib/auth/models.py:100
+msgid "first name"
+msgstr "nom propi"
+
+#: contrib/auth/models.py:101
+msgid "last name"
+msgstr "cognoms"
+
+#: contrib/auth/models.py:102
+msgid "e-mail address"
+msgstr "adreça de correu electrònic"
+
+#: contrib/auth/models.py:103
+msgid "password"
+msgstr "contrasenya"
+
+#: contrib/auth/models.py:103
+msgid ""
+"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
+"password form</a>."
msgstr ""
+"Utilitzi '[algo]$[salt]$[hexdigest]' o el <a href=\"password/\">formulari de "
+"canvi de contrasenya</a>."
-#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:301
-#: contrib/admin/views/doc.py:303 contrib/admin/views/doc.py:309
-#: contrib/admin/views/doc.py:310 contrib/admin/views/doc.py:312
-msgid "Integer"
-msgstr "Enter"
+#: contrib/auth/models.py:104
+msgid "staff status"
+msgstr "és membre del personal"
-#: contrib/admin/views/doc.py:292
-msgid "Boolean (Either True or False)"
-msgstr "Booleà (Verdader o Fals)"
+#: contrib/auth/models.py:104
+msgid "Designates whether the user can log into this admin site."
+msgstr "Indica si l'usuari pot entrar en el lloc administratiu."
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:311
-#, python-format
-msgid "String (up to %(maxlength)s)"
-msgstr "Cadena (fins a %(maxlength)s)"
+#: contrib/auth/models.py:105
+msgid "active"
+msgstr "actiu"
-#: contrib/admin/views/doc.py:294
-msgid "Comma-separated integers"
-msgstr "Enters separats per comes"
+#: contrib/auth/models.py:105
+msgid ""
+"Designates whether this user can log into the Django admin. Unselect this "
+"instead of deleting accounts."
+msgstr ""
+"Designa si aquest usuari pot iniciar sessió a la interfície administrativa "
+"Djano. Deselecciona-ho enlloc de esborrar comptes d'usuari."
-#: contrib/admin/views/doc.py:295
-msgid "Date (without time)"
-msgstr "Data (sense hora)"
+#: contrib/auth/models.py:106
+msgid "superuser status"
+msgstr "estat de superusuari"
-#: contrib/admin/views/doc.py:296
-msgid "Date (with time)"
-msgstr "Data (amb hora)"
+#: contrib/auth/models.py:106
+msgid ""
+"Designates that this user has all permissions without explicitly assigning "
+"them."
+msgstr ""
+"Designa que aquest usuari té tots els permisos sense assignar-los "
+"explícitament."
-#: contrib/admin/views/doc.py:297
-msgid "E-mail address"
-msgstr "Adreça de correu electrònic"
+#: contrib/auth/models.py:107
+msgid "last login"
+msgstr "últim inici de sessió"
-#: contrib/admin/views/doc.py:298 contrib/admin/views/doc.py:299
-#: contrib/admin/views/doc.py:302
-msgid "File path"
-msgstr "Ruta del fitxer"
+#: contrib/auth/models.py:108
+msgid "date joined"
+msgstr "data de creació"
-#: contrib/admin/views/doc.py:300
-msgid "Decimal number"
-msgstr "Número decimal"
+#: contrib/auth/models.py:110
+msgid ""
+"In addition to the permissions manually assigned, this user will also get "
+"all permissions granted to each group he/she is in."
+msgstr ""
+"Junt amb els permissos asignats manualment, aquest usuari tindrà, també, els "
+"permissos dels grups dels que sigui membre."
-#: contrib/admin/views/doc.py:306
-msgid "Boolean (Either True, False or None)"
-msgstr "Booleà (Verdader, Fals o 'None' (cap))"
+#: contrib/auth/models.py:111
+msgid "user permissions"
+msgstr "permissos de l'usuari"
-#: contrib/admin/views/doc.py:307
-msgid "Relation to parent model"
-msgstr "Relació amb el model pare"
+#: contrib/auth/models.py:115
+msgid "user"
+msgstr "usuari"
-#: contrib/admin/views/doc.py:308
-msgid "Phone number"
-msgstr "Número de telèfon"
+#: contrib/auth/models.py:116
+msgid "users"
+msgstr "usuaris"
-#: contrib/admin/views/doc.py:313
-msgid "Text"
-msgstr "Texte"
+#: contrib/auth/models.py:122
+msgid "Personal info"
+msgstr "Informaciò personal"
-#: contrib/admin/views/doc.py:314
-msgid "Time"
-msgstr "Hora"
+#: contrib/auth/models.py:123
+msgid "Permissions"
+msgstr "permissos"
-#: contrib/admin/views/doc.py:316
-msgid "U.S. state (two uppercase letters)"
-msgstr "Estat dels E.U.A. (dos lletres majúscules)"
+#: contrib/auth/models.py:124
+msgid "Important dates"
+msgstr "Dates importants"
-#: contrib/admin/views/doc.py:317
-msgid "XML text"
-msgstr "Texte XML"
+#: contrib/auth/models.py:125
+msgid "Groups"
+msgstr "Grups"
-#: contrib/admin/views/doc.py:343
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
+#: contrib/auth/models.py:269
+msgid "message"
+msgstr "missatge"
+
+#: newforms/models.py:173 newforms/fields.py:366
+msgid "Select a valid choice. That choice is not one of the available choices."
msgstr ""
+"Esculli una opció vàlida; Aquesta opció no és una de les opcions disponibles."
-#: contrib/admin/views/auth.py:30
-#, fuzzy
-msgid "Add user"
-msgstr "Agregar %s"
+#: newforms/models.py:186 newforms/fields.py:82 newforms/fields.py:378
+#: newforms/fields.py:454 newforms/fields.py:465
+#: db/models/fields/__init__.py:117 db/models/fields/__init__.py:274
+#: db/models/fields/__init__.py:612 db/models/fields/__init__.py:623
+#: oldforms/__init__.py:357
+msgid "This field is required."
+msgstr "Aquest camp és obligatori."
-#: contrib/admin/views/auth.py:57
-#, fuzzy
-msgid "Password changed successfully."
-msgstr "Canvi de clau exitò"
+#: newforms/models.py:190 newforms/fields.py:382 newforms/fields.py:458
+msgid "Enter a list of values."
+msgstr "Introdueixi una llista de valors."
-#: contrib/admin/views/auth.py:64
-#, fuzzy, python-format
-msgid "Change password: %s"
-msgstr "Canviar clau"
+#: newforms/models.py:196 newforms/fields.py:391
+#, python-format
+msgid "Select a valid choice. %s is not one of the available choices."
+msgstr "Esculli una opció vàlida; %s' no és una de les opcions vàlides."
-#: newforms/fields.py:101 newforms/fields.py:254
-#, fuzzy, python-format
+#: newforms/fields.py:105 newforms/fields.py:258
+#, python-format
msgid "Ensure this value has at most %d characters."
-msgstr "Aseguris de que el seu texte té menys de %s caracter."
+msgstr "Asseguris de que el seu texte té com a màxim %d caracters."
-#: newforms/fields.py:103 newforms/fields.py:256
-#, fuzzy, python-format
+#: newforms/fields.py:107 newforms/fields.py:260
+#, python-format
msgid "Ensure this value has at least %d characters."
-msgstr "Aseguris de que el seu texte té menys de %s caracter."
+msgstr "Asseguris de que el seu texte té almenys %d caracters."
-#: newforms/fields.py:126 core/validators.py:120
+#: newforms/fields.py:130 core/validators.py:120
msgid "Enter a whole number."
-msgstr "Introdueixi un número senser."
+msgstr "Introdueixi un número sencer."
-#: newforms/fields.py:128
-#, fuzzy, python-format
+#: newforms/fields.py:132
+#, python-format
msgid "Ensure this value is less than or equal to %s."
-msgstr "Aquest valor ha de ser una potència de %s."
+msgstr "Aquest valor ha de ser menor o igual a %s."
-#: newforms/fields.py:130
+#: newforms/fields.py:134
#, python-format
msgid "Ensure this value is greater than or equal to %s."
-msgstr ""
+msgstr "Asseguris de que aquest valor sigui superior o igual a %s."
-#: newforms/fields.py:163
-#, fuzzy
+#: newforms/fields.py:167
msgid "Enter a valid date."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introdueixi una data vàlida."
-#: newforms/fields.py:190
-#, fuzzy
+#: newforms/fields.py:194
msgid "Enter a valid time."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introdueixi una hora vàlida."
-#: newforms/fields.py:226
-#, fuzzy
+#: newforms/fields.py:230
msgid "Enter a valid date/time."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introdueixi una data/hora vàlides."
-#: newforms/fields.py:240
-#, fuzzy
+#: newforms/fields.py:244
msgid "Enter a valid value."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introdueixi un valor vàlid."
-#: newforms/fields.py:269 core/validators.py:161
+#: newforms/fields.py:273 core/validators.py:162
msgid "Enter a valid e-mail address."
-msgstr "Introdueixi una adreça de correu vàlida."
+msgstr "Introdueixi una adreça de correu vàlida."
-#: newforms/fields.py:287 newforms/fields.py:309
-#, fuzzy
+#: newforms/fields.py:291 newforms/fields.py:313
msgid "Enter a valid URL."
-msgstr "Introdueixi un nom de fitxer vàlid."
+msgstr "Introdueixi una URL vàlida."
-#: newforms/fields.py:311
-#, fuzzy
+#: newforms/fields.py:315
msgid "This URL appears to be a broken link."
-msgstr "La URL %sés un enllaç trencat."
+msgstr "Aquesta URL sembla ser un enllaç trencat."
-#: newforms/fields.py:359
-#, fuzzy
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Esculli una opció vàlida; %(data)s' no està dintre de %(choices)s."
+#: db/models/manipulators.py:307
+#, python-format
+msgid "%(object)s with this %(type)s already exists for the given %(field)s."
+msgstr "Ja existeix un %(object)s del tipus %(type)s amb aquest %(field)s."
-#: newforms/fields.py:377 newforms/fields.py:453
-#, fuzzy
-msgid "Enter a list of values."
-msgstr "Introdueixi un nom de fitxer vàlid."
+#: db/models/fields/related.py:53
+#, python-format
+msgid "Please enter a valid %s."
+msgstr "Si us plau, introdueixi un %s vàlid."
-#: newforms/fields.py:386
-#, fuzzy, python-format
-msgid "Select a valid choice. %s is not one of the available choices."
-msgstr "Esculli una opció vàlida; %(data)s' no està dintre de %(choices)s."
+#: db/models/fields/related.py:642
+msgid "Separate multiple IDs with commas."
+msgstr "Separi múltiples IDs amb comes."
-#: template/defaultfilters.py:436
-msgid "yes,no,maybe"
-msgstr "si,no,potser"
+#: db/models/fields/related.py:644
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr "Premi \"Control\" o \"Command\" en un Mac per escollir més d'un."
+
+#: db/models/fields/related.py:691
+#, python-format
+msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
+msgid_plural ""
+"Please enter valid %(self)s IDs. The values %(value)r are invalid."
+msgstr[0] ""
+"Si us plau, introdueixi IDs de %(self)s vàlids. El valor %(value)r és "
+"invàlid."
+msgstr[1] ""
+"Si us plau, introdueixi IDs de %(self)s vàlids. Els valors %(value)r són "
+"invàlids."
+
+#: db/models/fields/__init__.py:42
+#, python-format
+msgid "%(optname)s with this %(fieldname)s already exists."
+msgstr "Ja existeix %(optname)s amb auqest %(fieldname)s."
+
+#: db/models/fields/__init__.py:369
+msgid "This value must be an integer."
+msgstr "Aquest valor ha de ser un enter."
+
+#: db/models/fields/__init__.py:404
+msgid "This value must be either True or False."
+msgstr "Aquest valor ha de ser True (Veritat) o False (Fals)"
+
+#: db/models/fields/__init__.py:425
+msgid "This field cannot be null."
+msgstr "Aquest camp no pot ser null (estar buit)."
+
+#: db/models/fields/__init__.py:459 core/validators.py:148
+msgid "Enter a valid date in YYYY-MM-DD format."
+msgstr "Introdueixi una data vàlida en el forma AAAA-MM-DD."
+
+#: db/models/fields/__init__.py:528 core/validators.py:157
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
+msgstr "Introdueixi un data/hora vàlida en format YYYY-MM-DD HH:MM."
+
+#: db/models/fields/__init__.py:632
+msgid "Enter a valid filename."
+msgstr "Introdueixi un nom de fitxer vàlid."
+
+#: db/models/fields/__init__.py:753
+msgid "This value must be either None, True or False."
+msgstr "Aquest valor ha de ser None (Cap), True (Veritat) o False (Fals)"
#: views/generic/create_update.py:43
-#, fuzzy, python-format
+#, python-format
msgid "The %(verbose_name)s was created successfully."
-msgstr "S'ha modificat amb èxist el/la %(name)s \"%(obj)s."
+msgstr "El/La %(verbose_name)s s'ha creat amb èxit."
#: views/generic/create_update.py:117
-#, fuzzy, python-format
+#, python-format
msgid "The %(verbose_name)s was updated successfully."
-msgstr "El/la %(name)s \"%(obj)s\".ha estat eliminat amb èxit."
+msgstr "El/La %(verbose_name)s s'ha actualtzat amb èxit."
#: views/generic/create_update.py:184
-#, fuzzy, python-format
+#, python-format
msgid "The %(verbose_name)s was deleted."
-msgstr "L'equip de %(site_name)s"
+msgstr "El %(verbose_name)s s'ha eliminat."
+
+#: oldforms/__init__.py:392
+#, python-format
+msgid "Ensure your text is less than %s character."
+msgid_plural "Ensure your text is less than %s characters."
+msgstr[0] "Asseguris de que el seu texte té menys de %s caracter."
+msgstr[1] "Asseguris de que el seu texte té menys de %s caracters."
+
+#: oldforms/__init__.py:397
+msgid "Line breaks are not allowed here."
+msgstr "No es permeten salts de línia."
+
+#: oldforms/__init__.py:498 oldforms/__init__.py:571 oldforms/__init__.py:610
+#, python-format
+msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
+msgstr "Esculli una opció vàlida; %(data)s' no està dintre de %(choices)s."
+
+#: oldforms/__init__.py:672 core/validators.py:174 core/validators.py:445
+msgid "No file was submitted. Check the encoding type on the form."
+msgstr ""
+"No s'ha enviat cap fitxer. Comprovi el tipus de codificació del formulari."
+
+#: oldforms/__init__.py:674
+msgid "The submitted file is empty."
+msgstr "El fitxer enviat està buit."
+
+#: oldforms/__init__.py:730
+msgid "Enter a whole number between -32,768 and 32,767."
+msgstr "Introdueixi un número enter entre -32,768 i 32,767."
+
+#: oldforms/__init__.py:740
+msgid "Enter a positive number."
+msgstr "Introdueixi un número positiu."
+
+#: oldforms/__init__.py:750
+msgid "Enter a whole number between 0 and 32,767."
+msgstr "Introdueixi un número entre 0 i 32,767."
+
+#: conf/global_settings.py:39
+msgid "Arabic"
+msgstr "Arabic"
+
+#: conf/global_settings.py:40
+msgid "Bengali"
+msgstr "Bengalí"
+
+#: conf/global_settings.py:41
+msgid "Bulgarian"
+msgstr "Bulgar"
+
+#: conf/global_settings.py:42
+msgid "Catalan"
+msgstr "Català"
+
+#: conf/global_settings.py:43
+msgid "Czech"
+msgstr "Txec"
+
+#: conf/global_settings.py:44
+msgid "Welsh"
+msgstr "Galès"
+
+#: conf/global_settings.py:45
+msgid "Danish"
+msgstr "Danès"
+
+#: conf/global_settings.py:46
+msgid "German"
+msgstr "Alemany"
+
+#: conf/global_settings.py:47
+msgid "Greek"
+msgstr "Grec"
+
+#: conf/global_settings.py:48
+msgid "English"
+msgstr "Anglès"
+
+#: conf/global_settings.py:49
+msgid "Spanish"
+msgstr "Espanyol"
+
+#: conf/global_settings.py:50
+msgid "Argentinean Spanish"
+msgstr "Castellà Argentí"
+
+#: conf/global_settings.py:51
+msgid "Finnish"
+msgstr "Finlandès"
+
+#: conf/global_settings.py:52
+msgid "French"
+msgstr "Francès"
+
+#: conf/global_settings.py:53
+msgid "Galician"
+msgstr "Galleg"
+
+#: conf/global_settings.py:54
+msgid "Hungarian"
+msgstr "Húngar"
+
+#: conf/global_settings.py:55
+msgid "Hebrew"
+msgstr "Hebreu"
+
+#: conf/global_settings.py:56
+msgid "Icelandic"
+msgstr "Islandès"
+
+#: conf/global_settings.py:57
+msgid "Italian"
+msgstr "Italià"
+
+#: conf/global_settings.py:58
+msgid "Japanese"
+msgstr "Japonès"
+
+#: conf/global_settings.py:59
+msgid "Korean"
+msgstr "Coreà"
+
+#: conf/global_settings.py:60
+msgid "Kannada"
+msgstr ""
+
+#: conf/global_settings.py:61
+msgid "Latvian"
+msgstr ""
+
+#: conf/global_settings.py:62
+msgid "Macedonian"
+msgstr "Macedoni"
+
+#: conf/global_settings.py:63
+msgid "Dutch"
+msgstr "Holandès"
+
+#: conf/global_settings.py:64
+msgid "Norwegian"
+msgstr "Norueg"
+
+#: conf/global_settings.py:65
+msgid "Polish"
+msgstr "Polac"
+
+#: conf/global_settings.py:66
+msgid "Portugese"
+msgstr "Portuguès"
+
+#: conf/global_settings.py:67
+msgid "Brazilian"
+msgstr "Brasileny"
+
+#: conf/global_settings.py:68
+msgid "Romanian"
+msgstr "Rumanès"
+
+#: conf/global_settings.py:69
+msgid "Russian"
+msgstr "Rús"
+
+#: conf/global_settings.py:70
+msgid "Slovak"
+msgstr "Eslovac"
+
+#: conf/global_settings.py:71
+msgid "Slovenian"
+msgstr "Esloveni"
+
+#: conf/global_settings.py:72
+msgid "Serbian"
+msgstr "Serbi"
+
+#: conf/global_settings.py:73
+msgid "Swedish"
+msgstr "Suec"
+
+#: conf/global_settings.py:74
+msgid "Tamil"
+msgstr ""
+
+#: conf/global_settings.py:75
+msgid "Telugu"
+msgstr ""
+
+#: conf/global_settings.py:76
+msgid "Turkish"
+msgstr "Turc"
+
+#: conf/global_settings.py:77
+msgid "Ukrainian"
+msgstr "Ucranià"
+
+#: conf/global_settings.py:78
+msgid "Simplified Chinese"
+msgstr "Xinés simplificat"
+
+#: conf/global_settings.py:79
+msgid "Traditional Chinese"
+msgstr "Xinés tradicional"
#: core/validators.py:64
msgid "This value must contain only letters, numbers and underscores."
-msgstr "Aquest valor ha de contenir només números, guions, i guions baixos."
+msgstr "Aquest valor ha de contenir només números, guions, i guions baixos."
#: core/validators.py:68
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
"slashes."
msgstr ""
-"Aquest valor ha de contenir només lletres, números, guions, guions baixos, i "
+"Aquest valor ha de contenir només lletres, números, guions, guions baixos, i "
"barres (/)."
#: core/validators.py:72
-#, fuzzy
msgid "This value must contain only letters, numbers, underscores or hyphens."
msgstr ""
-"Aquest valor ha de contenir només lletres, números, guions, guions baixos, i "
-"barres (/)."
+"Aquest valor ha de contenir només lletres, números, guions o guions baixos"
#: core/validators.py:76
msgid "Uppercase letters are not allowed here."
-msgstr "No es permeten majúscules aquí."
+msgstr "No es permeten majúscules aquí."
#: core/validators.py:80
msgid "Lowercase letters are not allowed here."
-msgstr "No es permeten minúscules aquí."
+msgstr "No es permeten minúscules aquí."
#: core/validators.py:87
msgid "Enter only digits separated by commas."
-msgstr "Introdueixi només dígits separats per comes."
+msgstr "Introdueixi només dígits separats per comes."
#: core/validators.py:99
msgid "Enter valid e-mail addresses separated by commas."
-msgstr "Introdueixi adreces de correu electrònic vàlides separades per comes."
+msgstr "Introdueixi adreces de correu electrònic vàlides separades per comes."
#: core/validators.py:103
msgid "Please enter a valid IP address."
-msgstr "Per favor introdueixi una adreça IP vàlida."
+msgstr "Per favor introdueixi una adreça IP vàlida."
#: core/validators.py:107
msgid "Empty values are not allowed here."
@@ -2120,264 +2739,260 @@ msgstr "No s'admeten valor buits."
#: core/validators.py:111
msgid "Non-numeric characters aren't allowed here."
-msgstr "No s'admeten caracters no numèrics."
+msgstr "No s'admeten caracters no numèrics."
#: core/validators.py:115
msgid "This value can't be comprised solely of digits."
-msgstr "Aquest valor no pot contenir només dígits."
+msgstr "Aquest valor no pot contenir només dígits."
#: core/validators.py:124
msgid "Only alphabetical characters are allowed here."
-msgstr "Només s'admeted caracters alfabètics aquí."
+msgstr "Només s'admeted caracters alfabètics aquí."
#: core/validators.py:139
msgid "Year must be 1900 or later."
-msgstr ""
+msgstr "L'any ha de ser posterior al 1900"
#: core/validators.py:143
-#, fuzzy, python-format
-msgid "Invalid date: %s."
-msgstr "URL invalida: %s"
+#, python-format
+msgid "Invalid date: %s"
+msgstr "Data invàlida: %s"
-#: core/validators.py:152
+#: core/validators.py:153
msgid "Enter a valid time in HH:MM format."
-msgstr "Introdueixi una hora vàlida en el format HH:MM."
+msgstr "Introdueixi una hora vàlida en el format HH:MM."
-#: core/validators.py:177
+#: core/validators.py:178
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgstr ""
-"Envii una imatge vàilda. El fitxer que ha enviat no era una imatge o estaba "
+"Envii una imatge vàilda. El fitxer que ha enviat no era una imatge o estaba "
"corrupte."
-#: core/validators.py:184
+#: core/validators.py:185
#, python-format
msgid "The URL %s does not point to a valid image."
-msgstr "La URL %s no apunta una imatge vàlida."
+msgstr "La URL %s no apunta una imatge vàlida."
-#: core/validators.py:188
+#: core/validators.py:189
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
-"El números de telèfon han de guardar-se en el format XXX-XXX-XXXX. \"%s\" no "
-"és vàlid."
+"El números de telèfon han de guardar-se en el format XXX-XXX-XXXX. \"%s\" no "
+"és vàlid."
-#: core/validators.py:196
+#: core/validators.py:197
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
-msgstr "La URL %s no apunta a un video QuickTime vàlid."
+msgstr "La URL %s no apunta a un video QuickTime vàlid."
-#: core/validators.py:200
+#: core/validators.py:201
msgid "A valid URL is required."
-msgstr "Es precisa d'una URL vàlida."
+msgstr "Es precisa d'una URL vàlida."
-#: core/validators.py:214
+#: core/validators.py:215
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
"%s"
msgstr ""
-"Es precisa HTML vàlid. Els errors específics sòn:\n"
+"Es precisa HTML vàlid. Els errors específics sòn:\n"
"%s"
-#: core/validators.py:221
+#: core/validators.py:222
#, python-format
msgid "Badly formed XML: %s"
msgstr "XML incorrectament formatejat: %s"
-#: core/validators.py:238
+#: core/validators.py:239
#, python-format
msgid "Invalid URL: %s"
msgstr "URL invalida: %s"
-#: core/validators.py:243 core/validators.py:245
+#: core/validators.py:244 core/validators.py:246
#, python-format
msgid "The URL %s is a broken link."
-msgstr "La URL %sés un enllaç trencat."
+msgstr "La URL %sés un enllaç trencat."
-#: core/validators.py:251
+#: core/validators.py:252
msgid "Enter a valid U.S. state abbreviation."
-msgstr "Introdueixi una abreviatura vàlida d'estat d'els E.U.A.."
+msgstr "Introdueixi una abreviatura vàlida d'estat d'els E.U.A.."
-#: core/validators.py:265
+#: core/validators.py:266
#, python-format
msgid "Watch your mouth! The word %s is not allowed here."
msgid_plural "Watch your mouth! The words %s are not allowed here."
-msgstr[0] "Vigili la seva boca! Aquí no admetem la paraula: %s."
-msgstr[1] "Vigili la seva boca! Aquí no admetem les paraules: %s."
+msgstr[0] "Vigili la seva boca! Aquí no admetem la paraula: %s."
+msgstr[1] "Vigili la seva boca! Aquí no admetem les paraules: %s."
-#: core/validators.py:272
+#: core/validators.py:273
#, python-format
msgid "This field must match the '%s' field."
msgstr "Aquest camp ha de concordar amb el camp '%s'."
-#: core/validators.py:291
+#: core/validators.py:292
msgid "Please enter something for at least one field."
msgstr "Si us plau, introdueixi alguna cosa alemnys en un camp."
-#: core/validators.py:300 core/validators.py:311
+#: core/validators.py:301 core/validators.py:312
msgid "Please enter both fields or leave them both empty."
msgstr "Si us plau, ompli els dos camps o deixi'ls tots dos en blanc."
-#: core/validators.py:318
+#: core/validators.py:320
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
-msgstr "S'ha de proporcionar aquest camps si %(field)s és %(value)s"
+msgstr "S'ha de proporcionar aquest camps si %(field)s és %(value)s"
-#: core/validators.py:330
+#: core/validators.py:333
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
-msgstr "S'ha de proporcionar aquest camps si %(field)s no és %(value)s"
+msgstr "S'ha de proporcionar aquest camps si %(field)s no és %(value)s"
-#: core/validators.py:349
+#: core/validators.py:352
msgid "Duplicate values are not allowed."
msgstr "No s'admeten valors duplicats."
-#: core/validators.py:364
-#, fuzzy, python-format
-msgid "This value must be between %s and %s."
-msgstr "Aquest valor ha de ser una potència de %s."
+#: core/validators.py:367
+#, python-format
+msgid "This value must be between %(lower)s and %(upper)s."
+msgstr "Aquest valor ha de estar comprés entre %(lower)s i %(upper)s."
-#: core/validators.py:366
-#, fuzzy, python-format
+#: core/validators.py:369
+#, python-format
msgid "This value must be at least %s."
-msgstr "Aquest valor ha de ser una potència de %s."
+msgstr "Aquest valor ha de ser com a mínim %s."
-#: core/validators.py:368
-#, fuzzy, python-format
+#: core/validators.py:371
+#, python-format
msgid "This value must be no more than %s."
-msgstr "Aquest valor ha de ser una potència de %s."
+msgstr "Aquest valor ha de ser com a màxim %s."
-#: core/validators.py:404
+#: core/validators.py:407
#, python-format
msgid "This value must be a power of %s."
-msgstr "Aquest valor ha de ser una potència de %s."
+msgstr "Aquest valor ha de ser una potència de %s."
-#: core/validators.py:415
+#: core/validators.py:418
msgid "Please enter a valid decimal number."
-msgstr "Si us plau, introdueixi un número decimal vàlid."
+msgstr "Si us plau, introdueixi un número decimal vàlid."
-#: core/validators.py:419
+#: core/validators.py:422
#, python-format
msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
"Please enter a valid decimal number with at most %s total digits."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digit."
+"Si us plau, introdueixi un número decimal vàlid amb no més de %s digit."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digits."
+"Si us plau, introdueixi un número decimal vàlid amb no més de %s digits."
-#: core/validators.py:422
-#, fuzzy, python-format
+#: core/validators.py:425
+#, python-format
msgid ""
"Please enter a valid decimal number with a whole part of at most %s digit."
msgid_plural ""
"Please enter a valid decimal number with a whole part of at most %s digits."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digit."
+"Si us plau, introdueixi un número decimal vàlid amb la part entera amb com a "
+"màxim %s dígit."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digits."
+"Si us plau, introdueixi un número decimal vàlid amb la part entera amb com a "
+"màxim %s dígits."
-#: core/validators.py:425
+#: core/validators.py:428
#, python-format
msgid "Please enter a valid decimal number with at most %s decimal place."
msgid_plural ""
"Please enter a valid decimal number with at most %s decimal places."
msgstr[0] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digit "
-"decimal."
+"Si us plau, introdueixi un número decimal vàlid amb no més de %s dígit en la "
+"part decimal."
msgstr[1] ""
-"Si us plau, introdueixi un número decimal vàlid amb no més de %s digits "
-"decimals."
+"Si us plau, introdueixi un número decimal vàlid amb no més de %s dígits en "
+"la part decimal."
-#: core/validators.py:435
+#: core/validators.py:438
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
-msgstr "Asseguris de que el fitxer que ha enviat té, com a mínim, %s bytes."
+msgstr "Asseguris de que el fitxer que ha enviat té, com a mínim, %s bytes."
-#: core/validators.py:436
+#: core/validators.py:439
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
-msgstr "Asseguris de que el fitxer que ha enviat té, com a màxim %s bytes."
+msgstr "Asseguris de que el fitxer que ha enviat té, com a màxim %s bytes."
-#: core/validators.py:453
+#: core/validators.py:456
msgid "The format for this field is wrong."
-msgstr "El format per aquest camp és incorrecte."
+msgstr "El format per aquest camp és incorrecte."
-#: core/validators.py:468
+#: core/validators.py:471
msgid "This field is invalid."
-msgstr "El camp no és vàlid."
+msgstr "El camp no és vàlid."
-#: core/validators.py:504
+#: core/validators.py:507
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "No s'ha pogut obtenir res de %s."
-#: core/validators.py:507
+#: core/validators.py:510
#, python-format
msgid ""
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
msgstr ""
"La URL %(url)s ha va tornar la capcelera Content-Type '%(contenttype)s', que "
-"no és vàlida."
+"no és vàlida."
-#: core/validators.py:540
+#: core/validators.py:543
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
"\"%(start)s\".)"
msgstr ""
-"Si us plau, tanqui l'etiqueta %(tag)s desde la linea %(line)s. (La linea "
-"comença amb \"%(start)s\".)"
+"Si us plau, tanqui l'etiqueta %(tag)s des de la línia %(line)s. (La línia "
+"comença amb \"%(start)s\".)"
-#: core/validators.py:544
+#: core/validators.py:547
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
"starts with \"%(start)s\".)"
msgstr ""
-"Part del text que comença en la linea %(line)s no està permés en aquest "
-"contexte. (La linea comença per \"%(start)s\".)"
+"Part del text que comença en la línia %(line)s no està permès en aquest "
+"context. (La línia comença per \"%(start)s\".)"
-#: core/validators.py:549
+#: core/validators.py:552
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
"(start)s\".)"
msgstr ""
-"El \"%(attr)s\" de la linea %(line)s no és un atribut vàlido. (La linea "
-"comença per \"%(start)s\".)"
+"El \"%(attr)s\" de la línia %(line)s no és un atribut vàlid. (La línia "
+"comença per \"%(start)s\".)"
-#: core/validators.py:554
+#: core/validators.py:557
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
"(start)s\".)"
msgstr ""
-"La \"<%(tag)s>\" de la linea %(line)s no és una etiqueta vàlida. (La línea "
-"comença per \"%(start)s\".)"
+"La \"<%(tag)s>\" de la línia %(line)s no és una etiqueta vàlida. (La línia "
+"comença per \"%(start)s\".)"
-#: core/validators.py:558
+#: core/validators.py:561
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
"starts with \"%(start)s\".)"
msgstr ""
-"A una etiqueta de la linea %(line)s li falta un o més atributs requerits.(La "
-"linea comença per \"%(start)s\".)"
+"Una etiqueta de la línia %(line)s li falta un o més atributs requerits.(La "
+"línia comença per \"%(start)s\".)"
-#: core/validators.py:563
+#: core/validators.py:566
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
"starts with \"%(start)s\".)"
msgstr ""
-"L'atribut \"%(attr)s\" de la linena %(line)s té un valor que no és vàlid. "
-"(La linea comença per \"%(start)s\".)"
-
-#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
-#~ msgstr "Ha <a href=\"/password_reset/\">oblidat la seva clau</a>?"
-
-#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
-#~ msgstr "Utilitzi '[algo]$[salt]$[hexdigest]'"
+"L'atribut \"%(attr)s\" de la línia %(line)s té un valor que no és vàlid. (La "
+"línia comença per \"%(start)s\".)"
diff --git a/django/conf/locale/ca/LC_MESSAGES/djangojs.mo b/django/conf/locale/ca/LC_MESSAGES/djangojs.mo
index 412c2eb876..d12c8f8d7a 100644
--- a/django/conf/locale/ca/LC_MESSAGES/djangojs.mo
+++ b/django/conf/locale/ca/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/django/conf/locale/ca/LC_MESSAGES/djangojs.po b/django/conf/locale/ca/LC_MESSAGES/djangojs.po
index 8903957b86..ed7231988b 100644
--- a/django/conf/locale/ca/LC_MESSAGES/djangojs.po
+++ b/django/conf/locale/ca/LC_MESSAGES/djangojs.po
@@ -3,20 +3,19 @@
# Copyright (C)
# This file is distributed under the same license as the PACKAGE package.
#
-# Jorge Gajon <gajon@gajon.org>, 2005.
-# Marc Fargas <marc@fargas.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: djangojs\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-02-15 11:05+1100\n"
-"PO-Revision-Date: 2007-01-19 10:30+0100\n"
+"POT-Creation-Date: 2007-05-20 18:25+0200\n"
+"PO-Revision-Date: 2007-05-20 18:24+0200\n"
"Last-Translator: Marc Fargas <marc@fargas.com>\n"
"Language-Team: <es@li.org>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: VIM 7.0\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
@@ -54,7 +53,7 @@ msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
-"Febrer Març Abril Maig Juny Juliol Agost Setembre Octubre Novembre Desembre"
+"Febrer Març Abril Maig Juny Juliol Agost Setembre Octubre Novembre Desembre"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
@@ -92,7 +91,7 @@ msgstr "Migdia"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
-msgstr "Cancel·lar"
+msgstr "Cancel·lar"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
@@ -109,7 +108,7 @@ msgstr "Ahir"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
-msgstr "Demà"
+msgstr "Demà"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
diff --git a/django/conf/locale/es_AR/LC_MESSAGES/django.mo b/django/conf/locale/es_AR/LC_MESSAGES/django.mo
index 7fb381c78f..717bbcbd05 100644
--- a/django/conf/locale/es_AR/LC_MESSAGES/django.mo
+++ b/django/conf/locale/es_AR/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/es_AR/LC_MESSAGES/django.po b/django/conf/locale/es_AR/LC_MESSAGES/django.po
index 27472353e4..02f80682e7 100644
--- a/django/conf/locale/es_AR/LC_MESSAGES/django.po
+++ b/django/conf/locale/es_AR/LC_MESSAGES/django.po
@@ -1,14 +1,13 @@
-# Translation of django.po to Argentinean spanish, based on Spanish
-# translation work by Ricardo Javier Cárdenes Medina.
-# This file is distributed under the same license as the Django package.
-# Copyright (C) 2006,2007 Ramiro Morales <rm0@gmx.net>
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR
#
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-03-24 11:16-0300\n"
-"PO-Revision-Date: 2007-03-24 11:54-0300\n"
+"POT-Creation-Date: 2007-05-19 13:22-0300\n"
+"PO-Revision-Date: 2007-05-19 13:33-0300\n"
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
@@ -16,93 +15,93 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: newforms/fields.py:78 newforms/fields.py:374 newforms/fields.py:450
-#: newforms/fields.py:461 newforms/models.py:177
+#: newforms/fields.py:82 newforms/fields.py:378 newforms/fields.py:454
+#: newforms/fields.py:465 newforms/models.py:186
#: db/models/fields/__init__.py:117 db/models/fields/__init__.py:274
-#: db/models/fields/__init__.py:610 db/models/fields/__init__.py:621
+#: db/models/fields/__init__.py:612 db/models/fields/__init__.py:623
#: oldforms/__init__.py:357
msgid "This field is required."
msgstr "Este campo es obligatorio."
-#: newforms/fields.py:101 newforms/fields.py:254
+#: newforms/fields.py:105 newforms/fields.py:258
#, python-format
msgid "Ensure this value has at most %d characters."
msgstr "Asegúrese de que este valor tenga como máximo %d caracteres."
-#: newforms/fields.py:103 newforms/fields.py:256
+#: newforms/fields.py:107 newforms/fields.py:260
#, python-format
msgid "Ensure this value has at least %d characters."
msgstr "Asegúrese de que este valor tenga al menos %d caracteres."
-#: newforms/fields.py:126 core/validators.py:120
+#: newforms/fields.py:130 core/validators.py:120
msgid "Enter a whole number."
msgstr "Introduzca un número entero."
-#: newforms/fields.py:128
+#: newforms/fields.py:132
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Asegúrese de que este valor sea menor o igual a %s."
-#: newforms/fields.py:130
+#: newforms/fields.py:134
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Asegúrese de que este valor sea mayor o igual a %s."
-#: newforms/fields.py:163
+#: newforms/fields.py:167
msgid "Enter a valid date."
-msgstr "Ingrese una fecha válida."
+msgstr "Introduzca una fecha válida."
-#: newforms/fields.py:190
+#: newforms/fields.py:194
msgid "Enter a valid time."
msgstr "Introduzca una hora válida."
-#: newforms/fields.py:226
+#: newforms/fields.py:230
msgid "Enter a valid date/time."
msgstr "Introduzca una fecha/hora válida."
-#: newforms/fields.py:240
+#: newforms/fields.py:244
msgid "Enter a valid value."
msgstr "Introduzca un valor válido."
-#: newforms/fields.py:269 core/validators.py:162
+#: newforms/fields.py:273 core/validators.py:162
msgid "Enter a valid e-mail address."
msgstr "Introduzca una dirección de correo electrónico válida"
-#: newforms/fields.py:287 newforms/fields.py:309
+#: newforms/fields.py:291 newforms/fields.py:313
msgid "Enter a valid URL."
msgstr "Introduzca una URL válida."
-#: newforms/fields.py:311
+#: newforms/fields.py:315
msgid "This URL appears to be a broken link."
msgstr "La URL parece ser un enlace roto."
-#: newforms/fields.py:360 newforms/models.py:164
+#: newforms/fields.py:366 newforms/models.py:173
msgid "Select a valid choice. That choice is not one of the available choices."
msgstr ""
"Seleccione una opción válida. Esa opción no es una de las opciones "
"disponibles."
-#: newforms/fields.py:378 newforms/fields.py:454 newforms/models.py:181
+#: newforms/fields.py:382 newforms/fields.py:458 newforms/models.py:190
msgid "Enter a list of values."
msgstr "Introduzca una lista de valores."
-#: newforms/fields.py:387 newforms/models.py:187
+#: newforms/fields.py:391 newforms/models.py:196
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr ""
"Seleccione una opción válida. %s no es una de las opciones disponibles."
-#: newforms/widgets.py:170 contrib/admin/filterspecs.py:150
+#: newforms/widgets.py:182 contrib/admin/filterspecs.py:150
#: oldforms/__init__.py:577
msgid "Unknown"
msgstr "Desconocido"
-#: newforms/widgets.py:170 contrib/admin/filterspecs.py:143
+#: newforms/widgets.py:182 contrib/admin/filterspecs.py:143
#: oldforms/__init__.py:577
msgid "Yes"
msgstr "Sí"
-#: newforms/widgets.py:170 contrib/admin/filterspecs.py:143
+#: newforms/widgets.py:182 contrib/admin/filterspecs.py:143
#: oldforms/__init__.py:577
msgid "No"
msgstr "No"
@@ -167,6 +166,21 @@ msgid_plural "minutes"
msgstr[0] "minuto"
msgstr[1] "minutos"
+#: utils/timesince.py:40
+#, python-format
+msgid "%d milliseconds"
+msgstr "%d milisegundos"
+
+#: utils/timesince.py:41
+#, python-format
+msgid "%(number)d %(type)s"
+msgstr ""
+
+#: utils/timesince.py:47
+#, python-format
+msgid ", %(number)d %(type)s"
+msgstr ""
+
#: utils/dates.py:6
msgid "Monday"
msgstr "Lunes"
@@ -319,23 +333,23 @@ msgstr "Nov."
msgid "Dec."
msgstr "Dic."
-#: utils/translation/trans_real.py:362
+#: utils/translation/trans_real.py:358
msgid "DATE_FORMAT"
msgstr "j N Y"
-#: utils/translation/trans_real.py:363
+#: utils/translation/trans_real.py:359
msgid "DATETIME_FORMAT"
msgstr "j N Y P"
-#: utils/translation/trans_real.py:364
+#: utils/translation/trans_real.py:360
msgid "TIME_FORMAT"
msgstr "P"
-#: utils/translation/trans_real.py:380
+#: utils/translation/trans_real.py:376
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:381
+#: utils/translation/trans_real.py:377
msgid "MONTH_DAY_FORMAT"
msgstr "j \\de F"
@@ -371,35 +385,35 @@ msgstr "redirección"
msgid "redirects"
msgstr "redirecciones"
-#: contrib/auth/models.py:38 contrib/auth/models.py:57
+#: contrib/auth/models.py:44 contrib/auth/models.py:64
msgid "name"
msgstr "nombre"
-#: contrib/auth/models.py:40
+#: contrib/auth/models.py:46
msgid "codename"
msgstr "nombre en código"
-#: contrib/auth/models.py:42
+#: contrib/auth/models.py:49
msgid "permission"
msgstr "permiso"
-#: contrib/auth/models.py:43 contrib/auth/models.py:58
+#: contrib/auth/models.py:50 contrib/auth/models.py:65
msgid "permissions"
msgstr "permisos"
-#: contrib/auth/models.py:60
+#: contrib/auth/models.py:68
msgid "group"
msgstr "grupo"
-#: contrib/auth/models.py:61 contrib/auth/models.py:100
+#: contrib/auth/models.py:69 contrib/auth/models.py:109
msgid "groups"
msgstr "grupos"
-#: contrib/auth/models.py:90
+#: contrib/auth/models.py:99
msgid "username"
msgstr "nombre de usuario"
-#: contrib/auth/models.py:90
+#: contrib/auth/models.py:99
msgid ""
"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
"digits and underscores)."
@@ -407,23 +421,23 @@ msgstr ""
"Requerido. Longitud máxima 30 caracteres alfanuméricos (letras, dígitos y "
"guiones bajos)."
-#: contrib/auth/models.py:91
+#: contrib/auth/models.py:100
msgid "first name"
msgstr "nombre"
-#: contrib/auth/models.py:92
+#: contrib/auth/models.py:101
msgid "last name"
msgstr "apellido"
-#: contrib/auth/models.py:93
+#: contrib/auth/models.py:102
msgid "e-mail address"
msgstr "dirección de correo"
-#: contrib/auth/models.py:94
+#: contrib/auth/models.py:103
msgid "password"
msgstr "contraseña"
-#: contrib/auth/models.py:94
+#: contrib/auth/models.py:103
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -431,19 +445,19 @@ msgstr ""
"Use '[algo]$[salt]$[hexdigest]' o use el <a href=\"password/\">formulario de "
"cambio de contraseña</a>."
-#: contrib/auth/models.py:95
+#: contrib/auth/models.py:104
msgid "staff status"
msgstr "es staff"
-#: contrib/auth/models.py:95
+#: contrib/auth/models.py:104
msgid "Designates whether the user can log into this admin site."
msgstr "Indica si el usuario puede ingresar a este sitio de administración."
-#: contrib/auth/models.py:96
+#: contrib/auth/models.py:105
msgid "active"
msgstr "activo"
-#: contrib/auth/models.py:96
+#: contrib/auth/models.py:105
msgid ""
"Designates whether this user can log into the Django admin. Unselect this "
"instead of deleting accounts."
@@ -451,11 +465,11 @@ msgstr ""
"Indica si el usuario puede ingresar al sitio de administración Django."
"Desactive este campo en lugar de eliminar usuarios."
-#: contrib/auth/models.py:97
+#: contrib/auth/models.py:106
msgid "superuser status"
msgstr "es superusuario"
-#: contrib/auth/models.py:97
+#: contrib/auth/models.py:106
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
@@ -463,15 +477,15 @@ msgstr ""
"Indica que este usuario posee todos los permisos, sin asignarle los mismos "
"explícitamente."
-#: contrib/auth/models.py:98
+#: contrib/auth/models.py:107
msgid "last login"
msgstr "último ingreso"
-#: contrib/auth/models.py:99
+#: contrib/auth/models.py:108
msgid "date joined"
msgstr "fecha de creación"
-#: contrib/auth/models.py:101
+#: contrib/auth/models.py:110
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -479,38 +493,42 @@ msgstr ""
"Además de los permisos asignados manualmente, este usuario también poseerá "
"todos los permisos de los grupos a los que pertenezca."
-#: contrib/auth/models.py:102
+#: contrib/auth/models.py:111
msgid "user permissions"
msgstr "permisos de usuario"
-#: contrib/auth/models.py:105
+#: contrib/auth/models.py:115
msgid "user"
msgstr "usuario"
-#: contrib/auth/models.py:106
+#: contrib/auth/models.py:116
msgid "users"
msgstr "usuarios"
-#: contrib/auth/models.py:111
+#: contrib/auth/models.py:122
msgid "Personal info"
msgstr "Información personal"
-#: contrib/auth/models.py:112
+#: contrib/auth/models.py:123
msgid "Permissions"
msgstr "Permisos"
-#: contrib/auth/models.py:113
+#: contrib/auth/models.py:124
msgid "Important dates"
msgstr "Fechas importantes"
-#: contrib/auth/models.py:114
+#: contrib/auth/models.py:125
msgid "Groups"
msgstr "Grupos"
-#: contrib/auth/models.py:258
+#: contrib/auth/models.py:269
msgid "message"
msgstr "mensaje"
+#: contrib/auth/models.py:282
+msgid "AnonymousUser"
+msgstr "UsuarioAnonimo"
+
#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
msgid "The two password fields didn't match."
msgstr "Los dos campos de contraseñas no coinciden entre si."
@@ -557,7 +575,7 @@ msgstr ""
"La antigua contraseña ingresada es incorrecta. Por favor ingrésela "
"nuevamente."
-#: contrib/auth/views.py:39
+#: contrib/auth/views.py:40
msgid "Logged out"
msgstr "Sesión cerrada"
@@ -652,8 +670,8 @@ msgstr "Los nombres de usuario no pueden contener el carácter '@'."
#, python-format
msgid "Your e-mail address is not your username. Try '%s' instead."
msgstr ""
-"Su dirección de correo no es su nombre de usuario. Intente nuevamente "
-"usando '%s'."
+"Su dirección de correo no es su nombre de usuario. Intente nuevamente usando "
+"'%s'."
#: contrib/admin/views/auth.py:19 contrib/admin/views/main.py:257
#, python-format
@@ -676,7 +694,7 @@ msgstr "Cambio de contraseña exitoso"
#: contrib/admin/views/auth.py:64
#, python-format
msgid "Change password: %s"
-msgstr "Cambiar contraseña: %S"
+msgstr "Cambiar contraseña: %s"
#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48
#: contrib/admin/views/doc.py:50
@@ -855,14 +873,14 @@ msgstr "No ha modificado ningún campo."
#: contrib/admin/views/main.py:345
#, python-format
msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "Se modificó con éxito %(name)s \"%(obj)s."
+msgstr "Se modificó con éxito %(name)s \"%(obj)s\"."
#: contrib/admin/views/main.py:353
#, python-format
msgid ""
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
msgstr ""
-"Se agregó con éxito %(name)s \"%(obj)s. Puede modificarlo nuevamente abajo."
+"Se agregó con éxito %(name)s \"%(obj)s\". Puede modificarlo nuevamente abajo."
#: contrib/admin/views/main.py:391
#, python-format
@@ -1189,8 +1207,8 @@ msgid ""
"mail and should be fixed shortly. Thanks for your patience."
msgstr ""
"Ha ocurrido un error. Se ha informado a los administradores del sitio "
-"mediante correo electrónico y debería ser solucionado en breve. Gracias "
-"por su paciencia."
+"mediante correo electrónico y debería ser solucionado en breve. Gracias por "
+"su paciencia."
#: contrib/admin/templates/admin/delete_confirmation.html:14
#, python-format
@@ -1230,8 +1248,8 @@ msgstr ""
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr ""
-"Introduzca una nueva contraseña para el usuario <strong>%(username)s"
-"</strong>."
+"Introduzca una nueva contraseña para el usuario <strong>%(username)s</"
+"strong>."
#: contrib/admin/templates/admin/auth/user/change_password.html:34
#: contrib/admin/templates/admin/auth/user/add_form.html:18
@@ -1542,16 +1560,476 @@ msgstr "página estática"
msgid "flat pages"
msgstr "páginas estáticas"
-#: contrib/localflavor/usa/forms.py:17
+#: contrib/localflavor/no/forms.py:15 contrib/localflavor/ch/forms.py:18
+msgid "Enter a zip code in the format XXXX."
+msgstr "Introduzca un zip code en formato XXX."
+
+#: contrib/localflavor/no/forms.py:36
+msgid "Enter a valid Norwegian social security number."
+msgstr "Introduzca un número de seguridad social Noruego válido."
+
+#: contrib/localflavor/us/forms.py:18
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
msgstr "Introduzca un zip code en el formato XXXXX o XXXXX-XXXX."
+#: contrib/localflavor/us/forms.py:51
+msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
+msgstr "Introduzca un Número de Seguridad Social en formato XXX-XX-XXXX."
+
+#: contrib/localflavor/jp/jp_prefectures.py:4
+msgid "Hokkaido"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:5
+msgid "Aomori"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:6
+msgid "Iwate"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:7
+msgid "Miyagi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:8
+msgid "Akita"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:9
+msgid "Yamagata"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:10
+msgid "Fukushima"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:11
+msgid "Ibaraki"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:12
+msgid "Tochigi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:13
+msgid "Gunma"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:14
+msgid "Saitama"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:15
+msgid "Chiba"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:16
+msgid "Tokyo"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:17
+msgid "Kanagawa"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:18
+msgid "Yamanashi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:19
+msgid "Nagano"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:20
+msgid "Niigata"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:21
+msgid "Toyama"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:22
+msgid "Ishikawa"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:23
+msgid "Fukui"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:24
+msgid "Gifu"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:25
+msgid "Shizuoka"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:26
+msgid "Aichi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:27
+msgid "Mie"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:28
+msgid "Shiga"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:29
+msgid "Kyoto"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:30
+msgid "Osaka"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:31
+msgid "Hyogo"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:32
+msgid "Nara"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:33
+msgid "Wakayama"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:34
+msgid "Tottori"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:35
+msgid "Shimane"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:36
+msgid "Okayama"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:37
+msgid "Hiroshima"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:38
+msgid "Yamaguchi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:39
+msgid "Tokushima"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:40
+msgid "Kagawa"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:41
+msgid "Ehime"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:42
+msgid "Kochi"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:43
+msgid "Fukuoka"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:44
+msgid "Saga"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:45
+msgid "Nagasaki"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:46
+msgid "Kumamoto"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:47
+msgid "Oita"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:48
+msgid "Miyazaki"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:49
+msgid "Kagoshima"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:50
+msgid "Okinawa"
+msgstr ""
+
+#: contrib/localflavor/jp/forms.py:21
+msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
+msgstr "Introduzca un código postal en formato XXXXXX o XXX-XXXX."
+
+#: contrib/localflavor/ch/forms.py:90
+msgid ""
+"Enter a valid Swiss identity or passport card number in X1234567<0 or "
+"1234567890 format."
+msgstr ""
+"Introduzca un número válido de tarjeta de identidad o pasaporte Suizos en "
+"formato X1234567<0 o 1234567890."
+
+#: contrib/localflavor/ch/ch_states.py:5
+msgid "Aargau"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:6
+msgid "Appenzell Innerrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:7
+msgid "Appenzell Ausserrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:8
+msgid "Basel-Stadt"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:9
+msgid "Basel-Land"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:10
+msgid "Berne"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:11
+msgid "Fribourg"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:12
+msgid "Geneva"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:13
+msgid "Glarus"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:14
+msgid "Graubuenden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:15
+msgid "Jura"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:16
+msgid "Lucerne"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:17
+msgid "Neuchatel"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:18
+msgid "Nidwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:19
+msgid "Obwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:20
+msgid "Schaffhausen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:21
+msgid "Schwyz"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:22
+msgid "Solothurn"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:23
+msgid "St. Gallen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:24
+msgid "Thurgau"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:25
+msgid "Ticino"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:26
+msgid "Uri"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:27
+msgid "Valais"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:28
+msgid "Vaud"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:29
+msgid "Zug"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:30
+msgid "Zurich"
+msgstr ""
+
+#: contrib/localflavor/fi/forms.py:14 contrib/localflavor/de/forms.py:16
+#: contrib/localflavor/fr/forms.py:17
+msgid "Enter a zip code in the format XXXXX."
+msgstr "Introduzca un zip code en formato XXXXX."
+
+#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
+msgid "Enter a valid Finnish social security number."
+msgstr "Introduzca un número de seguridad social finlandés válido."
+
+#: contrib/localflavor/au/forms.py:18
+msgid "Enter a 4 digit post code."
+msgstr "Introduzca un post code de 4 dígitos."
+
+#: contrib/localflavor/is_/forms.py:16
+msgid ""
+"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
+msgstr ""
+"Introduzca un número de identificación islandés válido. El formato es XXXXXX-"
+"XXXX."
+
+#: contrib/localflavor/is_/forms.py:30
+msgid "The Icelandic identification number is not valid."
+msgstr "El número de identificación islandés no es válido."
+
#: contrib/localflavor/uk/forms.py:18
msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr ""
"Introduzca un postcode. Se requiere un espacio entre las dos secciones del "
"mismo."
+#: contrib/localflavor/de/de_states.py:5
+msgid "Baden-Wuerttemberg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:6
+msgid "Bavaria"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:7
+msgid "Berlin"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:8
+msgid "Brandenburg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:9
+msgid "Bremen"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:10
+msgid "Hamburg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:11
+msgid "Hessen"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:12
+msgid "Mecklenburg-Western Pomerania"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:13
+msgid "Lower Saxony"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:14
+msgid "North Rhine-Westphalia"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:15
+msgid "Rhineland-Palatinate"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:16
+msgid "Saarland"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:17
+msgid "Saxony"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:18
+msgid "Saxony-Anhalt"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:19
+msgid "Schleswig-Holstein"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:20
+msgid "Thuringia"
+msgstr ""
+
+#: contrib/localflavor/de/forms.py:60
+msgid ""
+"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
+msgstr ""
+"Introduzca un número de tarjeta de identidad alemán válido en formato "
+"XXXXXXXXXXX-XXXXXXX-XXXXXXX-X."
+
+#: contrib/localflavor/br/forms.py:18
+msgid "Enter a zip code in the format XXXXX-XXX."
+msgstr "Introduzca un zip code en formato XXXXX-XXX."
+
+#: contrib/localflavor/br/forms.py:30
+msgid "Phone numbers must be in XX-XXXX-XXXX format."
+msgstr "Los números telefónicos deben respetar el formato XX-XXXX-XXXX."
+
+#: contrib/localflavor/br/forms.py:72
+msgid "This field requires only numbers."
+msgstr "Este campo permite sólo valores numéricos."
+
+#: contrib/localflavor/br/forms.py:74
+msgid "This field requires at most 11 digits or 14 characters."
+msgstr "Este campo requiere como máximo 11 dígitos o 14 caracteres."
+
+#: contrib/localflavor/br/forms.py:84
+msgid "Invalid CPF number."
+msgstr "Número CPF inválido."
+
+#: contrib/localflavor/br/forms.py:106
+msgid "This field requires at least 14 digits"
+msgstr "Este campo requiere al menos 14 dígitos."
+
+#: contrib/localflavor/br/forms.py:116
+msgid "Invalid CNPJ number."
+msgstr "Número CNPJ inválido."
+
+#: contrib/localflavor/cl/forms.py:21
+msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
+msgstr "Introduzca un RUT chileno válido. EL formato es XX.XXX.XXX-X."
+
+#: contrib/localflavor/cl/forms.py:26
+msgid "Enter valid a Chilean RUT"
+msgstr "Introduzca un RUT chileno válido."
+
+#: contrib/localflavor/it/forms.py:16
+msgid "Enter a valid zip code."
+msgstr "Introduzca un zip code válido."
+
+#: contrib/localflavor/it/forms.py:41
+msgid "Enter a valid Social Security number."
+msgstr "Introduzca un número de Seguridad Social válido."
+
+#: contrib/localflavor/it/forms.py:68
+msgid "Enter a valid VAT number."
+msgstr "Introduzca un número VAT válido."
+
#: contrib/comments/models.py:67 contrib/comments/models.py:166
msgid "object ID"
msgstr "ID de objeto"
@@ -1931,31 +2409,31 @@ msgstr "Ya existe un(a) %(object)s con este/a %(type)s para %(field)s."
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "Ya existe %(optname)s con este %(fieldname)s."
-#: db/models/fields/__init__.py:367
+#: db/models/fields/__init__.py:369
msgid "This value must be an integer."
msgstr "Este valor debe ser un número entero."
-#: db/models/fields/__init__.py:402
+#: db/models/fields/__init__.py:404
msgid "This value must be either True or False."
msgstr "Este valor debe ser True o False."
-#: db/models/fields/__init__.py:423
+#: db/models/fields/__init__.py:425
msgid "This field cannot be null."
msgstr "Este campo no puede ser nulo."
-#: db/models/fields/__init__.py:457 core/validators.py:148
+#: db/models/fields/__init__.py:459 core/validators.py:148
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Introduzca una fecha válida en formato AAAA-MM-DD."
-#: db/models/fields/__init__.py:526 core/validators.py:157
+#: db/models/fields/__init__.py:528 core/validators.py:157
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Introduzca una fecha/hora válida en formato AAAA-MM-DD HH:MM."
-#: db/models/fields/__init__.py:630
+#: db/models/fields/__init__.py:632
msgid "Enter a valid filename."
msgstr "Introduzca un nombre de archivo válido."
-#: db/models/fields/__init__.py:751
+#: db/models/fields/__init__.py:753
msgid "This value must be either None, True or False."
msgstr "Este valor debe ser None, True o False."
@@ -2027,7 +2505,7 @@ msgstr "Introduzca un número entero entre 0 y 32.767."
#: views/generic/create_update.py:43
#, python-format
msgid "The %(verbose_name)s was created successfully."
-msgstr "Se creó con éxito %(verbose_name)."
+msgstr "Se creó con éxito %(verbose_name)s."
#: views/generic/create_update.py:117
#, python-format
@@ -2048,150 +2526,158 @@ msgid "Bengali"
msgstr "Bengalí"
#: conf/global_settings.py:41
+msgid "Bulgarian"
+msgstr "Búlgaro"
+
+#: conf/global_settings.py:42
msgid "Catalan"
msgstr "Catalán"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:43
msgid "Czech"
msgstr "Checo"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:44
msgid "Welsh"
msgstr "Galés"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:45
msgid "Danish"
msgstr "Danés"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:46
msgid "German"
msgstr "Alemán"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:47
msgid "Greek"
msgstr "Griego"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:48
msgid "English"
msgstr "Inglés"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:49
msgid "Spanish"
msgstr "Español"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:50
msgid "Argentinean Spanish"
msgstr "Español Argentino"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:51
msgid "Finnish"
msgstr "Finlandés"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:52
msgid "French"
msgstr "Francés"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:53
msgid "Galician"
msgstr "Gallego"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:54
msgid "Hungarian"
msgstr "Húngaro"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:55
msgid "Hebrew"
msgstr "Hebreo"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:56
msgid "Icelandic"
msgstr "Islandés"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:57
msgid "Italian"
msgstr "Italiano"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:58
msgid "Japanese"
msgstr "Japonés"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:59
+msgid "Korean"
+msgstr "Koreano"
+
+#: conf/global_settings.py:60
msgid "Kannada"
msgstr "Canarés"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:61
msgid "Latvian"
msgstr "Letón"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:62
msgid "Macedonian"
msgstr "Macedonio"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:63
msgid "Dutch"
msgstr "Holandés"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:64
msgid "Norwegian"
msgstr "Noruego"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:65
msgid "Polish"
msgstr "Polaco"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:66
msgid "Portugese"
msgstr "Portugués"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:67
msgid "Brazilian"
msgstr "Brasileño"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:68
msgid "Romanian"
msgstr "Rumano"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:69
msgid "Russian"
msgstr "Ruso"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:70
msgid "Slovak"
msgstr "Eslovaco"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:71
msgid "Slovenian"
msgstr "Esloveno"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:72
msgid "Serbian"
msgstr "Serbio"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:73
msgid "Swedish"
msgstr "Sueco"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:74
msgid "Tamil"
msgstr "Tamil"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:75
msgid "Telugu"
msgstr "Telugu"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:76
msgid "Turkish"
msgstr "Turco"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:77
msgid "Ukrainian"
msgstr "Ucraniano"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:78
msgid "Simplified Chinese"
msgstr "Chino simplificado"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:79
msgid "Traditional Chinese"
msgstr "Chino tradicional"
@@ -2199,6 +2685,28 @@ msgstr "Chino tradicional"
msgid "yes,no,maybe"
msgstr "si,no,talvez"
+#: template/defaultfilters.py:520
+#, python-format
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: template/defaultfilters.py:522
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#: template/defaultfilters.py:524
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#: template/defaultfilters.py:525
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
#: core/validators.py:64
msgid "This value must contain only letters, numbers and underscores."
msgstr "Este valor debe contener sólo letras, números y guiones bajos."
@@ -2282,8 +2790,8 @@ msgstr "La URL %s no apunta a una imagen válida."
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
-"Los números telefónicos deben respetar el formato XXX-XXX-XXXX. \"%s\" "
-"no es válido."
+"Los números telefónicos deben respetar el formato XXX-XXX-XXXX. \"%s\" no es "
+"válido."
#: core/validators.py:197
#, python-format
@@ -2386,8 +2894,8 @@ msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
"Please enter a valid decimal number with at most %s total digits."
msgstr[0] ""
-"Por favor, introduzca un número decimal válido con un máximo de un "
-"dígito en total."
+"Por favor, introduzca un número decimal válido con un máximo de un dígito en "
+"total."
msgstr[1] ""
"Por favor, introduzca un número decimal válido con un maximo de %s dígitos "
"en total."
diff --git a/django/conf/locale/ru/LC_MESSAGES/django.mo b/django/conf/locale/ru/LC_MESSAGES/django.mo
index 12e240529f..5718d58bcb 100644
--- a/django/conf/locale/ru/LC_MESSAGES/django.mo
+++ b/django/conf/locale/ru/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/ru/LC_MESSAGES/django.po b/django/conf/locale/ru/LC_MESSAGES/django.po
index f329efe24f..cbd995c81f 100644
--- a/django/conf/locale/ru/LC_MESSAGES/django.po
+++ b/django/conf/locale/ru/LC_MESSAGES/django.po
@@ -1,26 +1,810 @@
# Translation of django.po to russian.
# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-# Dmitry Sorokin <ds@dial.com.ru>, 2005.
#
msgid ""
msgstr ""
"Project-Id-Version: django 0.95\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-05-16 10:11+0200\n"
+"POT-Creation-Date: 2007-05-04 16:07+1300\n"
"PO-Revision-Date: 2006-09-07 15:28+0300\n"
-"Last-Translator: Alexander Yakovlev <AYakovlev@rambler.ru>\n"
+"Last-Translator: Vasiliy Stavenko <stavenko@gmail.com>\n"
"Language-Team: Dialcom Services <greg@dial.com.ru>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Poedit-Language: Russian\n"
"X-Poedit-Country: RUSSIAN FEDERATION\n"
"X-Poedit-SourceCharset: utf-8\n"
-#: contrib/comments/models.py:67
-#: contrib/comments/models.py:166
+#: oldforms/__init__.py:357 db/models/fields/__init__.py:117
+#: db/models/fields/__init__.py:274 db/models/fields/__init__.py:615
+#: db/models/fields/__init__.py:626 newforms/models.py:178
+#: newforms/fields.py:80 newforms/fields.py:378 newforms/fields.py:454
+#: newforms/fields.py:465
+msgid "This field is required."
+msgstr "Обязательное поле."
+
+#: oldforms/__init__.py:392
+#, python-format
+msgid "Ensure your text is less than %s character."
+msgid_plural "Ensure your text is less than %s characters."
+msgstr[0] "Убедитесь, что длина вашего текста меньше %s символа."
+msgstr[1] "Убедитесь, что длина вашего текста меньше %s символов."
+msgstr[2] "Убедитесь, что длина вашего текста меньше %s символов."
+
+#: oldforms/__init__.py:397
+msgid "Line breaks are not allowed here."
+msgstr "Переносы строк здесь не допускаются."
+
+#: oldforms/__init__.py:498 oldforms/__init__.py:571 oldforms/__init__.py:610
+#, python-format
+msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
+msgstr "Выберите корректный вариант; '%(data)s' нет в %(choices)s."
+
+#: oldforms/__init__.py:577 newforms/widgets.py:180
+#: contrib/admin/filterspecs.py:150
+msgid "Unknown"
+msgstr "Неизвестно"
+
+#: oldforms/__init__.py:577 newforms/widgets.py:180
+#: contrib/admin/filterspecs.py:143
+msgid "Yes"
+msgstr "Да"
+
+#: oldforms/__init__.py:577 newforms/widgets.py:180
+#: contrib/admin/filterspecs.py:143
+msgid "No"
+msgstr "Нет"
+
+#: oldforms/__init__.py:672 core/validators.py:174 core/validators.py:445
+msgid "No file was submitted. Check the encoding type on the form."
+msgstr "Не получен файл. Проверьте кодирование формы (encoding)."
+
+#: oldforms/__init__.py:674
+msgid "The submitted file is empty."
+msgstr "Указанный файл пуст."
+
+#: oldforms/__init__.py:730
+msgid "Enter a whole number between -32,768 and 32,767."
+msgstr "Введите целое число в диапазоне от -32768 до 32767."
+
+#: oldforms/__init__.py:740
+msgid "Enter a positive number."
+msgstr "Введите положительное число."
+
+#: oldforms/__init__.py:750
+msgid "Enter a whole number between 0 and 32,767."
+msgstr "Введите целое число в диапазоне от 0 до 32767."
+
+#: db/models/manipulators.py:307
+#, python-format
+msgid "%(object)s with this %(type)s already exists for the given %(field)s."
+msgstr "%(object)s с типом %(type)s уже существует для данного %(field)s."
+
+#: db/models/manipulators.py:308 contrib/admin/views/main.py:335
+#: contrib/admin/views/main.py:337 contrib/admin/views/main.py:339
+msgid "and"
+msgstr "и"
+
+#: db/models/fields/__init__.py:42
+#, python-format
+msgid "%(optname)s with this %(fieldname)s already exists."
+msgstr "%(optname)s с %(fieldname)s уже существует."
+
+#: db/models/fields/__init__.py:369
+msgid "This value must be an integer."
+msgstr "Это значение должно быть целым числом."
+
+#: db/models/fields/__init__.py:404
+msgid "This value must be either True or False."
+msgstr "Значение должно либо True, либо False."
+
+#: db/models/fields/__init__.py:425
+msgid "This field cannot be null."
+msgstr "Это поле не может быть нулевым."
+
+#: db/models/fields/__init__.py:462 core/validators.py:148
+msgid "Enter a valid date in YYYY-MM-DD format."
+msgstr "Вводите правильную дату в формате YYYY-MM-DD."
+
+#: db/models/fields/__init__.py:531 core/validators.py:157
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
+msgstr "Введите правильные дату/время в формате YYYY-MM-DD HH:MM."
+
+#: db/models/fields/__init__.py:635
+msgid "Enter a valid filename."
+msgstr "Укажите правильное имя файла."
+
+#: db/models/fields/__init__.py:756
+#, fuzzy
+msgid "This value must be either None, True or False."
+msgstr "Значение должно либо True, либо False."
+
+#: db/models/fields/related.py:53
+#, python-format
+msgid "Please enter a valid %s."
+msgstr "Пожалуйста, введите правильный %s."
+
+#: db/models/fields/related.py:642
+msgid "Separate multiple IDs with commas."
+msgstr "Несколько значений ID разделите запятыми."
+
+#: db/models/fields/related.py:644
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr ""
+"Удерживайте \"Control\" (или \"Command\" на Mac) для выбора нескольких."
+
+#: db/models/fields/related.py:691
+#, python-format
+msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
+msgid_plural ""
+"Please enter valid %(self)s IDs. The values %(value)r are invalid."
+msgstr[0] ""
+"Пожалуйста, введите корректный ID для %(self)s. Значение %(value)r "
+"недопустимо."
+msgstr[1] ""
+"Пожалуйста, введите корректные ID для %(self)s. Значения %(value)r "
+"недопустимы."
+msgstr[2] ""
+"Пожалуйста, введите корректные ID для %(self)s. Значения %(value)r "
+"недопустимы."
+
+#: conf/global_settings.py:39
+msgid "Arabic"
+msgstr "Арабский"
+
+#: conf/global_settings.py:40
+msgid "Bengali"
+msgstr "Бенгальский"
+
+#: conf/global_settings.py:41
+msgid "Catalan"
+msgstr "Каталанский"
+
+#: conf/global_settings.py:42
+msgid "Czech"
+msgstr "Чешский"
+
+#: conf/global_settings.py:43
+msgid "Welsh"
+msgstr "Уэльский"
+
+#: conf/global_settings.py:44
+msgid "Danish"
+msgstr "Датский"
+
+#: conf/global_settings.py:45
+msgid "German"
+msgstr "Немецкий"
+
+#: conf/global_settings.py:46
+msgid "Greek"
+msgstr "Греческий"
+
+#: conf/global_settings.py:47
+msgid "English"
+msgstr "Английский"
+
+#: conf/global_settings.py:48
+msgid "Spanish"
+msgstr "Испанский"
+
+#: conf/global_settings.py:49
+msgid "Argentinean Spanish"
+msgstr "Аргентинский испанский"
+
+#: conf/global_settings.py:50
+msgid "Finnish"
+msgstr "Финский"
+
+#: conf/global_settings.py:51
+msgid "French"
+msgstr "Французский"
+
+#: conf/global_settings.py:52
+msgid "Galician"
+msgstr "Галльский"
+
+#: conf/global_settings.py:53
+msgid "Hungarian"
+msgstr "Венгерский"
+
+#: conf/global_settings.py:54
+msgid "Hebrew"
+msgstr "Иврит"
+
+#: conf/global_settings.py:55
+msgid "Icelandic"
+msgstr "Исландский"
+
+#: conf/global_settings.py:56
+msgid "Italian"
+msgstr "Итальянский"
+
+#: conf/global_settings.py:57
+msgid "Japanese"
+msgstr "Японский"
+
+#: conf/global_settings.py:58
+msgid "Korean"
+msgstr "Корейский"
+
+#: conf/global_settings.py:59
+msgid "Kannada"
+msgstr "Каннада"
+
+#: conf/global_settings.py:60
+msgid "Latvian"
+msgstr "Латвийский"
+
+#: conf/global_settings.py:61
+msgid "Macedonian"
+msgstr "Македоский"
+
+#: conf/global_settings.py:62
+msgid "Dutch"
+msgstr "Голландский"
+
+#: conf/global_settings.py:63
+msgid "Norwegian"
+msgstr "Норвежский"
+
+#: conf/global_settings.py:64
+msgid "Polish"
+msgstr "Польский"
+
+#: conf/global_settings.py:65
+msgid "Portugese"
+msgstr "Португальский"
+
+#: conf/global_settings.py:66
+msgid "Brazilian"
+msgstr "Бразильский"
+
+#: conf/global_settings.py:67
+msgid "Romanian"
+msgstr "Румынский"
+
+#: conf/global_settings.py:68
+msgid "Russian"
+msgstr "Русский"
+
+#: conf/global_settings.py:69
+msgid "Slovak"
+msgstr "Словацкий"
+
+#: conf/global_settings.py:70
+msgid "Slovenian"
+msgstr "Словенский"
+
+#: conf/global_settings.py:71
+msgid "Serbian"
+msgstr "Сербский"
+
+#: conf/global_settings.py:72
+msgid "Swedish"
+msgstr "Шведский"
+
+#: conf/global_settings.py:73
+msgid "Tamil"
+msgstr "Тамиль"
+
+#: conf/global_settings.py:74
+msgid "Telugu"
+msgstr "Телугу"
+
+#: conf/global_settings.py:75
+msgid "Turkish"
+msgstr "Турецкий"
+
+#: conf/global_settings.py:76
+msgid "Ukrainian"
+msgstr "Украинский"
+
+#: conf/global_settings.py:77
+msgid "Simplified Chinese"
+msgstr "Упрощенный китайский"
+
+#: conf/global_settings.py:78
+msgid "Traditional Chinese"
+msgstr "Традиционный китайский"
+
+#: core/validators.py:64
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Значение должно состоять только из букв, цифр и знаков подчеркивания."
+
+#: core/validators.py:68
+msgid ""
+"This value must contain only letters, numbers, underscores, dashes or "
+"slashes."
+msgstr ""
+"Значение должно состоять только из букв, цифр, знаков подчеркивания, тире "
+"или наклонной черты вправо."
+
+#: core/validators.py:72
+msgid "This value must contain only letters, numbers, underscores or hyphens."
+msgstr ""
+"Значение должно состоять только из букв, цифр, знаков подчеркивания "
+"или тире."
+
+#: core/validators.py:76
+msgid "Uppercase letters are not allowed here."
+msgstr "Заглавные буквы недопустимы."
+
+#: core/validators.py:80
+msgid "Lowercase letters are not allowed here."
+msgstr "Строчные буквы здесь недопустимы."
+
+#: core/validators.py:87
+msgid "Enter only digits separated by commas."
+msgstr "Введите цифры, разделённые запятыми."
+
+#: core/validators.py:99
+msgid "Enter valid e-mail addresses separated by commas."
+msgstr "Введите правильные адреса электронной почты, разделённые запятыми."
+
+#: core/validators.py:103
+msgid "Please enter a valid IP address."
+msgstr "Пожалуйста, введите правильный IP-адрес."
+
+#: core/validators.py:107
+msgid "Empty values are not allowed here."
+msgstr "Пустое значение здесь недопустимо."
+
+#: core/validators.py:111
+msgid "Non-numeric characters aren't allowed here."
+msgstr "Нецифровые символы здесь недопустимы."
+
+#: core/validators.py:115
+msgid "This value can't be comprised solely of digits."
+msgstr "Это значение не может быть составлено только из цифр."
+
+#: core/validators.py:120 newforms/fields.py:128
+msgid "Enter a whole number."
+msgstr "Введите целое число."
+
+#: core/validators.py:124
+msgid "Only alphabetical characters are allowed here."
+msgstr "Здесь разрешены только алфавитные символы."
+
+#: core/validators.py:139
+msgid "Year must be 1900 or later."
+msgstr "Год должен быть больше или равен 1900"
+
+#: core/validators.py:143
+msgid "Invalid date: %s"
+msgstr "неправильная дата: %s"
+
+#: core/validators.py:153
+msgid "Enter a valid time in HH:MM format."
+msgstr "Введите правильное время в формате HH:MM."
+
+#: core/validators.py:162 newforms/fields.py:273
+msgid "Enter a valid e-mail address."
+msgstr "Укажите правильный адрес электронной почты."
+
+#: core/validators.py:178
+msgid ""
+"Upload a valid image. The file you uploaded was either not an image or a "
+"corrupted image."
+msgstr ""
+"Загрузите реальное изображение. Файл, который вы загрузили, не является "
+"изображением или был поврежден."
+
+#: core/validators.py:185
+#, python-format
+msgid "The URL %s does not point to a valid image."
+msgstr "URL %s не указывает на реальное изображение."
+
+#: core/validators.py:189
+#, python-format
+msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
+msgstr "Телефонные номера должен быть в формате XXX-XXX-XXXX. \"%s\" неверен."
+
+#: core/validators.py:197
+#, python-format
+msgid "The URL %s does not point to a valid QuickTime video."
+msgstr "URL %s не указывает на реальное видео QuickTime."
+
+#: core/validators.py:201
+msgid "A valid URL is required."
+msgstr "Правильный URL обязателен."
+
+#: core/validators.py:215
+#, python-format
+msgid ""
+"Valid HTML is required. Specific errors are:\n"
+"%s"
+msgstr ""
+"Правильный HTML обязателен. Специфичные ошибки:\n"
+"%s"
+
+#: core/validators.py:222
+#, python-format
+msgid "Badly formed XML: %s"
+msgstr "Неверный формат XML: %s"
+
+#: core/validators.py:239
+#, python-format
+msgid "Invalid URL: %s"
+msgstr "Неверный URL: %s"
+
+#: core/validators.py:244 core/validators.py:246
+#, python-format
+msgid "The URL %s is a broken link."
+msgstr "URL %s - сломанная ссылка."
+
+#: core/validators.py:252
+msgid "Enter a valid U.S. state abbreviation."
+msgstr "Введите правильную аббревиатуру штата США."
+
+#: core/validators.py:266
+#, python-format
+msgid "Watch your mouth! The word %s is not allowed here."
+msgid_plural "Watch your mouth! The words %s are not allowed here."
+msgstr[0] "Следите за своими словами! Слово %s здесь запрещено."
+msgstr[1] "Следите за своими словами! Слова %s здесь запрещены."
+msgstr[2] "Следите за своими словами! Слова %s здесь запрещены."
+
+#: core/validators.py:273
+#, python-format
+msgid "This field must match the '%s' field."
+msgstr "Это поле должно совпадать с полем '%s'."
+
+#: core/validators.py:292
+msgid "Please enter something for at least one field."
+msgstr "Пожалуйста, заполните хотя бы одно поле."
+
+#: core/validators.py:301 core/validators.py:312
+msgid "Please enter both fields or leave them both empty."
+msgstr "Пожалуйста, заполните оба поля или оставьте их оба пустыми."
+
+#: core/validators.py:320
+#, python-format
+msgid "This field must be given if %(field)s is %(value)s"
+msgstr "Это поле должно быть заполнено, если %(field)s равно %(value)s"
+
+#: core/validators.py:333
+#, python-format
+msgid "This field must be given if %(field)s is not %(value)s"
+msgstr "Это поле должно быть заполнено, если %(field)s не равно %(value)s"
+
+#: core/validators.py:352
+msgid "Duplicate values are not allowed."
+msgstr "Двойные значения запрещены."
+
+#: core/validators.py:367
+#, python-format
+msgid "This value must be between %(lower)s and %(upper)s."
+msgstr "Это значение должно быть больше %(lower)s и меньше %(upper)s."
+
+#: core/validators.py:369
+#, python-format
+msgid "This value must be at least %s."
+msgstr "Это значение должно быть не меньше %s."
+
+#: core/validators.py:371
+#, python-format
+msgid "This value must be no more than %s."
+msgstr "Это значение не должно быть больше %s."
+
+#: core/validators.py:407
+#, python-format
+msgid "This value must be a power of %s."
+msgstr "Это значение должно быть степенью %s."
+
+#: core/validators.py:418
+msgid "Please enter a valid decimal number."
+msgstr "Пожалуйста, введите корректное десятичное число."
+
+#: core/validators.py:422
+#, python-format
+msgid "Please enter a valid decimal number with at most %s total digit."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s total digits."
+msgstr[0] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаком."
+msgstr[1] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаками."
+msgstr[2] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаками."
+
+#: core/validators.py:425
+#, python-format
+msgid ""
+"Please enter a valid decimal number with a whole part of at most %s digit."
+msgid_plural ""
+"Please enter a valid decimal number with a whole part of at most %s digits."
+msgstr[0] ""
+"Пожалуйста, введите корректное десятичное число с целой частью из %s знака."
+msgstr[1] ""
+"Пожалуйста, введите корректное десятичное число с целой частью из %s знаков."
+msgstr[2] ""
+"Пожалуйста, введите корректное десятичное число с целой частью из %s знаков."
+
+#: core/validators.py:428
+#, python-format
+msgid "Please enter a valid decimal number with at most %s decimal place."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s decimal places."
+msgstr[0] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаком "
+"после запятой."
+msgstr[1] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаками "
+"после запятой."
+msgstr[2] ""
+"Пожалуйста, введите корректное десятичное число максимально с %s знаками "
+"после запятой."
+
+#: core/validators.py:438
+#, python-format
+msgid "Make sure your uploaded file is at least %s bytes big."
+msgstr "Убедитесь, что загруженный файл не меньше %s байт."
+
+#: core/validators.py:439
+#, python-format
+msgid "Make sure your uploaded file is at most %s bytes big."
+msgstr "Убедитесь, что загруженный файл не больше %s байт."
+
+#: core/validators.py:456
+msgid "The format for this field is wrong."
+msgstr "Формат этого поля неверен."
+
+#: core/validators.py:471
+msgid "This field is invalid."
+msgstr "Это поле неверно."
+
+#: core/validators.py:507
+#, python-format
+msgid "Could not retrieve anything from %s."
+msgstr "Невозможно получить ничего с %s."
+
+#: core/validators.py:510
+#, python-format
+msgid ""
+"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
+msgstr "URL %(url)s вернул неверный заголовок Content-Type '%(contenttype)s'."
+
+#: core/validators.py:543
+#, python-format
+msgid ""
+"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
+"\"%(start)s\".)"
+msgstr ""
+"Пожалуйста, закройте незакрытый тэг %(tag)s на строке %(line)s. (Строка "
+"начинается с \"%(start)s\".)"
+
+#: core/validators.py:547
+#, python-format
+msgid ""
+"Some text starting on line %(line)s is not allowed in that context. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Что-то из текста, начинающегося на строке %(line)s, недопустимо в том "
+"контексте. (Строка начинается с \"%(start)s\".)"
+
+#: core/validators.py:552
+#, python-format
+msgid ""
+"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"%(attr)s\" на строке %(line)s - неправильный атрибут. (Строка начинается с "
+"\"%(start)s\".)"
+
+#: core/validators.py:557
+#, python-format
+msgid ""
+"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"<%(tag)s>\" на строке %(line)s - неправильный тег. (Строка начинается с \"%"
+"(start)s\".)"
+
+#: core/validators.py:561
+#, python-format
+msgid ""
+"A tag on line %(line)s is missing one or more required attributes. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"В теге на строке %(line)s не хватает одного или более обязательных "
+"атрибутов. (Строка начинается с \"%(start)s\".)"
+
+#: core/validators.py:566
+#, python-format
+msgid ""
+"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Атрибут \"%(attr)s\" на строке %(line)s имеет недопустимое значение. (Строка "
+"начинается с \"%(start)s\".)"
+
+#: views/generic/create_update.py:43
+#, python-format
+msgid "The %(verbose_name)s was created successfully."
+msgstr "Объект %(verbose_name)s был успешно создан."
+
+#: views/generic/create_update.py:117
+#, python-format
+msgid "The %(verbose_name)s was updated successfully."
+msgstr "Объект %(verbose_name)s был успешно изменен."
+
+#: views/generic/create_update.py:184
+#, python-format
+msgid "The %(verbose_name)s was deleted."
+msgstr "Объект %(verbose_name)s был успешно удален."
+
+#: newforms/models.py:165 newforms/fields.py:366
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Выберите корректный вариант. Вашего варианта нет среди допустимых"
+
+#: newforms/models.py:182 newforms/fields.py:382 newforms/fields.py:458
+msgid "Enter a list of values."
+msgstr "Укажите список занчений."
+
+#: newforms/models.py:188 newforms/fields.py:391
+#, python-format
+msgid "Select a valid choice. %s is not one of the available choices."
+msgstr "Выберите корректный вариант. %s нет среди допустимых значений."
+
+#: newforms/fields.py:103 newforms/fields.py:258
+#, python-format
+msgid "Ensure this value has at most %d characters."
+msgstr "Убедитесь, что значение содержит менее %d символов."
+
+#: newforms/fields.py:105 newforms/fields.py:260
+#, python-format
+msgid "Ensure this value has at least %d characters."
+msgstr "Убедитесь, что значение содержит более %d символов."
+
+#: newforms/fields.py:130
+#, python-format
+msgid "Ensure this value is less than or equal to %s."
+msgstr "Убедитесь что это значение меньше или равно %s."
+
+#: newforms/fields.py:132
+#, python-format
+msgid "Ensure this value is greater than or equal to %s."
+msgstr "Убедитесь что это значение больше или равно %s"
+
+#: newforms/fields.py:166
+msgid "Enter a valid date."
+msgstr "Укажите дату правильно."
+
+#: newforms/fields.py:194
+msgid "Enter a valid time."
+msgstr "Укажите время правильно."
+
+#: newforms/fields.py:230
+msgid "Enter a valid date/time."
+msgstr "Укажите дату и время правильно."
+
+#: newforms/fields.py:244
+msgid "Enter a valid value."
+msgstr "Укажите значение правильно"
+
+#: newforms/fields.py:291 newforms/fields.py:313
+msgid "Enter a valid URL."
+msgstr "Укажите правильный URL"
+
+#: newforms/fields.py:315
+msgid "This URL appears to be a broken link."
+msgstr "Этот URL похоже сломанная ссылка."
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "th"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "st"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "nd"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "rd"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:47
+#, python-format
+msgid "%(value).1f million"
+msgid_plural "%(value).1f million"
+msgstr[0] "%(value).1f миллион"
+msgstr[1] "%(value).1f миллиона"
+msgstr[2] "%(value).1f миллионов"
+
+#: contrib/humanize/templatetags/humanize.py:50
+#, python-format
+msgid "%(value).1f billion"
+msgid_plural "%(value).1f billion"
+msgstr[0] "%(value).1f миллиард"
+msgstr[1] "%(value).1f миллиарда"
+msgstr[2] "%(value).1f миллиардов"
+
+#: contrib/humanize/templatetags/humanize.py:53
+#, python-format
+msgid "%(value).1f trillion"
+msgid_plural "%(value).1f trillion"
+msgstr[0] "%(value).1f триллион"
+msgstr[1] "%(value).1f триллиона"
+msgstr[2] "%(value).1f триллионов"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "one"
+msgstr "один"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "two"
+msgstr "два"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "three"
+msgstr "три"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "four"
+msgstr "четыре"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "five"
+msgstr "пять"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "six"
+msgstr "шесть"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "seven"
+msgstr "семь"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "eight"
+msgstr "восемь"
+
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "nine"
+msgstr "девять"
+
+#: contrib/redirects/models.py:7
+msgid "redirect from"
+msgstr "Перенаправить от"
+
+#: contrib/redirects/models.py:8
+msgid ""
+"This should be an absolute path, excluding the domain name. Example: '/"
+"events/search/'."
+msgstr ""
+"Это должен быть абсолютный путь без доменного имени. Пример: '/events/"
+"search/'."
+
+#: contrib/redirects/models.py:9
+msgid "redirect to"
+msgstr "Перенаправить на"
+
+#: contrib/redirects/models.py:10
+msgid ""
+"This can be either an absolute path (as above) or a full URL starting with "
+"'http://'."
+msgstr ""
+"Это должен быть абсолютный путь (как выше) или полный URL, начинающийся с "
+"'http://'."
+
+#: contrib/redirects/models.py:13
+msgid "redirect"
+msgstr "Перенаправление"
+
+#: contrib/redirects/models.py:14
+msgid "redirects"
+msgstr "Перенаправления"
+
+#: contrib/comments/models.py:67 contrib/comments/models.py:166
msgid "object ID"
msgstr "ID объекта"
@@ -28,8 +812,7 @@ msgstr "ID объекта"
msgid "headline"
msgstr "Заголовок"
-#: contrib/comments/models.py:69
-#: contrib/comments/models.py:90
+#: contrib/comments/models.py:69 contrib/comments/models.py:90
#: contrib/comments/models.py:167
msgid "comment"
msgstr "Комментарий"
@@ -70,18 +853,15 @@ msgstr "рейтинг №8"
msgid "is valid rating"
msgstr "Допустимый рейтинг"
-#: contrib/comments/models.py:83
-#: contrib/comments/models.py:169
+#: contrib/comments/models.py:83 contrib/comments/models.py:169
msgid "date/time submitted"
msgstr "Дата/время добавления"
-#: contrib/comments/models.py:84
-#: contrib/comments/models.py:170
+#: contrib/comments/models.py:84 contrib/comments/models.py:170
msgid "is public"
msgstr "Публичный"
-#: contrib/comments/models.py:85
-#: contrib/admin/views/doc.py:289
+#: contrib/comments/models.py:85 contrib/admin/views/doc.py:304
msgid "IP address"
msgstr "IP-адрес"
@@ -90,15 +870,18 @@ msgid "is removed"
msgstr "Удален"
#: contrib/comments/models.py:86
-msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
-msgstr "Отметьте, если комментарий нежелателен. Сообщение \"Этот комментарий был удалён\" будет показано взамен."
+msgid ""
+"Check this box if the comment is inappropriate. A \"This comment has been "
+"removed\" message will be displayed instead."
+msgstr ""
+"Отметьте, если комментарий нежелателен. Сообщение \"Этот комментарий был "
+"удалён\" будет показано взамен."
#: contrib/comments/models.py:91
msgid "comments"
msgstr "Комментарии"
-#: contrib/comments/models.py:131
-#: contrib/comments/models.py:207
+#: contrib/comments/models.py:131 contrib/comments/models.py:207
msgid "Content object"
msgstr "Объект содержимого"
@@ -215,34 +998,41 @@ msgstr "Неверный ID комментария"
msgid "No voting for yourself"
msgstr "Нельзя голосовать за себя"
-#: contrib/comments/views/comments.py:28
-msgid "This rating is required because you've entered at least one other rating."
-msgstr "Этот рейтинг обязателен, так как вы уже ввели как минимум еще один рейтинг."
+#: contrib/comments/views/comments.py:27
+msgid ""
+"This rating is required because you've entered at least one other rating."
+msgstr ""
+"Этот рейтинг обязателен, так как вы уже ввели как минимум еще один рейтинг."
-#: contrib/comments/views/comments.py:112
+#: contrib/comments/views/comments.py:111
#, python-format
msgid ""
-"This comment was posted by a user who has posted fewer than %(count)s comment:\n"
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comment:\n"
"\n"
"%(text)s"
msgid_plural ""
-"This comment was posted by a user who has posted fewer than %(count)s comments:\n"
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comments:\n"
"\n"
"%(text)s"
msgstr[0] ""
-"Этот комментарий сделан пользователем, который отправил меньше %(count)s комментария:\n"
+"Этот комментарий сделан пользователем, который отправил меньше %(count)s "
+"комментария:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"Этот комментарий сделан пользователем, который отправил меньше %(count)s комментариев:\n"
+"Этот комментарий сделан пользователем, который отправил меньше %(count)s "
+"комментариев:\n"
"\n"
"%(text)s"
msgstr[2] ""
-"Этот комментарий сделан пользователем, который отправил меньше %(count)s комментариев:\n"
+"Этот комментарий сделан пользователем, который отправил меньше %(count)s "
+"комментариев:\n"
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:116
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -253,31 +1043,48 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:189
+#: contrib/comments/views/comments.py:188
#: contrib/comments/views/comments.py:280
msgid "Only POSTs are allowed"
msgstr "Разрешены только POSTы"
-#: contrib/comments/views/comments.py:193
+#: contrib/comments/views/comments.py:192
#: contrib/comments/views/comments.py:284
msgid "One or more of the required fields wasn't submitted"
msgstr "Одно или больше обязательных полей не были заполнены"
-#: contrib/comments/views/comments.py:197
+#: contrib/comments/views/comments.py:196
#: contrib/comments/views/comments.py:286
msgid "Somebody tampered with the comment form (security violation)"
msgstr "Кто-то вмешался в форму комментария (нарушение безопасности)"
-#: contrib/comments/views/comments.py:207
+#: contrib/comments/views/comments.py:206
#: contrib/comments/views/comments.py:292
-msgid "The comment form had an invalid 'target' parameter -- the object ID was invalid"
-msgstr "Форма комментария имела неверный параметр 'target' -- ID объекта неверен"
+msgid ""
+"The comment form had an invalid 'target' parameter -- the object ID was "
+"invalid"
+msgstr ""
+"Форма комментария имела неверный параметр 'target' -- ID объекта неверен"
#: contrib/comments/views/comments.py:257
#: contrib/comments/views/comments.py:321
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Форма комментария не предоставила ни 'предпросмотр', ни 'отправить'"
+#: contrib/comments/templates/comments/freeform.html:4
+msgid "Your name:"
+msgstr "Имя пользователя:"
+
+#: contrib/comments/templates/comments/freeform.html:5
+#: contrib/comments/templates/comments/form.html:28
+msgid "Comment:"
+msgstr "Комментарий:"
+
+#: contrib/comments/templates/comments/freeform.html:10
+#: contrib/comments/templates/comments/form.html:35
+msgid "Preview comment"
+msgstr "Предпросмотр комментария"
+
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
#: contrib/admin/templates/admin/login.html:17
@@ -285,20 +1092,12 @@ msgid "Username:"
msgstr "Имя:"
#: contrib/comments/templates/comments/form.html:6
-#: contrib/admin/templates/admin/login.html:20
-msgid "Password:"
-msgstr "Пароль:"
-
-#: contrib/comments/templates/comments/form.html:6
-msgid "Forgotten your password?"
-msgstr "Забыли свой пароль?"
-
-#: contrib/comments/templates/comments/form.html:8
#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/admin_doc/bookmarklets.html:4
@@ -314,6 +1113,15 @@ msgstr "Забыли свой пароль?"
msgid "Log out"
msgstr "Выход"
+#: contrib/comments/templates/comments/form.html:8
+#: contrib/admin/templates/admin/login.html:20
+msgid "Password:"
+msgstr "Пароль:"
+
+#: contrib/comments/templates/comments/form.html:8
+msgid "Forgotten your password?"
+msgstr "Забыли свой пароль?"
+
#: contrib/comments/templates/comments/form.html:12
msgid "Ratings"
msgstr "Рейтинги"
@@ -332,19 +1140,21 @@ msgstr "Необязательное"
msgid "Post a photo"
msgstr "Добавить фотографию"
-#: contrib/comments/templates/comments/form.html:27
-#: contrib/comments/templates/comments/freeform.html:5
-msgid "Comment:"
-msgstr "Комментарий:"
+#: contrib/sites/models.py:10
+msgid "domain name"
+msgstr "Доменное имя"
-#: contrib/comments/templates/comments/form.html:32
-#: contrib/comments/templates/comments/freeform.html:9
-msgid "Preview comment"
-msgstr "Предпросмотр комментария"
+#: contrib/sites/models.py:11
+msgid "display name"
+msgstr "Выводимое имя"
-#: contrib/comments/templates/comments/freeform.html:4
-msgid "Your name:"
-msgstr "Имя пользователя:"
+#: contrib/sites/models.py:15
+msgid "site"
+msgstr "Сайт"
+
+#: contrib/sites/models.py:16
+msgid "sites"
+msgstr "Сайты"
#: contrib/admin/filterspecs.py:40
#, python-format
@@ -355,9 +1165,8 @@ msgstr ""
"<h3>По %s:</h3>\n"
"<ul>\n"
-#: contrib/admin/filterspecs.py:70
-#: contrib/admin/filterspecs.py:88
-#: contrib/admin/filterspecs.py:143
+#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88
+#: contrib/admin/filterspecs.py:143 contrib/admin/filterspecs.py:169
msgid "All"
msgstr "Все"
@@ -381,18 +1190,6 @@ msgstr "В этом месяце"
msgid "This year"
msgstr "В этом году"
-#: contrib/admin/filterspecs.py:143
-msgid "Yes"
-msgstr "Да"
-
-#: contrib/admin/filterspecs.py:143
-msgid "No"
-msgstr "Нет"
-
-#: contrib/admin/filterspecs.py:150
-msgid "Unknown"
-msgstr "Неизвестно"
-
#: contrib/admin/models.py:16
msgid "action time"
msgstr "Время действия"
@@ -421,219 +1218,312 @@ msgstr "Журнальная запись"
msgid "log entries"
msgstr "Журнальные записи"
-#: contrib/admin/templatetags/admin_list.py:228
+#: contrib/admin/templatetags/admin_list.py:247
msgid "All dates"
msgstr "Все даты"
-#: contrib/admin/views/decorators.py:9
-#: contrib/auth/forms.py:36
-#: contrib/auth/forms.py:41
-msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
-msgstr "Пожалуйста, введите верные имя пользователя и пароль. Помните, оба поля чувствительны к регистру."
+#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Пожалуйста, введите верные имя пользователя и пароль. Помните, оба поля "
+"чувствительны к регистру."
-#: contrib/admin/views/decorators.py:23
+#: contrib/admin/views/decorators.py:24
#: contrib/admin/templates/admin/login.html:25
msgid "Log in"
msgstr "Вход"
-#: contrib/admin/views/decorators.py:61
-msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
-msgstr "Пожалуйста, войдите снова, поскольку ваша сессия устарела. Не беспокойтесь: введенные вами данные сохранены."
+#: contrib/admin/views/decorators.py:62
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Пожалуйста, войдите снова, поскольку ваша сессия устарела. Не беспокойтесь: "
+"введенные вами данные сохранены."
-#: contrib/admin/views/decorators.py:68
-msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
-msgstr "Похоже, ваш броузер не настроен на прием cookies. Пожалуйства, включите cookie, перезагрузите страницу и попытайтесь снова."
+#: contrib/admin/views/decorators.py:69
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Похоже, ваш броузер не настроен на прием cookies. Пожалуйства, включите "
+"cookie, перезагрузите страницу и попытайтесь снова."
-#: contrib/admin/views/decorators.py:82
+#: contrib/admin/views/decorators.py:83
msgid "Usernames cannot contain the '@' character."
msgstr "Имя пользователя не может включать символ '@'."
-#: contrib/admin/views/decorators.py:84
+#: contrib/admin/views/decorators.py:85
#, python-format
msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Ваш адрес электронной почты не является вашим именем пользователя. Попробуйте '%s' взамен."
-
-#: contrib/admin/views/main.py:226
-msgid "Site administration"
-msgstr "Администрирование сайта"
+msgstr ""
+"Ваш адрес электронной почты не является вашим именем пользователя. "
+"Попробуйте '%s' взамен."
-#: contrib/admin/views/main.py:260
+#: contrib/admin/views/auth.py:19 contrib/admin/views/main.py:257
#, python-format
msgid "The %(name)s \"%(obj)s\" was added successfully."
msgstr "%(name)s \"%(obj)s\" был успешно добавлен."
-#: contrib/admin/views/main.py:264
-#: contrib/admin/views/main.py:348
+#: contrib/admin/views/auth.py:24 contrib/admin/views/main.py:261
+#: contrib/admin/views/main.py:347
msgid "You may edit it again below."
msgstr "Ниже можно снова редактировать его"
-#: contrib/admin/views/main.py:272
-#: contrib/admin/views/main.py:357
+#: contrib/admin/views/auth.py:30
+msgid "Add user"
+msgstr "Добавить пользователя"
+
+#: contrib/admin/views/auth.py:57
+msgid "Password changed successfully."
+msgstr "Пароль успешно обновлен"
+
+#: contrib/admin/views/auth.py:64
+msgid "Change password: %s"
+msgstr "Изменение пароля: %s"
+
+#: contrib/admin/views/main.py:223
+msgid "Site administration"
+msgstr "Администрирование сайта"
+
+#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356
#, python-format
msgid "You may add another %s below."
msgstr "Вы можете добавить %s внизу."
-#: contrib/admin/views/main.py:290
+#: contrib/admin/views/main.py:289
#, python-format
msgid "Add %s"
msgstr "Добавить %s"
-#: contrib/admin/views/main.py:336
+#: contrib/admin/views/main.py:335
#, python-format
msgid "Added %s."
msgstr "Добавлен %s."
-#: contrib/admin/views/main.py:336
-#: contrib/admin/views/main.py:338
-#: contrib/admin/views/main.py:340
-msgid "and"
-msgstr "и"
-
-#: contrib/admin/views/main.py:338
+#: contrib/admin/views/main.py:337
#, python-format
msgid "Changed %s."
msgstr "Изменен %s."
-#: contrib/admin/views/main.py:340
+#: contrib/admin/views/main.py:339
#, python-format
msgid "Deleted %s."
msgstr "Удален %s."
-#: contrib/admin/views/main.py:343
+#: contrib/admin/views/main.py:342
msgid "No fields changed."
msgstr "Ни одно поле не изменено."
-#: contrib/admin/views/main.py:346
+#: contrib/admin/views/main.py:345
#, python-format
msgid "The %(name)s \"%(obj)s\" was changed successfully."
msgstr "%(name)s \"%(obj)s\" был успешно изменен."
-#: contrib/admin/views/main.py:354
+#: contrib/admin/views/main.py:353
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr "%(name)s \"%(obj)s\" был успешно добавлен. Ниже можно снова редактировать его."
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"%(name)s \"%(obj)s\" был успешно добавлен. Ниже можно снова редактировать "
+"его."
-#: contrib/admin/views/main.py:392
+#: contrib/admin/views/main.py:391
#, python-format
msgid "Change %s"
msgstr "Изменить %s"
-#: contrib/admin/views/main.py:470
+#: contrib/admin/views/main.py:476
#, python-format
msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
msgstr "Один или более %(fieldname)s в %(name)s: %(obj)s"
-#: contrib/admin/views/main.py:475
+#: contrib/admin/views/main.py:481
#, python-format
msgid "One or more %(fieldname)s in %(name)s:"
msgstr "Один или более %(fieldname)s в %(name)s:"
-#: contrib/admin/views/main.py:508
+#: contrib/admin/views/main.py:514
#, python-format
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
msgstr "%(name)s \"%(obj)s\" был успешно удален."
-#: contrib/admin/views/main.py:511
+#: contrib/admin/views/main.py:517
msgid "Are you sure?"
msgstr "Вы уверены?"
-#: contrib/admin/views/main.py:533
+#: contrib/admin/views/main.py:539
#, python-format
msgid "Change history: %s"
msgstr "История изменений: %s"
-#: contrib/admin/views/main.py:565
+#: contrib/admin/views/main.py:573
#, python-format
msgid "Select %s"
msgstr "Выберите %s"
-#: contrib/admin/views/main.py:565
-#, python-format
+#: contrib/admin/views/main.py:573
msgid "Select %s to change"
msgstr "Выберите %s для изменения"
-#: contrib/admin/views/doc.py:277
-#: contrib/admin/views/doc.py:286
-#: contrib/admin/views/doc.py:288
-#: contrib/admin/views/doc.py:294
-#: contrib/admin/views/doc.py:295
-#: contrib/admin/views/doc.py:297
+#: contrib/admin/views/main.py:768
+msgid "Database error"
+msgstr "Ошибка базы данных"
+
+#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48
+#: contrib/admin/views/doc.py:50
+msgid "tag:"
+msgstr "Тэг:"
+
+#: contrib/admin/views/doc.py:77 contrib/admin/views/doc.py:79
+#: contrib/admin/views/doc.py:81
+msgid "filter:"
+msgstr "Фильтр:"
+
+#: contrib/admin/views/doc.py:135 contrib/admin/views/doc.py:137
+#: contrib/admin/views/doc.py:139
+msgid "view:"
+msgstr "view:"
+
+#: contrib/admin/views/doc.py:164
+#, python-format
+msgid "App %r not found"
+msgstr "Приложение %r не найдено"
+
+#: contrib/admin/views/doc.py:171
+msgid "Model %(name)r not found in app %(label)r"
+msgstr "Модель %(name) не найдена в приложении %(label)r"
+
+#: contrib/admin/views/doc.py:183
+#, python-format
+msgid "the related `%(label)s.%(type)s` object"
+msgstr "зависимый `%(label)s.%(type)s` объект"
+
+#: contrib/admin/views/doc.py:183 contrib/admin/views/doc.py:205
+#: contrib/admin/views/doc.py:219 contrib/admin/views/doc.py:224
+msgid "model:"
+msgstr "модель:"
+
+#: contrib/admin/views/doc.py:214
+#, python-format
+msgid "related `%(label)s.%(name)s` objects"
+msgstr "зависимые `%(label)s.%(name)s` объекты"
+
+#: contrib/admin/views/doc.py:219
+msgid "all %s"
+msgstr "все %s"
+
+#: contrib/admin/views/doc.py:224
+#, python-format
+msgid "number of %s"
+msgstr "количество %s"
+
+#: contrib/admin/views/doc.py:229
+#, python-format
+msgid "Fields on %s objects"
+msgstr "Поля для %s объектов"
+
+#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:301
+#: contrib/admin/views/doc.py:303 contrib/admin/views/doc.py:309
+#: contrib/admin/views/doc.py:310 contrib/admin/views/doc.py:312
msgid "Integer"
msgstr "Целое"
-#: contrib/admin/views/doc.py:278
+#: contrib/admin/views/doc.py:292
msgid "Boolean (Either True or False)"
msgstr "Логическое (True или False)"
-#: contrib/admin/views/doc.py:279
-#: contrib/admin/views/doc.py:296
+#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:311
#, python-format
msgid "String (up to %(maxlength)s)"
msgstr "Строка (до %(maxlength)s символов)"
-#: contrib/admin/views/doc.py:280
+#: contrib/admin/views/doc.py:294
msgid "Comma-separated integers"
msgstr "Целые, разделенные запятыми"
-#: contrib/admin/views/doc.py:281
+#: contrib/admin/views/doc.py:295
msgid "Date (without time)"
msgstr "Дата (без указания времени)"
-#: contrib/admin/views/doc.py:282
+#: contrib/admin/views/doc.py:296
msgid "Date (with time)"
msgstr "Дата (с указанием времени)"
-#: contrib/admin/views/doc.py:283
+#: contrib/admin/views/doc.py:297
msgid "E-mail address"
msgstr "Адрес электронной почты"
-#: contrib/admin/views/doc.py:284
-#: contrib/admin/views/doc.py:287
+#: contrib/admin/views/doc.py:298 contrib/admin/views/doc.py:299
+#: contrib/admin/views/doc.py:302
msgid "File path"
msgstr "Путь к файлу"
-#: contrib/admin/views/doc.py:285
+#: contrib/admin/views/doc.py:300
msgid "Decimal number"
msgstr "Десятичное число"
-#: contrib/admin/views/doc.py:291
+#: contrib/admin/views/doc.py:306
msgid "Boolean (Either True, False or None)"
msgstr "Логическое (True, False или None)"
-#: contrib/admin/views/doc.py:292
+#: contrib/admin/views/doc.py:307
msgid "Relation to parent model"
msgstr "Связь с родительской моделью"
-#: contrib/admin/views/doc.py:293
+#: contrib/admin/views/doc.py:308
msgid "Phone number"
msgstr "Номер телефона"
-#: contrib/admin/views/doc.py:298
+#: contrib/admin/views/doc.py:313
msgid "Text"
msgstr "Текст"
-#: contrib/admin/views/doc.py:299
+#: contrib/admin/views/doc.py:314
msgid "Time"
msgstr "Время"
-#: contrib/admin/views/doc.py:300
-#: contrib/flatpages/models.py:7
+#: contrib/admin/views/doc.py:315 contrib/flatpages/models.py:7
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:301
+#: contrib/admin/views/doc.py:316
msgid "U.S. state (two uppercase letters)"
msgstr "Штат США (две заглавные буквы)"
-#: contrib/admin/views/doc.py:302
+#: contrib/admin/views/doc.py:317
msgid "XML text"
msgstr "Текст XML"
+#: contrib/admin/views/doc.py:343
+#, python-format
+msgid "%s does not appear to be a urlpattern object"
+msgstr "%s не похож на объект urlpattern"
+
+#: contrib/admin/templates/widget/file.html:2
+msgid "Currently:"
+msgstr "Современно:"
+
+#: contrib/admin/templates/widget/file.html:3
+msgid "Change:"
+msgstr "Изменить:"
+
+#: contrib/admin/templates/widget/date_time.html:3
+msgid "Date:"
+msgstr "Дата:"
+
+#: contrib/admin/templates/widget/date_time.html:4
+msgid "Time:"
+msgstr "Время:"
+
#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
@@ -642,9 +1532,12 @@ msgstr "Документация"
#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/auth/user/change_password.html:9
+#: contrib/admin/templates/admin/auth/user/change_password.html:15
+#: contrib/admin/templates/admin/auth/user/change_password.html:46
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
#: contrib/admin/templates/admin_doc/bookmarklets.html:4
@@ -661,11 +1554,13 @@ msgid "Change password"
msgstr "Изменение пароля"
#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/500.html:4
#: contrib/admin/templates/admin/change_list.html:6
-#: contrib/admin/templates/admin/base.html:28
-#: contrib/admin/templates/admin/delete_confirmation.html:6
+#: contrib/admin/templates/admin/500.html:4
+#: contrib/admin/templates/admin/invalid_setup.html:4
#: contrib/admin/templates/admin/change_form.html:13
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/delete_confirmation.html:6
+#: contrib/admin/templates/admin/auth/user/change_password.html:12
#: contrib/admin/templates/registration/password_change_done.html:4
#: contrib/admin/templates/registration/password_reset_form.html:4
#: contrib/admin/templates/registration/logged_out.html:4
@@ -676,7 +1571,7 @@ msgid "Home"
msgstr "Начало"
#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/change_form.html:20
+#: contrib/admin/templates/admin/change_form.html:21
msgid "History"
msgstr "История"
@@ -697,16 +1592,22 @@ msgid "DATE_WITH_TIME_FULL"
msgstr "j N Y H:i"
#: contrib/admin/templates/admin/object_history.html:36
-msgid "This object doesn't have a change history. It probably wasn't added via this admin site."
-msgstr "Данный обьект не имеет истории изменений. Возможно, он был добавлен не через данный административный сайт."
+msgid ""
+"This object doesn't have a change history. It probably wasn't added via this "
+"admin site."
+msgstr ""
+"Данный обьект не имеет истории изменений. Возможно, он был добавлен не через "
+"данный административный сайт."
-#: contrib/admin/templates/admin/base_site.html:4
-msgid "Django site admin"
-msgstr "Административный сайт Django"
+#: contrib/admin/templates/admin/change_list.html:12
+#, python-format
+msgid "Add %(name)s"
+msgstr "Добавить %(name)s"
-#: contrib/admin/templates/admin/base_site.html:7
-msgid "Django administration"
-msgstr "Администрирование Django"
+#: contrib/admin/templates/admin/filter.html:2
+#, python-format
+msgid " By %(filter_title)s "
+msgstr " По %(filter_title)s "
#: contrib/admin/templates/admin/500.html:4
msgid "Server error"
@@ -721,8 +1622,56 @@ msgid "Server Error <em>(500)</em>"
msgstr "Ошибка сервера <em>(500)</em>"
#: contrib/admin/templates/admin/500.html:10
-msgid "There's been an error. It's been reported to the site administrators via e-mail and should be fixed shortly. Thanks for your patience."
-msgstr "Произошла ошибка. Отчет об ошибке отправлен администраторам сайта по электронной почте, ошибка должна быть вскоре исправлена. Благодарим вас на терпение и помощь."
+msgid ""
+"There's been an error. It's been reported to the site administrators via e-"
+"mail and should be fixed shortly. Thanks for your patience."
+msgstr ""
+"Произошла ошибка. Отчет об ошибке отправлен администраторам сайта по "
+"электронной почте, ошибка должна быть вскоре исправлена. Благодарим вас на "
+"терпение и помощь."
+
+#: contrib/admin/templates/admin/invalid_setup.html:8
+msgid ""
+"Something's wrong with your database installation. Make sure the appropriate "
+"database tables have been created, and make sure the database is readable by "
+"the appropriate user."
+msgstr ""
+"Неправильно настроена ваша даза данных. Убедитесь в том что соответсвующие "
+"таблицы базы данных были созданы, а также в что что база данных читаема для "
+"соответсвующим пользователем."
+
+#: contrib/admin/templates/admin/search_form.html:8
+msgid "Go"
+msgstr "Вперёд"
+
+#: contrib/admin/templates/admin/search_form.html:10
+#, python-format
+msgid "1 result"
+msgid_plural "%(counter)s results"
+msgstr[0] "1 результат"
+msgstr[1] "%(counter)s результата"
+msgstr[2] "%(counter)s результатов"
+
+#: contrib/admin/templates/admin/search_form.html:10
+#, python-format
+msgid "%(full_result_count)s total"
+msgstr "%(full_result_count)s всего"
+
+#: contrib/admin/templates/admin/pagination.html:10
+msgid "Show all"
+msgstr "Показать всё"
+
+#: contrib/admin/templates/admin/base_site.html:4
+msgid "Django site admin"
+msgstr "Административный сайт Django"
+
+#: contrib/admin/templates/admin/base_site.html:7
+msgid "Django administration"
+msgstr "Администрирование Django"
+
+#: contrib/admin/templates/admin/filters.html:4
+msgid "Filter"
+msgstr "Фильтр"
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
@@ -738,6 +1687,11 @@ msgstr "К сожалению, запрашиваемая вами страниÑ
msgid "Models available in the %(name)s application."
msgstr "Модели доступны в приложении %(name)s."
+#: contrib/admin/templates/admin/index.html:18
+#, python-format
+msgid "%(name)s"
+msgstr "%(name)s"
+
#: contrib/admin/templates/admin/index.html:28
#: contrib/admin/templates/admin/change_form.html:15
msgid "Add"
@@ -763,16 +1717,27 @@ msgstr "Мои действия"
msgid "None available"
msgstr "Недоступно"
-#: contrib/admin/templates/admin/change_list.html:11
-#, python-format
-msgid "Add %(name)s"
-msgstr "Добавить %(name)s"
+#: contrib/admin/templates/admin/change_form.html:22
+msgid "View on site"
+msgstr "Смотреть сайт"
-#: contrib/admin/templates/admin/login.html:22
-msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
-msgstr "Вы <a href=\"/password_reset/\">забыли пароль</a>?"
+#: contrib/admin/templates/admin/change_form.html:32
+#: contrib/admin/templates/admin/auth/user/change_password.html:24
+msgid "Please correct the error below."
+msgid_plural "Please correct the errors below."
+msgstr[0] "Пожалуйста, исправьте ошибку ниже."
+msgstr[1] "Пожалуйста, исправьте ошибки ниже."
+msgstr[2] "Пожалуйста, исправьте ошибки ниже."
+
+#: contrib/admin/templates/admin/change_form.html:50
+msgid "Ordering"
+msgstr "Очерёдность"
+
+#: contrib/admin/templates/admin/change_form.html:53
+msgid "Order:"
+msgstr "Порядок:"
-#: contrib/admin/templates/admin/base.html:23
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Добро пожаловать,"
@@ -782,59 +1747,29 @@ msgid "Delete"
msgstr "Удалить"
#: contrib/admin/templates/admin/delete_confirmation.html:14
-#, python-format
-msgid "Deleting the %(object_name)s '%(object)s' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:"
-msgstr "Удаление объекта %(object_name)s '%(object)s' привело бы к удалению связанных элементов, но предоставленных вам прав недостаточно для удаления следующих типов объектов:"
+#, python-format
+msgid ""
+"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
+"related objects, but your account doesn't have permission to delete the "
+"following types of objects:"
+msgstr ""
+"Удаление %(object_name)s '%(escaped_object)s' приведет к удалению "
+"связанных объектов, но ваша учетная запись не имеет прав для удаления "
+"следующих типов объектов:"
#: contrib/admin/templates/admin/delete_confirmation.html:21
-#, python-format
-msgid "Are you sure you want to delete the %(object_name)s \"%(object)s\"? All of the following related items will be deleted:"
-msgstr "Вы уверены, что хотите удалить %(object_name)s \"%(object)s\"? Все следующие связанные объекты также будут удалены:"
+#, python-format
+msgid ""
+"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
+"All of the following related items will be deleted:"
+msgstr ""
+"Вы уверены, что хотите удалить %(object_name)s \"%(escaped_object)s\"? Все следующие "
+"связанные объекты также будут удалены:"
#: contrib/admin/templates/admin/delete_confirmation.html:26
msgid "Yes, I'm sure"
msgstr "Да, я уверен"
-#: contrib/admin/templates/admin/filter.html:2
-#, python-format
-msgid " By %(title)s "
-msgstr " По %(title)s "
-
-#: contrib/admin/templates/admin/search_form.html:8
-msgid "Go"
-msgstr "Вперёд"
-
-#: contrib/admin/templates/admin/search_form.html:10
-#, python-format
-msgid "1 result"
-msgid_plural "%(counter)s results"
-msgstr[0] "1 результат"
-msgstr[1] "%(counter)s результата"
-msgstr[2] "%(counter)s результатов"
-
-#: contrib/admin/templates/admin/search_form.html:10
-msgid "%(full_result_count)s total"
-msgstr "%(full_result_count)s всего"
-
-#: contrib/admin/templates/admin/change_form.html:21
-msgid "View on site"
-msgstr "Смотреть сайт"
-
-#: contrib/admin/templates/admin/change_form.html:30
-msgid "Please correct the error below."
-msgid_plural "Please correct the errors below."
-msgstr[0] "Пожалуйста, исправьте ошибку ниже."
-msgstr[1] "Пожалуйста, исправьте ошибки ниже."
-msgstr[2] "Пожалуйста, исправьте ошибки ниже."
-
-#: contrib/admin/templates/admin/change_form.html:48
-msgid "Ordering"
-msgstr "Очерёдность"
-
-#: contrib/admin/templates/admin/change_form.html:51
-msgid "Order:"
-msgstr "Порядок:"
-
#: contrib/admin/templates/admin/submit_line.html:4
msgid "Save as new"
msgstr "Сохранить как новое"
@@ -851,6 +1786,38 @@ msgstr "Сохранить и продолжить редактирование"
msgid "Save"
msgstr "Сохранить"
+#: contrib/admin/templates/admin/auth/user/change_password.html:28
+#, python-format
+msgid "Enter a new password for the user <strong>%(username)s</strong>."
+msgstr "Введите новый пароль для пользователя <strong>%(username)s</strong>"
+
+#: contrib/admin/templates/admin/auth/user/change_password.html:34
+#: contrib/admin/templates/admin/auth/user/add_form.html:18
+msgid "Password"
+msgstr "Пароль"
+
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:23
+msgid "Password (again)"
+msgstr "Пароль (еще раз)"
+
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
+#: contrib/admin/templates/admin/auth/user/add_form.html:24
+msgid "Enter the same password as above, for verification."
+msgstr "Введите тот же пароль что и сверху, для верификации"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:6
+msgid ""
+"First, enter a username and password. Then, you'll be able to edit more user "
+"options."
+msgstr ""
+"Сначала введите имя пользователя и пароль. Затем вы сможете "
+"редактировать больше опций"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:12
+msgid "Username"
+msgstr "Имя"
+
#: contrib/admin/templates/registration/password_change_done.html:4
#: contrib/admin/templates/registration/password_change_form.html:4
#: contrib/admin/templates/registration/password_change_form.html:6
@@ -875,8 +1842,12 @@ msgid "Password reset"
msgstr "Сброс пароля"
#: contrib/admin/templates/registration/password_reset_form.html:12
-msgid "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you."
-msgstr "Забыли пароль? Введите свой адрес электронной почты ниже, мы очистим ваш старый пароль и вышлем вам по e-mail новый."
+msgid ""
+"Forgotten your password? Enter your e-mail address below, and we'll reset "
+"your password and e-mail the new one to you."
+msgstr ""
+"Забыли пароль? Введите свой адрес электронной почты ниже, мы очистим ваш "
+"старый пароль и вышлем вам по e-mail новый."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -900,12 +1871,20 @@ msgid "Password reset successful"
msgstr "Успешная очистка пароля"
#: contrib/admin/templates/registration/password_reset_done.html:12
-msgid "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly."
-msgstr "Мы отправили новый пароль по указанному вами адресу электронной почты. Вскоре вы его получите."
+msgid ""
+"We've e-mailed a new password to the e-mail address you submitted. You "
+"should be receiving it shortly."
+msgstr ""
+"Мы отправили новый пароль по указанному вами адресу электронной почты. "
+"Вскоре вы его получите."
#: contrib/admin/templates/registration/password_change_form.html:12
-msgid "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly."
-msgstr "В целях безопасности, пожалуйста, введите свой старый пароль, затем - новый пароль дважды, с тем, чтобы мы могли убедиться в правильности написания."
+msgid ""
+"Please enter your old password, for security's sake, and then enter your new "
+"password twice so we can verify you typed it in correctly."
+msgstr ""
+"В целях безопасности, пожалуйста, введите свой старый пароль, затем - новый "
+"пароль дважды, с тем, чтобы мы могли убедиться в правильности написания."
#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
@@ -974,10 +1953,13 @@ msgid ""
msgstr ""
"\n"
"<p class=\"help\">Для установки закладок перетащите ссылку к себе на панель\n"
-"закладок или щелкните правой кнопкой мыши по ссылке и добавьте ее в закладки. Теперь у вас есть возможность\n"
-"выбрать закладку с любой страницы сайта. Обратите внимание: некоторые из этих\n"
+"закладок или щелкните правой кнопкой мыши по ссылке и добавьте ее в "
+"закладки. Теперь у вас есть возможность\n"
+"выбрать закладку с любой страницы сайта. Обратите внимание: некоторые из "
+"этих\n"
"закладок требуют, чтобы вы просматривали сайт с компьютера, определенного\n"
-"как \"внутренний\" (уточните у своего системного администратора, если не уверены, является ли\n"
+"как \"внутренний\" (уточните у своего системного администратора, если не "
+"уверены, является ли\n"
"ваш компьютер \"внутренним\").</p>\n"
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
@@ -985,16 +1967,24 @@ msgid "Documentation for this page"
msgstr "Документация по данной странице"
#: contrib/admin/templates/admin_doc/bookmarklets.html:20
-msgid "Jumps you from any page to the documentation for the view that generates that page."
-msgstr "Перенаправляет вас с любой страницы к документации view, который генерирует эту страницу."
+msgid ""
+"Jumps you from any page to the documentation for the view that generates "
+"that page."
+msgstr ""
+"Перенаправляет вас с любой страницы к документации view, который генерирует "
+"эту страницу."
#: contrib/admin/templates/admin_doc/bookmarklets.html:22
msgid "Show object ID"
msgstr "Показать ID обьекта"
#: contrib/admin/templates/admin_doc/bookmarklets.html:23
-msgid "Shows the content-type and unique ID for pages that represent a single object."
-msgstr "Показывает тип наполнения и уникальный ID для страниц, представляющих один объект."
+msgid ""
+"Shows the content-type and unique ID for pages that represent a single "
+"object."
+msgstr ""
+"Показывает тип наполнения и уникальный ID для страниц, представляющих один "
+"объект."
#: contrib/admin/templates/admin_doc/bookmarklets.html:25
msgid "Edit this object (current window)"
@@ -1002,7 +1992,9 @@ msgstr "Редактировать данный обьект (в текущем
#: contrib/admin/templates/admin_doc/bookmarklets.html:26
msgid "Jumps to the admin page for pages that represent a single object."
-msgstr "Перейдет на административную страницу для страниц, представляющих один объект."
+msgstr ""
+"Перейдет на административную страницу для страниц, представляющих один "
+"объект."
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
msgid "Edit this object (new window)"
@@ -1012,260 +2004,739 @@ msgstr "Редактировать данный обьект (в новом ок
msgid "As above, but opens the admin page in a new window."
msgstr "То же что и выше, но откроет административную страницу в новом окне."
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Дата:"
-
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Время:"
-
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Современно:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Изменить:"
-
-#: contrib/redirects/models.py:7
-msgid "redirect from"
-msgstr "Перенаправить из"
-
-#: contrib/redirects/models.py:8
-msgid "This should be an absolute path, excluding the domain name. Example: '/events/search/'."
-msgstr "Это должен быть абсолютный путь без доменного имени. Пример: '/events/search/'."
-
-#: contrib/redirects/models.py:9
-msgid "redirect to"
-msgstr "Перенаправить на"
-
-#: contrib/redirects/models.py:10
-msgid "This can be either an absolute path (as above) or a full URL starting with 'http://'."
-msgstr "Это должен быть абсолютный путь (как выше) или полный URL, начинающийся с 'http://'."
-
-#: contrib/redirects/models.py:12
-msgid "redirect"
-msgstr "Перенаправление"
-
-#: contrib/redirects/models.py:13
-msgid "redirects"
-msgstr "Перенаправления"
-
-#: contrib/flatpages/models.py:8
-msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr "Пример: '/about/contact/'. Будьте уверенны, что вставили завепршающий слэш."
-
-#: contrib/flatpages/models.py:9
-msgid "title"
-msgstr "Заголовок"
-
-#: contrib/flatpages/models.py:10
-msgid "content"
-msgstr "Содержимое"
-
-#: contrib/flatpages/models.py:11
-msgid "enable comments"
-msgstr "Активировать комментарии"
-
-#: contrib/flatpages/models.py:12
-msgid "template name"
-msgstr "Имя шаблона"
-
-#: contrib/flatpages/models.py:13
-msgid "Example: 'flatpages/contact_page'. If this isn't provided, the system will use 'flatpages/default'."
-msgstr "Пример: 'flatpages/contact_page'. Если этот файл не присутствует, система будет использовать 'flatpages/default'."
-
-#: contrib/flatpages/models.py:14
-msgid "registration required"
-msgstr "Регистрация обязательна"
+#: contrib/contenttypes/models.py:36
+msgid "python model class name"
+msgstr "имя класса python модуля"
-#: contrib/flatpages/models.py:14
-msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr "Если отмечено, только вошедшие пользователи смогут видеть страницу."
+#: contrib/contenttypes/models.py:39
+msgid "content type"
+msgstr "Тип содержимого"
-#: contrib/flatpages/models.py:18
-msgid "flat page"
-msgstr "Простая страница"
+#: contrib/contenttypes/models.py:40
+msgid "content types"
+msgstr "Типы содержимого"
-#: contrib/flatpages/models.py:19
-msgid "flat pages"
-msgstr "Простые страницы"
+#: contrib/auth/views.py:40
+msgid "Logged out"
+msgstr "Не авторизован"
-#: contrib/auth/models.py:13
-#: contrib/auth/models.py:26
+#: contrib/auth/models.py:44 contrib/auth/models.py:64
msgid "name"
msgstr "Имя"
-#: contrib/auth/models.py:15
+#: contrib/auth/models.py:46
msgid "codename"
msgstr "Кодовое название"
-#: contrib/auth/models.py:17
+#: contrib/auth/models.py:49
msgid "permission"
msgstr "Право"
-#: contrib/auth/models.py:18
-#: contrib/auth/models.py:27
+#: contrib/auth/models.py:50 contrib/auth/models.py:65
msgid "permissions"
msgstr "Права"
-#: contrib/auth/models.py:29
+#: contrib/auth/models.py:68
msgid "group"
msgstr "Группа"
-#: contrib/auth/models.py:30
-#: contrib/auth/models.py:65
+#: contrib/auth/models.py:69 contrib/auth/models.py:109
msgid "groups"
msgstr "Группы"
-#: contrib/auth/models.py:55
+#: contrib/auth/models.py:99
msgid "username"
msgstr "Имя пользователя"
-#: contrib/auth/models.py:56
+#: contrib/auth/models.py:99
+msgid ""
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
+msgstr ""
+"Необходимое поле. 30 символов или менее. Используйте только цифры, буквы "
+"и нижнее подчеркивание."
+
+#: contrib/auth/models.py:100
msgid "first name"
msgstr "Имя"
-#: contrib/auth/models.py:57
+#: contrib/auth/models.py:101
msgid "last name"
msgstr "Фамилия"
-#: contrib/auth/models.py:58
+#: contrib/auth/models.py:102
msgid "e-mail address"
msgstr "Адрес электронной почты"
-#: contrib/auth/models.py:59
+#: contrib/auth/models.py:103
msgid "password"
msgstr "Пароль"
-#: contrib/auth/models.py:59
-msgid "Use '[algo]$[salt]$[hexdigest]'"
-msgstr "Используйте '[algo]$[salt]$[hexdigest]'"
+#: contrib/auth/models.py:103
+msgid ""
+"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
+"password form</a>."
+msgstr ""
+"Используйте '[algo]$[salt]$[hexdigest]' или <a href=\"password/\">change "
+"форма смены пароля</a>."
-#: contrib/auth/models.py:60
+#: contrib/auth/models.py:104
msgid "staff status"
msgstr "Статус персонала"
-#: contrib/auth/models.py:60
+#: contrib/auth/models.py:104
msgid "Designates whether the user can log into this admin site."
msgstr "Отметьте, если пользователь может входить в админ. часть сайта."
-#: contrib/auth/models.py:61
+#: contrib/auth/models.py:105
msgid "active"
msgstr "Активный"
-#: contrib/auth/models.py:62
+#: contrib/auth/models.py:105
+msgid ""
+"Designates whether this user can log into the Django admin. Unselect this "
+"instead of deleting accounts."
+msgstr ""
+"Отметьте, если пользователь может входить в админ. часть сайта. Убирайте эту "
+"отметку вместо удаления аккаунта."
+
+#: contrib/auth/models.py:106
msgid "superuser status"
msgstr "Статус суперпользователя"
-#: contrib/auth/models.py:63
+#: contrib/auth/models.py:106
+msgid ""
+"Designates that this user has all permissions without explicitly assigning "
+"them."
+msgstr "Указывает, что пользователь имеет все права без явного их назначения"
+
+#: contrib/auth/models.py:107
msgid "last login"
msgstr "Последний вход"
-#: contrib/auth/models.py:64
+#: contrib/auth/models.py:108
msgid "date joined"
msgstr "Дата регистрации"
-#: contrib/auth/models.py:66
-msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
-msgstr "В добавление к правам, присвоенным вручную, этот пользователь получит все права групп, к которым он принадлежит."
+#: contrib/auth/models.py:110
+msgid ""
+"In addition to the permissions manually assigned, this user will also get "
+"all permissions granted to each group he/she is in."
+msgstr ""
+"В добавление к правам, присвоенным вручную, этот пользователь получит все "
+"права групп, к которым он принадлежит."
-#: contrib/auth/models.py:67
+#: contrib/auth/models.py:111
msgid "user permissions"
msgstr "права пользователя"
-#: contrib/auth/models.py:70
+#: contrib/auth/models.py:115
msgid "user"
msgstr "Пользователь"
-#: contrib/auth/models.py:71
+#: contrib/auth/models.py:116
msgid "users"
msgstr "Пользователи"
-#: contrib/auth/models.py:76
+#: contrib/auth/models.py:122
msgid "Personal info"
msgstr "Персональная информация"
-#: contrib/auth/models.py:77
+#: contrib/auth/models.py:123
msgid "Permissions"
msgstr "Права"
-#: contrib/auth/models.py:78
+#: contrib/auth/models.py:124
msgid "Important dates"
msgstr "Важные даты"
-#: contrib/auth/models.py:79
+#: contrib/auth/models.py:125
msgid "Groups"
msgstr "Группы"
-#: contrib/auth/models.py:219
+#: contrib/auth/models.py:269
msgid "message"
msgstr "Сообщение"
-#: contrib/auth/forms.py:30
-msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
+#: contrib/auth/models.py:282
+msgid "AnonymousUser"
+msgstr "Анонимный пользователь"
+
+#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+msgid "The two password fields didn't match."
+msgstr "Два поля с паролями не соответствуют"
+
+#: contrib/auth/forms.py:25
+msgid "A user with that username already exists."
+msgstr "Пользователь с этим именем уже существует."
+
+#: contrib/auth/forms.py:53
+msgid ""
+"Your Web browser doesn't appear to have cookies enabled. Cookies are "
+"required for logging in."
msgstr "У вашего браузера не включены cookies. Cookies необходимы для входа."
-#: contrib/contenttypes/models.py:25
-msgid "python model class name"
-msgstr "имя класса python модуля"
+#: contrib/auth/forms.py:62
+msgid "This account is inactive."
+msgstr "Это учетная запись не активна"
-#: contrib/contenttypes/models.py:28
-msgid "content type"
-msgstr "Тип содержимого"
+#: contrib/auth/forms.py:85
+msgid ""
+"That e-mail address doesn't have an associated user account. Are you sure "
+"you've registered?"
+msgstr ""
+"Этот адрес электронной почты не связан ни с одной учетной записью. Вы уверены "
+"что вы зарегистрированы?"
-#: contrib/contenttypes/models.py:29
-msgid "content types"
-msgstr "Типы содержимого"
+#: contrib/auth/forms.py:117
+msgid "The two 'new password' fields didn't match."
+msgstr "Два поля 'Новый пароль' не одинаковы."
+
+#: contrib/auth/forms.py:124
+msgid "Your old password was entered incorrectly. Please enter it again."
+msgstr "Ваш старый пароль введен неправильно. пожалуйста введите правильно."
+
+#: contrib/localflavor/uk/forms.py:18
+msgid "Enter a postcode. A space is required between the two postcode parts."
+msgstr "Укажите почтовый код. Необходим пробел между двумя частями почтового кода"
+
+#: contrib/localflavor/br/forms.py:18
+msgid "Enter a zip code in the format XXXXX-XXX."
+msgstr "Введите Zip код в формате XXXXX-XXX."
+
+#: contrib/localflavor/br/forms.py:30
+msgid "Phone numbers must be in XX-XXXX-XXXX format."
+msgstr "Телефонные номера должен быть в формате XX-XXXX-XXXX. "
+
+#: contrib/localflavor/br/forms.py:72
+msgid "This field requires only numbers."
+msgstr "Это поле требует только числа."
+
+#: contrib/localflavor/br/forms.py:74
+msgid "This field requires at most 11 digits or 14 characters."
+msgstr "Это поле требует 11 цифр или 14 символов."
+
+#: contrib/localflavor/br/forms.py:84
+msgid "Invalid CPF number."
+msgstr "неправильный CPF номер"
+
+#: contrib/localflavor/br/forms.py:106
+msgid "This field requires at least 14 digits"
+msgstr "Это поле требует не меньше 14 цифр."
+
+#: contrib/localflavor/br/forms.py:116
+msgid "Invalid CNPJ number."
+msgstr "Неправильный CNPJ номер."
+
+#: contrib/localflavor/fr/forms.py:17 contrib/localflavor/de/forms.py:16
+#: contrib/localflavor/fi/forms.py:14
+msgid "Enter a zip code in the format XXXXX."
+msgstr "Укажите zip код в формате XXXXX."
+
+#: contrib/localflavor/jp/forms.py:21
+msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
+msgstr "Укажите почтовый код в формате XXXXXXX или XXX-XXXX."
+
+#: contrib/localflavor/jp/jp_prefectures.py:4
+msgid "Hokkaido"
+msgstr "Хоккаидо"
+
+#: contrib/localflavor/jp/jp_prefectures.py:5
+msgid "Aomori"
+msgstr "Аомори"
+
+#: contrib/localflavor/jp/jp_prefectures.py:6
+msgid "Iwate"
+msgstr "Иватэ"
+
+#: contrib/localflavor/jp/jp_prefectures.py:7
+msgid "Miyagi"
+msgstr "Мияги"
+
+#: contrib/localflavor/jp/jp_prefectures.py:8
+msgid "Akita"
+msgstr "Акита"
+
+#: contrib/localflavor/jp/jp_prefectures.py:9
+msgid "Yamagata"
+msgstr "Ямагата"
+
+#: contrib/localflavor/jp/jp_prefectures.py:10
+msgid "Fukushima"
+msgstr "Фукушима"
+
+#: contrib/localflavor/jp/jp_prefectures.py:11
+msgid "Ibaraki"
+msgstr "Ибакари"
+
+#: contrib/localflavor/jp/jp_prefectures.py:12
+msgid "Tochigi"
+msgstr "Точиги"
+
+#: contrib/localflavor/jp/jp_prefectures.py:13
+msgid "Gunma"
+msgstr "Гунма"
+
+#: contrib/localflavor/jp/jp_prefectures.py:14
+msgid "Saitama"
+msgstr "Сайтама"
+
+#: contrib/localflavor/jp/jp_prefectures.py:15
+msgid "Chiba"
+msgstr "Чиба"
+
+#: contrib/localflavor/jp/jp_prefectures.py:16
+msgid "Tokyo"
+msgstr "Токио"
+
+#: contrib/localflavor/jp/jp_prefectures.py:17
+msgid "Kanagawa"
+msgstr "Канагава"
+
+#: contrib/localflavor/jp/jp_prefectures.py:18
+msgid "Yamanashi"
+msgstr "Яманаши"
+
+#: contrib/localflavor/jp/jp_prefectures.py:19
+msgid "Nagano"
+msgstr "Нагано"
+
+#: contrib/localflavor/jp/jp_prefectures.py:20
+msgid "Niigata"
+msgstr "Ниигата"
+
+#: contrib/localflavor/jp/jp_prefectures.py:21
+msgid "Toyama"
+msgstr "Тояма"
+
+#: contrib/localflavor/jp/jp_prefectures.py:22
+msgid "Ishikawa"
+msgstr "Ишикава"
-#: contrib/sessions/models.py:35
+#: contrib/localflavor/jp/jp_prefectures.py:23
+msgid "Fukui"
+msgstr "Фукуй"
+
+#: contrib/localflavor/jp/jp_prefectures.py:24
+msgid "Gifu"
+msgstr "Гифу"
+
+#: contrib/localflavor/jp/jp_prefectures.py:25
+msgid "Shizuoka"
+msgstr "Шизуока"
+
+#: contrib/localflavor/jp/jp_prefectures.py:26
+msgid "Aichi"
+msgstr "Айчи"
+
+#: contrib/localflavor/jp/jp_prefectures.py:27
+msgid "Mie"
+msgstr "Ми"
+
+#: contrib/localflavor/jp/jp_prefectures.py:28
+msgid "Shiga"
+msgstr "Шига"
+
+#: contrib/localflavor/jp/jp_prefectures.py:29
+msgid "Kyoto"
+msgstr "Киото"
+
+#: contrib/localflavor/jp/jp_prefectures.py:30
+msgid "Osaka"
+msgstr "Осака"
+
+#: contrib/localflavor/jp/jp_prefectures.py:31
+msgid "Hyogo"
+msgstr "Хиого"
+
+#: contrib/localflavor/jp/jp_prefectures.py:32
+msgid "Nara"
+msgstr "Нара"
+
+#: contrib/localflavor/jp/jp_prefectures.py:33
+msgid "Wakayama"
+msgstr "Вакаяма"
+
+#: contrib/localflavor/jp/jp_prefectures.py:34
+msgid "Tottori"
+msgstr "Тоттори"
+
+#: contrib/localflavor/jp/jp_prefectures.py:35
+msgid "Shimane"
+msgstr "Шимане"
+
+#: contrib/localflavor/jp/jp_prefectures.py:36
+msgid "Okayama"
+msgstr "Окаяма"
+
+#: contrib/localflavor/jp/jp_prefectures.py:37
+msgid "Hiroshima"
+msgstr "Хиросима"
+
+#: contrib/localflavor/jp/jp_prefectures.py:38
+msgid "Yamaguchi"
+msgstr "Ямагучи"
+
+#: contrib/localflavor/jp/jp_prefectures.py:39
+msgid "Tokushima"
+msgstr "Токушима"
+
+#: contrib/localflavor/jp/jp_prefectures.py:40
+msgid "Kagawa"
+msgstr "Кагава"
+
+#: contrib/localflavor/jp/jp_prefectures.py:41
+msgid "Ehime"
+msgstr "Ехиме"
+
+#: contrib/localflavor/jp/jp_prefectures.py:42
+msgid "Kochi"
+msgstr "Кочи"
+
+#: contrib/localflavor/jp/jp_prefectures.py:43
+msgid "Fukuoka"
+msgstr "Фукуока"
+
+#: contrib/localflavor/jp/jp_prefectures.py:44
+msgid "Saga"
+msgstr "Сага"
+
+#: contrib/localflavor/jp/jp_prefectures.py:45
+msgid "Nagasaki"
+msgstr "Нагасаки"
+
+#: contrib/localflavor/jp/jp_prefectures.py:46
+msgid "Kumamoto"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:47
+msgid "Oita"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:48
+msgid "Miyazaki"
+msgstr "Миязаки"
+
+#: contrib/localflavor/jp/jp_prefectures.py:49
+msgid "Кагосима"
+msgstr ""
+
+#: contrib/localflavor/jp/jp_prefectures.py:50
+msgid "Okinawa"
+msgstr "Окинава"
+
+#: contrib/localflavor/au/forms.py:18
+msgid "Enter a 4 digit post code."
+msgstr "Укажите 4 цифровой почтовый код."
+
+#: contrib/localflavor/us/forms.py:18
+msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
+msgstr ""
+
+#: contrib/localflavor/us/forms.py:51
+msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:5
+msgid "Baden-Wuerttemberg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:6
+msgid "Bavaria"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:7
+#, fuzzy
+msgid "Berlin"
+msgstr "Бразильский"
+
+#: contrib/localflavor/de/de_states.py:8
+msgid "Brandenburg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:9
+msgid "Bremen"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:10
+#, fuzzy
+msgid "Hamburg"
+msgstr "авг"
+
+#: contrib/localflavor/de/de_states.py:11
+#, fuzzy
+msgid "Hessen"
+msgstr "Сообщение"
+
+#: contrib/localflavor/de/de_states.py:12
+msgid "Mecklenburg-Western Pomerania"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:13
+msgid "Lower Saxony"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:14
+msgid "North Rhine-Westphalia"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:15
+msgid "Rhineland-Palatinate"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:16
+msgid "Saarland"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:17
+msgid "Saxony"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:18
+msgid "Saxony-Anhalt"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:19
+msgid "Schleswig-Holstein"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:20
+msgid "Thuringia"
+msgstr ""
+
+#: contrib/localflavor/de/forms.py:60
+msgid ""
+"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
+msgstr ""
+
+#: contrib/localflavor/it/forms.py:16
+msgid "Enter a valid zip code."
+msgstr "Укажите правильный zip код"
+
+#: contrib/localflavor/it/forms.py:41
+#, fuzzy
+msgid "Enter a valid Social Security number."
+msgstr "Укажите правильное имя файла."
+
+#: contrib/localflavor/it/forms.py:68
+#, fuzzy
+msgid "Enter a valid VAT number."
+msgstr "Укажите правильное имя файла."
+
+#: contrib/localflavor/no/forms.py:15 contrib/localflavor/ch/forms.py:18
+#, fuzzy
+msgid "Enter a zip code in the format XXXX."
+msgstr "Введите правильное время в формате HH:MM."
+
+#: contrib/localflavor/no/forms.py:36
+#, fuzzy
+msgid "Enter a valid Norwegian social security number."
+msgstr "Пожалуйста, введите корректное десятичное число."
+
+#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
+#, fuzzy
+msgid "Enter a valid Finnish social security number."
+msgstr "Укажите правильное имя файла."
+
+#: contrib/localflavor/is_/forms.py:16
+msgid ""
+"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
+msgstr "Укажите правильный исландский идентификатор. Формат XXXXXX-XXXX"
+
+#: contrib/localflavor/is_/forms.py:30
+msgid "The Icelandic identification number is not valid."
+msgstr "Исландский идентификационный номер не правилен"
+
+#: contrib/localflavor/cl/forms.py:21
+msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
+msgstr ""
+
+#: contrib/localflavor/cl/forms.py:26
+#, fuzzy
+msgid "Enter valid a Chilean RUT"
+msgstr "Укажите правильное имя файла."
+
+#: contrib/localflavor/ch/ch_states.py:5
+msgid "Aargau"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:6
+msgid "Appenzell Innerrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:7
+msgid "Appenzell Ausserrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:8
+msgid "Basel-Stadt"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:9
+msgid "Basel-Land"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:10
+#, fuzzy
+msgid "Berne"
+msgstr "Имя пользователя"
+
+#: contrib/localflavor/ch/ch_states.py:11
+msgid "Fribourg"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:12
+msgid "Geneva"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:13
+#, fuzzy
+msgid "Glarus"
+msgstr "Группы"
+
+#: contrib/localflavor/ch/ch_states.py:14
+msgid "Graubuenden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:15
+msgid "Jura"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:16
+#, fuzzy
+msgid "Lucerne"
+msgstr "Имя пользователя"
+
+#: contrib/localflavor/ch/ch_states.py:17
+msgid "Neuchatel"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:18
+msgid "Nidwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:19
+msgid "Obwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:20
+msgid "Schaffhausen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:21
+msgid "Schwyz"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:22
+msgid "Solothurn"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:23
+msgid "St. Gallen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:24
+#, fuzzy
+msgid "Thurgau"
+msgstr "Четверг"
+
+#: contrib/localflavor/ch/ch_states.py:25
+msgid "Ticino"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:26
+msgid "Uri"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:27
+msgid "Valais"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:28
+msgid "Vaud"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:29
+#, fuzzy
+msgid "Zug"
+msgstr "авг"
+
+#: contrib/localflavor/ch/ch_states.py:30
+msgid "Zurich"
+msgstr ""
+
+#: contrib/localflavor/ch/forms.py:90
+msgid ""
+"Enter a valid Swiss identity or passport card number in X1234567<0 or "
+"1234567890 format."
+msgstr ""
+
+#: contrib/sessions/models.py:68
msgid "session key"
msgstr "Ключ сессии"
-#: contrib/sessions/models.py:36
+#: contrib/sessions/models.py:69
msgid "session data"
msgstr "Данные сессии"
-#: contrib/sessions/models.py:37
+#: contrib/sessions/models.py:70
msgid "expire date"
msgstr "Дата окончания"
-#: contrib/sessions/models.py:41
+#: contrib/sessions/models.py:74
msgid "session"
msgstr "Сессия"
-#: contrib/sessions/models.py:42
+#: contrib/sessions/models.py:75
msgid "sessions"
msgstr "Сессии"
-#: contrib/sites/models.py:10
-msgid "domain name"
-msgstr "Доменное имя"
+#: contrib/flatpages/models.py:8
+msgid ""
+"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
+msgstr ""
+"Пример: '/about/contact/'. Убедитесь что вставили завершающий слэш."
-#: contrib/sites/models.py:11
-msgid "display name"
-msgstr "Выводимое имя"
+#: contrib/flatpages/models.py:9
+msgid "title"
+msgstr "Заголовок"
-#: contrib/sites/models.py:15
-msgid "site"
-msgstr "Сайт"
+#: contrib/flatpages/models.py:10
+msgid "content"
+msgstr "Содержимое"
-#: contrib/sites/models.py:16
-msgid "sites"
-msgstr "Сайты"
+#: contrib/flatpages/models.py:11
+msgid "enable comments"
+msgstr "Активировать комментарии"
-#: utils/translation.py:360
-msgid "DATE_FORMAT"
-msgstr "d.m.Y"
+#: contrib/flatpages/models.py:12
+msgid "template name"
+msgstr "Имя шаблона"
-#: utils/translation.py:361
-msgid "DATETIME_FORMAT"
-msgstr "d.m.Y H:i"
+#: contrib/flatpages/models.py:13
+msgid ""
+"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
+"will use 'flatpages/default.html'."
+msgstr ""
+"Пример: 'flatpages/contact_page'. Если этот файл не присутствует, система "
+"будет использовать 'flatpages/default.html'."
-#: utils/translation.py:362
-msgid "TIME_FORMAT"
-msgstr "H:i"
+#: contrib/flatpages/models.py:14
+msgid "registration required"
+msgstr "Регистрация обязательна"
+
+#: contrib/flatpages/models.py:14
+msgid "If this is checked, only logged-in users will be able to view the page."
+msgstr "Если отмечено, только вошедшие пользователи смогут видеть страницу."
+
+#: contrib/flatpages/models.py:18
+msgid "flat page"
+msgstr "Простая страница"
+
+#: contrib/flatpages/models.py:19
+msgid "flat pages"
+msgstr "Простые страницы"
#: utils/dates.py:6
msgid "Monday"
@@ -1303,28 +2774,23 @@ msgstr "Январь"
msgid "February"
msgstr "Февраль"
-#: utils/dates.py:14
-#: utils/dates.py:27
+#: utils/dates.py:14 utils/dates.py:27
msgid "March"
msgstr "Март"
-#: utils/dates.py:14
-#: utils/dates.py:27
+#: utils/dates.py:14 utils/dates.py:27
msgid "April"
msgstr "Апрель"
-#: utils/dates.py:14
-#: utils/dates.py:27
+#: utils/dates.py:14 utils/dates.py:27
msgid "May"
msgstr "Май"
-#: utils/dates.py:14
-#: utils/dates.py:27
+#: utils/dates.py:14 utils/dates.py:27
msgid "June"
msgstr "Июнь"
-#: utils/dates.py:15
-#: utils/dates.py:27
+#: utils/dates.py:15 utils/dates.py:27
msgid "July"
msgstr "Июль"
@@ -1466,441 +2932,94 @@ msgstr[0] "минута"
msgstr[1] "минуты"
msgstr[2] "минут"
-#: conf/global_settings.py:37
-msgid "Bengali"
-msgstr "Бенгальский"
-
-#: conf/global_settings.py:38
-msgid "Czech"
-msgstr "Чешский"
-
-#: conf/global_settings.py:39
-msgid "Welsh"
-msgstr "Уэльский"
-
-#: conf/global_settings.py:40
-msgid "Danish"
-msgstr "Датский"
-
-#: conf/global_settings.py:41
-msgid "German"
-msgstr "Немецкий"
-
-#: conf/global_settings.py:42
-msgid "Greek"
-msgstr "Греческий"
-
-#: conf/global_settings.py:43
-msgid "English"
-msgstr "Английский"
-
-#: conf/global_settings.py:44
-msgid "Spanish"
-msgstr "Испанский"
-
-#: conf/global_settings.py:45
-msgid "French"
-msgstr "Французский"
-
-#: conf/global_settings.py:46
-msgid "Galician"
-msgstr "Галльский"
-
-#: conf/global_settings.py:47
-msgid "Hungarian"
-msgstr "Венгерский"
-
-#: conf/global_settings.py:48
-msgid "Hebrew"
-msgstr "Иврит"
-
-#: conf/global_settings.py:49
-msgid "Icelandic"
-msgstr "Исландский"
-
-#: conf/global_settings.py:50
-msgid "Italian"
-msgstr "Итальянский"
-
-#: conf/global_settings.py:51
-msgid "Japanese"
-msgstr "Японский"
-
-#: conf/global_settings.py:52
-msgid "Dutch"
-msgstr "Голландский"
-
-#: conf/global_settings.py:53
-msgid "Norwegian"
-msgstr "Норвежский"
-
-#: conf/global_settings.py:54
-msgid "Brazilian"
-msgstr "Бразильский"
-
-#: conf/global_settings.py:55
-msgid "Romanian"
-msgstr "Румынский"
-
-#: conf/global_settings.py:56
-msgid "Russian"
-msgstr "Русский"
-
-#: conf/global_settings.py:57
-msgid "Slovak"
-msgstr "Словацкий"
-
-#: conf/global_settings.py:58
-msgid "Slovenian"
-msgstr "Словенский"
-
-#: conf/global_settings.py:59
-msgid "Serbian"
-msgstr "Сербский"
-
-#: conf/global_settings.py:60
-msgid "Swedish"
-msgstr "Шведский"
-
-#: conf/global_settings.py:61
-msgid "Ukrainian"
-msgstr "Украинский"
-
-#: conf/global_settings.py:62
-msgid "Simplified Chinese"
-msgstr "Упрощенный китайский"
-
-#: conf/global_settings.py:63
-msgid "Traditional Chinese"
-msgstr "Традиционный китайский"
-
-#: core/validators.py:60
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Значение должно состоять только из букв, цифр и знаков подчеркивания."
-
-#: core/validators.py:64
-msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
-msgstr "Значение должно состоять только из букв, цифр, знаков подчеркивания, тире или наклонной черты вправо."
-
-#: core/validators.py:72
-msgid "Uppercase letters are not allowed here."
-msgstr "Заглавные буквы недопустимы."
-
-#: core/validators.py:76
-msgid "Lowercase letters are not allowed here."
-msgstr "Строчные буквы здесь недопустимы."
-
-#: core/validators.py:83
-msgid "Enter only digits separated by commas."
-msgstr "Введите цифры, разделённые запятыми."
-
-#: core/validators.py:95
-msgid "Enter valid e-mail addresses separated by commas."
-msgstr "Введите правильные адреса электронной почты, разделённые запятыми."
-
-#: core/validators.py:99
-msgid "Please enter a valid IP address."
-msgstr "Пожалуйста, введите правильный IP-адрес."
-
-#: core/validators.py:103
-msgid "Empty values are not allowed here."
-msgstr "Пустое значение здесь недопустимо."
-
-#: core/validators.py:107
-msgid "Non-numeric characters aren't allowed here."
-msgstr "Нецифровые символы здесь недопустимы."
-
-#: core/validators.py:111
-msgid "This value can't be comprised solely of digits."
-msgstr "Это значение не может быть составлено только из цифр."
-
-#: core/validators.py:116
-msgid "Enter a whole number."
-msgstr "Введите целое число."
-
-#: core/validators.py:120
-msgid "Only alphabetical characters are allowed here."
-msgstr "Здесь разрешены только алфавитные символы."
-
-#: core/validators.py:124
-msgid "Enter a valid date in YYYY-MM-DD format."
-msgstr "Вводите правильную дату в формате YYYY-MM-DD."
-
-#: core/validators.py:128
-msgid "Enter a valid time in HH:MM format."
-msgstr "Введите правильное время в формате HH:MM."
-
-#: core/validators.py:132
-#: db/models/fields/__init__.py:468
-msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
-msgstr "Введите правильные дату/время в формате YYYY-MM-DD HH:MM."
-
-#: core/validators.py:136
-msgid "Enter a valid e-mail address."
-msgstr "Укажите правильный адрес электронной почты."
-
-#: core/validators.py:148
-msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
-msgstr "Загрузите реальное изображение. Файл, который вы загрузили, не является изображением или был поврежден."
-
-#: core/validators.py:155
+#: utils/timesince.py:40
#, python-format
-msgid "The URL %s does not point to a valid image."
-msgstr "URL %s не указывает на реальное изображение."
-
-#: core/validators.py:159
-#, python-format
-msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
-msgstr "Телефонные номера должен быть в формате XXX-XXX-XXXX. \"%s\" неверен."
+msgid "%d milliseconds"
+msgstr "%d милисекунд"
-#: core/validators.py:167
+#: utils/timesince.py:41
#, python-format
-msgid "The URL %s does not point to a valid QuickTime video."
-msgstr "URL %s не указывает на реальное видео QuickTime."
-
-#: core/validators.py:171
-msgid "A valid URL is required."
-msgstr "Правильный URL обязателен."
-
-#: core/validators.py:185
-#, python-format
-msgid ""
-"Valid HTML is required. Specific errors are:\n"
-"%s"
+msgid "%(number)d %(type)s"
msgstr ""
-"Правильный HTML обязателен. Специфичные ошибки:\n"
-"%s"
-
-#: core/validators.py:192
-#, python-format
-msgid "Badly formed XML: %s"
-msgstr "Неверный формат XML: %s"
-
-#: core/validators.py:202
-#, python-format
-msgid "Invalid URL: %s"
-msgstr "Неверный URL: %s"
-
-#: core/validators.py:206
-#: core/validators.py:208
-#, python-format
-msgid "The URL %s is a broken link."
-msgstr "URL %s - сломанная ссылка."
-
-#: core/validators.py:214
-msgid "Enter a valid U.S. state abbreviation."
-msgstr "Введите правильную аббревиатуру штата США."
-#: core/validators.py:229
+#: utils/timesince.py:47
#, python-format
-msgid "Watch your mouth! The word %s is not allowed here."
-msgid_plural "Watch your mouth! The words %s are not allowed here."
-msgstr[0] "Следите за своими словами! Слово %s здесь запрещено."
-msgstr[1] "Следите за своими словами! Слова %s здесь запрещены."
-msgstr[2] "Следите за своими словами! Слова %s здесь запрещены."
-
-#: core/validators.py:236
-#, python-format
-msgid "This field must match the '%s' field."
-msgstr "Это поле должно совпадать с полем '%s'."
-
-#: core/validators.py:255
-msgid "Please enter something for at least one field."
-msgstr "Пожалуйста, заполните хотя бы одно поле."
-
-#: core/validators.py:264
-#: core/validators.py:275
-msgid "Please enter both fields or leave them both empty."
-msgstr "Пожалуйста, заполните оба поля или оставьте их оба пустыми."
-
-#: core/validators.py:282
-#, python-format
-msgid "This field must be given if %(field)s is %(value)s"
-msgstr "Это поле должно быть заполнено, если %(field)s равно %(value)s"
-
-#: core/validators.py:294
-#, python-format
-msgid "This field must be given if %(field)s is not %(value)s"
-msgstr "Это поле должно быть заполнено, если %(field)s не равно %(value)s"
-
-#: core/validators.py:313
-msgid "Duplicate values are not allowed."
-msgstr "Двойные значения запрещены."
-
-#: core/validators.py:336
-#, python-format
-msgid "This value must be a power of %s."
-msgstr "Это значение должно быть степенью %s."
-
-#: core/validators.py:347
-msgid "Please enter a valid decimal number."
-msgstr "Пожалуйста, введите корректное десятичное число."
-
-#: core/validators.py:349
-#, python-format
-msgid "Please enter a valid decimal number with at most %s total digit."
-msgid_plural "Please enter a valid decimal number with at most %s total digits."
-msgstr[0] "Пожалуйста, введите корректное десятичное число максимально с %s знаком."
-msgstr[1] "Пожалуйста, введите корректное десятичное число максимально с %s знаками."
-msgstr[2] "Пожалуйста, введите корректное десятичное число максимально с %s знаками."
-
-#: core/validators.py:352
-#, python-format
-msgid "Please enter a valid decimal number with at most %s decimal place."
-msgid_plural "Please enter a valid decimal number with at most %s decimal places."
-msgstr[0] "Пожалуйста, введите корректное десятичное число максимально с %s знаком после запятой."
-msgstr[1] "Пожалуйста, введите корректное десятичное число максимально с %s знаками после запятой."
-msgstr[2] "Пожалуйста, введите корректное десятичное число максимально с %s знаками после запятой."
-
-#: core/validators.py:362
-#, python-format
-msgid "Make sure your uploaded file is at least %s bytes big."
-msgstr "Убедитесь, что загруженный файл не меньше %s байт."
-
-#: core/validators.py:363
-#, python-format
-msgid "Make sure your uploaded file is at most %s bytes big."
-msgstr "Убедитесь, что загруженный файл не больше %s байт."
-
-#: core/validators.py:376
-msgid "The format for this field is wrong."
-msgstr "Формат этого поля неверен."
-
-#: core/validators.py:391
-msgid "This field is invalid."
-msgstr "Это поле неверно."
-
-#: core/validators.py:426
-#, python-format
-msgid "Could not retrieve anything from %s."
-msgstr "Невозможно получить ничего с %s."
-
-#: core/validators.py:429
-#, python-format
-msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
-msgstr "URL %(url)s вернул неверный заголовок Content-Type '%(contenttype)s'."
-
-#: core/validators.py:462
-#, python-format
-msgid "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with \"%(start)s\".)"
-msgstr "Пожалуйста, закройте незакрытый тэг %(tag)s на строке %(line)s. (Строка начинается с \"%(start)s\".)"
+msgid ", %(number)d %(type)s"
+msgstr ""
-#: core/validators.py:466
-#, python-format
-msgid "Some text starting on line %(line)s is not allowed in that context. (Line starts with \"%(start)s\".)"
-msgstr "Что-то из текста, начинающегося на строке %(line)s, недопустимо в том контексте. (Строка начинается с \"%(start)s\".)"
+#: utils/dateformat.py:40
+msgid "p.m."
+msgstr ""
-#: core/validators.py:471
-#, python-format
-msgid "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%(start)s\".)"
-msgstr "\"%(attr)s\" на строке %(line)s - неправильный атрибут. (Строка начинается с \"%(start)s\".)"
+#: utils/dateformat.py:41
+msgid "a.m."
+msgstr ""
-#: core/validators.py:476
-#, python-format
-msgid "\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%(start)s\".)"
-msgstr "\"<%(tag)s>\" на строке %(line)s - неправильный тег. (Строка начинается с \"%(start)s\".)"
+#: utils/dateformat.py:46
+msgid "PM"
+msgstr ""
-#: core/validators.py:480
-#, python-format
-msgid "A tag on line %(line)s is missing one or more required attributes. (Line starts with \"%(start)s\".)"
-msgstr "В теге на строке %(line)s не хватает одного или более обязательных атрибутов. (Строка начинается с \"%(start)s\".)"
+#: utils/dateformat.py:47
+msgid "AM"
+msgstr ""
-#: core/validators.py:485
-#, python-format
-msgid "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line starts with \"%(start)s\".)"
-msgstr "Атрибут \"%(attr)s\" на строке %(line)s имеет недопустимое значение. (Строка начинается с \"%(start)s\".)"
+#: utils/dateformat.py:95
+msgid "midnight"
+msgstr "полночь"
-#: db/models/manipulators.py:302
-#, python-format
-msgid "%(object)s with this %(type)s already exists for the given %(field)s."
-msgstr "%(object)s с типом %(type)s уже существует для данного %(field)s."
+#: utils/dateformat.py:97
+msgid "noon"
+msgstr "полдень"
-#: db/models/fields/__init__.py:40
-#, python-format
-msgid "%(optname)s with this %(fieldname)s already exists."
-msgstr "%(optname)s с %(fieldname)s уже существует."
+#: utils/translation/trans_real.py:358
+msgid "DATE_FORMAT"
+msgstr "d.m.Y"
-#: db/models/fields/__init__.py:114
-#: db/models/fields/__init__.py:265
-#: db/models/fields/__init__.py:542
-#: db/models/fields/__init__.py:553
-#: forms/__init__.py:346
-msgid "This field is required."
-msgstr "Обязательное поле."
+#: utils/translation/trans_real.py:359
+msgid "DATETIME_FORMAT"
+msgstr "d.m.Y H:i"
-#: db/models/fields/__init__.py:337
-msgid "This value must be an integer."
-msgstr "Это значение должно быть целым числом."
+#: utils/translation/trans_real.py:360
+msgid "TIME_FORMAT"
+msgstr "H:i"
-#: db/models/fields/__init__.py:369
-msgid "This value must be either True or False."
-msgstr "Значение должно либо True, либо False."
+#: utils/translation/trans_real.py:376
+msgid "YEAR_MONTH_FORMAT"
+msgstr "d.m.Y"
-#: db/models/fields/__init__.py:385
-msgid "This field cannot be null."
-msgstr "Это поле не может быть нулевым."
+#: utils/translation/trans_real.py:377
+msgid "MONTH_DAY_FORMAT"
+msgstr "d.m.Y"
-#: db/models/fields/__init__.py:562
-msgid "Enter a valid filename."
-msgstr "Укажите правильное имя файла."
+#: template/defaultfilters.py:491
+msgid "yes,no,maybe"
+msgstr "да,нет,может быть"
-#: db/models/fields/related.py:43
+#: template/defaultfilters.py:520
#, python-format
-msgid "Please enter a valid %s."
-msgstr "Пожалуйста, введите правильный %s."
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] "%(size)d байт"
+msgstr[1] "%(size)d байта"
+msgstr[2] "%(size)d байт"
-#: db/models/fields/related.py:579
-msgid "Separate multiple IDs with commas."
-msgstr "Несколько значений ID разделите запятыми."
-
-#: db/models/fields/related.py:581
-msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr "Удерживайте \"Control\" (или \"Command\" на Mac) для выбора нескольких."
-
-#: db/models/fields/related.py:625
+#: template/defaultfilters.py:522
#, python-format
-msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
-msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
-msgstr[0] "Пожалуйста, введите корректный ID для %(self)s. Значение %(value)r недопустимо."
-msgstr[1] "Пожалуйста, введите корректные ID для %(self)s. Значения %(value)r недопустимы."
-msgstr[2] "Пожалуйста, введите корректные ID для %(self)s. Значения %(value)r недопустимы."
+msgid "%.1f KB"
+msgstr "%.1f Кб"
-#: forms/__init__.py:380
+#: template/defaultfilters.py:524
#, python-format
-msgid "Ensure your text is less than %s character."
-msgid_plural "Ensure your text is less than %s characters."
-msgstr[0] "Убедитесь, что длина вашего текста меньше %s символа."
-msgstr[1] "Убедитесь, что длина вашего текста меньше %s символов."
-msgstr[2] "Убедитесь, что длина вашего текста меньше %s символов."
-
-#: forms/__init__.py:385
-msgid "Line breaks are not allowed here."
-msgstr "Переносы строк здесь не допускаются."
+msgid "%.1f MB"
+msgstr "%.1f Мб"
-#: forms/__init__.py:480
-#: forms/__init__.py:551
-#: forms/__init__.py:589
+#: template/defaultfilters.py:525
#, python-format
-msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
-msgstr "Выберите корректный вариант; '%(data)s' нет в %(choices)s."
-
-#: forms/__init__.py:645
-msgid "The submitted file is empty."
-msgstr "Указанный файл пуст."
+msgid "%.1f GB"
+msgstr "%.1f Гб"
-#: forms/__init__.py:699
-msgid "Enter a whole number between -32,768 and 32,767."
-msgstr "Введите целое число в диапазоне от -32768 до 32767."
-
-#: forms/__init__.py:708
-msgid "Enter a positive number."
-msgstr "Введите положительное число."
-
-#: forms/__init__.py:717
-msgid "Enter a whole number between 0 and 32,767."
-msgstr "Введите целое число в диапазоне от 0 до 32767."
-
-#: template/defaultfilters.py:379
-msgid "yes,no,maybe"
-msgstr "да,нет,может быть"
+#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
+#~ msgstr "Вы <a href=\"/password_reset/\">забыли пароль</a>?"
+#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
+#~ msgstr "Используйте '[algo]$[salt]$[hexdigest]'"
diff --git a/django/conf/locale/te/LC_MESSAGES/django.mo b/django/conf/locale/te/LC_MESSAGES/django.mo
index 318ce76779..8823b2015c 100644
--- a/django/conf/locale/te/LC_MESSAGES/django.mo
+++ b/django/conf/locale/te/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/te/LC_MESSAGES/django.po b/django/conf/locale/te/LC_MESSAGES/django.po
index b2e450c0a7..248baf2249 100644
--- a/django/conf/locale/te/LC_MESSAGES/django.po
+++ b/django/conf/locale/te/LC_MESSAGES/django.po
@@ -2,19 +2,19 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
-# pavithran <pavithran.s@gmail.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-09-25 15:43+0200\n"
-"PO-Revision-Date: 2007-02-28 18:35+0530\n"
+"PO-Revision-Date: 2007-05-19 12:44+0530\n"
"Last-Translator: pavithran <pavithran.s@gmail.com>\n"
"Language-Team: Telugu <indlinux-telugu@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; nplurals=n>1;"
#: contrib/comments/models.py:67 contrib/comments/models.py:166
msgid "object ID"
@@ -144,7 +144,7 @@ msgstr "కర్మ స్కొరులు"
#: contrib/comments/models.py:242
#, python-format
msgid "%(score)d rating by %(user)s"
-msgstr "%(user) రేటింగ్"
+msgstr "%(score)d కి %(user)s రేటింగ్"
#: contrib/comments/models.py:258
#, python-format
@@ -153,9 +153,9 @@ msgid ""
"\n"
"%(text)s"
msgstr ""
-"%(user)s చేత చేయబడ్డ వ్యాఖ్యానములు"
+"%(user)s చేత చేయబడ్డ వ్యాఖ్యానములు:\n"
"\n"
-"%(text)లు"
+"%(text)s"
#: contrib/comments/models.py:265
msgid "flag date"
@@ -220,12 +220,12 @@ msgid_plural ""
"\n"
"%(text)s"
msgstr[0] ""
-"ఈ వ్యాఖ్యానము చేసిన యూజర్ %(count)లు కన్న తక్కువ సమర్పించాడు "
+"ఈ వ్యాఖ్యానము చేసిన యూజర్ %(count)s లు కన్న తక్కువ సమర్పించాడు "
"వ్యాఖ్యానము:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"ఈ వ్యాఖ్యానము చేసిన యూజర్ %(count)లు కన్న తక్కువ సమర్పించాడు"
+"ఈ వ్యాఖ్యానము చేసిన యూజర్ %(count)s లు కన్న తక్కువ సమర్పించాడు"
"వ్యాఖ్యానములు:\n"
"\n"
"%(text)s"
@@ -343,7 +343,8 @@ msgstr "మీ పేరు"
msgid ""
"<h3>By %s:</h3>\n"
"<ul>\n"
-msgstr "<h3> %s తో:</h3>\n"
+msgstr ""
+"<h3> %s తో:</h3>\n"
"<ul>\n"
#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88
@@ -513,17 +514,17 @@ msgstr "%s ని మార్చంది"
#: contrib/admin/views/main.py:473
#, python-format
msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "ఒకటి కాని ,అంత కన్నఎక్కువ %(name)లు లో %(fieldname)లు : %(obj)లు "
+msgstr "ఒకటి కాని ,అంత కన్నఎక్కువ %(name)s లో %(fieldname)s : %(obj)s "
#: contrib/admin/views/main.py:478
#, python-format
msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "ఒకటి కాని ,అంత కన్నఎక్కువ %(name)లు లో %(fieldname)లు"
+msgstr "ఒకటి కాని ,అంత కన్నఎక్కువ %(name)s లో %(fieldname)s"
#: contrib/admin/views/main.py:511
#, python-format
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "%(name)లు \"%(obj)s\"జయప్రదంగా తీసివేయబడ్డడి"
+msgstr "%(name)s \"%(obj)s\"జయప్రదంగా తీసివేయబడ్డడి"
#: contrib/admin/views/main.py:514
msgid "Are you sure?"
@@ -532,7 +533,7 @@ msgstr "మీరు కచ్చితంగా ఉన్నారా?"
#: contrib/admin/views/main.py:536
#, python-format
msgid "Change history: %s"
-msgstr "మార్చబడిన పురాణము"
+msgstr "మార్చబడిన పురాణము: %s"
#: contrib/admin/views/main.py:570
#, python-format
@@ -796,12 +797,12 @@ msgstr "క్షమించండి మీరు కోరిన పేజి
#: contrib/admin/templates/admin/index.html:17
#, python-format
msgid "Models available in the %(name)s application."
-msgstr "మొడల్ లు %(name)లో దొరికే అప్ప్లికేషన్"
+msgstr "మొడల్ లు %(name)s లో దొరికే అప్ప్లికేషన్"
#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "%(name)s"
-msgstr "%(name)లు"
+msgstr "%(name)s"
#: contrib/admin/templates/admin/index.html:28
#: contrib/admin/templates/admin/change_form.html:15
@@ -831,7 +832,7 @@ msgstr "ఏమి దొరకలేదు"
#: contrib/admin/templates/admin/change_list.html:11
#, python-format
msgid "Add %(name)s"
-msgstr "%(name)లు జత చేయు"
+msgstr "%(name)s జత చేయు"
#: contrib/admin/templates/admin/login.html:22
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
@@ -1794,7 +1795,7 @@ msgstr "సంవత్సరము 1900 లేక దాని తరువాà
#: core/validators.py:142
#, python-format
msgid "Invalid date: %s."
-msgstr "సరికాని తారీఖు"
+msgstr "సరికాని తారీఖు : %s."
#: core/validators.py:146 db/models/fields/__init__.py:415
msgid "Enter a valid date in YYYY-MM-DD format."
@@ -1846,8 +1847,10 @@ msgstr "సరైన URL కావాలి"
msgid ""
"Valid HTML is required. Specific errors are:\n"
"%s"
-msgstr "సరైన HTML ఇవ్వండి .ప్రత్యేకమైన తప్పులు :\n"
+msgstr ""
+"సరైన HTML ఇవ్వండి .ప్రత్యేకమైన తప్పులు :\n"
"%s"
+
#: core/validators.py:220
#, python-format
msgid "Badly formed XML: %s"
@@ -1856,7 +1859,7 @@ msgstr ""
#: core/validators.py:230
#, python-format
msgid "Invalid URL: %s"
-msgstr ""
+msgstr "సరికాని URL: %s"
#: core/validators.py:234 core/validators.py:236
#, python-format
@@ -2004,27 +2007,27 @@ msgstr ""
#: views/generic/create_update.py:43
#, python-format
msgid "The %(verbose_name)s was created successfully."
-msgstr "%(verbose_name)లు జయప్రదంగా తయారయింది"
+msgstr "%(verbose_name)s జయప్రదంగా తయారయింది"
#: views/generic/create_update.py:117
#, python-format
msgid "The %(verbose_name)s was updated successfully."
-msgstr "%(verbose_name)లు జయప్రదంగా @@"
+msgstr "%(verbose_name)s జయప్రదంగా @@"
#: views/generic/create_update.py:184
#, python-format
msgid "The %(verbose_name)s was deleted."
-msgstr "%(verbose_name)లు తీసివేయబడినది"
+msgstr "%(verbose_name)s తీసివేయబడినది"
#: db/models/manipulators.py:302
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
-msgstr "%(field)ల లో %(object)తో %(type) ఉన్నాయి"
+msgstr "%(field)s లో %(object)s తో %(type)s ఉన్నాయి"
#: db/models/fields/__init__.py:40
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
-msgstr "%(optname)లు తో %(fieldname) ముందే ఉన్నాయి ."
+msgstr "%(optname)s తో %(fieldname)s ముందే ఉన్నాయి ."
#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265
#: db/models/fields/__init__.py:551 db/models/fields/__init__.py:562
@@ -2082,7 +2085,7 @@ msgstr "లైన్ బ్రేక్స్ కి ఇక్కడ ఆనà±
#: forms/__init__.py:487 forms/__init__.py:560 forms/__init__.py:599
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
-msgstr "సరైనది ఎంచుకోండి; %(choices) ల లో '%(data)s' లేవు "
+msgstr "సరైనది ఎంచుకోండి; %(choices)s లో '%(data)s' లేవు "
#: forms/__init__.py:663
msgid "The submitted file is empty."
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 22ffc282a4..9d1a4f0332 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -169,8 +169,8 @@ def items_for_result(cl, result):
# Booleans are special: We use images.
elif isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField):
result_repr = _boolean_icon(field_val)
- # FloatFields are special: Zero-pad the decimals.
- elif isinstance(f, models.FloatField):
+ # DecimalFields are special: Zero-pad the decimals.
+ elif isinstance(f, models.DecimalField):
if field_val is not None:
result_repr = ('%%.%sf' % f.decimal_places) % field_val
else:
diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py
index 8d79f49e0c..a21eb99f09 100644
--- a/django/contrib/admin/views/doc.py
+++ b/django/contrib/admin/views/doc.py
@@ -295,10 +295,11 @@ DATA_TYPE_MAPPING = {
'CommaSeparatedIntegerField': _('Comma-separated integers'),
'DateField' : _('Date (without time)'),
'DateTimeField' : _('Date (with time)'),
+ 'DecimalField' : _('Decimal number'),
'EmailField' : _('E-mail address'),
'FileField' : _('File path'),
'FilePathField' : _('File path'),
- 'FloatField' : _('Decimal number'),
+ 'FloatField' : _('Floating point number'),
'ForeignKey' : _('Integer'),
'ImageField' : _('File path'),
'IntegerField' : _('Integer'),
diff --git a/django/contrib/formtools/preview.py b/django/contrib/formtools/preview.py
index 351d991762..dcb58e85d8 100644
--- a/django/contrib/formtools/preview.py
+++ b/django/contrib/formtools/preview.py
@@ -83,7 +83,7 @@ class FormPreview(object):
"""
while 1:
try:
- f = self.form.fields[name]
+ f = self.form.base_fields[name]
except KeyError:
break # This field name isn't being used by the form.
name += '_'
diff --git a/tests/regressiontests/markup/models.py b/django/contrib/markup/models.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/markup/models.py
+++ b/django/contrib/markup/models.py
diff --git a/tests/regressiontests/markup/tests.py b/django/contrib/markup/tests.py
index bd3f52b9dd..bd3f52b9dd 100644
--- a/tests/regressiontests/markup/tests.py
+++ b/django/contrib/markup/tests.py
diff --git a/django/contrib/sessions/middleware.py b/django/contrib/sessions/middleware.py
index 1498f3c8ba..434997d616 100644
--- a/django/contrib/sessions/middleware.py
+++ b/django/contrib/sessions/middleware.py
@@ -36,6 +36,9 @@ class SessionWrapper(object):
def get(self, key, default=None):
return self._session.get(key, default)
+ def pop(self, key, *args):
+ return self._session.pop(key, *args)
+
def set_test_cookie(self):
self[TEST_COOKIE_NAME] = TEST_COOKIE_VALUE
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
new file mode 100644
index 0000000000..5a28effa86
--- /dev/null
+++ b/django/contrib/sessions/tests.py
@@ -0,0 +1,19 @@
+r"""
+>>> s = SessionWrapper(None)
+
+Inject data into the session cache.
+>>> s._session_cache = {}
+>>> s._session_cache['some key'] = 'exists'
+
+>>> s.pop('some key')
+'exists'
+
+>>> s.pop('some key', 'does not exist')
+'does not exist'
+"""
+
+from django.contrib.sessions.middleware import SessionWrapper
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 44ede4460a..30949837e4 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -1,7 +1,7 @@
from django.core import urlresolvers
import urllib
-PING_URL = "http://www.google.com/webmasters/sitemaps/ping"
+PING_URL = "http://www.google.com/webmasters/tools/ping"
class SitemapNotFound(Exception):
pass
@@ -29,7 +29,7 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
- url = "%s%s" % (current_site.domain, sitemap_url)
+ url = "http://%s%s" % (current_site.domain, sitemap_url)
params = urllib.urlencode({'sitemap':url})
urllib.urlopen("%s?%s" % (ping_url, params))
diff --git a/tests/regressiontests/markup/__init__.py b/django/contrib/webdesign/models.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/markup/__init__.py
+++ b/django/contrib/webdesign/models.py
diff --git a/django/contrib/webdesign/tests.py b/django/contrib/webdesign/tests.py
new file mode 100644
index 0000000000..eeb1956a01
--- /dev/null
+++ b/django/contrib/webdesign/tests.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+r"""
+>>> words(7)
+u'lorem ipsum dolor sit amet consectetur adipisicing'
+
+>>> paragraphs(1)
+['Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.']
+
+"""
+
+from django.contrib.webdesign.lorem_ipsum import *
+import datetime
+
+if __name__ == '__main__':
+ import doctest
+ doctest.testmod()
diff --git a/django/core/management.py b/django/core/management.py
index 7d9709b1b6..e8e09e928a 100644
--- a/django/core/management.py
+++ b/django/core/management.py
@@ -870,7 +870,7 @@ def inspectdb():
if field_type == 'CharField' and row[3]:
extra_params['maxlength'] = row[3]
- if field_type == 'FloatField':
+ if field_type == 'DecimalField':
extra_params['max_digits'] = row[4]
extra_params['decimal_places'] = row[5]
@@ -945,11 +945,11 @@ def get_validation_errors(outfile, app=None):
e.add(opts, '"%s": You can\'t use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.' % f.name)
if isinstance(f, models.CharField) and f.maxlength in (None, 0):
e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name)
- if isinstance(f, models.FloatField):
+ if isinstance(f, models.DecimalField):
if f.decimal_places is None:
- e.add(opts, '"%s": FloatFields require a "decimal_places" attribute.' % f.name)
+ e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name)
if f.max_digits is None:
- e.add(opts, '"%s": FloatFields require a "max_digits" attribute.' % f.name)
+ e.add(opts, '"%s": DecimalFields require a "max_digits" attribute.' % f.name)
if isinstance(f, models.FileField) and not f.upload_to:
e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name)
if isinstance(f, models.ImageField):
diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py
index 7c029e7029..20adce798d 100644
--- a/django/core/serializers/json.py
+++ b/django/core/serializers/json.py
@@ -4,19 +4,24 @@ Serialize data to/from JSON
import datetime
from django.utils import simplejson
+from django.utils.simplejson import decoder
from django.core.serializers.python import Serializer as PythonSerializer
from django.core.serializers.python import Deserializer as PythonDeserializer
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal # Python 2.3 fallback
class Serializer(PythonSerializer):
"""
Convert a queryset to JSON.
"""
def end_serialization(self):
- simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options)
+ simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
def getvalue(self):
if callable(getattr(self.stream, 'getvalue', None)):
@@ -30,12 +35,13 @@ def Deserializer(stream_or_string, **options):
stream = StringIO(stream_or_string)
else:
stream = stream_or_string
+ #for obj in PythonDeserializer(simplejson.load(stream, cls=DjangoJSONDecoder)):
for obj in PythonDeserializer(simplejson.load(stream)):
yield obj
-class DateTimeAwareJSONEncoder(simplejson.JSONEncoder):
+class DjangoJSONEncoder(simplejson.JSONEncoder):
"""
- JSONEncoder subclass that knows how to encode date/time types
+ JSONEncoder subclass that knows how to encode date/time and decimal types.
"""
DATE_FORMAT = "%Y-%m-%d"
@@ -48,5 +54,33 @@ class DateTimeAwareJSONEncoder(simplejson.JSONEncoder):
return o.strftime(self.DATE_FORMAT)
elif isinstance(o, datetime.time):
return o.strftime(self.TIME_FORMAT)
+ elif isinstance(o, decimal.Decimal):
+ return str(o)
else:
- return super(DateTimeAwareJSONEncoder, self).default(o)
+ return super(DjangoJSONEncoder, self).default(o)
+
+# Older, deprecated class name (for backwards compatibility purposes).
+DateTimeAwareJSONEncoder = DjangoJSONEncoder
+
+## Our override for simplejson.JSONNumber, because we want to use decimals in
+## preference to floats (we can convert decimal -> float when they stored, if
+## needed, but cannot go the other way).
+#def DjangoNumber(match, context):
+# match = DjangoNumber.regex.match(match.string, *match.span())
+# integer, frac, exp = match.groups()
+# if exp:
+# res = float(integer + (frac or '') + (exp or ''))
+# elif frac:
+# res = decimal.Decimal(integer + frac)
+# else:
+# res = int(integer)
+# return res, None
+#decoder.pattern(r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?')(DjangoNumber)
+#
+#converters = decoder.ANYTHING[:]
+#converters[-1] = DjangoNumber
+#decoder.JSONScanner = decoder.Scanner(converters)
+#
+#class DjangoJSONDecoder(simplejson.JSONDecoder):
+# _scanner = decoder.Scanner(converters)
+#
diff --git a/django/core/validators.py b/django/core/validators.py
index 42bf59439f..c737de22e8 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -25,6 +25,7 @@ email_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
+decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
integer_re = re.compile(r'^-?\d+$')
ip4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$', re.IGNORECASE)
@@ -406,28 +407,35 @@ class IsAPowerOf(object):
if val != int(val):
raise ValidationError, _("This value must be a power of %s.") % self.power_of
-class IsValidFloat(object):
+class IsValidDecimal(object):
def __init__(self, max_digits, decimal_places):
self.max_digits, self.decimal_places = max_digits, decimal_places
def __call__(self, field_data, all_data):
- data = str(field_data)
- try:
- float(data)
- except ValueError:
+ match = decimal_re.search(str(field_data))
+ if not match:
raise ValidationError, _("Please enter a valid decimal number.")
- # Negative floats require more space to input.
- max_allowed_length = data.startswith('-') and (self.max_digits + 2) or (self.max_digits + 1)
- if len(data) > max_allowed_length:
+
+ digits = len(match.group('digits') or '')
+ decimals = len(match.group('decimals') or '')
+
+ if digits + decimals > self.max_digits:
raise ValidationError, ungettext("Please enter a valid decimal number with at most %s total digit.",
"Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits
- if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places - 1)) or ('.' in data and len(data) > (max_allowed_length - (self.decimal_places - len(data.split('.')[1])))):
+ if digits > (self.max_digits - self.decimal_places):
raise ValidationError, ungettext( "Please enter a valid decimal number with a whole part of at most %s digit.",
"Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places)
- if '.' in data and len(data.split('.')[1]) > self.decimal_places:
+ if decimals > self.decimal_places:
raise ValidationError, ungettext("Please enter a valid decimal number with at most %s decimal place.",
"Please enter a valid decimal number with at most %s decimal places.", self.decimal_places) % self.decimal_places
+def isValidFloat(field_data, all_data):
+ data = str(field_data)
+ try:
+ float(data)
+ except ValueError:
+ raise ValidationError, gettext("Please enter a valid floating point number.")
+
class HasAllowableSize(object):
"""
Checks that the file-upload field data is a certain size. min_size and
diff --git a/django/db/backends/ado_mssql/creation.py b/django/db/backends/ado_mssql/creation.py
index 5158ba02f9..a1098ea43e 100644
--- a/django/db/backends/ado_mssql/creation.py
+++ b/django/db/backends/ado_mssql/creation.py
@@ -5,9 +5,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'smalldatetime',
'DateTimeField': 'smalldatetime',
+ 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
- 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'double precision',
'ImageField': 'varchar(100)',
'IntegerField': 'int',
'IPAddressField': 'char(15)',
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index ca6a7cc9ce..8bab8bb900 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -15,7 +15,7 @@ except ImportError, e:
# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
# inadvertently passes the version test.
version = Database.version_info
-if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
+if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
(len(version) < 5 or version[3] != 'final' or version[4] < 2))):
raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__
@@ -36,6 +36,8 @@ IntegrityError = Database.IntegrityError
django_conversions = conversions.copy()
django_conversions.update({
FIELD_TYPE.TIME: util.typecast_time,
+ FIELD_TYPE.DECIMAL: util.typecast_decimal,
+ FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
})
# This should match the numerical portion of the version numbers (we can treat
diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py
index 22ed901653..1b23fbff6e 100644
--- a/django/db/backends/mysql/creation.py
+++ b/django/db/backends/mysql/creation.py
@@ -9,9 +9,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
+ 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
- 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'double precision',
'ImageField': 'varchar(100)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index 558fe49787..39733311c5 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -76,7 +76,7 @@ def get_indexes(cursor, table_name):
DATA_TYPES_REVERSE = {
FIELD_TYPE.BLOB: 'TextField',
FIELD_TYPE.CHAR: 'CharField',
- FIELD_TYPE.DECIMAL: 'FloatField',
+ FIELD_TYPE.DECIMAL: 'DecimalField',
FIELD_TYPE.DATE: 'DateField',
FIELD_TYPE.DATETIME: 'DateTimeField',
FIELD_TYPE.DOUBLE: 'FloatField',
diff --git a/django/db/backends/mysql_old/base.py b/django/db/backends/mysql_old/base.py
index 497c8fdc77..bcd87457dd 100644
--- a/django/db/backends/mysql_old/base.py
+++ b/django/db/backends/mysql_old/base.py
@@ -24,6 +24,8 @@ django_conversions.update({
FIELD_TYPE.DATETIME: util.typecast_timestamp,
FIELD_TYPE.DATE: util.typecast_date,
FIELD_TYPE.TIME: util.typecast_time,
+ FIELD_TYPE.DECIMAL: util.typecast_decimal,
+ FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
})
# This should match the numerical portion of the version numbers (we can treat
diff --git a/django/db/backends/mysql_old/creation.py b/django/db/backends/mysql_old/creation.py
index 22ed901653..1b23fbff6e 100644
--- a/django/db/backends/mysql_old/creation.py
+++ b/django/db/backends/mysql_old/creation.py
@@ -9,9 +9,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
+ 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
- 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'double precision',
'ImageField': 'varchar(100)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
diff --git a/django/db/backends/mysql_old/introspection.py b/django/db/backends/mysql_old/introspection.py
index 5ea626a5a9..cb5b8320d9 100644
--- a/django/db/backends/mysql_old/introspection.py
+++ b/django/db/backends/mysql_old/introspection.py
@@ -76,7 +76,7 @@ def get_indexes(cursor, table_name):
DATA_TYPES_REVERSE = {
FIELD_TYPE.BLOB: 'TextField',
FIELD_TYPE.CHAR: 'CharField',
- FIELD_TYPE.DECIMAL: 'FloatField',
+ FIELD_TYPE.DECIMAL: 'DecimalField',
FIELD_TYPE.DATE: 'DateField',
FIELD_TYPE.DATETIME: 'DateTimeField',
FIELD_TYPE.DOUBLE: 'FloatField',
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index da65df172e..14a864ac28 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -5,9 +5,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar2(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'date',
+ 'DecimalField': 'number(%(max_digits)s, %(decimal_places)s)',
'FileField': 'varchar2(100)',
'FilePathField': 'varchar2(100)',
- 'FloatField': 'number(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'double precision',
'ImageField': 'varchar2(100)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py
index ecc8f372a8..7634206178 100644
--- a/django/db/backends/oracle/introspection.py
+++ b/django/db/backends/oracle/introspection.py
@@ -46,5 +46,5 @@ DATA_TYPES_REVERSE = {
1114: 'DateTimeField',
1184: 'DateTimeField',
1266: 'TimeField',
- 1700: 'FloatField',
+ 1700: 'DecimalField',
}
diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py
index a6a2351c6e..912d49b493 100644
--- a/django/db/backends/postgresql/base.py
+++ b/django/db/backends/postgresql/base.py
@@ -277,6 +277,7 @@ except AttributeError:
Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time))
Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp))
Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean))
+Database.register_type(Database.new_type((1700,), "NUMERIC", util.typecast_decimal))
OPERATOR_MAPPING = {
'exact': '= %s',
diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py
index 6c130f368e..4646b68ab8 100644
--- a/django/db/backends/postgresql/creation.py
+++ b/django/db/backends/postgresql/creation.py
@@ -9,9 +9,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'timestamp with time zone',
+ 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
- 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'double precision',
'ImageField': 'varchar(100)',
'IntegerField': 'integer',
'IPAddressField': 'inet',
diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py
index 6e1d60c4ff..2605490afd 100644
--- a/django/db/backends/postgresql/introspection.py
+++ b/django/db/backends/postgresql/introspection.py
@@ -72,6 +72,7 @@ DATA_TYPES_REVERSE = {
21: 'SmallIntegerField',
23: 'IntegerField',
25: 'TextField',
+ 701: 'FloatField',
869: 'IPAddressField',
1043: 'CharField',
1082: 'DateField',
@@ -79,5 +80,5 @@ DATA_TYPES_REVERSE = {
1114: 'DateTimeField',
1184: 'DateTimeField',
1266: 'TimeField',
- 1700: 'FloatField',
+ 1700: 'DecimalField',
}
diff --git a/django/db/backends/postgresql_psycopg2/introspection.py b/django/db/backends/postgresql_psycopg2/introspection.py
index a546da8c45..aa45fe7db7 100644
--- a/django/db/backends/postgresql_psycopg2/introspection.py
+++ b/django/db/backends/postgresql_psycopg2/introspection.py
@@ -72,6 +72,7 @@ DATA_TYPES_REVERSE = {
21: 'SmallIntegerField',
23: 'IntegerField',
25: 'TextField',
+ 701: 'FloatField',
869: 'IPAddressField',
1043: 'CharField',
1082: 'DateField',
@@ -79,5 +80,5 @@ DATA_TYPES_REVERSE = {
1114: 'DateTimeField',
1184: 'DateTimeField',
1266: 'TimeField',
- 1700: 'FloatField',
+ 1700: 'DecimalField',
}
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index ce148ec1b5..2cd24d71fa 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -17,6 +17,11 @@ except ImportError, e:
module = 'sqlite3'
raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal # for Python 2.3
+
DatabaseError = Database.DatabaseError
IntegrityError = Database.IntegrityError
@@ -26,6 +31,8 @@ Database.register_converter("date", util.typecast_date)
Database.register_converter("datetime", util.typecast_timestamp)
Database.register_converter("timestamp", util.typecast_timestamp)
Database.register_converter("TIMESTAMP", util.typecast_timestamp)
+Database.register_converter("decimal", util.typecast_decimal)
+Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
try:
# Only exists in Python 2.4+
diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py
index 77f570b2e8..e63046ab7d 100644
--- a/django/db/backends/sqlite3/creation.py
+++ b/django/db/backends/sqlite3/creation.py
@@ -8,9 +8,10 @@ DATA_TYPES = {
'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
+ 'DecimalField': 'decimal',
'FileField': 'varchar(100)',
'FilePathField': 'varchar(100)',
- 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)',
+ 'FloatField': 'real',
'ImageField': 'varchar(100)',
'IntegerField': 'integer',
'IPAddressField': 'char(15)',
diff --git a/django/db/backends/util.py b/django/db/backends/util.py
index 6047f7df08..0e824f9431 100644
--- a/django/db/backends/util.py
+++ b/django/db/backends/util.py
@@ -2,6 +2,11 @@ import datetime
from time import time
from django.utils.encoding import smart_unicode
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal # for Python 2.3
+
class CursorDebugWrapper(object):
def __init__(self, cursor, db):
self.cursor = cursor
@@ -91,6 +96,11 @@ def typecast_boolean(s):
if not s: return False
return str(s)[0].lower() == 't'
+def typecast_decimal(s):
+ if s is None:
+ return None
+ return decimal.Decimal(s)
+
###############################################
# Converters from Python to database (string) #
###############################################
@@ -98,6 +108,11 @@ def typecast_boolean(s):
def rev_typecast_boolean(obj, d):
return obj and '1' or '0'
+def rev_typecast_decimal(d):
+ if d is None:
+ return None
+ return str(d)
+
##################################################################################
# Helper functions for dictfetch* for databases that don't natively support them #
##################################################################################
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 5003f0e389..20fe2e4813 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -11,6 +11,10 @@ from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.encoding import smart_unicode
import datetime, os, time
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal # for Python 2.3
class NOT_PROVIDED:
pass
@@ -574,6 +578,65 @@ class DateTimeField(DateField):
defaults.update(kwargs)
return super(DateTimeField, self).formfield(**defaults)
+class DecimalField(Field):
+ empty_strings_allowed = False
+ def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
+ self.max_digits, self.decimal_places = max_digits, decimal_places
+ Field.__init__(self, verbose_name, name, **kwargs)
+
+ def to_python(self, value):
+ if value is None:
+ return value
+ try:
+ return decimal.Decimal(value)
+ except decimal.InvalidOperation:
+ raise validators.ValidationError, ugettext("This value must be a decimal number.")
+
+ def _format(self, value):
+ if isinstance(value, basestring):
+ return value
+ else:
+ return self.format_number(value)
+
+ def format_number(self, value):
+ """
+ Formats a number into a string with the requisite number of digits and
+ decimal places.
+ """
+ num_chars = self.max_digits
+ # Allow for a decimal point
+ if self.decimal_places > 0:
+ num_chars += 1
+ # Allow for a minus sign
+ if value < 0:
+ num_chars += 1
+
+ return u"%.*f" % (self.decimal_places, value)
+
+ def get_db_prep_save(self, value):
+ if value is not None:
+ value = self._format(value)
+ return super(DecimalField, self).get_db_prep_save(value)
+
+ def get_db_prep_lookup(self, lookup_type, value):
+ if lookup_type == 'range':
+ value = [self._format(v) for v in value]
+ else:
+ value = self._format(value)
+ return super(DecimalField, self).get_db_prep_lookup(lookup_type, value)
+
+ def get_manipulator_field_objs(self):
+ return [curry(oldforms.DecimalField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
+
+ def formfield(self, **kwargs):
+ defaults = {
+ 'max_digits': self.max_digits,
+ 'decimal_places': self.decimal_places,
+ 'form_class': forms.DecimalField,
+ }
+ defaults.update(kwargs)
+ return super(DecimalField, self).formfield(**defaults)
+
class EmailField(CharField):
def __init__(self, *args, **kwargs):
kwargs['maxlength'] = 75
@@ -684,12 +747,14 @@ class FilePathField(Field):
class FloatField(Field):
empty_strings_allowed = False
- def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
- self.max_digits, self.decimal_places = max_digits, decimal_places
- Field.__init__(self, verbose_name, name, **kwargs)
def get_manipulator_field_objs(self):
- return [curry(oldforms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
+ return [oldforms.FloatField]
+
+ def formfield(self, **kwargs):
+ defaults = {'form_class': forms.FloatField}
+ defaults.update(kwargs)
+ return super(FloatField, self).formfield(**defaults)
class ImageField(FileField):
def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 4c667e02af..5bc0e4ca54 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -155,9 +155,12 @@ class QueryDict(MultiValueDict):
self._assert_mutable()
MultiValueDict.update(self, other_dict)
- def pop(self, key):
+ def pop(self, key, *args):
self._assert_mutable()
- return [str_to_unicode(v, self.encoding) for v in MultiValueDict.pop(self, key)]
+ val = MultiValueDict.pop(self, key, *args)
+ if isinstance(val, list):
+ return [str_to_unicode(v, self.encoding) for v in val]
+ return str_to_unicode(val, self.encoding)
def popitem(self):
self._assert_mutable()
diff --git a/django/newforms/fields.py b/django/newforms/fields.py
index d67eefdd3c..3172488d99 100644
--- a/django/newforms/fields.py
+++ b/django/newforms/fields.py
@@ -19,7 +19,7 @@ __all__ = (
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
'RegexField', 'EmailField', 'URLField', 'BooleanField',
'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
- 'ComboField', 'MultiValueField',
+ 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
'SplitDateTimeField',
)
@@ -31,6 +31,11 @@ try:
except NameError:
from sets import Set as set # Python 2.3 fallback
+try:
+ from decimal import Decimal
+except ImportError:
+ from django.utils._decimal import Decimal # Python 2.3 fallback
+
class Field(object):
widget = TextInput # Default widget to use when rendering this type of Field.
hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
@@ -134,6 +139,67 @@ class IntegerField(Field):
raise ValidationError(ugettext(u'Ensure this value is greater than or equal to %s.') % self.min_value)
return value
+class FloatField(Field):
+ def __init__(self, max_value=None, min_value=None, *args, **kwargs):
+ self.max_value, self.min_value = max_value, min_value
+ Field.__init__(self, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ Validates that float() can be called on the input. Returns a float.
+ Returns None for empty values.
+ """
+ super(FloatField, self).clean(value)
+ if not self.required and value in EMPTY_VALUES:
+ return None
+ try:
+ value = float(value)
+ except (ValueError, TypeError):
+ raise ValidationError(ugettext('Enter a number.'))
+ if self.max_value is not None and value > self.max_value:
+ raise ValidationError(ugettext('Ensure this value is less than or equal to %s.') % self.max_value)
+ if self.min_value is not None and value < self.min_value:
+ raise ValidationError(ugettext('Ensure this value is greater than or equal to %s.') % self.min_value)
+ return value
+
+decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
+
+class DecimalField(Field):
+ def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs):
+ self.max_value, self.min_value = max_value, min_value
+ self.max_digits, self.decimal_places = max_digits, decimal_places
+ Field.__init__(self, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ Validates that the input is a decimal number. Returns a Decimal
+ instance. Returns None for empty values. Ensures that there are no more
+ than max_digits in the number, and no more than decimal_places digits
+ after the decimal point.
+ """
+ super(DecimalField, self).clean(value)
+ if not self.required and value in EMPTY_VALUES:
+ return None
+ value = value.strip()
+ match = decimal_re.search(value)
+ if not match:
+ raise ValidationError(ugettext('Enter a number.'))
+ else:
+ value = Decimal(value)
+ digits = len(match.group('digits') or '')
+ decimals = len(match.group('decimals') or '')
+ if self.max_value is not None and value > self.max_value:
+ raise ValidationError(ugettext('Ensure this value is less than or equal to %s.') % self.max_value)
+ if self.min_value is not None and value < self.min_value:
+ raise ValidationError(ugettext('Ensure this value is greater than or equal to %s.') % self.min_value)
+ if self.max_digits is not None and (digits + decimals) > self.max_digits:
+ raise ValidationError(ugettext('Ensure that there are no more than %s digits in total.') % self.max_digits)
+ if self.decimal_places is not None and decimals > self.decimal_places:
+ raise ValidationError(ugettext('Ensure that there are no more than %s decimal places.') % self.decimal_places)
+ if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places):
+ raise ValidationError(ugettext('Ensure that there are no more than %s digits before the decimal point.') % (self.max_digits - self.decimal_places))
+ return value
+
DEFAULT_DATE_INPUT_FORMATS = (
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
diff --git a/django/newforms/util.py b/django/newforms/util.py
index 455d6c3105..37fe841b61 100644
--- a/django/newforms/util.py
+++ b/django/newforms/util.py
@@ -1,9 +1,14 @@
from django.utils.html import escape
from django.utils.encoding import smart_unicode
-# Converts a dictionary to a single string with key="value", XML-style with
-# a leading space. Assumes keys do not need to be XML-escaped.
-flatatt = lambda attrs: u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
+def flatatt(attrs):
+ """
+ Convert a dictionary of attributes to a single string.
+ The returned string will contain a leading space followed by key="value",
+ XML-style pairs. It is assumed that the keys do not need to be XML-escaped.
+ If the passed dictionary is empty, then return an empty string.
+ """
+ return u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
class ErrorDict(dict):
"""
diff --git a/django/oldforms/__init__.py b/django/oldforms/__init__.py
index d802f33468..bc787f860c 100644
--- a/django/oldforms/__init__.py
+++ b/django/oldforms/__init__.py
@@ -760,14 +760,27 @@ class PositiveSmallIntegerField(IntegerField):
raise validators.CriticalValidationError, ugettext("Enter a whole number between 0 and 32,767.")
class FloatField(TextField):
+ def __init__(self, field_name, is_required=False, validator_list=None):
+ if validator_list is None: validator_list = []
+ validator_list = [validators.isValidFloat] + validator_list
+ TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list)
+
+ def html2python(data):
+ if data == '' or data is None:
+ return None
+ return float(data)
+ html2python = staticmethod(html2python)
+
+class DecimalField(TextField):
def __init__(self, field_name, max_digits, decimal_places, is_required=False, validator_list=None):
if validator_list is None: validator_list = []
self.max_digits, self.decimal_places = max_digits, decimal_places
- validator_list = [self.isValidFloat] + validator_list
- TextField.__init__(self, field_name, max_digits+2, max_digits+2, is_required, validator_list)
+ validator_list = [self.isValidDecimal] + validator_list
+ # Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point.
+ super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list)
- def isValidFloat(self, field_data, all_data):
- v = validators.IsValidFloat(self.max_digits, self.decimal_places)
+ def isValidDecimal(self, field_data, all_data):
+ v = validators.IsValidDecimal(self.max_digits, self.decimal_places)
try:
v(field_data, all_data)
except validators.ValidationError, e:
@@ -776,7 +789,14 @@ class FloatField(TextField):
def html2python(data):
if data == '' or data is None:
return None
- return float(data)
+ try:
+ import decimal
+ except ImportError:
+ from django.utils import decimal
+ try:
+ return decimal.Decimal(data)
+ except decimal.InvalidOperation, e:
+ raise ValueError, e
html2python = staticmethod(html2python)
####################
diff --git a/django/utils/_decimal.py b/django/utils/_decimal.py
new file mode 100644
index 0000000000..677d26bb32
--- /dev/null
+++ b/django/utils/_decimal.py
@@ -0,0 +1,3079 @@
+# Copyright (c) 2004 Python Software Foundation.
+# All rights reserved.
+
+# Written by Eric Price <eprice at tjhsst.edu>
+# and Facundo Batista <facundo at taniquetil.com.ar>
+# and Raymond Hettinger <python at rcn.com>
+# and Aahz <aahz at pobox.com>
+# and Tim Peters
+
+# This module is currently Py2.3 compatible and should be kept that way
+# unless a major compelling advantage arises. IOW, 2.3 compatibility is
+# strongly preferred, but not guaranteed.
+
+# Also, this module should be kept in sync with the latest updates of
+# the IBM specification as it evolves. Those updates will be treated
+# as bug fixes (deviation from the spec is a compatibility, usability
+# bug) and will be backported. At this point the spec is stabilizing
+# and the updates are becoming fewer, smaller, and less significant.
+
+"""
+This is a Py2.3 implementation of decimal floating point arithmetic based on
+the General Decimal Arithmetic Specification:
+
+ www2.hursley.ibm.com/decimal/decarith.html
+
+and IEEE standard 854-1987:
+
+ www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
+
+Decimal floating point has finite precision with arbitrarily large bounds.
+
+The purpose of the module is to support arithmetic using familiar
+"schoolhouse" rules and to avoid the some of tricky representation
+issues associated with binary floating point. The package is especially
+useful for financial applications or for contexts where users have
+expectations that are at odds with binary floating point (for instance,
+in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
+of the expected Decimal("0.00") returned by decimal floating point).
+
+Here are some examples of using the decimal module:
+
+>>> from decimal import *
+>>> setcontext(ExtendedContext)
+>>> Decimal(0)
+Decimal("0")
+>>> Decimal("1")
+Decimal("1")
+>>> Decimal("-.0123")
+Decimal("-0.0123")
+>>> Decimal(123456)
+Decimal("123456")
+>>> Decimal("123.45e12345678901234567890")
+Decimal("1.2345E+12345678901234567892")
+>>> Decimal("1.33") + Decimal("1.27")
+Decimal("2.60")
+>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41")
+Decimal("-2.20")
+>>> dig = Decimal(1)
+>>> print dig / Decimal(3)
+0.333333333
+>>> getcontext().prec = 18
+>>> print dig / Decimal(3)
+0.333333333333333333
+>>> print dig.sqrt()
+1
+>>> print Decimal(3).sqrt()
+1.73205080756887729
+>>> print Decimal(3) ** 123
+4.85192780976896427E+58
+>>> inf = Decimal(1) / Decimal(0)
+>>> print inf
+Infinity
+>>> neginf = Decimal(-1) / Decimal(0)
+>>> print neginf
+-Infinity
+>>> print neginf + inf
+NaN
+>>> print neginf * inf
+-Infinity
+>>> print dig / 0
+Infinity
+>>> getcontext().traps[DivisionByZero] = 1
+>>> print dig / 0
+Traceback (most recent call last):
+ ...
+ ...
+ ...
+DivisionByZero: x / 0
+>>> c = Context()
+>>> c.traps[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
+0
+>>> c.divide(Decimal(0), Decimal(0))
+Decimal("NaN")
+>>> c.traps[InvalidOperation] = 1
+>>> print c.flags[InvalidOperation]
+1
+>>> c.flags[InvalidOperation] = 0
+>>> print c.flags[InvalidOperation]
+0
+>>> print c.divide(Decimal(0), Decimal(0))
+Traceback (most recent call last):
+ ...
+ ...
+ ...
+InvalidOperation: 0 / 0
+>>> print c.flags[InvalidOperation]
+1
+>>> c.flags[InvalidOperation] = 0
+>>> c.traps[InvalidOperation] = 0
+>>> print c.divide(Decimal(0), Decimal(0))
+NaN
+>>> print c.flags[InvalidOperation]
+1
+>>>
+"""
+
+__all__ = [
+ # Two major classes
+ 'Decimal', 'Context',
+
+ # Contexts
+ 'DefaultContext', 'BasicContext', 'ExtendedContext',
+
+ # Exceptions
+ 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
+ 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
+
+ # Constants for use in setting up contexts
+ 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
+ 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
+
+ # Functions for manipulating contexts
+ 'setcontext', 'getcontext'
+]
+
+import copy as _copy
+
+#Rounding
+ROUND_DOWN = 'ROUND_DOWN'
+ROUND_HALF_UP = 'ROUND_HALF_UP'
+ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
+ROUND_CEILING = 'ROUND_CEILING'
+ROUND_FLOOR = 'ROUND_FLOOR'
+ROUND_UP = 'ROUND_UP'
+ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
+
+#Rounding decision (not part of the public API)
+NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY
+ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end.
+
+#Errors
+
+class DecimalException(ArithmeticError):
+ """Base exception class.
+
+ Used exceptions derive from this.
+ If an exception derives from another exception besides this (such as
+ Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
+ called if the others are present. This isn't actually used for
+ anything, though.
+
+ handle -- Called when context._raise_error is called and the
+ trap_enabler is set. First argument is self, second is the
+ context. More arguments can be given, those being after
+ the explanation in _raise_error (For example,
+ context._raise_error(NewError, '(-x)!', self._sign) would
+ call NewError().handle(context, self._sign).)
+
+ To define a new exception, it should be sufficient to have it derive
+ from DecimalException.
+ """
+ def handle(self, context, *args):
+ pass
+
+
+class Clamped(DecimalException):
+ """Exponent of a 0 changed to fit bounds.
+
+ This occurs and signals clamped if the exponent of a result has been
+ altered in order to fit the constraints of a specific concrete
+ representation. This may occur when the exponent of a zero result would
+ be outside the bounds of a representation, or when a large normal
+ number would have an encoded exponent that cannot be represented. In
+ this latter case, the exponent is reduced to fit and the corresponding
+ number of zero digits are appended to the coefficient ("fold-down").
+ """
+
+
+class InvalidOperation(DecimalException):
+ """An invalid operation was performed.
+
+ Various bad things cause this:
+
+ Something creates a signaling NaN
+ -INF + INF
+ 0 * (+-)INF
+ (+-)INF / (+-)INF
+ x % 0
+ (+-)INF % x
+ x._rescale( non-integer )
+ sqrt(-x) , x > 0
+ 0 ** 0
+ x ** (non-integer)
+ x ** (+-)INF
+ An operand is invalid
+ """
+ def handle(self, context, *args):
+ if args:
+ if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
+ return Decimal( (args[1]._sign, args[1]._int, 'n') )
+ return NaN
+
+class ConversionSyntax(InvalidOperation):
+ """Trying to convert badly formed string.
+
+ This occurs and signals invalid-operation if an string is being
+ converted to a number and it does not conform to the numeric string
+ syntax. The result is [0,qNaN].
+ """
+
+ def handle(self, context, *args):
+ return (0, (0,), 'n') #Passed to something which uses a tuple.
+
+class DivisionByZero(DecimalException, ZeroDivisionError):
+ """Division by 0.
+
+ This occurs and signals division-by-zero if division of a finite number
+ by zero was attempted (during a divide-integer or divide operation, or a
+ power operation with negative right-hand operand), and the dividend was
+ not zero.
+
+ The result of the operation is [sign,inf], where sign is the exclusive
+ or of the signs of the operands for divide, or is 1 for an odd power of
+ -0, for power.
+ """
+
+ def handle(self, context, sign, double = None, *args):
+ if double is not None:
+ return (Infsign[sign],)*2
+ return Infsign[sign]
+
+class DivisionImpossible(InvalidOperation):
+ """Cannot perform the division adequately.
+
+ This occurs and signals invalid-operation if the integer result of a
+ divide-integer or remainder operation had too many digits (would be
+ longer than precision). The result is [0,qNaN].
+ """
+
+ def handle(self, context, *args):
+ return (NaN, NaN)
+
+class DivisionUndefined(InvalidOperation, ZeroDivisionError):
+ """Undefined result of division.
+
+ This occurs and signals invalid-operation if division by zero was
+ attempted (during a divide-integer, divide, or remainder operation), and
+ the dividend is also zero. The result is [0,qNaN].
+ """
+
+ def handle(self, context, tup=None, *args):
+ if tup is not None:
+ return (NaN, NaN) #for 0 %0, 0 // 0
+ return NaN
+
+class Inexact(DecimalException):
+ """Had to round, losing information.
+
+ This occurs and signals inexact whenever the result of an operation is
+ not exact (that is, it needed to be rounded and any discarded digits
+ were non-zero), or if an overflow or underflow condition occurs. The
+ result in all cases is unchanged.
+
+ The inexact signal may be tested (or trapped) to determine if a given
+ operation (or sequence of operations) was inexact.
+ """
+ pass
+
+class InvalidContext(InvalidOperation):
+ """Invalid context. Unknown rounding, for example.
+
+ This occurs and signals invalid-operation if an invalid context was
+ detected during an operation. This can occur if contexts are not checked
+ on creation and either the precision exceeds the capability of the
+ underlying concrete representation or an unknown or unsupported rounding
+ was specified. These aspects of the context need only be checked when
+ the values are required to be used. The result is [0,qNaN].
+ """
+
+ def handle(self, context, *args):
+ return NaN
+
+class Rounded(DecimalException):
+ """Number got rounded (not necessarily changed during rounding).
+
+ This occurs and signals rounded whenever the result of an operation is
+ rounded (that is, some zero or non-zero digits were discarded from the
+ coefficient), or if an overflow or underflow condition occurs. The
+ result in all cases is unchanged.
+
+ The rounded signal may be tested (or trapped) to determine if a given
+ operation (or sequence of operations) caused a loss of precision.
+ """
+ pass
+
+class Subnormal(DecimalException):
+ """Exponent < Emin before rounding.
+
+ This occurs and signals subnormal whenever the result of a conversion or
+ operation is subnormal (that is, its adjusted exponent is less than
+ Emin, before any rounding). The result in all cases is unchanged.
+
+ The subnormal signal may be tested (or trapped) to determine if a given
+ or operation (or sequence of operations) yielded a subnormal result.
+ """
+ pass
+
+class Overflow(Inexact, Rounded):
+ """Numerical overflow.
+
+ This occurs and signals overflow if the adjusted exponent of a result
+ (from a conversion or from an operation that is not an attempt to divide
+ by zero), after rounding, would be greater than the largest value that
+ can be handled by the implementation (the value Emax).
+
+ The result depends on the rounding mode:
+
+ For round-half-up and round-half-even (and for round-half-down and
+ round-up, if implemented), the result of the operation is [sign,inf],
+ where sign is the sign of the intermediate result. For round-down, the
+ result is the largest finite number that can be represented in the
+ current precision, with the sign of the intermediate result. For
+ round-ceiling, the result is the same as for round-down if the sign of
+ the intermediate result is 1, or is [0,inf] otherwise. For round-floor,
+ the result is the same as for round-down if the sign of the intermediate
+ result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded
+ will also be raised.
+ """
+
+ def handle(self, context, sign, *args):
+ if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
+ ROUND_HALF_DOWN, ROUND_UP):
+ return Infsign[sign]
+ if sign == 0:
+ if context.rounding == ROUND_CEILING:
+ return Infsign[sign]
+ return Decimal((sign, (9,)*context.prec,
+ context.Emax-context.prec+1))
+ if sign == 1:
+ if context.rounding == ROUND_FLOOR:
+ return Infsign[sign]
+ return Decimal( (sign, (9,)*context.prec,
+ context.Emax-context.prec+1))
+
+
+class Underflow(Inexact, Rounded, Subnormal):
+ """Numerical underflow with result rounded to 0.
+
+ This occurs and signals underflow if a result is inexact and the
+ adjusted exponent of the result would be smaller (more negative) than
+ the smallest value that can be handled by the implementation (the value
+ Emin). That is, the result is both inexact and subnormal.
+
+ The result after an underflow will be a subnormal number rounded, if
+ necessary, so that its exponent is not less than Etiny. This may result
+ in 0 with the sign of the intermediate result and an exponent of Etiny.
+
+ In all cases, Inexact, Rounded, and Subnormal will also be raised.
+ """
+
+# List of public traps and flags
+_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
+ Underflow, InvalidOperation, Subnormal]
+
+# Map conditions (per the spec) to signals
+_condition_map = {ConversionSyntax:InvalidOperation,
+ DivisionImpossible:InvalidOperation,
+ DivisionUndefined:InvalidOperation,
+ InvalidContext:InvalidOperation}
+
+##### Context Functions #######################################
+
+# The getcontext() and setcontext() function manage access to a thread-local
+# current context. Py2.4 offers direct support for thread locals. If that
+# is not available, use threading.currentThread() which is slower but will
+# work for older Pythons. If threads are not part of the build, create a
+# mock threading object with threading.local() returning the module namespace.
+
+try:
+ import threading
+except ImportError:
+ # Python was compiled without threads; create a mock object instead
+ import sys
+ class MockThreading:
+ def local(self, sys=sys):
+ return sys.modules[__name__]
+ threading = MockThreading()
+ del sys, MockThreading
+
+try:
+ threading.local
+
+except AttributeError:
+
+ #To fix reloading, force it to create a new context
+ #Old contexts have different exceptions in their dicts, making problems.
+ if hasattr(threading.currentThread(), '__decimal_context__'):
+ del threading.currentThread().__decimal_context__
+
+ def setcontext(context):
+ """Set this thread's context to context."""
+ if context in (DefaultContext, BasicContext, ExtendedContext):
+ context = context.copy()
+ context.clear_flags()
+ threading.currentThread().__decimal_context__ = context
+
+ def getcontext():
+ """Returns this thread's context.
+
+ If this thread does not yet have a context, returns
+ a new context and sets this thread's context.
+ New contexts are copies of DefaultContext.
+ """
+ try:
+ return threading.currentThread().__decimal_context__
+ except AttributeError:
+ context = Context()
+ threading.currentThread().__decimal_context__ = context
+ return context
+
+else:
+
+ local = threading.local()
+ if hasattr(local, '__decimal_context__'):
+ del local.__decimal_context__
+
+ def getcontext(_local=local):
+ """Returns this thread's context.
+
+ If this thread does not yet have a context, returns
+ a new context and sets this thread's context.
+ New contexts are copies of DefaultContext.
+ """
+ try:
+ return _local.__decimal_context__
+ except AttributeError:
+ context = Context()
+ _local.__decimal_context__ = context
+ return context
+
+ def setcontext(context, _local=local):
+ """Set this thread's context to context."""
+ if context in (DefaultContext, BasicContext, ExtendedContext):
+ context = context.copy()
+ context.clear_flags()
+ _local.__decimal_context__ = context
+
+ del threading, local # Don't contaminate the namespace
+
+
+##### Decimal class ###########################################
+
+class Decimal(object):
+ """Floating point class for decimal arithmetic."""
+
+ __slots__ = ('_exp','_int','_sign', '_is_special')
+ # Generally, the value of the Decimal instance is given by
+ # (-1)**_sign * _int * 10**_exp
+ # Special values are signified by _is_special == True
+
+ # We're immutable, so use __new__ not __init__
+ def __new__(cls, value="0", context=None):
+ """Create a decimal point instance.
+
+ >>> Decimal('3.14') # string input
+ Decimal("3.14")
+ >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent)
+ Decimal("3.14")
+ >>> Decimal(314) # int or long
+ Decimal("314")
+ >>> Decimal(Decimal(314)) # another decimal instance
+ Decimal("314")
+ """
+
+ self = object.__new__(cls)
+ self._is_special = False
+
+ # From an internal working value
+ if isinstance(value, _WorkRep):
+ self._sign = value.sign
+ self._int = tuple(map(int, str(value.int)))
+ self._exp = int(value.exp)
+ return self
+
+ # From another decimal
+ if isinstance(value, Decimal):
+ self._exp = value._exp
+ self._sign = value._sign
+ self._int = value._int
+ self._is_special = value._is_special
+ return self
+
+ # From an integer
+ if isinstance(value, (int,long)):
+ if value >= 0:
+ self._sign = 0
+ else:
+ self._sign = 1
+ self._exp = 0
+ self._int = tuple(map(int, str(abs(value))))
+ return self
+
+ # tuple/list conversion (possibly from as_tuple())
+ if isinstance(value, (list,tuple)):
+ if len(value) != 3:
+ raise ValueError, 'Invalid arguments'
+ if value[0] not in (0,1):
+ raise ValueError, 'Invalid sign'
+ for digit in value[1]:
+ if not isinstance(digit, (int,long)) or digit < 0:
+ raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
+
+ self._sign = value[0]
+ self._int = tuple(value[1])
+ if value[2] in ('F','n','N'):
+ self._exp = value[2]
+ self._is_special = True
+ else:
+ self._exp = int(value[2])
+ return self
+
+ if isinstance(value, float):
+ raise TypeError("Cannot convert float to Decimal. " +
+ "First convert the float to a string")
+
+ # Other argument types may require the context during interpretation
+ if context is None:
+ context = getcontext()
+
+ # From a string
+ # REs insist on real strings, so we can too.
+ if isinstance(value, basestring):
+ if _isinfinity(value):
+ self._exp = 'F'
+ self._int = (0,)
+ self._is_special = True
+ if _isinfinity(value) == 1:
+ self._sign = 0
+ else:
+ self._sign = 1
+ return self
+ if _isnan(value):
+ sig, sign, diag = _isnan(value)
+ self._is_special = True
+ if len(diag) > context.prec: #Diagnostic info too long
+ self._sign, self._int, self._exp = \
+ context._raise_error(ConversionSyntax)
+ return self
+ if sig == 1:
+ self._exp = 'n' #qNaN
+ else: #sig == 2
+ self._exp = 'N' #sNaN
+ self._sign = sign
+ self._int = tuple(map(int, diag)) #Diagnostic info
+ return self
+ try:
+ self._sign, self._int, self._exp = _string2exact(value)
+ except ValueError:
+ self._is_special = True
+ self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
+ return self
+
+ raise TypeError("Cannot convert %r to Decimal" % value)
+
+ def _isnan(self):
+ """Returns whether the number is not actually one.
+
+ 0 if a number
+ 1 if NaN
+ 2 if sNaN
+ """
+ if self._is_special:
+ exp = self._exp
+ if exp == 'n':
+ return 1
+ elif exp == 'N':
+ return 2
+ return 0
+
+ def _isinfinity(self):
+ """Returns whether the number is infinite
+
+ 0 if finite or not a number
+ 1 if +INF
+ -1 if -INF
+ """
+ if self._exp == 'F':
+ if self._sign:
+ return -1
+ return 1
+ return 0
+
+ def _check_nans(self, other = None, context=None):
+ """Returns whether the number is not actually one.
+
+ if self, other are sNaN, signal
+ if self, other are NaN return nan
+ return 0
+
+ Done before operations.
+ """
+
+ self_is_nan = self._isnan()
+ if other is None:
+ other_is_nan = False
+ else:
+ other_is_nan = other._isnan()
+
+ if self_is_nan or other_is_nan:
+ if context is None:
+ context = getcontext()
+
+ if self_is_nan == 2:
+ return context._raise_error(InvalidOperation, 'sNaN',
+ 1, self)
+ if other_is_nan == 2:
+ return context._raise_error(InvalidOperation, 'sNaN',
+ 1, other)
+ if self_is_nan:
+ return self
+
+ return other
+ return 0
+
+ def __nonzero__(self):
+ """Is the number non-zero?
+
+ 0 if self == 0
+ 1 if self != 0
+ """
+ if self._is_special:
+ return 1
+ return sum(self._int) != 0
+
+ def __cmp__(self, other, context=None):
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ return 1 # Comparison involving NaN's always reports self > other
+
+ # INF = INF
+ return cmp(self._isinfinity(), other._isinfinity())
+
+ if not self and not other:
+ return 0 #If both 0, sign comparison isn't certain.
+
+ #If different signs, neg one is less
+ if other._sign < self._sign:
+ return -1
+ if self._sign < other._sign:
+ return 1
+
+ self_adjusted = self.adjusted()
+ other_adjusted = other.adjusted()
+ if self_adjusted == other_adjusted and \
+ self._int + (0,)*(self._exp - other._exp) == \
+ other._int + (0,)*(other._exp - self._exp):
+ return 0 #equal, except in precision. ([0]*(-x) = [])
+ elif self_adjusted > other_adjusted and self._int[0] != 0:
+ return (-1)**self._sign
+ elif self_adjusted < other_adjusted and other._int[0] != 0:
+ return -((-1)**self._sign)
+
+ # Need to round, so make sure we have a valid context
+ if context is None:
+ context = getcontext()
+
+ context = context._shallow_copy()
+ rounding = context._set_rounding(ROUND_UP) #round away from 0
+
+ flags = context._ignore_all_flags()
+ res = self.__sub__(other, context=context)
+
+ context._regard_flags(*flags)
+
+ context.rounding = rounding
+
+ if not res:
+ return 0
+ elif res._sign:
+ return -1
+ return 1
+
+ def __eq__(self, other):
+ if not isinstance(other, (Decimal, int, long)):
+ return NotImplemented
+ return self.__cmp__(other) == 0
+
+ def __ne__(self, other):
+ if not isinstance(other, (Decimal, int, long)):
+ return NotImplemented
+ return self.__cmp__(other) != 0
+
+ def compare(self, other, context=None):
+ """Compares one to another.
+
+ -1 => a < b
+ 0 => a = b
+ 1 => a > b
+ NaN => one is NaN
+ Like __cmp__, but returns Decimal instances.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ #compare(NaN, NaN) = NaN
+ if (self._is_special or other and other._is_special):
+ ans = self._check_nans(other, context)
+ if ans:
+ return ans
+
+ return Decimal(self.__cmp__(other, context))
+
+ def __hash__(self):
+ """x.__hash__() <==> hash(x)"""
+ # Decimal integers must hash the same as the ints
+ # Non-integer decimals are normalized and hashed as strings
+ # Normalization assures that hast(100E-1) == hash(10)
+ if self._is_special:
+ if self._isnan():
+ raise TypeError('Cannot hash a NaN value.')
+ return hash(str(self))
+ i = int(self)
+ if self == Decimal(i):
+ return hash(i)
+ assert self.__nonzero__() # '-0' handled by integer case
+ return hash(str(self.normalize()))
+
+ def as_tuple(self):
+ """Represents the number as a triple tuple.
+
+ To show the internals exactly as they are.
+ """
+ return (self._sign, self._int, self._exp)
+
+ def __repr__(self):
+ """Represents the number as an instance of Decimal."""
+ # Invariant: eval(repr(d)) == d
+ return 'Decimal("%s")' % str(self)
+
+ def __str__(self, eng = 0, context=None):
+ """Return string representation of the number in scientific notation.
+
+ Captures all of the information in the underlying representation.
+ """
+
+ if self._is_special:
+ if self._isnan():
+ minus = '-'*self._sign
+ if self._int == (0,):
+ info = ''
+ else:
+ info = ''.join(map(str, self._int))
+ if self._isnan() == 2:
+ return minus + 'sNaN' + info
+ return minus + 'NaN' + info
+ if self._isinfinity():
+ minus = '-'*self._sign
+ return minus + 'Infinity'
+
+ if context is None:
+ context = getcontext()
+
+ tmp = map(str, self._int)
+ numdigits = len(self._int)
+ leftdigits = self._exp + numdigits
+ if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
+ if self._exp < 0 and self._exp >= -6: #short, no need for e/E
+ s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
+ return s
+ #exp is closest mult. of 3 >= self._exp
+ exp = ((self._exp - 1)// 3 + 1) * 3
+ if exp != self._exp:
+ s = '0.'+'0'*(exp - self._exp)
+ else:
+ s = '0'
+ if exp != 0:
+ if context.capitals:
+ s += 'E'
+ else:
+ s += 'e'
+ if exp > 0:
+ s += '+' #0.0e+3, not 0.0e3
+ s += str(exp)
+ s = '-'*self._sign + s
+ return s
+ if eng:
+ dotplace = (leftdigits-1)%3+1
+ adjexp = leftdigits -1 - (leftdigits-1)%3
+ else:
+ adjexp = leftdigits-1
+ dotplace = 1
+ if self._exp == 0:
+ pass
+ elif self._exp < 0 and adjexp >= 0:
+ tmp.insert(leftdigits, '.')
+ elif self._exp < 0 and adjexp >= -6:
+ tmp[0:0] = ['0'] * int(-leftdigits)
+ tmp.insert(0, '0.')
+ else:
+ if numdigits > dotplace:
+ tmp.insert(dotplace, '.')
+ elif numdigits < dotplace:
+ tmp.extend(['0']*(dotplace-numdigits))
+ if adjexp:
+ if not context.capitals:
+ tmp.append('e')
+ else:
+ tmp.append('E')
+ if adjexp > 0:
+ tmp.append('+')
+ tmp.append(str(adjexp))
+ if eng:
+ while tmp[0:1] == ['0']:
+ tmp[0:1] = []
+ if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
+ tmp[0:0] = ['0']
+ if self._sign:
+ tmp.insert(0, '-')
+
+ return ''.join(tmp)
+
+ def to_eng_string(self, context=None):
+ """Convert to engineering-type string.
+
+ Engineering notation has an exponent which is a multiple of 3, so there
+ are up to 3 digits left of the decimal place.
+
+ Same rules for when in exponential and when as a value as in __str__.
+ """
+ return self.__str__(eng=1, context=context)
+
+ def __neg__(self, context=None):
+ """Returns a copy with the sign switched.
+
+ Rounds, if it has reason.
+ """
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ if not self:
+ # -Decimal('0') is Decimal('0'), not Decimal('-0')
+ sign = 0
+ elif self._sign:
+ sign = 0
+ else:
+ sign = 1
+
+ if context is None:
+ context = getcontext()
+ if context._rounding_decision == ALWAYS_ROUND:
+ return Decimal((sign, self._int, self._exp))._fix(context)
+ return Decimal( (sign, self._int, self._exp))
+
+ def __pos__(self, context=None):
+ """Returns a copy, unless it is a sNaN.
+
+ Rounds the number (if more then precision digits)
+ """
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ sign = self._sign
+ if not self:
+ # + (-0) = 0
+ sign = 0
+
+ if context is None:
+ context = getcontext()
+
+ if context._rounding_decision == ALWAYS_ROUND:
+ ans = self._fix(context)
+ else:
+ ans = Decimal(self)
+ ans._sign = sign
+ return ans
+
+ def __abs__(self, round=1, context=None):
+ """Returns the absolute value of self.
+
+ If the second argument is 0, do not round.
+ """
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ if not round:
+ if context is None:
+ context = getcontext()
+ context = context._shallow_copy()
+ context._set_rounding_decision(NEVER_ROUND)
+
+ if self._sign:
+ ans = self.__neg__(context=context)
+ else:
+ ans = self.__pos__(context=context)
+
+ return ans
+
+ def __add__(self, other, context=None):
+ """Returns self + other.
+
+ -INF + INF (or the reverse) cause InvalidOperation errors.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if context is None:
+ context = getcontext()
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ return ans
+
+ if self._isinfinity():
+ #If both INF, same sign => same as both, opposite => error.
+ if self._sign != other._sign and other._isinfinity():
+ return context._raise_error(InvalidOperation, '-INF + INF')
+ return Decimal(self)
+ if other._isinfinity():
+ return Decimal(other) #Can't both be infinity here
+
+ shouldround = context._rounding_decision == ALWAYS_ROUND
+
+ exp = min(self._exp, other._exp)
+ negativezero = 0
+ if context.rounding == ROUND_FLOOR and self._sign != other._sign:
+ #If the answer is 0, the sign should be negative, in this case.
+ negativezero = 1
+
+ if not self and not other:
+ sign = min(self._sign, other._sign)
+ if negativezero:
+ sign = 1
+ return Decimal( (sign, (0,), exp))
+ if not self:
+ exp = max(exp, other._exp - context.prec-1)
+ ans = other._rescale(exp, watchexp=0, context=context)
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+ if not other:
+ exp = max(exp, self._exp - context.prec-1)
+ ans = self._rescale(exp, watchexp=0, context=context)
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+
+ op1 = _WorkRep(self)
+ op2 = _WorkRep(other)
+ op1, op2 = _normalize(op1, op2, shouldround, context.prec)
+
+ result = _WorkRep()
+ if op1.sign != op2.sign:
+ # Equal and opposite
+ if op1.int == op2.int:
+ if exp < context.Etiny():
+ exp = context.Etiny()
+ context._raise_error(Clamped)
+ return Decimal((negativezero, (0,), exp))
+ if op1.int < op2.int:
+ op1, op2 = op2, op1
+ #OK, now abs(op1) > abs(op2)
+ if op1.sign == 1:
+ result.sign = 1
+ op1.sign, op2.sign = op2.sign, op1.sign
+ else:
+ result.sign = 0
+ #So we know the sign, and op1 > 0.
+ elif op1.sign == 1:
+ result.sign = 1
+ op1.sign, op2.sign = (0, 0)
+ else:
+ result.sign = 0
+ #Now, op1 > abs(op2) > 0
+
+ if op2.sign == 0:
+ result.int = op1.int + op2.int
+ else:
+ result.int = op1.int - op2.int
+
+ result.exp = op1.exp
+ ans = Decimal(result)
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+
+ __radd__ = __add__
+
+ def __sub__(self, other, context=None):
+ """Return self + (-other)"""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context=context)
+ if ans:
+ return ans
+
+ # -Decimal(0) = Decimal(0), which we don't want since
+ # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
+ # so we change the sign directly to a copy
+ tmp = Decimal(other)
+ tmp._sign = 1-tmp._sign
+
+ return self.__add__(tmp, context=context)
+
+ def __rsub__(self, other, context=None):
+ """Return other + (-self)"""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ tmp = Decimal(self)
+ tmp._sign = 1 - tmp._sign
+ return other.__add__(tmp, context=context)
+
+ def _increment(self, round=1, context=None):
+ """Special case of add, adding 1eExponent
+
+ Since it is common, (rounding, for example) this adds
+ (sign)*one E self._exp to the number more efficiently than add.
+
+ For example:
+ Decimal('5.624e10')._increment() == Decimal('5.625e10')
+ """
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ return Decimal(self) # Must be infinite, and incrementing makes no difference
+
+ L = list(self._int)
+ L[-1] += 1
+ spot = len(L)-1
+ while L[spot] == 10:
+ L[spot] = 0
+ if spot == 0:
+ L[0:0] = [1]
+ break
+ L[spot-1] += 1
+ spot -= 1
+ ans = Decimal((self._sign, L, self._exp))
+
+ if context is None:
+ context = getcontext()
+ if round and context._rounding_decision == ALWAYS_ROUND:
+ ans = ans._fix(context)
+ return ans
+
+ def __mul__(self, other, context=None):
+ """Return self * other.
+
+ (+-) INF * 0 (or its reverse) raise InvalidOperation.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if context is None:
+ context = getcontext()
+
+ resultsign = self._sign ^ other._sign
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ return ans
+
+ if self._isinfinity():
+ if not other:
+ return context._raise_error(InvalidOperation, '(+-)INF * 0')
+ return Infsign[resultsign]
+
+ if other._isinfinity():
+ if not self:
+ return context._raise_error(InvalidOperation, '0 * (+-)INF')
+ return Infsign[resultsign]
+
+ resultexp = self._exp + other._exp
+ shouldround = context._rounding_decision == ALWAYS_ROUND
+
+ # Special case for multiplying by zero
+ if not self or not other:
+ ans = Decimal((resultsign, (0,), resultexp))
+ if shouldround:
+ #Fixing in case the exponent is out of bounds
+ ans = ans._fix(context)
+ return ans
+
+ # Special case for multiplying by power of 10
+ if self._int == (1,):
+ ans = Decimal((resultsign, other._int, resultexp))
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+ if other._int == (1,):
+ ans = Decimal((resultsign, self._int, resultexp))
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+
+ op1 = _WorkRep(self)
+ op2 = _WorkRep(other)
+
+ ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
+ if shouldround:
+ ans = ans._fix(context)
+
+ return ans
+ __rmul__ = __mul__
+
+ def __div__(self, other, context=None):
+ """Return self / other."""
+ return self._divide(other, context=context)
+ __truediv__ = __div__
+
+ def _divide(self, other, divmod = 0, context=None):
+ """Return a / b, to context.prec precision.
+
+ divmod:
+ 0 => true division
+ 1 => (a //b, a%b)
+ 2 => a //b
+ 3 => a%b
+
+ Actually, if divmod is 2 or 3 a tuple is returned, but errors for
+ computing the other value are not raised.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ if divmod in (0, 1):
+ return NotImplemented
+ return (NotImplemented, NotImplemented)
+
+ if context is None:
+ context = getcontext()
+
+ sign = self._sign ^ other._sign
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ if divmod:
+ return (ans, ans)
+ return ans
+
+ if self._isinfinity() and other._isinfinity():
+ if divmod:
+ return (context._raise_error(InvalidOperation,
+ '(+-)INF // (+-)INF'),
+ context._raise_error(InvalidOperation,
+ '(+-)INF % (+-)INF'))
+ return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
+
+ if self._isinfinity():
+ if divmod == 1:
+ return (Infsign[sign],
+ context._raise_error(InvalidOperation, 'INF % x'))
+ elif divmod == 2:
+ return (Infsign[sign], NaN)
+ elif divmod == 3:
+ return (Infsign[sign],
+ context._raise_error(InvalidOperation, 'INF % x'))
+ return Infsign[sign]
+
+ if other._isinfinity():
+ if divmod:
+ return (Decimal((sign, (0,), 0)), Decimal(self))
+ context._raise_error(Clamped, 'Division by infinity')
+ return Decimal((sign, (0,), context.Etiny()))
+
+ # Special cases for zeroes
+ if not self and not other:
+ if divmod:
+ return context._raise_error(DivisionUndefined, '0 / 0', 1)
+ return context._raise_error(DivisionUndefined, '0 / 0')
+
+ if not self:
+ if divmod:
+ otherside = Decimal(self)
+ otherside._exp = min(self._exp, other._exp)
+ return (Decimal((sign, (0,), 0)), otherside)
+ exp = self._exp - other._exp
+ if exp < context.Etiny():
+ exp = context.Etiny()
+ context._raise_error(Clamped, '0e-x / y')
+ if exp > context.Emax:
+ exp = context.Emax
+ context._raise_error(Clamped, '0e+x / y')
+ return Decimal( (sign, (0,), exp) )
+
+ if not other:
+ if divmod:
+ return context._raise_error(DivisionByZero, 'divmod(x,0)',
+ sign, 1)
+ return context._raise_error(DivisionByZero, 'x / 0', sign)
+
+ #OK, so neither = 0, INF or NaN
+
+ shouldround = context._rounding_decision == ALWAYS_ROUND
+
+ #If we're dividing into ints, and self < other, stop.
+ #self.__abs__(0) does not round.
+ if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
+
+ if divmod == 1 or divmod == 3:
+ exp = min(self._exp, other._exp)
+ ans2 = self._rescale(exp, context=context, watchexp=0)
+ if shouldround:
+ ans2 = ans2._fix(context)
+ return (Decimal( (sign, (0,), 0) ),
+ ans2)
+
+ elif divmod == 2:
+ #Don't round the mod part, if we don't need it.
+ return (Decimal( (sign, (0,), 0) ), Decimal(self))
+
+ op1 = _WorkRep(self)
+ op2 = _WorkRep(other)
+ op1, op2, adjust = _adjust_coefficients(op1, op2)
+ res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
+ if divmod and res.exp > context.prec + 1:
+ return context._raise_error(DivisionImpossible)
+
+ prec_limit = 10 ** context.prec
+ while 1:
+ while op2.int <= op1.int:
+ res.int += 1
+ op1.int -= op2.int
+ if res.exp == 0 and divmod:
+ if res.int >= prec_limit and shouldround:
+ return context._raise_error(DivisionImpossible)
+ otherside = Decimal(op1)
+ frozen = context._ignore_all_flags()
+
+ exp = min(self._exp, other._exp)
+ otherside = otherside._rescale(exp, context=context, watchexp=0)
+ context._regard_flags(*frozen)
+ if shouldround:
+ otherside = otherside._fix(context)
+ return (Decimal(res), otherside)
+
+ if op1.int == 0 and adjust >= 0 and not divmod:
+ break
+ if res.int >= prec_limit and shouldround:
+ if divmod:
+ return context._raise_error(DivisionImpossible)
+ shouldround=1
+ # Really, the answer is a bit higher, so adding a one to
+ # the end will make sure the rounding is right.
+ if op1.int != 0:
+ res.int *= 10
+ res.int += 1
+ res.exp -= 1
+
+ break
+ res.int *= 10
+ res.exp -= 1
+ adjust += 1
+ op1.int *= 10
+ op1.exp -= 1
+
+ if res.exp == 0 and divmod and op2.int > op1.int:
+ #Solves an error in precision. Same as a previous block.
+
+ if res.int >= prec_limit and shouldround:
+ return context._raise_error(DivisionImpossible)
+ otherside = Decimal(op1)
+ frozen = context._ignore_all_flags()
+
+ exp = min(self._exp, other._exp)
+ otherside = otherside._rescale(exp, context=context)
+
+ context._regard_flags(*frozen)
+
+ return (Decimal(res), otherside)
+
+ ans = Decimal(res)
+ if shouldround:
+ ans = ans._fix(context)
+ return ans
+
+ def __rdiv__(self, other, context=None):
+ """Swaps self/other and returns __div__."""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+ return other.__div__(self, context=context)
+ __rtruediv__ = __rdiv__
+
+ def __divmod__(self, other, context=None):
+ """
+ (self // other, self % other)
+ """
+ return self._divide(other, 1, context)
+
+ def __rdivmod__(self, other, context=None):
+ """Swaps self/other and returns __divmod__."""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+ return other.__divmod__(self, context=context)
+
+ def __mod__(self, other, context=None):
+ """
+ self % other
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ return ans
+
+ if self and not other:
+ return context._raise_error(InvalidOperation, 'x % 0')
+
+ return self._divide(other, 3, context)[1]
+
+ def __rmod__(self, other, context=None):
+ """Swaps self/other and returns __mod__."""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+ return other.__mod__(self, context=context)
+
+ def remainder_near(self, other, context=None):
+ """
+ Remainder nearest to 0- abs(remainder-near) <= other/2
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ ans = self._check_nans(other, context)
+ if ans:
+ return ans
+ if self and not other:
+ return context._raise_error(InvalidOperation, 'x % 0')
+
+ if context is None:
+ context = getcontext()
+ # If DivisionImpossible causes an error, do not leave Rounded/Inexact
+ # ignored in the calling function.
+ context = context._shallow_copy()
+ flags = context._ignore_flags(Rounded, Inexact)
+ #keep DivisionImpossible flags
+ (side, r) = self.__divmod__(other, context=context)
+
+ if r._isnan():
+ context._regard_flags(*flags)
+ return r
+
+ context = context._shallow_copy()
+ rounding = context._set_rounding_decision(NEVER_ROUND)
+
+ if other._sign:
+ comparison = other.__div__(Decimal(-2), context=context)
+ else:
+ comparison = other.__div__(Decimal(2), context=context)
+
+ context._set_rounding_decision(rounding)
+ context._regard_flags(*flags)
+
+ s1, s2 = r._sign, comparison._sign
+ r._sign, comparison._sign = 0, 0
+
+ if r < comparison:
+ r._sign, comparison._sign = s1, s2
+ #Get flags now
+ self.__divmod__(other, context=context)
+ return r._fix(context)
+ r._sign, comparison._sign = s1, s2
+
+ rounding = context._set_rounding_decision(NEVER_ROUND)
+
+ (side, r) = self.__divmod__(other, context=context)
+ context._set_rounding_decision(rounding)
+ if r._isnan():
+ return r
+
+ decrease = not side._iseven()
+ rounding = context._set_rounding_decision(NEVER_ROUND)
+ side = side.__abs__(context=context)
+ context._set_rounding_decision(rounding)
+
+ s1, s2 = r._sign, comparison._sign
+ r._sign, comparison._sign = 0, 0
+ if r > comparison or decrease and r == comparison:
+ r._sign, comparison._sign = s1, s2
+ context.prec += 1
+ if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
+ context.prec -= 1
+ return context._raise_error(DivisionImpossible)[1]
+ context.prec -= 1
+ if self._sign == other._sign:
+ r = r.__sub__(other, context=context)
+ else:
+ r = r.__add__(other, context=context)
+ else:
+ r._sign, comparison._sign = s1, s2
+
+ return r._fix(context)
+
+ def __floordiv__(self, other, context=None):
+ """self // other"""
+ return self._divide(other, 2, context)[0]
+
+ def __rfloordiv__(self, other, context=None):
+ """Swaps self/other and returns __floordiv__."""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+ return other.__floordiv__(self, context=context)
+
+ def __float__(self):
+ """Float representation."""
+ return float(str(self))
+
+ def __int__(self):
+ """Converts self to an int, truncating if necessary."""
+ if self._is_special:
+ if self._isnan():
+ context = getcontext()
+ return context._raise_error(InvalidContext)
+ elif self._isinfinity():
+ raise OverflowError, "Cannot convert infinity to long"
+ if self._exp >= 0:
+ s = ''.join(map(str, self._int)) + '0'*self._exp
+ else:
+ s = ''.join(map(str, self._int))[:self._exp]
+ if s == '':
+ s = '0'
+ sign = '-'*self._sign
+ return int(sign + s)
+
+ def __long__(self):
+ """Converts to a long.
+
+ Equivalent to long(int(self))
+ """
+ return long(self.__int__())
+
+ def _fix(self, context):
+ """Round if it is necessary to keep self within prec precision.
+
+ Rounds and fixes the exponent. Does not raise on a sNaN.
+
+ Arguments:
+ self - Decimal instance
+ context - context used.
+ """
+ if self._is_special:
+ return self
+ if context is None:
+ context = getcontext()
+ prec = context.prec
+ ans = self._fixexponents(context)
+ if len(ans._int) > prec:
+ ans = ans._round(prec, context=context)
+ ans = ans._fixexponents(context)
+ return ans
+
+ def _fixexponents(self, context):
+ """Fix the exponents and return a copy with the exponent in bounds.
+ Only call if known to not be a special value.
+ """
+ folddown = context._clamp
+ Emin = context.Emin
+ ans = self
+ ans_adjusted = ans.adjusted()
+ if ans_adjusted < Emin:
+ Etiny = context.Etiny()
+ if ans._exp < Etiny:
+ if not ans:
+ ans = Decimal(self)
+ ans._exp = Etiny
+ context._raise_error(Clamped)
+ return ans
+ ans = ans._rescale(Etiny, context=context)
+ #It isn't zero, and exp < Emin => subnormal
+ context._raise_error(Subnormal)
+ if context.flags[Inexact]:
+ context._raise_error(Underflow)
+ else:
+ if ans:
+ #Only raise subnormal if non-zero.
+ context._raise_error(Subnormal)
+ else:
+ Etop = context.Etop()
+ if folddown and ans._exp > Etop:
+ context._raise_error(Clamped)
+ ans = ans._rescale(Etop, context=context)
+ else:
+ Emax = context.Emax
+ if ans_adjusted > Emax:
+ if not ans:
+ ans = Decimal(self)
+ ans._exp = Emax
+ context._raise_error(Clamped)
+ return ans
+ context._raise_error(Inexact)
+ context._raise_error(Rounded)
+ return context._raise_error(Overflow, 'above Emax', ans._sign)
+ return ans
+
+ def _round(self, prec=None, rounding=None, context=None):
+ """Returns a rounded version of self.
+
+ You can specify the precision or rounding method. Otherwise, the
+ context determines it.
+ """
+
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ if self._isinfinity():
+ return Decimal(self)
+
+ if context is None:
+ context = getcontext()
+
+ if rounding is None:
+ rounding = context.rounding
+ if prec is None:
+ prec = context.prec
+
+ if not self:
+ if prec <= 0:
+ dig = (0,)
+ exp = len(self._int) - prec + self._exp
+ else:
+ dig = (0,) * prec
+ exp = len(self._int) + self._exp - prec
+ ans = Decimal((self._sign, dig, exp))
+ context._raise_error(Rounded)
+ return ans
+
+ if prec == 0:
+ temp = Decimal(self)
+ temp._int = (0,)+temp._int
+ prec = 1
+ elif prec < 0:
+ exp = self._exp + len(self._int) - prec - 1
+ temp = Decimal( (self._sign, (0, 1), exp))
+ prec = 1
+ else:
+ temp = Decimal(self)
+
+ numdigits = len(temp._int)
+ if prec == numdigits:
+ return temp
+
+ # See if we need to extend precision
+ expdiff = prec - numdigits
+ if expdiff > 0:
+ tmp = list(temp._int)
+ tmp.extend([0] * expdiff)
+ ans = Decimal( (temp._sign, tmp, temp._exp - expdiff))
+ return ans
+
+ #OK, but maybe all the lost digits are 0.
+ lostdigits = self._int[expdiff:]
+ if lostdigits == (0,) * len(lostdigits):
+ ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
+ #Rounded, but not Inexact
+ context._raise_error(Rounded)
+ return ans
+
+ # Okay, let's round and lose data
+
+ this_function = getattr(temp, self._pick_rounding_function[rounding])
+ #Now we've got the rounding function
+
+ if prec != context.prec:
+ context = context._shallow_copy()
+ context.prec = prec
+ ans = this_function(prec, expdiff, context)
+ context._raise_error(Rounded)
+ context._raise_error(Inexact, 'Changed in rounding')
+
+ return ans
+
+ _pick_rounding_function = {}
+
+ def _round_down(self, prec, expdiff, context):
+ """Also known as round-towards-0, truncate."""
+ return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+
+ def _round_half_up(self, prec, expdiff, context, tmp = None):
+ """Rounds 5 up (away from 0)"""
+
+ if tmp is None:
+ tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
+ if self._int[prec] >= 5:
+ tmp = tmp._increment(round=0, context=context)
+ if len(tmp._int) > prec:
+ return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+ return tmp
+
+ def _round_half_even(self, prec, expdiff, context):
+ """Round 5 to even, rest to nearest."""
+
+ tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+ half = (self._int[prec] == 5)
+ if half:
+ for digit in self._int[prec+1:]:
+ if digit != 0:
+ half = 0
+ break
+ if half:
+ if self._int[prec-1] & 1 == 0:
+ return tmp
+ return self._round_half_up(prec, expdiff, context, tmp)
+
+ def _round_half_down(self, prec, expdiff, context):
+ """Round 5 down"""
+
+ tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
+ half = (self._int[prec] == 5)
+ if half:
+ for digit in self._int[prec+1:]:
+ if digit != 0:
+ half = 0
+ break
+ if half:
+ return tmp
+ return self._round_half_up(prec, expdiff, context, tmp)
+
+ def _round_up(self, prec, expdiff, context):
+ """Rounds away from 0."""
+ tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
+ for digit in self._int[prec:]:
+ if digit != 0:
+ tmp = tmp._increment(round=1, context=context)
+ if len(tmp._int) > prec:
+ return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
+ else:
+ return tmp
+ return tmp
+
+ def _round_ceiling(self, prec, expdiff, context):
+ """Rounds up (not away from 0 if negative.)"""
+ if self._sign:
+ return self._round_down(prec, expdiff, context)
+ else:
+ return self._round_up(prec, expdiff, context)
+
+ def _round_floor(self, prec, expdiff, context):
+ """Rounds down (not towards 0 if negative)"""
+ if not self._sign:
+ return self._round_down(prec, expdiff, context)
+ else:
+ return self._round_up(prec, expdiff, context)
+
+ def __pow__(self, n, modulo = None, context=None):
+ """Return self ** n (mod modulo)
+
+ If modulo is None (default), don't take it mod modulo.
+ """
+ n = _convert_other(n)
+ if n is NotImplemented:
+ return n
+
+ if context is None:
+ context = getcontext()
+
+ if self._is_special or n._is_special or n.adjusted() > 8:
+ #Because the spot << doesn't work with really big exponents
+ if n._isinfinity() or n.adjusted() > 8:
+ return context._raise_error(InvalidOperation, 'x ** INF')
+
+ ans = self._check_nans(n, context)
+ if ans:
+ return ans
+
+ if not n._isinteger():
+ return context._raise_error(InvalidOperation, 'x ** (non-integer)')
+
+ if not self and not n:
+ return context._raise_error(InvalidOperation, '0 ** 0')
+
+ if not n:
+ return Decimal(1)
+
+ if self == Decimal(1):
+ return Decimal(1)
+
+ sign = self._sign and not n._iseven()
+ n = int(n)
+
+ if self._isinfinity():
+ if modulo:
+ return context._raise_error(InvalidOperation, 'INF % x')
+ if n > 0:
+ return Infsign[sign]
+ return Decimal( (sign, (0,), 0) )
+
+ #with ludicrously large exponent, just raise an overflow and return inf.
+ if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
+ and self:
+
+ tmp = Decimal('inf')
+ tmp._sign = sign
+ context._raise_error(Rounded)
+ context._raise_error(Inexact)
+ context._raise_error(Overflow, 'Big power', sign)
+ return tmp
+
+ elength = len(str(abs(n)))
+ firstprec = context.prec
+
+ if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
+ return context._raise_error(Overflow, 'Too much precision.', sign)
+
+ mul = Decimal(self)
+ val = Decimal(1)
+ context = context._shallow_copy()
+ context.prec = firstprec + elength + 1
+ if n < 0:
+ #n is a long now, not Decimal instance
+ n = -n
+ mul = Decimal(1).__div__(mul, context=context)
+
+ spot = 1
+ while spot <= n:
+ spot <<= 1
+
+ spot >>= 1
+ #Spot is the highest power of 2 less than n
+ while spot:
+ val = val.__mul__(val, context=context)
+ if val._isinfinity():
+ val = Infsign[sign]
+ break
+ if spot & n:
+ val = val.__mul__(mul, context=context)
+ if modulo is not None:
+ val = val.__mod__(modulo, context=context)
+ spot >>= 1
+ context.prec = firstprec
+
+ if context._rounding_decision == ALWAYS_ROUND:
+ return val._fix(context)
+ return val
+
+ def __rpow__(self, other, context=None):
+ """Swaps self/other and returns __pow__."""
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+ return other.__pow__(self, context=context)
+
+ def normalize(self, context=None):
+ """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
+
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ dup = self._fix(context)
+ if dup._isinfinity():
+ return dup
+
+ if not dup:
+ return Decimal( (dup._sign, (0,), 0) )
+ end = len(dup._int)
+ exp = dup._exp
+ while dup._int[end-1] == 0:
+ exp += 1
+ end -= 1
+ return Decimal( (dup._sign, dup._int[:end], exp) )
+
+
+ def quantize(self, exp, rounding=None, context=None, watchexp=1):
+ """Quantize self so its exponent is the same as that of exp.
+
+ Similar to self._rescale(exp._exp) but with error checking.
+ """
+ if self._is_special or exp._is_special:
+ ans = self._check_nans(exp, context)
+ if ans:
+ return ans
+
+ if exp._isinfinity() or self._isinfinity():
+ if exp._isinfinity() and self._isinfinity():
+ return self #if both are inf, it is OK
+ if context is None:
+ context = getcontext()
+ return context._raise_error(InvalidOperation,
+ 'quantize with one INF')
+ return self._rescale(exp._exp, rounding, context, watchexp)
+
+ def same_quantum(self, other):
+ """Test whether self and other have the same exponent.
+
+ same as self._exp == other._exp, except NaN == sNaN
+ """
+ if self._is_special or other._is_special:
+ if self._isnan() or other._isnan():
+ return self._isnan() and other._isnan() and True
+ if self._isinfinity() or other._isinfinity():
+ return self._isinfinity() and other._isinfinity() and True
+ return self._exp == other._exp
+
+ def _rescale(self, exp, rounding=None, context=None, watchexp=1):
+ """Rescales so that the exponent is exp.
+
+ exp = exp to scale to (an integer)
+ rounding = rounding version
+ watchexp: if set (default) an error is returned if exp is greater
+ than Emax or less than Etiny.
+ """
+ if context is None:
+ context = getcontext()
+
+ if self._is_special:
+ if self._isinfinity():
+ return context._raise_error(InvalidOperation, 'rescale with an INF')
+
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ if watchexp and (context.Emax < exp or context.Etiny() > exp):
+ return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+
+ if not self:
+ ans = Decimal(self)
+ ans._int = (0,)
+ ans._exp = exp
+ return ans
+
+ diff = self._exp - exp
+ digits = len(self._int) + diff
+
+ if watchexp and digits > context.prec:
+ return context._raise_error(InvalidOperation, 'Rescale > prec')
+
+ tmp = Decimal(self)
+ tmp._int = (0,) + tmp._int
+ digits += 1
+
+ if digits < 0:
+ tmp._exp = -digits + tmp._exp
+ tmp._int = (0,1)
+ digits = 1
+ tmp = tmp._round(digits, rounding, context=context)
+
+ if tmp._int[0] == 0 and len(tmp._int) > 1:
+ tmp._int = tmp._int[1:]
+ tmp._exp = exp
+
+ tmp_adjusted = tmp.adjusted()
+ if tmp and tmp_adjusted < context.Emin:
+ context._raise_error(Subnormal)
+ elif tmp and tmp_adjusted > context.Emax:
+ return context._raise_error(InvalidOperation, 'rescale(a, INF)')
+ return tmp
+
+ def to_integral(self, rounding=None, context=None):
+ """Rounds to the nearest integer, without raising inexact, rounded."""
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+ if self._exp >= 0:
+ return self
+ if context is None:
+ context = getcontext()
+ flags = context._ignore_flags(Rounded, Inexact)
+ ans = self._rescale(0, rounding, context=context)
+ context._regard_flags(flags)
+ return ans
+
+ def sqrt(self, context=None):
+ """Return the square root of self.
+
+ Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
+ Should quadratically approach the right answer.
+ """
+ if self._is_special:
+ ans = self._check_nans(context=context)
+ if ans:
+ return ans
+
+ if self._isinfinity() and self._sign == 0:
+ return Decimal(self)
+
+ if not self:
+ #exponent = self._exp / 2, using round_down.
+ #if self._exp < 0:
+ # exp = (self._exp+1) // 2
+ #else:
+ exp = (self._exp) // 2
+ if self._sign == 1:
+ #sqrt(-0) = -0
+ return Decimal( (1, (0,), exp))
+ else:
+ return Decimal( (0, (0,), exp))
+
+ if context is None:
+ context = getcontext()
+
+ if self._sign == 1:
+ return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
+
+ tmp = Decimal(self)
+
+ expadd = tmp._exp // 2
+ if tmp._exp & 1:
+ tmp._int += (0,)
+ tmp._exp = 0
+ else:
+ tmp._exp = 0
+
+ context = context._shallow_copy()
+ flags = context._ignore_all_flags()
+ firstprec = context.prec
+ context.prec = 3
+ if tmp.adjusted() & 1 == 0:
+ ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) )
+ ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
+ context=context), context=context)
+ ans._exp -= 1 + tmp.adjusted() // 2
+ else:
+ ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
+ ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
+ context=context), context=context)
+ ans._exp -= 1 + tmp.adjusted() // 2
+
+ #ans is now a linear approximation.
+
+ Emax, Emin = context.Emax, context.Emin
+ context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
+
+ half = Decimal('0.5')
+
+ maxp = firstprec + 2
+ rounding = context._set_rounding(ROUND_HALF_EVEN)
+ while 1:
+ context.prec = min(2*context.prec - 2, maxp)
+ ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
+ context=context), context=context)
+ if context.prec == maxp:
+ break
+
+ #round to the answer's precision-- the only error can be 1 ulp.
+ context.prec = firstprec
+ prevexp = ans.adjusted()
+ ans = ans._round(context=context)
+
+ #Now, check if the other last digits are better.
+ context.prec = firstprec + 1
+ # In case we rounded up another digit and we should actually go lower.
+ if prevexp != ans.adjusted():
+ ans._int += (0,)
+ ans._exp -= 1
+
+
+ lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
+ context._set_rounding(ROUND_UP)
+ if lower.__mul__(lower, context=context) > (tmp):
+ ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
+
+ else:
+ upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
+ context._set_rounding(ROUND_DOWN)
+ if upper.__mul__(upper, context=context) < tmp:
+ ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
+
+ ans._exp += expadd
+
+ context.prec = firstprec
+ context.rounding = rounding
+ ans = ans._fix(context)
+
+ rounding = context._set_rounding_decision(NEVER_ROUND)
+ if not ans.__mul__(ans, context=context) == self:
+ # Only rounded/inexact if here.
+ context._regard_flags(flags)
+ context._raise_error(Rounded)
+ context._raise_error(Inexact)
+ else:
+ #Exact answer, so let's set the exponent right.
+ #if self._exp < 0:
+ # exp = (self._exp +1)// 2
+ #else:
+ exp = self._exp // 2
+ context.prec += ans._exp - exp
+ ans = ans._rescale(exp, context=context)
+ context.prec = firstprec
+ context._regard_flags(flags)
+ context.Emax, context.Emin = Emax, Emin
+
+ return ans._fix(context)
+
+ def max(self, other, context=None):
+ """Returns the larger value.
+
+ like max(self, other) except if one is not a number, returns
+ NaN (and signals if one is sNaN). Also rounds.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ # if one operand is a quiet NaN and the other is number, then the
+ # number is always returned
+ sn = self._isnan()
+ on = other._isnan()
+ if sn or on:
+ if on == 1 and sn != 2:
+ return self
+ if sn == 1 and on != 2:
+ return other
+ return self._check_nans(other, context)
+
+ ans = self
+ c = self.__cmp__(other)
+ if c == 0:
+ # if both operands are finite and equal in numerical value
+ # then an ordering is applied:
+ #
+ # if the signs differ then max returns the operand with the
+ # positive sign and min returns the operand with the negative sign
+ #
+ # if the signs are the same then the exponent is used to select
+ # the result.
+ if self._sign != other._sign:
+ if self._sign:
+ ans = other
+ elif self._exp < other._exp and not self._sign:
+ ans = other
+ elif self._exp > other._exp and self._sign:
+ ans = other
+ elif c == -1:
+ ans = other
+
+ if context is None:
+ context = getcontext()
+ if context._rounding_decision == ALWAYS_ROUND:
+ return ans._fix(context)
+ return ans
+
+ def min(self, other, context=None):
+ """Returns the smaller value.
+
+ like min(self, other) except if one is not a number, returns
+ NaN (and signals if one is sNaN). Also rounds.
+ """
+ other = _convert_other(other)
+ if other is NotImplemented:
+ return other
+
+ if self._is_special or other._is_special:
+ # if one operand is a quiet NaN and the other is number, then the
+ # number is always returned
+ sn = self._isnan()
+ on = other._isnan()
+ if sn or on:
+ if on == 1 and sn != 2:
+ return self
+ if sn == 1 and on != 2:
+ return other
+ return self._check_nans(other, context)
+
+ ans = self
+ c = self.__cmp__(other)
+ if c == 0:
+ # if both operands are finite and equal in numerical value
+ # then an ordering is applied:
+ #
+ # if the signs differ then max returns the operand with the
+ # positive sign and min returns the operand with the negative sign
+ #
+ # if the signs are the same then the exponent is used to select
+ # the result.
+ if self._sign != other._sign:
+ if other._sign:
+ ans = other
+ elif self._exp > other._exp and not self._sign:
+ ans = other
+ elif self._exp < other._exp and self._sign:
+ ans = other
+ elif c == 1:
+ ans = other
+
+ if context is None:
+ context = getcontext()
+ if context._rounding_decision == ALWAYS_ROUND:
+ return ans._fix(context)
+ return ans
+
+ def _isinteger(self):
+ """Returns whether self is an integer"""
+ if self._exp >= 0:
+ return True
+ rest = self._int[self._exp:]
+ return rest == (0,)*len(rest)
+
+ def _iseven(self):
+ """Returns 1 if self is even. Assumes self is an integer."""
+ if self._exp > 0:
+ return 1
+ return self._int[-1+self._exp] & 1 == 0
+
+ def adjusted(self):
+ """Return the adjusted exponent of self"""
+ try:
+ return self._exp + len(self._int) - 1
+ #If NaN or Infinity, self._exp is string
+ except TypeError:
+ return 0
+
+ # support for pickling, copy, and deepcopy
+ def __reduce__(self):
+ return (self.__class__, (str(self),))
+
+ def __copy__(self):
+ if type(self) == Decimal:
+ return self # I'm immutable; therefore I am my own clone
+ return self.__class__(str(self))
+
+ def __deepcopy__(self, memo):
+ if type(self) == Decimal:
+ return self # My components are also immutable
+ return self.__class__(str(self))
+
+##### Context class ###########################################
+
+
+# get rounding method function:
+rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
+for name in rounding_functions:
+ #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
+ globalname = name[1:].upper()
+ val = globals()[globalname]
+ Decimal._pick_rounding_function[val] = name
+
+del name, val, globalname, rounding_functions
+
+class Context(object):
+ """Contains the context for a Decimal instance.
+
+ Contains:
+ prec - precision (for use in rounding, division, square roots..)
+ rounding - rounding type. (how you round)
+ _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
+ traps - If traps[exception] = 1, then the exception is
+ raised when it is caused. Otherwise, a value is
+ substituted in.
+ flags - When an exception is caused, flags[exception] is incremented.
+ (Whether or not the trap_enabler is set)
+ Should be reset by user of Decimal instance.
+ Emin - Minimum exponent
+ Emax - Maximum exponent
+ capitals - If 1, 1*10^1 is printed as 1E+1.
+ If 0, printed as 1e1
+ _clamp - If 1, change exponents if too high (Default 0)
+ """
+
+ def __init__(self, prec=None, rounding=None,
+ traps=None, flags=None,
+ _rounding_decision=None,
+ Emin=None, Emax=None,
+ capitals=None, _clamp=0,
+ _ignored_flags=None):
+ if flags is None:
+ flags = []
+ if _ignored_flags is None:
+ _ignored_flags = []
+ if not isinstance(flags, dict):
+ flags = dict([(s,s in flags) for s in _signals])
+ del s
+ if traps is not None and not isinstance(traps, dict):
+ traps = dict([(s,s in traps) for s in _signals])
+ del s
+ for name, val in locals().items():
+ if val is None:
+ setattr(self, name, _copy.copy(getattr(DefaultContext, name)))
+ else:
+ setattr(self, name, val)
+ del self.self
+
+ def __repr__(self):
+ """Show the current context."""
+ s = []
+ s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
+ s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
+ s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
+ return ', '.join(s) + ')'
+
+ def clear_flags(self):
+ """Reset all flags to zero"""
+ for flag in self.flags:
+ self.flags[flag] = 0
+
+ def _shallow_copy(self):
+ """Returns a shallow copy from self."""
+ nc = Context(self.prec, self.rounding, self.traps, self.flags,
+ self._rounding_decision, self.Emin, self.Emax,
+ self.capitals, self._clamp, self._ignored_flags)
+ return nc
+
+ def copy(self):
+ """Returns a deep copy from self."""
+ nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
+ self._rounding_decision, self.Emin, self.Emax,
+ self.capitals, self._clamp, self._ignored_flags)
+ return nc
+ __copy__ = copy
+
+ def _raise_error(self, condition, explanation = None, *args):
+ """Handles an error
+
+ If the flag is in _ignored_flags, returns the default response.
+ Otherwise, it increments the flag, then, if the corresponding
+ trap_enabler is set, it reaises the exception. Otherwise, it returns
+ the default value after incrementing the flag.
+ """
+ error = _condition_map.get(condition, condition)
+ if error in self._ignored_flags:
+ #Don't touch the flag
+ return error().handle(self, *args)
+
+ self.flags[error] += 1
+ if not self.traps[error]:
+ #The errors define how to handle themselves.
+ return condition().handle(self, *args)
+
+ # Errors should only be risked on copies of the context
+ #self._ignored_flags = []
+ raise error, explanation
+
+ def _ignore_all_flags(self):
+ """Ignore all flags, if they are raised"""
+ return self._ignore_flags(*_signals)
+
+ def _ignore_flags(self, *flags):
+ """Ignore the flags, if they are raised"""
+ # Do not mutate-- This way, copies of a context leave the original
+ # alone.
+ self._ignored_flags = (self._ignored_flags + list(flags))
+ return list(flags)
+
+ def _regard_flags(self, *flags):
+ """Stop ignoring the flags, if they are raised"""
+ if flags and isinstance(flags[0], (tuple,list)):
+ flags = flags[0]
+ for flag in flags:
+ self._ignored_flags.remove(flag)
+
+ def __hash__(self):
+ """A Context cannot be hashed."""
+ # We inherit object.__hash__, so we must deny this explicitly
+ raise TypeError, "Cannot hash a Context."
+
+ def Etiny(self):
+ """Returns Etiny (= Emin - prec + 1)"""
+ return int(self.Emin - self.prec + 1)
+
+ def Etop(self):
+ """Returns maximum exponent (= Emax - prec + 1)"""
+ return int(self.Emax - self.prec + 1)
+
+ def _set_rounding_decision(self, type):
+ """Sets the rounding decision.
+
+ Sets the rounding decision, and returns the current (previous)
+ rounding decision. Often used like:
+
+ context = context._shallow_copy()
+ # That so you don't change the calling context
+ # if an error occurs in the middle (say DivisionImpossible is raised).
+
+ rounding = context._set_rounding_decision(NEVER_ROUND)
+ instance = instance / Decimal(2)
+ context._set_rounding_decision(rounding)
+
+ This will make it not round for that operation.
+ """
+
+ rounding = self._rounding_decision
+ self._rounding_decision = type
+ return rounding
+
+ def _set_rounding(self, type):
+ """Sets the rounding type.
+
+ Sets the rounding type, and returns the current (previous)
+ rounding type. Often used like:
+
+ context = context.copy()
+ # so you don't change the calling context
+ # if an error occurs in the middle.
+ rounding = context._set_rounding(ROUND_UP)
+ val = self.__sub__(other, context=context)
+ context._set_rounding(rounding)
+
+ This will make it round up for that operation.
+ """
+ rounding = self.rounding
+ self.rounding= type
+ return rounding
+
+ def create_decimal(self, num='0'):
+ """Creates a new Decimal instance but using self as context."""
+ d = Decimal(num, context=self)
+ return d._fix(self)
+
+ #Methods
+ def abs(self, a):
+ """Returns the absolute value of the operand.
+
+ If the operand is negative, the result is the same as using the minus
+ operation on the operand. Otherwise, the result is the same as using
+ the plus operation on the operand.
+
+ >>> ExtendedContext.abs(Decimal('2.1'))
+ Decimal("2.1")
+ >>> ExtendedContext.abs(Decimal('-100'))
+ Decimal("100")
+ >>> ExtendedContext.abs(Decimal('101.5'))
+ Decimal("101.5")
+ >>> ExtendedContext.abs(Decimal('-101.5'))
+ Decimal("101.5")
+ """
+ return a.__abs__(context=self)
+
+ def add(self, a, b):
+ """Return the sum of the two operands.
+
+ >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
+ Decimal("19.00")
+ >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
+ Decimal("1.02E+4")
+ """
+ return a.__add__(b, context=self)
+
+ def _apply(self, a):
+ return str(a._fix(self))
+
+ def compare(self, a, b):
+ """Compares values numerically.
+
+ If the signs of the operands differ, a value representing each operand
+ ('-1' if the operand is less than zero, '0' if the operand is zero or
+ negative zero, or '1' if the operand is greater than zero) is used in
+ place of that operand for the comparison instead of the actual
+ operand.
+
+ The comparison is then effected by subtracting the second operand from
+ the first and then returning a value according to the result of the
+ subtraction: '-1' if the result is less than zero, '0' if the result is
+ zero or negative zero, or '1' if the result is greater than zero.
+
+ >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
+ Decimal("-1")
+ >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
+ Decimal("0")
+ >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
+ Decimal("0")
+ >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
+ Decimal("1")
+ >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
+ Decimal("1")
+ >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
+ Decimal("-1")
+ """
+ return a.compare(b, context=self)
+
+ def divide(self, a, b):
+ """Decimal division in a specified context.
+
+ >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
+ Decimal("0.333333333")
+ >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
+ Decimal("0.666666667")
+ >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
+ Decimal("2.5")
+ >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
+ Decimal("0.1")
+ >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
+ Decimal("1")
+ >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
+ Decimal("4.00")
+ >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
+ Decimal("1.20")
+ >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
+ Decimal("10")
+ >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
+ Decimal("1000")
+ >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
+ Decimal("1.20E+6")
+ """
+ return a.__div__(b, context=self)
+
+ def divide_int(self, a, b):
+ """Divides two numbers and returns the integer part of the result.
+
+ >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
+ Decimal("0")
+ >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
+ Decimal("3")
+ >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
+ Decimal("3")
+ """
+ return a.__floordiv__(b, context=self)
+
+ def divmod(self, a, b):
+ return a.__divmod__(b, context=self)
+
+ def max(self, a,b):
+ """max compares two values numerically and returns the maximum.
+
+ If either operand is a NaN then the general rules apply.
+ Otherwise, the operands are compared as as though by the compare
+ operation. If they are numerically equal then the left-hand operand
+ is chosen as the result. Otherwise the maximum (closer to positive
+ infinity) of the two operands is chosen as the result.
+
+ >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
+ Decimal("3")
+ >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
+ Decimal("3")
+ >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
+ Decimal("1")
+ >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
+ Decimal("7")
+ """
+ return a.max(b, context=self)
+
+ def min(self, a,b):
+ """min compares two values numerically and returns the minimum.
+
+ If either operand is a NaN then the general rules apply.
+ Otherwise, the operands are compared as as though by the compare
+ operation. If they are numerically equal then the left-hand operand
+ is chosen as the result. Otherwise the minimum (closer to negative
+ infinity) of the two operands is chosen as the result.
+
+ >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
+ Decimal("2")
+ >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
+ Decimal("-10")
+ >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
+ Decimal("1.0")
+ >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
+ Decimal("7")
+ """
+ return a.min(b, context=self)
+
+ def minus(self, a):
+ """Minus corresponds to unary prefix minus in Python.
+
+ The operation is evaluated using the same rules as subtract; the
+ operation minus(a) is calculated as subtract('0', a) where the '0'
+ has the same exponent as the operand.
+
+ >>> ExtendedContext.minus(Decimal('1.3'))
+ Decimal("-1.3")
+ >>> ExtendedContext.minus(Decimal('-1.3'))
+ Decimal("1.3")
+ """
+ return a.__neg__(context=self)
+
+ def multiply(self, a, b):
+ """multiply multiplies two operands.
+
+ If either operand is a special value then the general rules apply.
+ Otherwise, the operands are multiplied together ('long multiplication'),
+ resulting in a number which may be as long as the sum of the lengths
+ of the two operands.
+
+ >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
+ Decimal("3.60")
+ >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
+ Decimal("21")
+ >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
+ Decimal("0.72")
+ >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
+ Decimal("-0.0")
+ >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
+ Decimal("4.28135971E+11")
+ """
+ return a.__mul__(b, context=self)
+
+ def normalize(self, a):
+ """normalize reduces an operand to its simplest form.
+
+ Essentially a plus operation with all trailing zeros removed from the
+ result.
+
+ >>> ExtendedContext.normalize(Decimal('2.1'))
+ Decimal("2.1")
+ >>> ExtendedContext.normalize(Decimal('-2.0'))
+ Decimal("-2")
+ >>> ExtendedContext.normalize(Decimal('1.200'))
+ Decimal("1.2")
+ >>> ExtendedContext.normalize(Decimal('-120'))
+ Decimal("-1.2E+2")
+ >>> ExtendedContext.normalize(Decimal('120.00'))
+ Decimal("1.2E+2")
+ >>> ExtendedContext.normalize(Decimal('0.00'))
+ Decimal("0")
+ """
+ return a.normalize(context=self)
+
+ def plus(self, a):
+ """Plus corresponds to unary prefix plus in Python.
+
+ The operation is evaluated using the same rules as add; the
+ operation plus(a) is calculated as add('0', a) where the '0'
+ has the same exponent as the operand.
+
+ >>> ExtendedContext.plus(Decimal('1.3'))
+ Decimal("1.3")
+ >>> ExtendedContext.plus(Decimal('-1.3'))
+ Decimal("-1.3")
+ """
+ return a.__pos__(context=self)
+
+ def power(self, a, b, modulo=None):
+ """Raises a to the power of b, to modulo if given.
+
+ The right-hand operand must be a whole number whose integer part (after
+ any exponent has been applied) has no more than 9 digits and whose
+ fractional part (if any) is all zeros before any rounding. The operand
+ may be positive, negative, or zero; if negative, the absolute value of
+ the power is used, and the left-hand operand is inverted (divided into
+ 1) before use.
+
+ If the increased precision needed for the intermediate calculations
+ exceeds the capabilities of the implementation then an Invalid operation
+ condition is raised.
+
+ If, when raising to a negative power, an underflow occurs during the
+ division into 1, the operation is not halted at that point but
+ continues.
+
+ >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
+ Decimal("8")
+ >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
+ Decimal("0.125")
+ >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
+ Decimal("69.7575744")
+ >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
+ Decimal("0")
+ >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
+ Decimal("0")
+ >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
+ Decimal("1")
+ >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
+ Decimal("Infinity")
+ >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
+ Decimal("Infinity")
+ >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
+ Decimal("0")
+ >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
+ Decimal("-0")
+ >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
+ Decimal("1")
+ >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
+ Decimal("-Infinity")
+ >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
+ Decimal("Infinity")
+ >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
+ Decimal("NaN")
+ """
+ return a.__pow__(b, modulo, context=self)
+
+ def quantize(self, a, b):
+ """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
+
+ The coefficient of the result is derived from that of the left-hand
+ operand. It may be rounded using the current rounding setting (if the
+ exponent is being increased), multiplied by a positive power of ten (if
+ the exponent is being decreased), or is unchanged (if the exponent is
+ already equal to that of the right-hand operand).
+
+ Unlike other operations, if the length of the coefficient after the
+ quantize operation would be greater than precision then an Invalid
+ operation condition is raised. This guarantees that, unless there is an
+ error condition, the exponent of the result of a quantize is always
+ equal to that of the right-hand operand.
+
+ Also unlike other operations, quantize will never raise Underflow, even
+ if the result is subnormal and inexact.
+
+ >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
+ Decimal("2.170")
+ >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
+ Decimal("2.17")
+ >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
+ Decimal("2.2")
+ >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
+ Decimal("2")
+ >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
+ Decimal("0E+1")
+ >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
+ Decimal("-Infinity")
+ >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
+ Decimal("NaN")
+ >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
+ Decimal("-0")
+ >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
+ Decimal("-0E+5")
+ >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
+ Decimal("NaN")
+ >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
+ Decimal("NaN")
+ >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
+ Decimal("217.0")
+ >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
+ Decimal("217")
+ >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
+ Decimal("2.2E+2")
+ >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
+ Decimal("2E+2")
+ """
+ return a.quantize(b, context=self)
+
+ def remainder(self, a, b):
+ """Returns the remainder from integer division.
+
+ The result is the residue of the dividend after the operation of
+ calculating integer division as described for divide-integer, rounded to
+ precision digits if necessary. The sign of the result, if non-zero, is
+ the same as that of the original dividend.
+
+ This operation will fail under the same conditions as integer division
+ (that is, if integer division on the same two operands would fail, the
+ remainder cannot be calculated).
+
+ >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
+ Decimal("2.1")
+ >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
+ Decimal("1")
+ >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
+ Decimal("-1")
+ >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
+ Decimal("0.2")
+ >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
+ Decimal("0.1")
+ >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
+ Decimal("1.0")
+ """
+ return a.__mod__(b, context=self)
+
+ def remainder_near(self, a, b):
+ """Returns to be "a - b * n", where n is the integer nearest the exact
+ value of "x / b" (if two integers are equally near then the even one
+ is chosen). If the result is equal to 0 then its sign will be the
+ sign of a.
+
+ This operation will fail under the same conditions as integer division
+ (that is, if integer division on the same two operands would fail, the
+ remainder cannot be calculated).
+
+ >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
+ Decimal("-0.9")
+ >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
+ Decimal("-2")
+ >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
+ Decimal("1")
+ >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
+ Decimal("-1")
+ >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
+ Decimal("0.2")
+ >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
+ Decimal("0.1")
+ >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
+ Decimal("-0.3")
+ """
+ return a.remainder_near(b, context=self)
+
+ def same_quantum(self, a, b):
+ """Returns True if the two operands have the same exponent.
+
+ The result is never affected by either the sign or the coefficient of
+ either operand.
+
+ >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
+ False
+ >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
+ True
+ >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
+ False
+ >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
+ True
+ """
+ return a.same_quantum(b)
+
+ def sqrt(self, a):
+ """Returns the square root of a non-negative number to context precision.
+
+ If the result must be inexact, it is rounded using the round-half-even
+ algorithm.
+
+ >>> ExtendedContext.sqrt(Decimal('0'))
+ Decimal("0")
+ >>> ExtendedContext.sqrt(Decimal('-0'))
+ Decimal("-0")
+ >>> ExtendedContext.sqrt(Decimal('0.39'))
+ Decimal("0.624499800")
+ >>> ExtendedContext.sqrt(Decimal('100'))
+ Decimal("10")
+ >>> ExtendedContext.sqrt(Decimal('1'))
+ Decimal("1")
+ >>> ExtendedContext.sqrt(Decimal('1.0'))
+ Decimal("1.0")
+ >>> ExtendedContext.sqrt(Decimal('1.00'))
+ Decimal("1.0")
+ >>> ExtendedContext.sqrt(Decimal('7'))
+ Decimal("2.64575131")
+ >>> ExtendedContext.sqrt(Decimal('10'))
+ Decimal("3.16227766")
+ >>> ExtendedContext.prec
+ 9
+ """
+ return a.sqrt(context=self)
+
+ def subtract(self, a, b):
+ """Return the difference between the two operands.
+
+ >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
+ Decimal("0.23")
+ >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
+ Decimal("0.00")
+ >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
+ Decimal("-0.77")
+ """
+ return a.__sub__(b, context=self)
+
+ def to_eng_string(self, a):
+ """Converts a number to a string, using scientific notation.
+
+ The operation is not affected by the context.
+ """
+ return a.to_eng_string(context=self)
+
+ def to_sci_string(self, a):
+ """Converts a number to a string, using scientific notation.
+
+ The operation is not affected by the context.
+ """
+ return a.__str__(context=self)
+
+ def to_integral(self, a):
+ """Rounds to an integer.
+
+ When the operand has a negative exponent, the result is the same
+ as using the quantize() operation using the given operand as the
+ left-hand-operand, 1E+0 as the right-hand-operand, and the precision
+ of the operand as the precision setting, except that no flags will
+ be set. The rounding mode is taken from the context.
+
+ >>> ExtendedContext.to_integral(Decimal('2.1'))
+ Decimal("2")
+ >>> ExtendedContext.to_integral(Decimal('100'))
+ Decimal("100")
+ >>> ExtendedContext.to_integral(Decimal('100.0'))
+ Decimal("100")
+ >>> ExtendedContext.to_integral(Decimal('101.5'))
+ Decimal("102")
+ >>> ExtendedContext.to_integral(Decimal('-101.5'))
+ Decimal("-102")
+ >>> ExtendedContext.to_integral(Decimal('10E+5'))
+ Decimal("1.0E+6")
+ >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
+ Decimal("7.89E+77")
+ >>> ExtendedContext.to_integral(Decimal('-Inf'))
+ Decimal("-Infinity")
+ """
+ return a.to_integral(context=self)
+
+class _WorkRep(object):
+ __slots__ = ('sign','int','exp')
+ # sign: 0 or 1
+ # int: int or long
+ # exp: None, int, or string
+
+ def __init__(self, value=None):
+ if value is None:
+ self.sign = None
+ self.int = 0
+ self.exp = None
+ elif isinstance(value, Decimal):
+ self.sign = value._sign
+ cum = 0
+ for digit in value._int:
+ cum = cum * 10 + digit
+ self.int = cum
+ self.exp = value._exp
+ else:
+ # assert isinstance(value, tuple)
+ self.sign = value[0]
+ self.int = value[1]
+ self.exp = value[2]
+
+ def __repr__(self):
+ return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
+
+ __str__ = __repr__
+
+
+
+def _normalize(op1, op2, shouldround = 0, prec = 0):
+ """Normalizes op1, op2 to have the same exp and length of coefficient.
+
+ Done during addition.
+ """
+ # Yes, the exponent is a long, but the difference between exponents
+ # must be an int-- otherwise you'd get a big memory problem.
+ numdigits = int(op1.exp - op2.exp)
+ if numdigits < 0:
+ numdigits = -numdigits
+ tmp = op2
+ other = op1
+ else:
+ tmp = op1
+ other = op2
+
+
+ if shouldround and numdigits > prec + 1:
+ # Big difference in exponents - check the adjusted exponents
+ tmp_len = len(str(tmp.int))
+ other_len = len(str(other.int))
+ if numdigits > (other_len + prec + 1 - tmp_len):
+ # If the difference in adjusted exps is > prec+1, we know
+ # other is insignificant, so might as well put a 1 after the precision.
+ # (since this is only for addition.) Also stops use of massive longs.
+
+ extend = prec + 2 - tmp_len
+ if extend <= 0:
+ extend = 1
+ tmp.int *= 10 ** extend
+ tmp.exp -= extend
+ other.int = 1
+ other.exp = tmp.exp
+ return op1, op2
+
+ tmp.int *= 10 ** numdigits
+ tmp.exp -= numdigits
+ return op1, op2
+
+def _adjust_coefficients(op1, op2):
+ """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
+
+ Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
+
+ Used on _WorkRep instances during division.
+ """
+ adjust = 0
+ #If op1 is smaller, make it larger
+ while op2.int > op1.int:
+ op1.int *= 10
+ op1.exp -= 1
+ adjust += 1
+
+ #If op2 is too small, make it larger
+ while op1.int >= (10 * op2.int):
+ op2.int *= 10
+ op2.exp -= 1
+ adjust -= 1
+
+ return op1, op2, adjust
+
+##### Helper Functions ########################################
+
+def _convert_other(other):
+ """Convert other to Decimal.
+
+ Verifies that it's ok to use in an implicit construction.
+ """
+ if isinstance(other, Decimal):
+ return other
+ if isinstance(other, (int, long)):
+ return Decimal(other)
+ return NotImplemented
+
+_infinity_map = {
+ 'inf' : 1,
+ 'infinity' : 1,
+ '+inf' : 1,
+ '+infinity' : 1,
+ '-inf' : -1,
+ '-infinity' : -1
+}
+
+def _isinfinity(num):
+ """Determines whether a string or float is infinity.
+
+ +1 for negative infinity; 0 for finite ; +1 for positive infinity
+ """
+ num = str(num).lower()
+ return _infinity_map.get(num, 0)
+
+def _isnan(num):
+ """Determines whether a string or float is NaN
+
+ (1, sign, diagnostic info as string) => NaN
+ (2, sign, diagnostic info as string) => sNaN
+ 0 => not a NaN
+ """
+ num = str(num).lower()
+ if not num:
+ return 0
+
+ #get the sign, get rid of trailing [+-]
+ sign = 0
+ if num[0] == '+':
+ num = num[1:]
+ elif num[0] == '-': #elif avoids '+-nan'
+ num = num[1:]
+ sign = 1
+
+ if num.startswith('nan'):
+ if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
+ return 0
+ return (1, sign, num[3:].lstrip('0'))
+ if num.startswith('snan'):
+ if len(num) > 4 and not num[4:].isdigit():
+ return 0
+ return (2, sign, num[4:].lstrip('0'))
+ return 0
+
+
+##### Setup Specific Contexts ################################
+
+# The default context prototype used by Context()
+# Is mutable, so that new contexts can have different default values
+
+DefaultContext = Context(
+ prec=28, rounding=ROUND_HALF_EVEN,
+ traps=[DivisionByZero, Overflow, InvalidOperation],
+ flags=[],
+ _rounding_decision=ALWAYS_ROUND,
+ Emax=999999999,
+ Emin=-999999999,
+ capitals=1
+)
+
+# Pre-made alternate contexts offered by the specification
+# Don't change these; the user should be able to select these
+# contexts and be able to reproduce results from other implementations
+# of the spec.
+
+BasicContext = Context(
+ prec=9, rounding=ROUND_HALF_UP,
+ traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
+ flags=[],
+)
+
+ExtendedContext = Context(
+ prec=9, rounding=ROUND_HALF_EVEN,
+ traps=[],
+ flags=[],
+)
+
+
+##### Useful Constants (internal use only) ####################
+
+#Reusable defaults
+Inf = Decimal('Inf')
+negInf = Decimal('-Inf')
+
+#Infsign[sign] is infinity w/ that sign
+Infsign = (Inf, negInf)
+
+NaN = Decimal('NaN')
+
+
+##### crud for parsing strings #################################
+import re
+
+# There's an optional sign at the start, and an optional exponent
+# at the end. The exponent has an optional sign and at least one
+# digit. In between, must have either at least one digit followed
+# by an optional fraction, or a decimal point followed by at least
+# one digit. Yuck.
+
+_parser = re.compile(r"""
+# \s*
+ (?P<sign>[-+])?
+ (
+ (?P<int>\d+) (\. (?P<frac>\d*))?
+ |
+ \. (?P<onlyfrac>\d+)
+ )
+ ([eE](?P<exp>[-+]? \d+))?
+# \s*
+ $
+""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
+
+del re
+
+# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
+
+def _string2exact(s):
+ m = _parser(s)
+ if m is None:
+ raise ValueError("invalid literal for Decimal: %r" % s)
+
+ if m.group('sign') == "-":
+ sign = 1
+ else:
+ sign = 0
+
+ exp = m.group('exp')
+ if exp is None:
+ exp = 0
+ else:
+ exp = int(exp)
+
+ intpart = m.group('int')
+ if intpart is None:
+ intpart = ""
+ fracpart = m.group('onlyfrac')
+ else:
+ fracpart = m.group('frac')
+ if fracpart is None:
+ fracpart = ""
+
+ exp -= len(fracpart)
+
+ mantissa = intpart + fracpart
+ tmp = map(int, mantissa)
+ backup = tmp
+ while tmp and tmp[0] == 0:
+ del tmp[0]
+
+ # It's a zero
+ if not tmp:
+ if backup:
+ return (sign, tuple(backup), exp)
+ return (sign, (0,), exp)
+ mantissa = tuple(tmp)
+
+ return (sign, mantissa, exp)
+
+
+if __name__ == '__main__':
+ import doctest, sys
+ doctest.testmod(sys.modules[__name__])
diff --git a/docs/forms.txt b/docs/forms.txt
index 329e84a1b1..f6cb55a3f6 100644
--- a/docs/forms.txt
+++ b/docs/forms.txt
@@ -567,6 +567,7 @@ check for the given property:
* isValidANSIDate
* isValidANSITime
* isValidEmail
+ * isValidFloat
* isValidImage
* isValidImageURL
* isValidPhone
@@ -664,10 +665,10 @@ fails. If no message is passed in, a default message is used.
Takes an integer argument and when called as a validator, checks that the
field being validated is a power of the integer.
-``IsValidFloat``
+``IsValidDecimal``
Takes a maximum number of digits and number of decimal places (in that
- order) and validates whether the field is a float with less than the
- maximum number of digits and decimal place.
+ order) and validates whether the field is a decimal with no more than the
+ maximum number of digits and decimal places.
``MatchesRegularExpression``
Takes a regular expression (a string) as a parameter and validates the
diff --git a/docs/install.txt b/docs/install.txt
index 6be52aab0d..c3ccd27f76 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -11,8 +11,8 @@ Being a Python Web framework, Django requires Python.
It works with any Python version 2.3 and higher.
-Get Python at www.python.org. If you're running Linux or Mac OS X, you probably
-already have it installed.
+Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
+probably already have it installed.
Install Apache and mod_python
=============================
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 5028918f92..19f8fb6d5f 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -184,6 +184,35 @@ A date and time field. Takes the same extra options as ``DateField``.
The admin represents this as two ``<input type="text">`` fields, with
JavaScript shortcuts.
+``DecimalField``
+~~~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+A fixed-precision decimal number, represented in Python by a ``Decimal`` instance.
+Has two **required** arguments:
+
+ ====================== ===================================================
+ Argument Description
+ ====================== ===================================================
+ ``max_digits`` The maximum number of digits allowed in the number.
+
+ ``decimal_places`` The number of decimal places to store with the
+ number.
+ ====================== ===================================================
+
+For example, to store numbers up to 999 with a resolution of 2 decimal places,
+you'd use::
+
+ models.DecimalField(..., max_digits=5, decimal_places=2)
+
+And to store numbers up to approximately one billion with a resolution of 10
+decimal places::
+
+ models.DecimalField(..., max_digits=19, decimal_places=10)
+
+The admin represents this as an ``<input type="text">`` (a single-line input).
+
``EmailField``
~~~~~~~~~~~~~~
@@ -290,28 +319,16 @@ because the ``match`` applies to the base filename (``foo.gif`` and
``FloatField``
~~~~~~~~~~~~~~
-A floating-point number. Has two **required** arguments:
+**Changed in Django development version**
- ====================== ===================================================
- Argument Description
- ====================== ===================================================
- ``max_digits`` The maximum number of digits allowed in the number.
+A floating-point number represented in Python by a ``float`` instance.
- ``decimal_places`` The number of decimal places to store with the
- number.
- ====================== ===================================================
-
-For example, to store numbers up to 999 with a resolution of 2 decimal places,
-you'd use::
-
- models.FloatField(..., max_digits=5, decimal_places=2)
-
-And to store numbers up to approximately one billion with a resolution of 10
-decimal places::
+The admin represents this as an ``<input type="text">`` (a single-line input).
- models.FloatField(..., max_digits=19, decimal_places=10)
+**NOTE:** The semantics of ``FloatField`` have changed in the Django
+development version. See the `Django 0.96 documentation`_ for the old behavior.
-The admin represents this as an ``<input type="text">`` (a single-line input).
+.. _Django 0.96 documentation: http://www.djangoproject.com/documentation/0.96/model-api/#floatfield
``ImageField``
~~~~~~~~~~~~~~
@@ -743,7 +760,7 @@ relationship should work. All are optional:
``limit_choices_to`` A dictionary of lookup arguments and values (see
the `Database API reference`_) that limit the
available admin choices for this object. Use this
- with functions from the Python ``datetime`` module
+ with functions from the Python ``datetime`` module
to limit choices of objects by date. For example::
limit_choices_to = {'pub_date__lte': datetime.now}
@@ -1760,8 +1777,8 @@ But this template code is good::
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
.. note::
- The string you return from ``get_absolute_url()`` must be use only ASCII
- characters (required by the URI spec, `RFC 2396`_) that has been
+ The string you return from ``get_absolute_url()`` must contain only ASCII
+ characters (required by the URI spec, `RFC 2396`_) that have been
URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
should be able to use the result directly without needing to do any
further processing. You may wish to use the
diff --git a/docs/newforms.txt b/docs/newforms.txt
index ed43670960..7ec4e9560c 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -602,6 +602,102 @@ when printed::
>>> str(f['subject'].errors)
''
+Using forms in views and templates
+----------------------------------
+
+Let's put this all together and use the ``ContactForm`` example in a Django
+view and template. This example view displays the contact form by default and
+validates/processes it if accessed via a POST request::
+
+ def contact(request):
+ if request.method == 'POST':
+ form = ContactForm(request.POST)
+ if form.is_valid():
+ # Do form processing here...
+ return HttpResponseRedirect('/url/on_success/')
+ else:
+ form = ContactForm()
+ return render_to_response('contact.html', {'form': form})
+
+Simple template output
+~~~~~~~~~~~~~~~~~~~~~~
+
+The template, ``contact.html``, is responsible for displaying the form as HTML.
+To do this, we can use the techniques outlined in the "Outputting forms as HTML"
+section above.
+
+The simplest way to display a form's HTML is to use the variable on its own,
+like this::
+
+ <form method="post">
+ <table>{{ form }}</table>
+ <input type="submit" />
+ </form>
+
+The above template code will display the form as an HTML table, using the
+``form.as_table()`` method explained previously. This works because Django's
+template system displays an object's ``__str__()`` value, and the ``Form``
+class' ``__str__()`` method calls its ``as_table()`` method.
+
+The following is equivalent but a bit more explicit::
+
+ <form method="post">
+ <table>{{ form.as_table }}</table>
+ <input type="submit" />
+ </form>
+
+``form.as_ul`` and ``form.as_p`` are also available, as you may expect.
+
+Note that in the above two examples, we included the ``<form>``, ``<table>``
+``<input type="submit" />``, ``</table>`` and ``</form>`` tags. The form
+convenience methods (``as_table()``, ``as_ul()`` and ``as_p()``) do not include
+that HTML.
+
+Complex template output
+~~~~~~~~~~~~~~~~~~~~~~~
+
+As we've stressed several times, the ``as_table()``, ``as_ul()`` and ``as_p()``
+methods are just shortcuts for the common case. You can also work with the
+individual fields for complete template control over the form's design.
+
+The easiest way is to iterate over the form's fields, with
+``{% for field in form %}``. For example::
+
+ <form method="post">
+ <dl>
+ {% for field in form %}
+ <dt>{{ field.label }}</dt>
+ <dd>{{ field }}</dd>
+ {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
+ {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
+ {% endfor %}
+ </dl>
+ <input type="submit" />
+ </form>
+
+This iteration technique is useful if you want to apply the same HTML
+formatting to each field, or if you don't know the names of the form fields
+ahead of time. Note that the fields will be listed in the order in which
+they're defined in the ``Form`` class.
+
+Alternatively, you can arrange the form's fields explicitly, by name. Do that
+by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
+For example::
+
+ <form method="post">
+ <ul class="myformclass">
+ <li>{{ form.sender.label }} {{ form.sender.label }}</li>
+ <li class="helptext">{{ form.sender.help_text }}</li>
+ {% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</dd>{% endif %}
+
+ <li>{{ form.subject.label }} {{ form.subject.label }}</li>
+ <li class="helptext">{{ form.subject.help_text }}</li>
+ {% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</dd>{% endif %}
+
+ ...
+ </ul>
+ </form>
+
Subclassing forms
-----------------
@@ -1157,10 +1253,11 @@ the full list of conversions:
``CommaSeparatedIntegerField`` ``CharField``
``DateField`` ``DateField``
``DateTimeField`` ``DateTimeField``
+ ``DecimalField`` ``DecimalField``
``EmailField`` ``EmailField``
``FileField`` ``CharField``
``FilePathField`` ``CharField``
- ``FloatField`` ``CharField``
+ ``FloatField`` ``FloatField``
``ForeignKey`` ``ModelChoiceField`` (see below)
``ImageField`` ``CharField``
``IntegerField`` ``IntegerField``
@@ -1185,6 +1282,11 @@ the full list of conversions:
``XMLField`` ``CharField`` with ``widget=Textarea``
=============================== ========================================
+
+.. note::
+ The ``FloatField`` form field and ``DecimalField`` model and form fields
+ are new in the development version.
+
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
types are special cases:
diff --git a/docs/settings.txt b/docs/settings.txt
index 4a62a3ecf0..0d5abe4a10 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -1063,7 +1063,7 @@ You can tell Django to stop reporting particular 404s by tweaking the
tuple of strings. For example::
IGNORABLE_404_ENDS = ('.php', '.cgi')
- IGNORABLE_404_STARTS = ('/phpmyadmin/')
+ IGNORABLE_404_STARTS = ('/phpmyadmin/',)
In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not*
be reported. Neither will any URL starting with ``/phpmyadmin/``.
diff --git a/docs/tutorial02.txt b/docs/tutorial02.txt
index 6e4b0ea35e..99f586b4a1 100644
--- a/docs/tutorial02.txt
+++ b/docs/tutorial02.txt
@@ -320,7 +320,7 @@ method a ``short_description`` attribute::
Let's add another improvement to the Poll change list page: Filters. Add the
-following line to ``Poll.admin``::
+following line to ``Poll.Admin``::
list_filter = ['pub_date']
diff --git a/tests/modeltests/invalid_models/models.py b/tests/modeltests/invalid_models/models.py
index af54ec3d35..90f2f54632 100644
--- a/tests/modeltests/invalid_models/models.py
+++ b/tests/modeltests/invalid_models/models.py
@@ -8,7 +8,7 @@ from django.db import models
class FieldErrors(models.Model):
charfield = models.CharField()
- floatfield = models.FloatField()
+ decimalfield = models.DecimalField()
filefield = models.FileField()
prepopulate = models.CharField(maxlength=10, prepopulate_from='bad')
choices = models.CharField(maxlength=10, choices='bad')
@@ -87,10 +87,10 @@ class SelfClashM2M(models.Model):
src_safe = models.CharField(maxlength=10)
selfclashm2m = models.CharField(maxlength=10)
- # Non-symmetrical M2M fields _do_ have related accessors, so
+ # Non-symmetrical M2M fields _do_ have related accessors, so
# there is potential for clashes.
selfclashm2m_set = models.ManyToManyField("SelfClashM2M", symmetrical=False)
-
+
m2m_1 = models.ManyToManyField("SelfClashM2M", related_name='id', symmetrical=False)
m2m_2 = models.ManyToManyField("SelfClashM2M", related_name='src_safe', symmetrical=False)
@@ -108,8 +108,8 @@ class Car(models.Model):
model = models.ForeignKey(Model)
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute.
-invalid_models.fielderrors: "floatfield": FloatFields require a "decimal_places" attribute.
-invalid_models.fielderrors: "floatfield": FloatFields require a "max_digits" attribute.
+invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
+invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
invalid_models.fielderrors: "prepopulate": prepopulate_from should be a list or tuple.
invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list).
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 5afa3d198d..ba5beed5e5 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -7,6 +7,10 @@ form_tests = r"""
>>> import datetime
>>> import time
>>> import re
+>>> try:
+... from decimal import Decimal
+... except ImportError:
+... from django.utils._decimal import Decimal
###########
# Widgets #
@@ -1046,6 +1050,133 @@ Traceback (most recent call last):
...
ValidationError: [u'Ensure this value is less than or equal to 20.']
+# FloatField ##################################################################
+
+>>> f = FloatField()
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('1')
+1.0
+>>> isinstance(f.clean('1'), float)
+True
+>>> f.clean('23')
+23.0
+>>> f.clean('3.14')
+3.1400000000000001
+>>> f.clean('a')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a number.']
+>>> f.clean('1.0 ')
+1.0
+>>> f.clean(' 1.0')
+1.0
+>>> f.clean(' 1.0 ')
+1.0
+>>> f.clean('1.0a')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a number.']
+
+>>> f = FloatField(required=False)
+>>> f.clean('')
+
+>>> f.clean(None)
+
+>>> f.clean('1')
+1.0
+
+FloatField accepts min_value and max_value just like IntegerField:
+>>> f = FloatField(max_value=1.5, min_value=0.5)
+
+>>> f.clean('1.6')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value is less than or equal to 1.5.']
+>>> f.clean('0.4')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
+>>> f.clean('1.5')
+1.5
+>>> f.clean('0.5')
+0.5
+
+# DecimalField ################################################################
+
+>>> f = DecimalField(max_digits=4, decimal_places=2)
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('1')
+Decimal("1")
+>>> isinstance(f.clean('1'), Decimal)
+True
+>>> f.clean('23')
+Decimal("23")
+>>> f.clean('3.14')
+Decimal("3.14")
+>>> f.clean('a')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a number.']
+>>> f.clean('1.0 ')
+Decimal("1.0")
+>>> f.clean(' 1.0')
+Decimal("1.0")
+>>> f.clean(' 1.0 ')
+Decimal("1.0")
+>>> f.clean('1.0a')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a number.']
+>>> f.clean('123.45')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure that there are no more than 4 digits in total.']
+>>> f.clean('1.234')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure that there are no more than 2 decimal places.']
+>>> f.clean('123.4')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure that there are no more than 2 digits before the decimal point.']
+>>> f = DecimalField(max_digits=4, decimal_places=2, required=False)
+>>> f.clean('')
+
+>>> f.clean(None)
+
+>>> f.clean('1')
+Decimal("1")
+
+DecimalField accepts min_value and max_value just like IntegerField:
+>>> f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
+
+>>> f.clean('1.6')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value is less than or equal to 1.5.']
+>>> f.clean('0.4')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
+>>> f.clean('1.5')
+Decimal("1.5")
+>>> f.clean('0.5')
+Decimal("0.5")
+
# DateField ###################################################################
>>> import datetime
@@ -3515,6 +3646,15 @@ u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
u'1'
>>> smart_unicode('foo')
u'foo'
+
+# flatatt tests
+>>> from django.newforms.util import flatatt
+>>> flatatt({'id': "header"})
+u' id="header"'
+>>> flatatt({'class': "news", 'title': "Read this"})
+u' class="news" title="Read this"'
+>>> flatatt({})
+u''
"""
__test__ = {
diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py
index e5d873c2c6..ca42752a9f 100644
--- a/tests/regressiontests/httpwrappers/tests.py
+++ b/tests/regressiontests/httpwrappers/tests.py
@@ -166,6 +166,9 @@ u'hello'
>>> q.pop('foo')
[u'bar', u'baz', u'another', u'hello']
+>>> q.pop('foo', 'not there')
+u'not there'
+
>>> q.get('foo', 'not there')
u'not there'
diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
index fea5c94cab..999b79ccaf 100644
--- a/tests/regressiontests/serializers_regress/models.py
+++ b/tests/regressiontests/serializers_regress/models.py
@@ -1,7 +1,7 @@
"""
A test spanning all the capabilities of all the serializers.
-This class sets up a model for each model field type
+This class sets up a model for each model field type
(except for image types, because of the PIL dependency).
"""
@@ -9,12 +9,12 @@ from django.db import models
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
-# The following classes are for testing basic data
+# The following classes are for testing basic data
# marshalling, including NULL values.
class BooleanData(models.Model):
data = models.BooleanField(null=True)
-
+
class CharData(models.Model):
data = models.CharField(maxlength=30, null=True)
@@ -24,6 +24,9 @@ class DateData(models.Model):
class DateTimeData(models.Model):
data = models.DateTimeField(null=True)
+class DecimalData(models.Model):
+ data = models.DecimalField(null=True, decimal_places=3, max_digits=5)
+
class EmailData(models.Model):
data = models.EmailField(null=True)
@@ -34,7 +37,7 @@ class FilePathData(models.Model):
data = models.FilePathField(null=True)
class FloatData(models.Model):
- data = models.FloatField(null=True, decimal_places=3, max_digits=5)
+ data = models.FloatField(null=True)
class IntegerData(models.Model):
data = models.IntegerField(null=True)
@@ -145,6 +148,9 @@ class CharPKData(models.Model):
# class DateTimePKData(models.Model):
# data = models.DateTimeField(primary_key=True)
+class DecimalPKData(models.Model):
+ data = models.DecimalField(primary_key=True, decimal_places=3, max_digits=5)
+
class EmailPKData(models.Model):
data = models.EmailField(primary_key=True)
@@ -155,7 +161,7 @@ class FilePathPKData(models.Model):
data = models.FilePathField(primary_key=True)
class FloatPKData(models.Model):
- data = models.FloatField(primary_key=True, decimal_places=3, max_digits=5)
+ data = models.FloatField(primary_key=True)
class IntegerPKData(models.Model):
data = models.IntegerField(primary_key=True)
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index 9da3467702..8395fe0320 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -16,6 +16,10 @@ from django.db import transaction
from django.core import management
from models import *
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal
# A set of functions that can be used to recreate
# test data objects of various kinds
@@ -118,10 +122,14 @@ test_data = [
(data_obj, 51, FileData, None),
(data_obj, 60, FilePathData, "/foo/bar/whiz.txt"),
(data_obj, 61, FilePathData, None),
- (data_obj, 70, FloatData, 12.345),
- (data_obj, 71, FloatData, -12.345),
- (data_obj, 72, FloatData, 0.0),
- (data_obj, 73, FloatData, None),
+ (data_obj, 70, DecimalData, decimal.Decimal('12.345')),
+ (data_obj, 71, DecimalData, decimal.Decimal('-12.345')),
+ (data_obj, 72, DecimalData, decimal.Decimal('0.0')),
+ (data_obj, 73, DecimalData, None),
+ (data_obj, 74, FloatData, 12.345),
+ (data_obj, 75, FloatData, -12.345),
+ (data_obj, 76, FloatData, 0.0),
+ (data_obj, 77, FloatData, None),
(data_obj, 80, IntegerData, 123456789),
(data_obj, 81, IntegerData, -123456789),
(data_obj, 82, IntegerData, 0),
@@ -204,9 +212,12 @@ The end."""),
(pk_obj, 640, EmailPKData, "hovercraft@example.com"),
(pk_obj, 650, FilePKData, 'file:///foo/bar/whiz.txt'),
(pk_obj, 660, FilePathPKData, "/foo/bar/whiz.txt"),
- (pk_obj, 670, FloatPKData, 12.345),
- (pk_obj, 671, FloatPKData, -12.345),
- (pk_obj, 672, FloatPKData, 0.0),
+ (pk_obj, 670, DecimalPKData, decimal.Decimal('12.345')),
+ (pk_obj, 671, DecimalPKData, decimal.Decimal('-12.345')),
+ (pk_obj, 672, DecimalPKData, decimal.Decimal('0.0')),
+ (pk_obj, 673, FloatPKData, 12.345),
+ (pk_obj, 674, FloatPKData, -12.345),
+ (pk_obj, 675, FloatPKData, 0.0),
(pk_obj, 680, IntegerPKData, 123456789),
(pk_obj, 681, IntegerPKData, -123456789),
(pk_obj, 682, IntegerPKData, 0),
diff --git a/tests/runtests.py b/tests/runtests.py
index a111ef1436..7d1ee1e29c 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -3,11 +3,15 @@
import os, sys, traceback
import unittest
+import django.contrib as contrib
+CONTRIB_DIR_NAME = 'django.contrib'
MODEL_TESTS_DIR_NAME = 'modeltests'
REGRESSION_TESTS_DIR_NAME = 'regressiontests'
+
TEST_DATABASE_NAME = 'django_test_db'
TEST_TEMPLATE_DIR = 'templates'
+CONTRIB_DIR = os.path.dirname(contrib.__file__)
MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)
REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME)
@@ -24,7 +28,7 @@ ALWAYS_INSTALLED_APPS = [
def get_test_models():
models = []
- for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR):
+ for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
for f in os.listdir(dirpath):
if f.startswith('__init__') or f.startswith('.') or f.startswith('sql') or f.startswith('invalid'):
continue
@@ -33,7 +37,7 @@ def get_test_models():
def get_invalid_models():
models = []
- for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR):
+ for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
for f in os.listdir(dirpath):
if f.startswith('__init__') or f.startswith('.') or f.startswith('sql'):
continue
@@ -109,8 +113,10 @@ def django_tests(verbosity, tests_to_run):
if verbosity >= 1:
print "Importing model %s" % model_name
mod = load_app(model_label)
- settings.INSTALLED_APPS.append(model_label)
- test_models.append(mod)
+ if mod:
+ if model_label not in settings.INSTALLED_APPS:
+ settings.INSTALLED_APPS.append(model_label)
+ test_models.append(mod)
except Exception, e:
sys.stderr.write("Error while importing %s:" % model_name + ''.join(traceback.format_exception(*sys.exc_info())[1:]))
continue