Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

newforms-admin: Merged to [6612]

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6613 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 1746760500a3232e7752626fc33deda7f6b74862 1 parent 11b6e1e
@jkocherhans jkocherhans authored
Showing with 12,093 additions and 9,397 deletions.
  1. +8 −2 AUTHORS
  2. +0 −10 django/conf/__init__.py
  3. +2 −1  django/conf/global_settings.py
  4. BIN  django/conf/locale/ca/LC_MESSAGES/django.mo
  5. +2,573 −2,275 django/conf/locale/ca/LC_MESSAGES/django.po
  6. BIN  django/conf/locale/es/LC_MESSAGES/django.mo
  7. +2,573 −2,275 django/conf/locale/es/LC_MESSAGES/django.po
  8. BIN  django/conf/locale/es_AR/LC_MESSAGES/django.mo
  9. +2,612 −2,066 django/conf/locale/es_AR/LC_MESSAGES/django.po
  10. BIN  django/conf/locale/es_AR/LC_MESSAGES/djangojs.mo
  11. +7 −7 django/conf/locale/es_AR/LC_MESSAGES/djangojs.po
  12. BIN  django/conf/locale/he/LC_MESSAGES/django.mo
  13. +2,769 −2,237 django/conf/locale/he/LC_MESSAGES/django.po
  14. BIN  django/conf/locale/hr/LC_MESSAGES/django.mo
  15. +131 −131 django/conf/locale/hr/LC_MESSAGES/django.po
  16. +9 −1 django/contrib/admin/media/js/urlify.js
  17. +2 −2 django/contrib/comments/feeds.py
  18. 0  django/contrib/localflavor/es/__init__.py
  19. +58 −0 django/contrib/localflavor/es/es_provinces.py
  20. +23 −0 django/contrib/localflavor/es/es_regions.py
  21. +173 −0 django/contrib/localflavor/es/forms.py
  22. +80 −14 django/contrib/localflavor/pl/forms.py
  23. +1 −0  django/contrib/sessions/backends/base.py
  24. +7 −5 django/contrib/sessions/middleware.py
  25. +23 −0 django/contrib/sessions/tests.py
  26. +1 −0  django/contrib/syndication/feeds.py
  27. +8 −0 django/core/cache/backends/base.py
  28. +7 −1 django/core/cache/backends/db.py
  29. +3 −0  django/core/cache/backends/dummy.py
  30. +20 −0 django/core/cache/backends/filebased.py
  31. +7 −0 django/core/cache/backends/locmem.py
  32. +3 −0  django/core/cache/backends/memcached.py
  33. +9 −0 django/core/cache/backends/simple.py
  34. +12 −7 django/core/handlers/modpython.py
  35. +13 −7 django/core/handlers/wsgi.py
  36. +2 −2 django/core/mail.py
  37. +61 −50 django/core/management/__init__.py
  38. +17 −10 django/core/management/base.py
  39. +6 −4 django/core/management/color.py
  40. +1 −1  django/core/management/commands/runserver.py
  41. +2 −0  django/core/management/validation.py
  42. +3 −2 django/core/urlresolvers.py
  43. +21 −0 django/db/backends/__init__.py
  44. +1 −1  django/db/backends/postgresql/operations.py
  45. +8 −1 django/db/backends/postgresql_psycopg2/base.py
  46. +4 −14 django/db/backends/util.py
  47. +2 −0  django/db/models/fields/__init__.py
  48. +74 −1 django/dispatch/saferef.py
  49. +17 −17 django/http/__init__.py
  50. +6 −4 django/middleware/common.py
  51. +4 −3 django/middleware/gzip.py
  52. +9 −1 django/newforms/fields.py
  53. +26 −3 django/newforms/widgets.py
  54. +8 −2 django/template/defaulttags.py
  55. +6 −2 django/templatetags/i18n.py
  56. +4 −1 django/test/utils.py
  57. +53 −20 django/utils/datastructures.py
  58. +1 −1  django/utils/encoding.py
  59. +8 −2 django/utils/feedgenerator.py
  60. +7 −9 django/utils/functional.py
  61. +2 −1  django/utils/http.py
  62. +1 −4 django/utils/translation/__init__.py
  63. +1 −1  django/utils/translation/trans_null.py
  64. +75 −58 django/utils/translation/trans_real.py
  65. +4 −5 django/views/debug.py
  66. +9 −3 django/views/static.py
  67. +11 −11 docs/apache_auth.txt
  68. +48 −6 docs/cache.txt
  69. +5 −0 docs/contributing.txt
  70. +8 −0 docs/databases.txt
  71. +10 −7 docs/django-admin.txt
  72. +1 −1  docs/flatpages.txt
  73. +6 −3 docs/i18n.txt
  74. +4 −1 docs/install.txt
  75. +8 −5 docs/middleware.txt
  76. +6 −4 docs/model-api.txt
  77. +9 −7 docs/modpython.txt
  78. +44 −8 docs/newforms.txt
  79. +2 −2 docs/request_response.txt
  80. +30 −7 docs/settings.txt
  81. +16 −0 docs/syndication_feeds.txt
  82. +37 −19 docs/templates.txt
  83. +1 −1  docs/templates_python.txt
  84. +1 −1  docs/tutorial01.txt
  85. +16 −14 docs/unicode.txt
  86. +4 −2 tests/modeltests/invalid_models/models.py
  87. +18 −12 tests/regressiontests/auth_backends/tests.py
  88. +6 −0 tests/regressiontests/cache/tests.py
  89. +19 −0 tests/regressiontests/datastructures/tests.py
  90. +25 −5 tests/regressiontests/forms/localflavor/pl.py
  91. +39 −11 tests/regressiontests/forms/models.py
  92. +2 −0  tests/regressiontests/forms/tests.py
  93. +23 −0 tests/regressiontests/forms/widgets.py
  94. +57 −0 tests/regressiontests/i18n/misc.py
  95. +7 −1 tests/regressiontests/i18n/tests.py
  96. +19 −4 tests/regressiontests/templates/tests.py
  97. +4 −0 tests/regressiontests/text/tests.py
  98. +27 −1 tests/regressiontests/utils/tests.py
  99. +3 −0  tests/runtests.py
View
10 AUTHORS
@@ -49,7 +49,8 @@ answer newbie questions, and generally made Django that much better:
andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com>
ant9000@netwise.it
- Florian Apolloner
+ Florian Apolloner
+ arien <regexbot@gmail.com>
David Ascher <http://ascher.ca/>
david@kazserve.org
Arthur <avandorp@gmail.com>
@@ -171,6 +172,7 @@ answer newbie questions, and generally made Django that much better:
Nagy Károly <charlie@rendszergazda.com>
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
Ian G. Kelly <ian.g.kelly@gmail.com>
+ Thomas Kerpe <thomas@kerpe.net>
Ben Khoo <khoobks@westnet.com.au>
Garth Kidd <http://www.deadlybloodyserious.com/>
kilian <kilian.cavalotti@lip6.fr>
@@ -218,6 +220,7 @@ answer newbie questions, and generally made Django that much better:
mccutchen@gmail.com
Christian Metts
michael.mcewan@gmail.com
+ michal@plovarna.cz
mikko@sorl.net
Slawek Mikula <slawek dot mikula at gmail dot com>
mitakummaa@gmail.com
@@ -262,13 +265,14 @@ answer newbie questions, and generally made Django that much better:
Brian Ray <http://brianray.chipy.org/>
remco@diji.biz
rhettg@gmail.com
+ ricardojbarrios@gmail.com
Matt Riggott
Henrique Romano <onaiort@gmail.com>
Armin Ronacher
Brian Rosner <brosner@gmail.com>
Oliver Rutherfurd <http://rutherfurd.net/>
ryankanno
- Manuel Saelices <msaelices@yaco.es>
+ Manuel Saelices <msaelices@yaco.es>
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
Vinay Sajip <vinay_sajip@yahoo.co.uk>
David Schein
@@ -276,6 +280,7 @@ answer newbie questions, and generally made Django that much better:
serbaut@gmail.com
John Shaffer <jshaffer2112@gmail.com>
Pete Shinners <pete@shinners.org>
+ jason.sidabras@gmail.com
Jozko Skrablin <jozko.skrablin@gmail.com>
SmileyChris <smileychris@gmail.com>
smurf@smurf.noris.de
@@ -330,6 +335,7 @@ answer newbie questions, and generally made Django that much better:
Jakub Wiśniowski <restless.being@gmail.com>
Maciej Wiśniowski <pigletto@gmail.com>
wojtek
+ Jason Yan <tailofthesun@gmail.com>
ye7cakf02@sneakemail.com
ymasuda@ethercube.com
Jarek Zgoda <jarek.zgoda@gmail.com>
View
10 django/conf/__init__.py
@@ -140,13 +140,3 @@ def get_all_members(self):
settings = LazySettings()
-# This function replaces itself with django.utils.translation.gettext() the
-# first time it's run. This is necessary because the import of
-# django.utils.translation requires a working settings module, and loading it
-# from within this file would cause a circular import.
-def first_time_gettext(*args):
- from django.utils.translation import gettext
- __builtins__['_'] = gettext
- return gettext(*args)
-
-__builtins__['_'] = first_time_gettext
View
3  django/conf/global_settings.py
@@ -30,7 +30,7 @@
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
-# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
+# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
# Languages we provide translations for, out of the box. The language name
@@ -275,6 +275,7 @@
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks).
SESSION_COOKIE_DOMAIN = None # A string like ".lawrence.com", or None for standard domain cookie.
SESSION_COOKIE_SECURE = False # Whether the session cookie should be secure (https:// only).
+SESSION_COOKIE_PATH = '/' # The path of the session cookie.
SESSION_SAVE_EVERY_REQUEST = False # Whether to save the session data on every request.
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether sessions expire when a user closes his browser.
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # The module to store session data
View
BIN  django/conf/locale/ca/LC_MESSAGES/django.mo
Binary file not shown
View
4,848 django/conf/locale/ca/LC_MESSAGES/django.po
2,573 additions, 2,275 deletions not shown
View
BIN  django/conf/locale/es/LC_MESSAGES/django.mo
Binary file not shown
View
4,848 django/conf/locale/es/LC_MESSAGES/django.po
2,573 additions, 2,275 deletions not shown
View
BIN  django/conf/locale/es_AR/LC_MESSAGES/django.mo
Binary file not shown
View
4,678 django/conf/locale/es_AR/LC_MESSAGES/django.po
2,612 additions, 2,066 deletions not shown
View
BIN  django/conf/locale/es_AR/LC_MESSAGES/djangojs.mo
Binary file not shown
View
14 django/conf/locale/es_AR/LC_MESSAGES/djangojs.po
@@ -6,12 +6,12 @@ msgid ""
msgstr ""
"Project-Id-Version: Django Javascript 1.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-07-14 13:45-0300\n"
+"POT-Creation-Date: 2007-10-06 14:18-0300\n"
"PO-Revision-Date: 2007-07-14 14:36-0300\n"
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
"Language-Team: Django-I18N <django-i18n@googlegroups.com>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/SelectFilter2.js:33
@@ -44,8 +44,8 @@ msgstr "Seleccione los items a agregar y haga click en "
msgid "Clear all"
msgstr "Eliminar todos"
-#: contrib/admin/media/js/dateparse.js:32
#: contrib/admin/media/js/calendar.js:24
+#: contrib/admin/media/js/dateparse.js:32
msgid ""
"January February March April May June July August September October November "
"December"
@@ -53,14 +53,14 @@ msgstr ""
"Enero Febrero Marzo Abril Mayo Junio Julio Agosto Setiembre Octubre "
"Noviembre Diciembre"
-#: contrib/admin/media/js/dateparse.js:33
-msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
-msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
-
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "D L M M J V S"
+#: contrib/admin/media/js/dateparse.js:33
+msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
+msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado"
+
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
View
BIN  django/conf/locale/he/LC_MESSAGES/django.mo
Binary file not shown
View
5,006 django/conf/locale/he/LC_MESSAGES/django.po
2,769 additions, 2,237 deletions not shown
View
BIN  django/conf/locale/hr/LC_MESSAGES/django.mo
Binary file not shown
View
262 django/conf/locale/hr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-08-06 23:19+0200\n"
-"PO-Revision-Date: 2007-08-12 23:05+0200\n"
+"PO-Revision-Date: 2007-10-12 21:22+0200\n"
"Last-Translator: Aljosa Mohorovic <aljosa.mohorovic@gmail.com>\n"
"Language-Team: Hrvatski jezik\n"
"MIME-Version: 1.0\n"
@@ -28,7 +28,7 @@ msgstr "Unos za ovo polje je obavezan."
#, python-format
msgid "Ensure your text is less than %s character."
msgid_plural "Ensure your text is less than %s characters."
-msgstr[0] "Uneseni tekst mora sadržavati manje od %s znaka."
+msgstr[0] ""
msgstr[1] "Uneseni tekst mora sadržavati manje od %s znakova."
#: oldforms/__init__.py:413
@@ -398,62 +398,62 @@ msgstr "URL %s ne prikazuje ispravnu sliku."
#: core/validators.py:196
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
-msgstr ""
+msgstr "Telefonski brojevi moraju biti u formatu XXX-XXX-XXXX. \"%s\" nije ispravan format."
#: core/validators.py:204
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
-msgstr ""
+msgstr "URL %s ne vodi na ispravan QuickTime video."
#: core/validators.py:208
msgid "A valid URL is required."
-msgstr ""
+msgstr "Ispravan URL je obavezan."
#: core/validators.py:222
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
"%s"
-msgstr ""
+msgstr "Ispravan HTML je obavezan. Pogreške:<br> %s"
#: core/validators.py:229
#, python-format
msgid "Badly formed XML: %s"
-msgstr ""
+msgstr "Loše formatiran XML: %s"
#: core/validators.py:246
#, python-format
msgid "Invalid URL: %s"
-msgstr ""
+msgstr "Neispravan URL: %s"
#: core/validators.py:251 core/validators.py:253
#, python-format
msgid "The URL %s is a broken link."
-msgstr ""
+msgstr "URL %s je neispravan (broken) link."
#: core/validators.py:259
msgid "Enter a valid U.S. state abbreviation."
-msgstr ""
+msgstr "Enter a valid U.S. state abbreviation."
#: core/validators.py:273
#, 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] ""
-msgstr[1] ""
+msgstr[0] "Pazite na izražavanje! Riječ %s nije dopuštena."
+msgstr[1] "Pazite na izražavanje! Riječi %s nisu dopuštene."
#: core/validators.py:280
#, python-format
msgid "This field must match the '%s' field."
-msgstr ""
+msgstr "Ovo polje mora biti jednako %s polju."
#: core/validators.py:299
msgid "Please enter something for at least one field."
-msgstr ""
+msgstr "Molim unesite nešto bar za jedno polje."
#: core/validators.py:308 core/validators.py:319
msgid "Please enter both fields or leave them both empty."
-msgstr ""
+msgstr "Molim unesite vrijednosti za oba polja ili ostavite oba polja prazna."
#: core/validators.py:327
#, python-format
@@ -463,7 +463,7 @@ msgstr ""
#: core/validators.py:340
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
-msgstr ""
+msgstr "Ovo polje je obavezno ako je %(field)s različito od %(value)s"
#: core/validators.py:359
msgid "Duplicate values are not allowed."
@@ -471,28 +471,27 @@ msgstr ""
#: core/validators.py:374
#, python-format
-#, fuzzy
msgid "This value must be between %(lower)s and %(upper)s."
-msgstr "i."
+msgstr "Vrijednost mora biti između %(lower)s i %(upper)s."
#: core/validators.py:376
#, python-format
msgid "This value must be at least %s."
-msgstr ""
+msgstr "Vrijednost mora biti bar %s."
#: core/validators.py:378
#, python-format
msgid "This value must be no more than %s."
-msgstr ""
+msgstr "Vrijednost ne može biti veća od %s."
#: core/validators.py:414
#, python-format
msgid "This value must be a power of %s."
-msgstr ""
+msgstr "Ova vrijednost na kvadrat mora biti %s."
#: core/validators.py:424
msgid "Please enter a valid decimal number."
-msgstr ""
+msgstr "Molim unesite ispravan decimalni broj."
#: core/validators.py:431
#, python-format
@@ -1879,7 +1878,6 @@ msgid "Documentation bookmarklets"
msgstr ""
#: contrib/admin/templates/admin_doc/bookmarklets.html:9
-#, fuzzy
msgid ""
"\n"
"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
@@ -1890,107 +1888,110 @@ msgid ""
"your computer is \"internal\").</p>\n"
msgstr ""
"\n"
-"<p class=\"help\"> i</p>"
+"<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"
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
msgid "Documentation for this page"
-msgstr ""
+msgstr "Dokumentacija za ovu stranicu"
#: 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 ""
+msgstr "Preusmjeri te sa bilo koje stranice na dokumentaciju za taj prikaz (view) koji generira stranicu."
#: contrib/admin/templates/admin_doc/bookmarklets.html:22
msgid "Show object ID"
-msgstr ""
+msgstr "Prikaži ID objekta"
#: contrib/admin/templates/admin_doc/bookmarklets.html:23
-#, fuzzy
msgid ""
"Shows the content-type and unique ID for pages that represent a single "
"object."
-msgstr "i."
+msgstr "Prikazuje tip sadržaja i jedinstveni ID za stranice koje predstavljaju pojedinačan objekt."
#: contrib/admin/templates/admin_doc/bookmarklets.html:25
msgid "Edit this object (current window)"
-msgstr ""
+msgstr "Uredi objekt (u trenutno prozoru)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:26
msgid "Jumps to the admin page for pages that represent a single object."
-msgstr ""
+msgstr "Preusmjeri na admin stranicu za stranice koje predstavljaju pojedinačan objekt."
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
msgid "Edit this object (new window)"
-msgstr ""
+msgstr "Uredi objekt (novi prozor)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:29
msgid "As above, but opens the admin page in a new window."
-msgstr ""
+msgstr "Isto kao prethodno, ali otvara admin stranicu u novom prozoru."
#: contrib/contenttypes/models.py:37
msgid "python model class name"
-msgstr ""
+msgstr "ime klase (class) python modela"
#: contrib/contenttypes/models.py:40
msgid "content type"
-msgstr ""
+msgstr "tip sadržaja"
#: contrib/contenttypes/models.py:41
msgid "content types"
-msgstr ""
+msgstr "tipovi sadržaja"
#: contrib/auth/views.py:41
msgid "Logged out"
-msgstr ""
+msgstr "Niste logirani"
#: contrib/auth/models.py:53 contrib/auth/models.py:73
msgid "name"
-msgstr ""
+msgstr "ime"
#: contrib/auth/models.py:55
msgid "codename"
-msgstr ""
+msgstr "kodno ime"
#: contrib/auth/models.py:58
msgid "permission"
-msgstr ""
+msgstr "privilegija"
#: contrib/auth/models.py:59 contrib/auth/models.py:74
msgid "permissions"
-msgstr ""
+msgstr "privilegije"
#: contrib/auth/models.py:77
msgid "group"
-msgstr ""
+msgstr "grupa"
#: contrib/auth/models.py:78 contrib/auth/models.py:121
msgid "groups"
-msgstr ""
+msgstr "grupe"
#: contrib/auth/models.py:111
msgid "username"
-msgstr ""
+msgstr "korisničko ime"
#: contrib/auth/models.py:111
-#, fuzzy
msgid ""
"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
"digits and underscores)."
-msgstr "i."
+msgstr "Obavezno 30 alfanumeričkih znakova ili manje (slova, brojevi i povlaka)."
#: contrib/auth/models.py:112
msgid "first name"
-msgstr ""
+msgstr "ime"
#: contrib/auth/models.py:113
msgid "last name"
-msgstr ""
+msgstr "prezime"
#: contrib/auth/models.py:114
msgid "e-mail address"
-msgstr ""
+msgstr "e-mail adresa"
#: contrib/auth/models.py:115
msgid "password"
@@ -2207,7 +2208,7 @@ msgstr ""
#: contrib/localflavor/de/de_states.py:17
msgid "Saxony"
-msgstr ""
+msgstr "Saxony"
#: contrib/localflavor/de/de_states.py:18
msgid "Saxony-Anhalt"
@@ -2899,306 +2900,305 @@ msgstr ""
#: contrib/localflavor/sk/sk_districts.py:85
msgid "Ziar nad Hronom"
-msgstr ""
+msgstr "Ziar nad Hronom"
#: contrib/localflavor/sk/sk_districts.py:86
msgid "Zilina"
-msgstr ""
+msgstr "Zilina"
#: contrib/localflavor/sk/forms.py:32
msgid "Enter a postal code in the format XXXXX or XXX XX."
-msgstr ""
+msgstr "Unesi ispravan poštanski broj formata XXXXX or XXX XX."
#: contrib/localflavor/cl/forms.py:32
msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
-msgstr ""
+msgstr "Unesi ispravan čileanski RUT formata XX.XXX.XXX-X."
#: contrib/localflavor/cl/forms.py:37
msgid "Enter valid a Chilean RUT"
-msgstr ""
+msgstr "Unesi ispravan čileanski RUT"
#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
msgid "Enter a valid Finnish social security number."
-msgstr ""
+msgstr "Unesi ispravan finski broj socijalnog osiguranja."
#: contrib/sessions/models.py:68
msgid "session key"
-msgstr ""
+msgstr "session ključ (key)"
#: contrib/sessions/models.py:69
msgid "session data"
-msgstr ""
+msgstr "session podaci"
#: contrib/sessions/models.py:70
msgid "expire date"
-msgstr ""
+msgstr "ističe datuma"
#: contrib/sessions/models.py:74
msgid "session"
-msgstr ""
+msgstr "session"
#: contrib/sessions/models.py:75
msgid "sessions"
-msgstr ""
+msgstr "sessions"
#: contrib/flatpages/models.py:8
-#, fuzzy
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr "i."
+msgstr "Primjer: '/about/contact/'. Provjerite ako imate prvi i preostale slash-eve (/)."
#: contrib/flatpages/models.py:9
msgid "title"
-msgstr ""
+msgstr "naslov"
#: contrib/flatpages/models.py:10
msgid "content"
-msgstr ""
+msgstr "sadržaj"
#: contrib/flatpages/models.py:11
msgid "enable comments"
-msgstr ""
+msgstr "uključi komentare"
#: contrib/flatpages/models.py:12
msgid "template name"
-msgstr ""
+msgstr "ime template-a"
#: contrib/flatpages/models.py:13
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
-msgstr ""
+msgstr "Primjer: 'flatpages/contact_page.html'. Ako navedeno nije definirano sistem će koristiti 'flatpages/default.html'."
#: contrib/flatpages/models.py:14
msgid "registration required"
-msgstr ""
+msgstr "registracija obavezna"
#: contrib/flatpages/models.py:14
msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr ""
+msgstr "Ako je ovo selektirano samo logirani korisnici moći će vidjeti ovu stranicu."
#: contrib/flatpages/models.py:18
msgid "flat page"
-msgstr ""
+msgstr "statična stranica"
#: contrib/flatpages/models.py:19
msgid "flat pages"
-msgstr ""
+msgstr "statične stranice"
#: utils/dates.py:6
msgid "Monday"
-msgstr ""
+msgstr "Ponedjeljak"
#: utils/dates.py:6
msgid "Tuesday"
-msgstr ""
+msgstr "Utorak"
#: utils/dates.py:6
msgid "Wednesday"
-msgstr ""
+msgstr "Srijeda"
#: utils/dates.py:6
msgid "Thursday"
-msgstr ""
+msgstr "Četvrtak"
#: utils/dates.py:6
msgid "Friday"
-msgstr ""
+msgstr "Petak"
#: utils/dates.py:7
msgid "Saturday"
-msgstr ""
+msgstr "Subota"
#: utils/dates.py:7
msgid "Sunday"
-msgstr ""
+msgstr "Nedjelja"
#: utils/dates.py:10
msgid "Mon"
-msgstr ""
+msgstr "Pon"
#: utils/dates.py:10
msgid "Tue"
-msgstr ""
+msgstr "Uto"
#: utils/dates.py:10
msgid "Wed"
-msgstr ""
+msgstr "Sri"
#: utils/dates.py:10
msgid "Thu"
-msgstr ""
+msgstr "Čet"
#: utils/dates.py:10
msgid "Fri"
-msgstr ""
+msgstr "Pet"
#: utils/dates.py:11
msgid "Sat"
-msgstr ""
+msgstr "Sub"
#: utils/dates.py:11
msgid "Sun"
-msgstr ""
+msgstr "Ned"
#: utils/dates.py:18
msgid "January"
-msgstr ""
+msgstr "Siječanj"
#: utils/dates.py:18
msgid "February"
-msgstr ""
+msgstr "Veljača"
#: utils/dates.py:18 utils/dates.py:31
msgid "March"
-msgstr ""
+msgstr "Ožujak"
#: utils/dates.py:18 utils/dates.py:31
msgid "April"
-msgstr ""
+msgstr "Travanj"
#: utils/dates.py:18 utils/dates.py:31
msgid "May"
-msgstr ""
+msgstr "Svibanj"
#: utils/dates.py:18 utils/dates.py:31
msgid "June"
-msgstr ""
+msgstr "Lipanj"
#: utils/dates.py:19 utils/dates.py:31
msgid "July"
-msgstr ""
+msgstr "Srpanj"
#: utils/dates.py:19
msgid "August"
-msgstr ""
+msgstr "Kolovoz"
#: utils/dates.py:19
msgid "September"
-msgstr ""
+msgstr "Rujan"
#: utils/dates.py:19
msgid "October"
-msgstr ""
+msgstr "Listopad"
#: utils/dates.py:19
msgid "November"
-msgstr ""
+msgstr "Studeni"
#: utils/dates.py:20
msgid "December"
-msgstr ""
+msgstr "Prosinac"
#: utils/dates.py:23
msgid "jan"
-msgstr ""
+msgstr "sij."
#: utils/dates.py:23
msgid "feb"
-msgstr ""
+msgstr "velj."
#: utils/dates.py:23
msgid "mar"
-msgstr ""
+msgstr "ožu."
#: utils/dates.py:23
msgid "apr"
-msgstr ""
+msgstr "tra."
#: utils/dates.py:23
msgid "may"
-msgstr ""
+msgstr "svi."
#: utils/dates.py:23
msgid "jun"
-msgstr ""
+msgstr "lip."
#: utils/dates.py:24
msgid "jul"
-msgstr ""
+msgstr "srp."
#: utils/dates.py:24
msgid "aug"
-msgstr ""
+msgstr "kol."
#: utils/dates.py:24
msgid "sep"
-msgstr ""
+msgstr "ruj."
#: utils/dates.py:24
msgid "oct"
-msgstr ""
+msgstr "lis."
#: utils/dates.py:24
msgid "nov"
-msgstr ""
+msgstr "stu."
#: utils/dates.py:24
msgid "dec"
-msgstr ""
+msgstr "pro."
#: utils/dates.py:31
msgid "Jan."
-msgstr ""
+msgstr "Sij."
#: utils/dates.py:31
msgid "Feb."
-msgstr ""
+msgstr "Velj."
#: utils/dates.py:32
msgid "Aug."
-msgstr ""
+msgstr "Kol."
#: utils/dates.py:32
msgid "Sept."
-msgstr ""
+msgstr "Ruj."
#: utils/dates.py:32
msgid "Oct."
-msgstr ""
+msgstr "Lis."
#: utils/dates.py:32
msgid "Nov."
-msgstr ""
+msgstr "Stu."
#: utils/dates.py:32
msgid "Dec."
-msgstr ""
+msgstr "Pro."
#: utils/timesince.py:12
msgid "year"
msgid_plural "years"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "godina"
+msgstr[1] "godina"
#: utils/timesince.py:13
msgid "month"
msgid_plural "months"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "mjesec"
+msgstr[1] "mjesec"
#: utils/timesince.py:14
msgid "week"
msgid_plural "weeks"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "tjedan"
+msgstr[1] "tjedan"
#: utils/timesince.py:15
msgid "day"
msgid_plural "days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "dan"
+msgstr[1] "dan"
#: utils/timesince.py:16
msgid "hour"
msgid_plural "hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "sati"
+msgstr[1] "sati"
#: utils/timesince.py:17
msgid "minute"
msgid_plural "minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "minute"
+msgstr[1] "minuta"
#: utils/timesince.py:39
#, python-format
@@ -3228,7 +3228,7 @@ msgstr ""
#: utils/dateformat.py:97
msgid "midnight"
-msgstr ""
+msgstr "ponoć"
#: utils/dateformat.py:99
msgid "noon"
@@ -3256,7 +3256,7 @@ msgstr ""
#: template/defaultfilters.py:485
msgid "yes,no,maybe"
-msgstr ""
+msgstr "da,ne,možda"
#: template/defaultfilters.py:514
#, python-format
View
10 django/contrib/admin/media/js/urlify.js
@@ -45,7 +45,14 @@ var UKRAINIAN_MAP = {
}
var CZECH_MAP = {
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
- 'ž':'z'
+ 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
+ 'Ů':'U', 'Ž':'Z'
+}
+
+var POLISH_MAP = {
+ 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z',
+ 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'e', 'Ł':'L', 'Ń':'N', 'Ó':'o', 'Ś':'S',
+ 'Ź':'Z', 'Ż':'Z'
}
var ALL_DOWNCODE_MAPS=new Array()
@@ -56,6 +63,7 @@ ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
ALL_DOWNCODE_MAPS[6]=CZECH_MAP
+ALL_DOWNCODE_MAPS[7]=POLISH_MAP
var Downcoder = new Object();
Downcoder.Initialize = function()
View
4 django/contrib/comments/feeds.py
@@ -4,7 +4,7 @@
from django.contrib.sites.models import Site
class LatestFreeCommentsFeed(Feed):
- "Feed of latest comments on the current site."
+ """Feed of latest free comments on the current site."""
comments_class = FreeComment
@@ -30,7 +30,7 @@ def items(self):
return self.get_query_set()[:40]
class LatestCommentsFeed(LatestFreeCommentsFeed):
- """Feed of latest free comments on the current site"""
+ """Feed of latest comments on the current site."""
comments_class = Comment
View
0  django/contrib/localflavor/es/__init__.py
No changes.
View
58 django/contrib/localflavor/es/es_provinces.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+from django.utils.translation import ugettext_lazy as _
+
+PROVINCE_CHOICES = (
+ ('01', _('Arava')),
+ ('02', _('Albacete')),
+ ('03', _('Alacant')),
+ ('04', _('Almeria')),
+ ('05', _('Avila')),
+ ('06', _('Badajoz')),
+ ('07', _('Illes Balears')),
+ ('08', _('Barcelona')),
+ ('09', _('Burgos')),
+ ('10', _('Caceres')),
+ ('11', _('Cadiz')),
+ ('12', _('Castello')),
+ ('13', _('Ciudad Real')),
+ ('14', _('Cordoba')),
+ ('15', _('A Coruna')),
+ ('16', _('Cuenca')),
+ ('17', _('Girona')),
+ ('18', _('Granada')),
+ ('19', _('Guadalajara')),
+ ('20', _('Guipuzkoa')),
+ ('21', _('Huelva')),
+ ('22', _('Huesca')),
+ ('23', _('Jaen')),
+ ('24', _('Leon')),
+ ('25', _('Lleida')),
+ ('26', _('La Rioja')),
+ ('27', _('Lugo')),
+ ('28', _('Madrid')),
+ ('29', _('Malaga')),
+ ('30', _('Murcia')),
+ ('31', _('Navarre')),
+ ('32', _('Ourense')),
+ ('33', _('Asturias')),
+ ('34', _('Palencia')),
+ ('35', _('Las Palmas')),
+ ('36', _('Pontevedra')),
+ ('37', _('Salamanca')),
+ ('38', _('Santa Cruz de Tenerife')),
+ ('39', _('Cantabria')),
+ ('40', _('Segovia')),
+ ('41', _('Seville')),
+ ('42', _('Soria')),
+ ('43', _('Tarragona')),
+ ('44', _('Teruel')),
+ ('45', _('Toledo')),
+ ('46', _('Valencia')),
+ ('47', _('Valladolid')),
+ ('48', _('Bizkaia')),
+ ('49', _('Zamora')),
+ ('50', _('Zaragoza')),
+ ('51', _('Ceuta')),
+ ('52', _('Melilla')),
+)
+
View
23 django/contrib/localflavor/es/es_regions.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from django.utils.translation import ugettext_lazy as _
+
+REGION_CHOICES = (
+ ('AN', _('Andalusia')),
+ ('AR', _('Aragon')),
+ ('O', _('Principality of Asturias')),
+ ('IB', _('Balearic Islands')),
+ ('PV', _('Basque Country')),
+ ('CN', _('Canary Islands')),
+ ('S', _('Cantabria')),
+ ('CM', _('Castile-La Mancha')),
+ ('CL', _('Castile and Leon')),
+ ('CT', _('Catalonia')),
+ ('EX', _('Extremadura')),
+ ('GA', _('Galicia')),
+ ('LO', _('La Rioja')),
+ ('M', _('Madrid')),
+ ('MU', _('Region of Murcia')),
+ ('NA', _('Foral Community of Navarre')),
+ ('VC', _('Valencian Community')),
+)
+
View
173 django/contrib/localflavor/es/forms.py
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+"""
+Spanish-specific Form helpers
+"""
+
+from django.newforms import ValidationError
+from django.newforms.fields import RegexField, Select, EMPTY_VALUES
+from django.utils.translation import ugettext as _
+import re
+
+class ESPostalCodeField(RegexField):
+ """
+ A form field that validates its input as a spanish postal code.
+
+ Spanish postal code is a five digits string, with two first digits
+ between 01 and 52, assigned to provinces code.
+ """
+ def __init__(self, *args, **kwargs):
+ super(ESPostalCodeField, self).__init__(
+ r'^(0[1-9]|[1-4][0-9]|5[0-2])\d{3}$',
+ max_length=None, min_length=None,
+ error_message=_('Enter a valid postal code in the range and format 01XXX - 52XXX.'),
+ *args, **kwargs)
+
+class ESPhoneNumberField(RegexField):
+ """
+ A form field that validates its input as a Spanish phone number.
+ Information numbers are ommited.
+
+ Spanish phone numbers are nine digit numbers, where first digit is 6 (for
+ cell phones), 8 (for special phones), or 9 (for landlines and special
+ phones)
+
+ TODO: accept and strip characters like dot, hyphen... in phone number
+ """
+ def __init__(self, *args, **kwargs):
+ super(ESPhoneNumberField, self).__init__(r'^(6|8|9)\d{8}$',
+ max_length=None, min_length=None,
+ error_message=_('Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.'),
+ *args, **kwargs)
+
+class ESIdentityCardNumberField(RegexField):
+ """
+ Spanish NIF/NIE/CIF (Fiscal Identification Number) code.
+
+ Validates three diferent formats:
+
+ NIF (individuals): 12345678A
+ CIF (companies): A12345678
+ NIE (foreigners): X12345678A
+
+ according to a couple of simple checksum algorithms.
+
+ Value can include a space or hyphen separator between number and letters.
+ Number length is not checked for NIF (or NIE), old values start with a 1,
+ and future values can contain digits greater than 8. The CIF control digit
+ can be a number or a letter depending on company type. Algorithm is not
+ public, and different authors have different opinions on which ones allows
+ letters, so both validations are assumed true for all types.
+ """
+ def __init__(self, only_nif=False, *args, **kwargs):
+ self.only_nif = only_nif
+ self.nif_control = 'TRWAGMYFPDXBNJZSQVHLCKE'
+ self.cif_control = 'JABCDEFGHI'
+ self.cif_types = 'ABCDEFGHKLMNPQS'
+ self.nie_types = 'XT'
+ if self.only_nif:
+ self.id_types = 'NIF or NIE'
+ else:
+ self.id_types = 'NIF, NIE, or CIF'
+ super(ESIdentityCardNumberField, self).__init__(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types + self.cif_types.lower() + self.nie_types.lower(), self.nif_control + self.nif_control.lower()),
+ max_length=None, min_length=None,
+ error_message=_('Please enter a valid %s.' % self.id_types),
+ *args, **kwargs)
+
+ def clean(self, value):
+ super(ESIdentityCardNumberField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ nif_get_checksum = lambda d: self.nif_control[int(d)%23]
+
+ value = value.upper().replace(' ', '').replace('-', '')
+ m = re.match(r'^([%s]?)[ -]?(\d+)[ -]?([%s]?)$' % (self.cif_types + self.nie_types, self.nif_control), value)
+ letter1, number, letter2 = m.groups()
+
+ if not letter1 and letter2:
+ # NIF
+ if letter2 == nif_get_checksum(number):
+ return value
+ else:
+ raise ValidationError, _('Invalid checksum for NIF.')
+ elif letter1 in self.nie_types and letter2:
+ # NIE
+ if letter2 == nif_get_checksum(number):
+ return value
+ else:
+ raise ValidationError, _('Invalid checksum for NIE.')
+ elif not self.only_nif and letter1 in self.cif_types and len(number) in [7, 8]:
+ # CIF
+ if not letter2:
+ number, letter2 = number[:-1], int(number[-1])
+ checksum = cif_get_checksum(number)
+ if letter2 in [checksum, self.cif_control[checksum]]:
+ return value
+ else:
+ raise ValidationError, _('Invalid checksum for CIF.')
+ else:
+ raise ValidationError, _('Please enter a valid %s.' % self.id_types)
+
+class ESCCCField(RegexField):
+ """
+ A form field that validates its input as a Spanish bank account or CCC
+ (Codigo Cuenta Cliente).
+
+ Spanish CCC is in format EEEE-OOOO-CC-AAAAAAAAAA where:
+
+ E = entity
+ O = office
+ C = checksum
+ A = account
+
+ It's also valid to use a space as delimiter, or to use no delimiter.
+
+ First checksum digit validates entity and office, and last one
+ validates account. Validation is done multiplying every digit of 10
+ digit value (with leading 0 if necessary) by number in its position in
+ string 1, 2, 4, 8, 5, 10, 9, 7, 3, 6. Sum resulting numbers and extract
+ it from 11. Result is checksum except when 10 then is 1, or when 11
+ then is 0.
+
+ TODO: allow IBAN validation too
+ """
+ def __init__(self, *args, **kwargs):
+ super(ESCCCField, self).__init__(r'^\d{4}[ -]?\d{4}[ -]?\d{2}[ -]?\d{10}$',
+ max_length=None, min_length=None,
+ error_message=_('Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.'),
+ *args, **kwargs)
+
+ def clean(self, value):
+ super(ESCCCField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ control_str = [1, 2, 4, 8, 5, 10, 9, 7, 3, 6]
+ m = re.match(r'^(\d{4})[ -]?(\d{4})[ -]?(\d{2})[ -]?(\d{10})$', value)
+ entity, office, checksum, account = m.groups()
+ get_checksum = lambda d: str(11 - sum([int(digit) * int(control) for digit, control in zip(d, control_str)]) % 11).replace('10', '1').replace('11', '0')
+ if get_checksum('00' + entity + office) + get_checksum(account) == checksum:
+ return value
+ else:
+ raise ValidationError, _('Invalid checksum for bank account number.')
+
+class ESRegionSelect(Select):
+ """
+ A Select widget that uses a list of spanish regions as its choices.
+ """
+ def __init__(self, attrs=None):
+ from es_regions import REGION_CHOICES
+ super(ESRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
+
+class ESProvinceSelect(Select):
+ """
+ A Select widget that uses a list of spanish provinces as its choices.
+ """
+ def __init__(self, attrs=None):
+ from es_provinces import PROVINCE_CHOICES
+ super(ESProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
+
+
+def cif_get_checksum(number):
+ s1 = sum([int(digit) for pos, digit in enumerate(number) if int(pos) % 2])
+ s2 = sum([sum([int(unit) for unit in str(int(digit) * 2)]) for pos, digit in enumerate(number) if not int(pos) % 2])
+ return 10 - ((s1 + s2) % 10)
+
View
94 django/contrib/localflavor/pl/forms.py
@@ -2,6 +2,8 @@
Polish-specific form helpers
"""
+import re
+
from django.newforms import ValidationError
from django.newforms.fields import Select, RegexField
from django.utils.translation import ugettext as _
@@ -34,20 +36,6 @@ class PLNationalIdentificationNumberField(RegexField):
The algorithm is documented at http://en.wikipedia.org/wiki/PESEL.
"""
- def has_valid_checksum(self, number):
- """
- Calculates a checksum with the provided algorithm.
- """
- multiple_table = (1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1)
- result = 0
- for i in range(len(number)):
- result += int(number[i])*multiple_table[i]
-
- if result % 10 == 0:
- return True
- else:
- return False
-
def __init__(self, *args, **kwargs):
super(PLNationalIdentificationNumberField, self).__init__(r'^\d{11}$',
max_length=None, min_length=None, error_message=_(u'National Identification Number consists of 11 digits.'),
@@ -59,17 +47,95 @@ def clean(self,value):
raise ValidationError(_(u'Wrong checksum for the National Identification Number.'))
return u'%s' % value
+ def has_valid_checksum(self, number):
+ """
+ Calculates a checksum with the provided algorithm.
+ """
+ multiple_table = (1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1)
+ result = 0
+ for i in range(len(number)):
+ result += int(number[i]) * multiple_table[i]
+ return result % 10 == 0
class PLTaxNumberField(RegexField):
"""
A form field that validates as Polish Tax Number (NIP).
Valid forms are: XXX-XXX-YY-YY or XX-XX-YYY-YYY.
+
+ Checksum algorithm based on documentation at
+ http://wipos.p.lodz.pl/zylla/ut/nip-rego.html
"""
+
def __init__(self, *args, **kwargs):
super(PLTaxNumberField, self).__init__(r'^\d{3}-\d{3}-\d{2}-\d{2}$|^\d{2}-\d{2}-\d{3}-\d{3}$',
max_length=None, min_length=None,
error_message=_(u'Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX.'), *args, **kwargs)
+ def clean(self,value):
+ super(PLTaxNumberField, self).clean(value)
+ value = re.sub("[-]", "", value)
+ if not self.has_valid_checksum(value):
+ raise ValidationError(_(u'Wrong checksum for the Tax Number (NIP).'))
+ return u'%s' % value
+
+ def has_valid_checksum(self, number):
+ """
+ Calculates a checksum with the provided algorithm.
+ """
+ multiple_table = (6, 5, 7, 2, 3, 4, 5, 6, 7)
+ result = 0
+ for i in range(len(number)-1):
+ result += int(number[i]) * multiple_table[i]
+
+ result %= 11
+ if result == int(number[-1]):
+ return True
+ else:
+ return False
+
+class PLNationalBusinessRegisterField(RegexField):
+ """
+ A form field that validated as Polish National Official Business Register Number (REGON)
+ Valid forms are: 7 or 9 digits number
+
+ More on the field: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm
+
+ The checksum algorithm is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html
+ """
+ def __init__(self, *args, **kwargs):
+ super(PLNationalBusinessRegisterField, self).__init__(r'^\d{7,9}$',
+ max_length=None, min_length=None, error_message=_(u'National Business Register Number (REGON) consists of 7 or 9 digits.'),
+ *args, **kwargs)
+
+ def clean(self,value):
+ super(PLNationalBusinessRegisterField, self).clean(value)
+ if not self.has_valid_checksum(value):
+ raise ValidationError(_(u'Wrong checksum for the National Business Register Number (REGON).'))
+ return u'%s' % value
+
+ def has_valid_checksum(self, number):
+ """
+ Calculates a checksum with the provided algorithm.
+ """
+ multiple_table_7 = (2, 3, 4, 5, 6, 7)
+ multiple_table_9 = (8, 9, 2, 3, 4, 5, 6, 7)
+ result = 0
+
+ if len(number) == 7:
+ multiple_table = multiple_table_7
+ else:
+ multiple_table = multiple_table_9
+
+ for i in range(len(number)-1):
+ result += int(number[i]) * multiple_table[i]
+
+ result %= 11
+ if result == 10:
+ result = 0
+ if result == int(number[-1]):
+ return True
+ else:
+ return False
class PLPostalCodeField(RegexField):
"""
View
1  django/contrib/sessions/backends/base.py
@@ -48,6 +48,7 @@ def get(self, key, default=None):
return self._session.get(key, default)
def pop(self, key, *args):
+ self.modified = self.modified or key in self._session
return self._session.pop(key, *args)
def set_test_cookie(self):
View
12 django/contrib/sessions/middleware.py
@@ -31,7 +31,7 @@ def process_response(self, request, response):
else:
max_age = settings.SESSION_COOKIE_AGE
rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE)
-
+
# Fixed length date must have '-' separation in the format
# DD-MMM-YYYY for compliance with Netscape cookie standard
expires = datetime.datetime.strftime(datetime.datetime.utcnow() + \
@@ -39,8 +39,10 @@ def process_response(self, request, response):
# Save the seesion data and refresh the client cookie.
request.session.save()
- response.set_cookie(settings.SESSION_COOKIE_NAME, request.session.session_key,
- max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
- secure=settings.SESSION_COOKIE_SECURE or None)
-
+ response.set_cookie(settings.SESSION_COOKIE_NAME,
+ request.session.session_key, max_age=max_age,
+ expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
+ path=settings.SESSION_COOKIE_PATH,
+ secure=settings.SESSION_COOKIE_SECURE or None)
+
return response
View
23 django/contrib/sessions/tests.py
@@ -3,6 +3,7 @@
>>> from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
>>> from django.contrib.sessions.backends.cache import SessionStore as CacheSession
>>> from django.contrib.sessions.backends.file import SessionStore as FileSession
+>>> from django.contrib.sessions.backends.base import SessionBase
>>> db_session = DatabaseSession()
>>> db_session.modified
@@ -52,6 +53,28 @@
>>> cache_session.delete(cache_session.session_key)
>>> cache_session.exists(cache_session.session_key)
False
+
+>>> s = SessionBase()
+>>> s._session['some key'] = 'exists' # Pre-populate the session with some data
+>>> s.accessed = False # Reset to pretend this wasn't accessed previously
+
+>>> s.accessed, s.modified
+(False, False)
+
+>>> s.pop('non existant key', 'does not exist')
+'does not exist'
+>>> s.accessed, s.modified
+(True, False)
+
+>>> s.accessed = False # Reset the accessed flag
+
+>>> s.pop('some key')
+'exists'
+>>> s.accessed, s.modified
+(True, True)
+
+>>> s.pop('some key', 'does not exist')
+'does not exist'
"""
if __name__ == '__main__':
View
1  django/contrib/syndication/feeds.py
@@ -89,6 +89,7 @@ def get_feed(self, url=None):
categories = self.__get_dynamic_attr('categories', obj),
feed_copyright = self.__get_dynamic_attr('feed_copyright', obj),
feed_guid = self.__get_dynamic_attr('feed_guid', obj),
+ ttl = self.__get_dynamic_attr('ttl', obj),
)
try:
View
8 django/core/cache/backends/base.py
@@ -14,6 +14,14 @@ def __init__(self, params):
timeout = 300
self.default_timeout = timeout
+ def add(self, key, value, timeout=None):
+ """
+ Set a value in the cache if the key does not already exist. If
+ timeout is given, that timeout will be used for the key; otherwise
+ the default cache timeout will be used.
+ """
+ raise NotImplementedError
+
def get(self, key, default=None):
"""
Fetch a given key from the cache. If the key does not exist, return
View
8 django/core/cache/backends/db.py
@@ -38,6 +38,12 @@ def get(self, key, default=None):
return pickle.loads(base64.decodestring(row[1]))
def set(self, key, value, timeout=None):
+ return self._base_set('set', key, value, timeout)
+
+ def add(self, key, value, timeout=None):
+ return self._base_set('add', key, value, timeout)
+
+ def _base_set(self, mode, key, value, timeout=None):
if timeout is None:
timeout = self.default_timeout
cursor = connection.cursor()
@@ -50,7 +56,7 @@ def set(self, key, value, timeout=None):
encoded = base64.encodestring(pickle.dumps(value, 2)).strip()
cursor.execute("SELECT cache_key FROM %s WHERE cache_key = %%s" % self._table, [key])
try:
- if cursor.fetchone():
+ if mode == 'set' and cursor.fetchone():
cursor.execute("UPDATE %s SET value = %%s, expires = %%s WHERE cache_key = %%s" % self._table, [encoded, str(exp), key])
else:
cursor.execute("INSERT INTO %s (cache_key, value, expires) VALUES (%%s, %%s, %%s)" % self._table, [key, encoded, str(exp)])
View
3  django/core/cache/backends/dummy.py
@@ -6,6 +6,9 @@ class CacheClass(BaseCache):
def __init__(self, *args, **kwargs):
pass
+ def add(self, *args, **kwargs):
+ pass
+
def get(self, key, default=None):
return default
View
20 django/core/cache/backends/filebased.py
@@ -17,6 +17,26 @@ def __init__(self, dir, params):
del self._cache
del self._expire_info
+ def add(self, key, value, timeout=None):
+ fname = self._key_to_file(key)
+ if timeout is None:
+ timeout = self.default_timeout
+ try:
+ filelist = os.listdir(self._dir)
+ except (IOError, OSError):
+ self._createdir()
+ filelist = []
+ if len(filelist) > self._max_entries:
+ self._cull(filelist)
+ if os.path.basename(fname) not in filelist:
+ try:
+ f = open(fname, 'wb')
+ now = time.time()
+ pickle.dump(now + timeout, f, 2)
+ pickle.dump(value, f, 2)
+ except (IOError, OSError):
+ pass
+
def get(self, key, default=None):
fname = self._key_to_file(key)
try:
View
7 django/core/cache/backends/locmem.py
@@ -14,6 +14,13 @@ def __init__(self, host, params):
SimpleCacheClass.__init__(self, host, params)
self._lock = RWLock()
+ def add(self, key, value, timeout=None):
+ self._lock.writer_enters()
+ try:
+ SimpleCacheClass.add(self, key, value, timeout)
+ finally:
+ self._lock.writer_leaves()
+
def get(self, key, default=None):
should_delete = False
self._lock.reader_enters()
View
3  django/core/cache/backends/memcached.py
@@ -16,6 +16,9 @@ def __init__(self, server, params):
BaseCache.__init__(self, params)
self._cache = memcache.Client(server.split(';'))
+ def add(self, key, value, timeout=0):
+ self._cache.add(key.encode('ascii', 'ignore'), value, timeout or self.default_timeout)
+
def get(self, key, default=None):
val = self._cache.get(smart_str(key))
if val is None:
View
9 django/core/cache/backends/simple.py
@@ -21,6 +21,15 @@ def __init__(self, host, params):
except (ValueError, TypeError):
self._cull_frequency = 3
+ def add(self, key, value, timeout=None):
+ if len(self._cache) >= self._max_entries:
+ self._cull()
+ if timeout is None:
+ timeout = self.default_timeout
+ if key not in self._cache.keys():
+ self._cache[key] = value
+ self._expire_info[key] = time.time() + timeout
+
def get(self, key, default=None):
now = time.time()
exp = self._expire_info.get(key)
View
19 django/core/handlers/modpython.py
@@ -136,6 +136,8 @@ def _get_method(self):
method = property(_get_method)
class ModPythonHandler(BaseHandler):
+ request_class = ModPythonRequest
+
def __call__(self, req):
# mod_python fakes the environ, and thus doesn't process SetEnv. This fixes that
os.environ.update(req.subprocess_env)
@@ -150,13 +152,16 @@ def __call__(self, req):
dispatcher.send(signal=signals.request_started)
try:
- request = ModPythonRequest(req)
- response = self.get_response(request)
-
- # Apply response middleware
- for middleware_method in self._response_middleware:
- response = middleware_method(request, response)
-
+ try:
+ request = self.request_class(req)
+ except UnicodeDecodeError:
+ response = http.HttpResponseBadRequest()
+ else:
+ response = self.get_response(request)
+
+ # Apply response middleware
+ for middleware_method in self._response_middleware:
+ response = middleware_method(request, response)
finally:
dispatcher.send(signal=signals.request_finished)
View
20 django/core/handlers/wsgi.py
@@ -165,7 +165,9 @@ def _get_raw_post_data(self):
content_length = int(self.environ.get('CONTENT_LENGTH', 0))
except ValueError: # if CONTENT_LENGTH was empty string or not an integer
content_length = 0
- safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
+ if content_length > 0:
+ safe_copyfileobj(self.environ['wsgi.input'], buf,
+ size=content_length)
self._raw_post_data = buf.getvalue()
buf.close()
return self._raw_post_data
@@ -179,6 +181,7 @@ def _get_raw_post_data(self):
class WSGIHandler(BaseHandler):
initLock = Lock()
+ request_class = WSGIRequest
def __call__(self, environ, start_response):
from django.conf import settings
@@ -194,13 +197,16 @@ def __call__(self, environ, start_response):
dispatcher.send(signal=signals.request_started)
try:
- request = WSGIRequest(environ)
- response = self.get_response(request)
-
- # Apply response middleware
- for middleware_method in self._response_middleware:
- response = middleware_method(request, response)
+ try:
+ request = self.request_class(environ)
+ except UnicodeDecodeError:
+ response = http.HttpResponseBadRequest()
+ else:
+ response = self.get_response(request)
+ # Apply response middleware
+ for middleware_method in self._response_middleware:
+ response = middleware_method(request, response)
finally:
dispatcher.send(signal=signals.request_finished)
View
4 django/core/mail.py
@@ -73,7 +73,7 @@ def __setitem__(self, name, val):
if '\n' in val or '\r' in val:
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
try:
- val = str(force_unicode(val))
+ val = force_unicode(val).encode('ascii')
except UnicodeEncodeError:
if name.lower() in ('to', 'from', 'cc'):
result = []
@@ -92,7 +92,7 @@ def __setitem__(self, name, val):
if '\n' in val or '\r' in val:
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
try:
- val = str(force_unicode(val))
+ val = force_unicode(val).encode('ascii')
except UnicodeEncodeError:
if name.lower() in ('to', 'from', 'cc'):
result = []
View
111 django/core/management/__init__.py
@@ -1,31 +1,35 @@
-import django
-from django.core.management.base import BaseCommand, CommandError, handle_default_options
-from optparse import OptionParser
import os
import sys
+from optparse import OptionParser
from imp import find_module
+import django
+from django.core.management.base import BaseCommand, CommandError, handle_default_options
+
# For backwards compatibility: get_version() used to be in this module.
get_version = django.get_version
-# A cache of loaded commands, so that call_command
+# A cache of loaded commands, so that call_command
# doesn't have to reload every time it is called
_commands = None
def find_commands(management_dir):
"""
- Given a path to a management directory, return a list of all the command names
- that are available. Returns an empty list if no commands are defined.
+ Given a path to a management directory, returns a list of all the command
+ names that are available.
+
+ Returns an empty list if no commands are defined.
"""
- command_dir = os.path.join(management_dir,'commands')
+ command_dir = os.path.join(management_dir, 'commands')
try:
- return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
+ return [f[:-3] for f in os.listdir(command_dir)
+ if not f.startswith('_') and f.endswith('.py')]
except OSError:
return []
def find_management_module(app_name):
"""
- Determine the path to the management module for the application named,
+ Determines the path to the management module for the application named,
without acutally importing the application or the management module.
Raises ImportError if the management module cannot be found for any reason.
@@ -36,23 +40,23 @@ def find_management_module(app_name):
path = None
while parts:
part = parts.pop()
- f,path,descr = find_module(part, path and [path] or None)
+ f, path, descr = find_module(part, path and [path] or None)
return path
-
+
def load_command_class(app_name, name):
"""
- Given a command name and an application name, returns the Command
+ Given a command name and an application name, returns the Command
class instance. All errors raised by the importation process
(ImportError, AttributeError) are allowed to propagate.
"""
- return getattr(__import__('%s.management.commands.%s' % (app_name, name),
+ return getattr(__import__('%s.management.commands.%s' % (app_name, name),
{}, {}, ['Command']), 'Command')()
def get_commands(load_user_commands=True, project_directory=None):
"""
Returns a dictionary of commands against the application in which
- those commands can be found. This works by looking for a
- management.commands package in django.core, and in each installed
+ those commands can be found. This works by looking for a
+ management.commands package in django.core, and in each installed
application -- if a commands package exists, all commands in that
package are registered.
@@ -62,38 +66,38 @@ def get_commands(load_user_commands=True, project_directory=None):
startapp command will be modified to use that directory.
The dictionary is in the format {command_name: app_name}. Key-value
- pairs from this dictionary can then be used in calls to
+ pairs from this dictionary can then be used in calls to
load_command_class(app_name, command_name)
-
+
If a specific version of a command must be loaded (e.g., with the
startapp command), the instantiated module can be placed in the
dictionary in place of the application name.
-
+
The dictionary is cached on the first call, and reused on subsequent
calls.
"""
global _commands
if _commands is None:
- _commands = dict([(name, 'django.core')
+ _commands = dict([(name, 'django.core')
for name in find_commands(__path__[0])])
if load_user_commands:
- # Get commands from all installed apps
+ # Get commands from all installed apps.
from django.conf import settings
for app_name in settings.INSTALLED_APPS:
try:
path = find_management_module(app_name)
- _commands.update(dict([(name, app_name)
+ _commands.update(dict([(name, app_name)
for name in find_commands(path)]))
except ImportError:
pass # No management module - ignore this app
-
+
if project_directory:
# Remove the "startproject" command from self.commands, because
# that's a django-admin.py command, not a manage.py command.
del _commands['startproject']
# Override the startapp command so that it always uses the
- # project_directory, not the current working directory
+ # project_directory, not the current working directory
# (which is default).
from django.core.management.commands.startapp import ProjectCommand
_commands['startapp'] = ProjectCommand(project_directory)
@@ -113,7 +117,7 @@ def call_command(name, *args, **options):
"""
try:
app_name = get_commands()[name]
- if isinstance(app_name, BaseCommand):
+ if isinstance(app_name, BaseCommand):
# If the command is already loaded, use it directly.
klass = app_name
else:
@@ -121,16 +125,16 @@ def call_command(name, *args, **options):
except KeyError:
raise CommandError, "Unknown command: %r" % name
return klass.execute(*args, **options)
-
-class LaxOptionParser(OptionParser):
+
+class LaxOptionParser(OptionParser):
"""
An option parser that doesn't raise any errors on unknown options.
-
+
This is needed because the --settings and --pythonpath options affect
- the commands (and thus the options) that are available to the user.
+ the commands (and thus the options) that are available to the user.
"""
- def error(self, msg):
- pass
+ def error(self, msg):
+ pass
class ManagementUtility(object):
"""
@@ -144,16 +148,19 @@ def __init__(self, argv=None):
self.prog_name = os.path.basename(self.argv[0])
self.project_directory = None
self.user_commands = False
-
+
def main_help_text(self):
"""
Returns the script's main help text, as a string.
"""
usage = ['%s <subcommand> [options] [args]' % self.prog_name]
- usage.append('Django command line tool, version %s' % django.get_version())
- usage.append("Type '%s help <subcommand>' for help on a specific subcommand." % self.prog_name)
+ usage.append('Django command line tool,'
+ ' version %s' % django.get_version())
+ usage.append("Type '%s help <subcommand>' for help on a specific"
+ " subcommand." % self.prog_name)
usage.append('Available subcommands:')
- commands = get_commands(self.user_commands, self.project_directory).keys()
+ commands = get_commands(self.user_commands,
+ self.project_directory).keys()
commands.sort()
for cmd in commands:
usage.append(' %s' % cmd)
@@ -166,33 +173,35 @@ def fetch_command(self, subcommand):
django-admin.py or manage.py) if it can't be found.
"""
try:
- app_name = get_commands(self.user_commands, self.project_directory)[subcommand]
- if isinstance(app_name, BaseCommand):
+ app_name = get_commands(self.user_commands,
+ self.project_directory)[subcommand]
+ if isinstance(app_name, BaseCommand):
# If the command is already loaded, use it directly.
klass = app_name
else:
klass = load_command_class(app_name, subcommand)
except KeyError:
- sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % (subcommand, self.prog_name))
+ sys.stderr.write("Unknown command: %r\nType '%s help' for"
+ " usage.\n" % (subcommand, self.prog_name))
sys.exit(1)
return klass
-
+
def execute(self):
"""
Given the command-line arguments, this figures out which subcommand is
being run, creates a parser appropriate to that command, and runs it.
"""
- # Preprocess options to extract --settings and --pythonpath. These options
- # could affect the commands that are available, so they must be processed
- # early
- parser = LaxOptionParser(version=get_version(),
- option_list=BaseCommand.option_list)
+ # Preprocess options to extract --settings and --pythonpath.
+ # These options could affect the commands that are available, so they
+ # must be processed early.
+ parser = LaxOptionParser(version=get_version(),
+ option_list=BaseCommand.option_list)
try:
- options, args = parser.parse_args(self.argv)
+ options, args = parser.parse_args(self.argv)
handle_default_options(options)
- except:
+ except:
pass # Ignore any option errors at this point.
-
+
try:
subcommand = self.argv[1]
except IndexError:
@@ -208,7 +217,8 @@ def execute(self):
# Special-cases: We want 'django-admin.py --version' and
# 'django-admin.py --help' to work, for backwards compatibility.
elif self.argv[1:] == ['--version']:
- print django.get_version()
+ # LaxOptionParser already takes care of printing the version.
+ pass
elif self.argv[1:] == ['--help']:
sys.stderr.write(self.main_help_text() + '\n')
else:
@@ -227,10 +237,10 @@ def __init__(self, argv, project_directory):
super(ProjectManagementUtility, self).__init__(argv)
self.project_directory = project_directory
self.user_commands = True
-
+
def setup_environ(settings_mod):
"""
- Configure the runtime environment. This can also be used by external
+ Configures the runtime environment. This can also be used by external
scripts wanting to set up a similar environment to manage.py.
"""
# Add this project to sys.path so that it's importable in the conventional
@@ -244,7 +254,8 @@ def setup_environ(settings_mod):
sys.path.pop()
# Set DJANGO_SETTINGS_MODULE appropriately.
- os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)
+ os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name,
+ settings_name)
return project_directory
def execute_from_command_line(argv=None):
View
27 django/core/management/base.py
@@ -1,10 +1,10 @@
+import os
+import sys
+from optparse import make_option, OptionParser
+
import django
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style
-import itertools
-from optparse import make_option, OptionParser
-import sys
-import os
class CommandError(Exception):
pass
@@ -19,7 +19,7 @@ def handle_default_options(options):
os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
if options.pythonpath: