diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2007-08-17 15:05:54 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2007-08-17 15:05:54 +0000 |
| commit | fcec755f01cfaba2a85bfc9511876debbce98631 (patch) | |
| tree | e990effbcd90e4d405b0f9dcc70cb38e47b6f3dc | |
| parent | 0f92ac52cbf81fb2ac01755c558e2e6ad54700e8 (diff) | |
newforms-admin: Merged from trunk up to [5916]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5918 bcc190cf-cafb-0310-a4f2-bffc1f526a37
112 files changed, 11893 insertions, 6032 deletions
@@ -67,9 +67,11 @@ answer newbie questions, and generally made Django that much better: Andrew Brehaut <http://brehaut.net/blog> brut.alll@gmail.com Jonathan Buchanan <jonathan.buchanan@gmail.com> + Trevor Caira <trevor@caira.com> Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com> Antonio Cavedoni <http://cavedoni.com/> C8E + cedric@terramater.net Chris Chamberlin <dja@cdc.msbx.net> Amit Chakradeo <http://amit.chakradeo.net/> ChaosKCW @@ -77,6 +79,7 @@ answer newbie questions, and generally made Django that much better: Bryan Chow <bryan at verdjn dot com> Michal Chruszcz <troll@pld-linux.org> Ian Clelland <clelland@gmail.com> + colin@owlfish.com crankycoder@gmail.com Pete Crosier <pete.crosier@gmail.com> Matt Croydon <http://www.postneo.com/> @@ -99,6 +102,7 @@ answer newbie questions, and generally made Django that much better: dusk@woofle.net Andy Dustman <farcepest@gmail.com> Clint Ecker + eibaan@gmail.com enlight Enrico <rico.bl@gmail.com> A. Murat Eren <meren@pardus.org.tr> @@ -119,16 +123,19 @@ answer newbie questions, and generally made Django that much better: martin.glueck@gmail.com GomoX <gomo@datafull.com> Mario Gonzalez <gonzalemario@gmail.com> + pradeep.gowda@gmail.com Simon Greenhill <dev@simon.net.nz> Owen Griffiths Espen Grindhaug <http://grindhaug.org/> Thomas Güttler <hv@tbz-pariv.de> + dAniel hAhler Brian Harring <ferringb@gmail.com> Brant Harris Hawkeye Joe Heck <http://www.rhonabwy.com/wp/> Joel Heenan <joelh-django@planetjoel.com> hipertracker@gmail.com + Brett Hoerner <bretthoerner@bretthoerner.com> Ian Holsman <http://feh.holsman.net/> Kieran Holland <http://www.kieranholland.com> Sung-Jin Hong <serialx.net@gmail.com> @@ -138,6 +145,7 @@ answer newbie questions, and generally made Django that much better: Hyun Mi Ae Tom Insam Baurzhan Ismagulov <ibr@radix50.net> + james_027@yahoo.com jcrasta@gmail.com Zak Johnson <zakj@nox.cx> Michael Josephson <http://www.sdjournal.com/> @@ -192,6 +200,7 @@ answer newbie questions, and generally made Django that much better: mmarshall Andreas Mock <andreas.mock@web.de> Reza Mohammadi <reza@zeerak.ir> + Aljosa Mohorovic <aljosa.mohorovic@gmail.com> Eric Moritz <http://eric.themoritzfamily.com/> mrmachine <real.human@mrmachine.net> Robin Munn <http://www.geekforgod.com/> @@ -254,6 +263,7 @@ answer newbie questions, and generally made Django that much better: thebjorn <bp@datakortet.no> Zach Thompson <zthompson47@gmail.com> tibimicu@gmax.net + tobias@neuyork.de Tom Tobin Joe Topjian <http://joe.terrarum.net/geek/code/python/django/> torne-django@wolfpuppy.org.uk @@ -274,6 +284,7 @@ answer newbie questions, and generally made Django that much better: charly.wilhelm@gmail.com Rachel Willmer <http://www.willmer.com/kb/> Gary Wilson <gary.wilson@gmail.com> + Jakub Wiśniowski <restless.being@gmail.com> wojtek ye7cakf02@sneakemail.com ymasuda@ethercube.com diff --git a/django/bin/make-messages.py b/django/bin/make-messages.py index e824611ca3..11616c9ca5 100755 --- a/django/bin/make-messages.py +++ b/django/bin/make-messages.py @@ -84,7 +84,7 @@ def make_messages(): thefile = '%s.py' % file cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 'b') + (stdin, stdout, stderr) = os.popen3(cmd, 't') msgs = stdout.read() errors = stderr.read() if errors: @@ -101,12 +101,13 @@ def make_messages(): thefile = file if file.endswith('.html'): src = open(os.path.join(dirpath, file), "rb").read() - open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src)) thefile = '%s.py' % file - if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) + open(os.path.join(dirpath, thefile), "wb").write(templatize(src)) + if verbose: + sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 'b') + (stdin, stdout, stderr) = os.popen3(cmd, 't') msgs = stdout.read() errors = stderr.read() if errors: diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 33f7aebb6b..f1ef70dbca 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -53,6 +53,7 @@ LANGUAGES = ( ('gl', gettext_noop('Galician')), ('hu', gettext_noop('Hungarian')), ('he', gettext_noop('Hebrew')), + ('hr', gettext_noop('Croatian')), ('is', gettext_noop('Icelandic')), ('it', gettext_noop('Italian')), ('ja', gettext_noop('Japanese')), @@ -80,7 +81,7 @@ LANGUAGES = ( ) # Languages using BiDi (right-to-left) layout -LANGUAGES_BIDI = ("he", "ar") +LANGUAGES_BIDI = ("he", "ar", "fa") # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. diff --git a/django/conf/locale/de/LC_MESSAGES/django.mo b/django/conf/locale/de/LC_MESSAGES/django.mo Binary files differindex d1981a679d..307976e4d5 100644 --- a/django/conf/locale/de/LC_MESSAGES/django.mo +++ b/django/conf/locale/de/LC_MESSAGES/django.mo diff --git a/django/conf/locale/de/LC_MESSAGES/django.po b/django/conf/locale/de/LC_MESSAGES/django.po index 3ccbefe249..6978cf2d44 100644 --- a/django/conf/locale/de/LC_MESSAGES/django.po +++ b/django/conf/locale/de/LC_MESSAGES/django.po @@ -3,10 +3,10 @@ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" -msgstr "" -"Project-Id-Version: Django 1.0\n" +"" +msgstr "Project-Id-Version: Django 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-04-09 22:42+0200\n" +"POT-Creation-Date: 2007-07-28 12:33+0200\n" "PO-Revision-Date: 2007-02-05 03:19+0100\n" "Last-Translator: Jannis Leidel <jl@websushi.org>\n" "Language-Team: \n" @@ -19,591 +19,590 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "X-Generator: KBabel 1.11.4\n" -#: conf/global_settings.py:39 +#:conf/global_settings.py:38 msgid "Arabic" msgstr "Arabisch" -#: conf/global_settings.py:40 +#:conf/global_settings.py:39 msgid "Bengali" msgstr "Bengali" -#: conf/global_settings.py:41 +#:conf/global_settings.py:40 +msgid "Bulgarian" +msgstr "Bulgarisch" + +#:conf/global_settings.py:41 msgid "Catalan" msgstr "Katalanisch" -#: conf/global_settings.py:42 +#:conf/global_settings.py:42 msgid "Czech" msgstr "Tschechisch" -#: conf/global_settings.py:43 +#:conf/global_settings.py:43 msgid "Welsh" msgstr "Walisisch" -#: conf/global_settings.py:44 +#:conf/global_settings.py:44 msgid "Danish" msgstr "Dänisch" -#: conf/global_settings.py:45 +#:conf/global_settings.py:45 msgid "German" msgstr "Deutsch" -#: conf/global_settings.py:46 +#:conf/global_settings.py:46 msgid "Greek" msgstr "Griechisch" -#: conf/global_settings.py:47 +#:conf/global_settings.py:47 msgid "English" msgstr "Englisch" -#: conf/global_settings.py:48 +#:conf/global_settings.py:48 msgid "Spanish" msgstr "Spanisch" -#: conf/global_settings.py:49 +#:conf/global_settings.py:49 msgid "Argentinean Spanish" msgstr "Argentinisches Spanisch" -#: conf/global_settings.py:50 +#:conf/global_settings.py:50 +msgid "Persian" +msgstr "Persisch" + +#:conf/global_settings.py:51 msgid "Finnish" msgstr "Finnisch" -#: conf/global_settings.py:51 +#:conf/global_settings.py:52 msgid "French" msgstr "Französisch" -#: conf/global_settings.py:52 +#:conf/global_settings.py:53 msgid "Galician" msgstr "Galicisch" -#: conf/global_settings.py:53 +#:conf/global_settings.py:54 msgid "Hungarian" msgstr "Ungarisch" -#: conf/global_settings.py:54 +#:conf/global_settings.py:55 msgid "Hebrew" msgstr "Hebräisch" -#: conf/global_settings.py:55 +#:conf/global_settings.py:56 msgid "Icelandic" msgstr "Isländisch" -#: conf/global_settings.py:56 +#:conf/global_settings.py:57 msgid "Italian" msgstr "Italienisch" -#: conf/global_settings.py:57 +#:conf/global_settings.py:58 msgid "Japanese" msgstr "Japanisch" -#: conf/global_settings.py:58 +#:conf/global_settings.py:59 msgid "Korean" msgstr "Koreanisch" -#: conf/global_settings.py:59 +#:conf/global_settings.py:60 msgid "Kannada" msgstr "Kannada" -#: conf/global_settings.py:60 +#:conf/global_settings.py:61 msgid "Latvian" msgstr "Lettisch" -#: conf/global_settings.py:61 +#:conf/global_settings.py:62 msgid "Macedonian" msgstr "Mazedonisch" -#: conf/global_settings.py:62 +#:conf/global_settings.py:63 msgid "Dutch" msgstr "Holländisch" -#: conf/global_settings.py:63 +#:conf/global_settings.py:64 msgid "Norwegian" msgstr "Norwegisch" -#: conf/global_settings.py:64 +#:conf/global_settings.py:65 msgid "Polish" msgstr "Polnisch" -#: conf/global_settings.py:65 +#:conf/global_settings.py:66 msgid "Portugese" msgstr "Portugiesisch" -#: conf/global_settings.py:66 +#:conf/global_settings.py:67 msgid "Brazilian" msgstr "Brasilianisches Portugiesisch" -#: conf/global_settings.py:67 +#:conf/global_settings.py:68 msgid "Romanian" msgstr "Rumänisch" -#: conf/global_settings.py:68 +#:conf/global_settings.py:69 msgid "Russian" msgstr "Russisch" -#: conf/global_settings.py:69 +#:conf/global_settings.py:70 msgid "Slovak" msgstr "Slowakisch" -#: conf/global_settings.py:70 +#:conf/global_settings.py:71 msgid "Slovenian" msgstr "Slowenisch" -#: conf/global_settings.py:71 +#:conf/global_settings.py:72 msgid "Serbian" msgstr "Serbisch" -#: conf/global_settings.py:72 +#:conf/global_settings.py:73 msgid "Swedish" msgstr "Schwedisch" -#: conf/global_settings.py:73 +#:conf/global_settings.py:74 msgid "Tamil" msgstr "Tamilisch" -#: conf/global_settings.py:74 +#:conf/global_settings.py:75 msgid "Telugu" msgstr "Telugisch" -#: conf/global_settings.py:75 +#:conf/global_settings.py:76 msgid "Turkish" msgstr "Türkisch" -#: conf/global_settings.py:76 +#:conf/global_settings.py:77 msgid "Ukrainian" msgstr "Ukrainisch" -#: conf/global_settings.py:77 +#:conf/global_settings.py:78 msgid "Simplified Chinese" msgstr "Vereinfachtes Chinesisch" -#: conf/global_settings.py:78 +#:conf/global_settings.py:79 msgid "Traditional Chinese" msgstr "Traditionelles Chinesisch" -#: contrib/admin/filterspecs.py:40 -#, python-format +#:contrib/admin/filterspecs.py:42 +#,python-format msgid "" "<h3>By %s:</h3>\n" "<ul>\n" -msgstr "" -"<h3>Nach %s:</h3>\n" +msgstr "<h3>Nach %s:</h3>\n" "<ul>\n" -#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88 -#: contrib/admin/filterspecs.py:143 contrib/admin/filterspecs.py:169 +#:contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90 +#:contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171 msgid "All" msgstr "Alle" -#: contrib/admin/filterspecs.py:109 +#:contrib/admin/filterspecs.py:111 msgid "Any date" msgstr "Alle Daten" -#: contrib/admin/filterspecs.py:110 +#:contrib/admin/filterspecs.py:112 msgid "Today" msgstr "Heute" -#: contrib/admin/filterspecs.py:113 +#:contrib/admin/filterspecs.py:115 msgid "Past 7 days" msgstr "Letzte 7 Tage" -#: contrib/admin/filterspecs.py:115 +#:contrib/admin/filterspecs.py:117 msgid "This month" msgstr "Diesen Monat" -#: contrib/admin/filterspecs.py:117 +#:contrib/admin/filterspecs.py:119 msgid "This year" msgstr "Dieses Jahr" -#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#:contrib/admin/filterspecs.py:145 newforms/widgets.py:181 +#:oldforms/__init__.py:587 msgid "Yes" msgstr "Ja" -#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#:contrib/admin/filterspecs.py:145 newforms/widgets.py:181 +#:oldforms/__init__.py:587 msgid "No" msgstr "Nein" -#: contrib/admin/filterspecs.py:150 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#:contrib/admin/filterspecs.py:152 newforms/widgets.py:181 +#:oldforms/__init__.py:587 msgid "Unknown" msgstr "Unbekannt" -#: contrib/admin/models.py:16 +#:contrib/admin/models.py:17 msgid "action time" msgstr "Zeitpunkt der Aktion" -#: contrib/admin/models.py:19 +#:contrib/admin/models.py:20 msgid "object id" msgstr "Objekt-ID" -#: contrib/admin/models.py:20 +#:contrib/admin/models.py:21 msgid "object repr" msgstr "Objekt Darst." -#: contrib/admin/models.py:21 +#:contrib/admin/models.py:22 msgid "action flag" msgstr "Aktionskennzeichen" -#: contrib/admin/models.py:22 +#:contrib/admin/models.py:23 msgid "change message" msgstr "Änderungsmeldung" -#: contrib/admin/models.py:25 +#:contrib/admin/models.py:26 msgid "log entry" msgstr "Logeintrag" -#: contrib/admin/models.py:26 +#:contrib/admin/models.py:27 msgid "log entries" msgstr "Logeinträge" -#: contrib/admin/templates/admin/404.html:4 -#: contrib/admin/templates/admin/404.html:8 +#:contrib/admin/templates/admin/404.html:4 +#:contrib/admin/templates/admin/404.html:8 msgid "Page not found" msgstr "Seite nicht gefunden" -#: contrib/admin/templates/admin/404.html:10 +#:contrib/admin/templates/admin/404.html:10 msgid "We're sorry, but the requested page could not be found." -msgstr "" -"Es tut uns leid, aber die angeforderte Seite konnte nicht gefunden werden." +msgstr "Es tut uns leid, aber die angeforderte Seite konnte nicht gefunden werden." -#: contrib/admin/templates/admin/500.html:4 -#: contrib/admin/templates/admin/base.html:30 -#: contrib/admin/templates/admin/change_form.html:13 -#: contrib/admin/templates/admin/change_list.html:6 -#: contrib/admin/templates/admin/delete_confirmation.html:6 -#: contrib/admin/templates/admin/invalid_setup.html:4 -#: contrib/admin/templates/admin/object_history.html:5 -#: contrib/admin/templates/admin/auth/user/change_password.html:12 -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 -#: contrib/admin/templates/registration/logged_out.html:4 -#: contrib/admin/templates/registration/password_change_done.html:4 -#: contrib/admin/templates/registration/password_change_form.html:4 -#: contrib/admin/templates/registration/password_reset_done.html:4 -#: contrib/admin/templates/registration/password_reset_form.html:4 +#:contrib/admin/templates/admin/500.html:4 +#:contrib/admin/templates/admin/base.html:30 +#:contrib/admin/templates/admin/change_form.html:13 +#:contrib/admin/templates/admin/change_list.html:6 +#:contrib/admin/templates/admin/delete_confirmation.html:6 +#:contrib/admin/templates/admin/invalid_setup.html:4 +#:contrib/admin/templates/admin/object_history.html:5 +#:contrib/admin/templates/admin/auth/user/change_password.html:12 +#:contrib/admin/templates/admin_doc/bookmarklets.html:3 +#:contrib/admin/templates/registration/logged_out.html:4 +#:contrib/admin/templates/registration/password_change_done.html:4 +#:contrib/admin/templates/registration/password_change_form.html:4 +#:contrib/admin/templates/registration/password_reset_done.html:4 +#:contrib/admin/templates/registration/password_reset_form.html:4 msgid "Home" msgstr "Start" -#: contrib/admin/templates/admin/500.html:4 +#:contrib/admin/templates/admin/500.html:4 msgid "Server error" msgstr "Serverfehler" -#: contrib/admin/templates/admin/500.html:6 +#:contrib/admin/templates/admin/500.html:6 msgid "Server error (500)" msgstr "Serverfehler (500)" -#: contrib/admin/templates/admin/500.html:9 +#:contrib/admin/templates/admin/500.html:9 msgid "Server Error <em>(500)</em>" msgstr "Serverfehler <em>(500)</em>" -#: contrib/admin/templates/admin/500.html:10 +#: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 "" -"Ein Fehler ist aufgetreten. Dieser Fehler wurde an die Serververwalter per E-" +msgstr "Ein Fehler ist aufgetreten. Dieser Fehler wurde an die Serververwalter per E-" "Mail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr " "Verständnis." -#: contrib/admin/templates/admin/base.html:25 +#:contrib/admin/templates/admin/base.html:25 msgid "Welcome," msgstr "Willkommen," -#: contrib/admin/templates/admin/base.html:25 -#: 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/auth/user/change_password.html:9 -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/admin/templates/registration/password_change_form.html:3 +#:contrib/admin/templates/admin/base.html:25 +#: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/auth/user/change_password.html:9 +#:contrib/admin/templates/admin_doc/bookmarklets.html:3 +#:contrib/admin/templates/registration/password_change_done.html:3 +#:contrib/admin/templates/registration/password_change_form.html:3 msgid "Documentation" msgstr "Dokumentation" -#: contrib/admin/templates/admin/base.html:25 -#: 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/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/bookmarklets.html:4 -#: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/missing_docutils.html:4 -#: contrib/admin/templates/admin_doc/model_detail.html:3 -#: contrib/admin/templates/admin_doc/model_index.html:5 -#: contrib/admin/templates/admin_doc/template_detail.html:4 -#: contrib/admin/templates/admin_doc/template_filter_index.html:5 -#: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 -#: contrib/admin/templates/admin_doc/view_index.html:5 -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/admin/templates/registration/password_change_form.html:3 +#:contrib/admin/templates/admin/base.html:25 +#: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/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/bookmarklets.html:4 +#:contrib/admin/templates/admin_doc/index.html:4 +#:contrib/admin/templates/admin_doc/missing_docutils.html:4 +#:contrib/admin/templates/admin_doc/model_detail.html:3 +#:contrib/admin/templates/admin_doc/model_index.html:5 +#:contrib/admin/templates/admin_doc/template_detail.html:4 +#:contrib/admin/templates/admin_doc/template_filter_index.html:5 +#:contrib/admin/templates/admin_doc/template_tag_index.html:5 +#:contrib/admin/templates/admin_doc/view_detail.html:4 +#:contrib/admin/templates/admin_doc/view_index.html:5 +#:contrib/admin/templates/registration/password_change_done.html:3 +#:contrib/admin/templates/registration/password_change_form.html:3 msgid "Change password" msgstr "Passwort ändern" -#: contrib/admin/templates/admin/base.html:25 -#: 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/auth/user/change_password.html:9 -#: contrib/admin/templates/admin_doc/bookmarklets.html:4 -#: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/missing_docutils.html:4 -#: contrib/admin/templates/admin_doc/model_detail.html:3 -#: contrib/admin/templates/admin_doc/model_index.html:5 -#: contrib/admin/templates/admin_doc/template_detail.html:4 -#: contrib/admin/templates/admin_doc/template_filter_index.html:5 -#: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 -#: contrib/admin/templates/admin_doc/view_index.html:5 -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/admin/templates/registration/password_change_form.html:3 -#: contrib/comments/templates/comments/form.html:6 +#:contrib/admin/templates/admin/base.html:25 +#: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/auth/user/change_password.html:9 +#:contrib/admin/templates/admin_doc/bookmarklets.html:4 +#:contrib/admin/templates/admin_doc/index.html:4 +#:contrib/admin/templates/admin_doc/missing_docutils.html:4 +#:contrib/admin/templates/admin_doc/model_detail.html:3 +#:contrib/admin/templates/admin_doc/model_index.html:5 +#:contrib/admin/templates/admin_doc/template_detail.html:4 +#:contrib/admin/templates/admin_doc/template_filter_index.html:5 +#:contrib/admin/templates/admin_doc/template_tag_index.html:5 +#:contrib/admin/templates/admin_doc/view_detail.html:4 +#:contrib/admin/templates/admin_doc/view_index.html:5 +#:contrib/admin/templates/registration/password_change_done.html:3 +#:contrib/admin/templates/registration/password_change_form.html:3 +#:contrib/comments/templates/comments/form.html:6 msgid "Log out" msgstr "Abmelden" -#: contrib/admin/templates/admin/base_site.html:4 +#:contrib/admin/templates/admin/base_site.html:4 msgid "Django site admin" msgstr "Django-Systemverwaltung" -#: contrib/admin/templates/admin/base_site.html:7 +#:contrib/admin/templates/admin/base_site.html:7 msgid "Django administration" msgstr "Django-Verwaltung" -#: contrib/admin/templates/admin/change_form.html:15 -#: contrib/admin/templates/admin/index.html:28 +#:contrib/admin/templates/admin/change_form.html:15 +#:contrib/admin/templates/admin/index.html:28 msgid "Add" msgstr "Hinzufügen" -#: contrib/admin/templates/admin/change_form.html:21 -#: contrib/admin/templates/admin/object_history.html:5 +#:contrib/admin/templates/admin/change_form.html:21 +#:contrib/admin/templates/admin/object_history.html:5 msgid "History" msgstr "Geschichte" -#: contrib/admin/templates/admin/change_form.html:22 +#:contrib/admin/templates/admin/change_form.html:22 msgid "View on site" msgstr "Im Web anzeigen" -#: contrib/admin/templates/admin/change_form.html:32 -#: contrib/admin/templates/admin/auth/user/change_password.html:24 +#: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] "Bitte den aufgeführten Fehler korrigieren." msgstr[1] "Bitte die aufgeführten Fehler korrigieren." -#: contrib/admin/templates/admin/change_form.html:50 +#:contrib/admin/templates/admin/change_form.html:50 msgid "Ordering" msgstr "Sortierung" -#: contrib/admin/templates/admin/change_form.html:53 +#:contrib/admin/templates/admin/change_form.html:53 msgid "Order:" msgstr "Reihenfolge:" -#: contrib/admin/templates/admin/change_list.html:12 -#, python-format +#:contrib/admin/templates/admin/change_list.html:12 +#,python-format msgid "Add %(name)s" msgstr "%(name)s hinzufügen" -#: contrib/admin/templates/admin/delete_confirmation.html:9 -#: contrib/admin/templates/admin/submit_line.html:3 +#:contrib/admin/templates/admin/delete_confirmation.html:9 +#:contrib/admin/templates/admin/submit_line.html:3 msgid "Delete" msgstr "Löschen" -#: contrib/admin/templates/admin/delete_confirmation.html:14 -#, python-format +#:contrib/admin/templates/admin/delete_confirmation.html:14 +#,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 "" -"Die Löschung des %(object_name)s '%(escaped_object)s' hätte die Löschung von " +msgstr "Die Löschung des %(object_name)s '%(escaped_object)s' hätte die Löschung von " "abhängigen Daten zur Folge, aber Sie haben nicht die nötigen Rechte um die " "folgenden abhängigen Daten zu löschen:" -#: contrib/admin/templates/admin/delete_confirmation.html:21 -#, python-format +#:contrib/admin/templates/admin/delete_confirmation.html:21 +#,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 "" -"Sind Sie sicher, dass Sie %(object_name)s \"%(escaped_object)s\" löschen " +msgstr "Sind Sie sicher, dass Sie %(object_name)s \"%(escaped_object)s\" löschen " "wollen? Es werden zusätzlich die folgenden abhängigen Daten mit gelöscht:" -#: contrib/admin/templates/admin/delete_confirmation.html:26 +#:contrib/admin/templates/admin/delete_confirmation.html:26 msgid "Yes, I'm sure" msgstr "Ja, ich bin sicher" -#: contrib/admin/templates/admin/filter.html:2 -#, python-format +#:contrib/admin/templates/admin/filter.html:2 +#,python-format msgid " By %(filter_title)s " msgstr " Nach %(filter_title)s " -#: contrib/admin/templates/admin/filters.html:4 +#:contrib/admin/templates/admin/filters.html:4 msgid "Filter" msgstr "Filter" -#: contrib/admin/templates/admin/index.html:17 -#, python-format +#:contrib/admin/templates/admin/index.html:17 +#,python-format msgid "Models available in the %(name)s application." msgstr "Modelle, die in der Anwendung %(name)s vorhanden sind." -#: contrib/admin/templates/admin/index.html:18 -#, python-format +#:contrib/admin/templates/admin/index.html:18 +#,python-format msgid "%(name)s" msgstr "%(name)s" -#: contrib/admin/templates/admin/index.html:34 +#:contrib/admin/templates/admin/index.html:34 msgid "Change" msgstr "Ändern" -#: contrib/admin/templates/admin/index.html:44 +#:contrib/admin/templates/admin/index.html:44 msgid "You don't have permission to edit anything." msgstr "Sie haben keine Berechtigung irgendwas zu ändern." -#: contrib/admin/templates/admin/index.html:52 +#:contrib/admin/templates/admin/index.html:52 msgid "Recent Actions" msgstr "Kürzliche Aktionen" -#: contrib/admin/templates/admin/index.html:53 +#:contrib/admin/templates/admin/index.html:53 msgid "My Actions" msgstr "Meine Aktionen" -#: contrib/admin/templates/admin/index.html:57 +#:contrib/admin/templates/admin/index.html:57 msgid "None available" msgstr "Keine vorhanden" -#: contrib/admin/templates/admin/invalid_setup.html:8 +#: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 "" -"Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, dass " -"die richtigen Datenbanktabellen angelegt wurden und " -"die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist." +msgstr "Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, dass " +"die richtigen Datenbanktabellen angelegt wurden und die Datenbank vom " +"verwendeten Datenbankbenutzer auch lesbar ist." -#: contrib/admin/templates/admin/login.html:17 -#: contrib/comments/templates/comments/form.html:6 -#: contrib/comments/templates/comments/form.html:8 +#:contrib/admin/templates/admin/login.html:17 +#:contrib/comments/templates/comments/form.html:6 +#:contrib/comments/templates/comments/form.html:8 msgid "Username:" msgstr "Benutzername:" -#: contrib/admin/templates/admin/login.html:20 -#: contrib/comments/templates/comments/form.html:8 +#:contrib/admin/templates/admin/login.html:20 +#:contrib/comments/templates/comments/form.html:8 msgid "Password:" msgstr "Passwort:" -#: contrib/admin/templates/admin/login.html:25 -#: contrib/admin/views/decorators.py:24 +#:contrib/admin/templates/admin/login.html:25 +#:contrib/admin/views/decorators.py:24 msgid "Log in" msgstr "Anmelden" -#: contrib/admin/templates/admin/object_history.html:18 +#:contrib/admin/templates/admin/object_history.html:18 msgid "Date/time" msgstr "Datum/Zeit" -#: contrib/admin/templates/admin/object_history.html:19 +#:contrib/admin/templates/admin/object_history.html:19 msgid "User" msgstr "Benutzer" -#: contrib/admin/templates/admin/object_history.html:20 +#:contrib/admin/templates/admin/object_history.html:20 msgid "Action" msgstr "Aktion" -#: contrib/admin/templates/admin/object_history.html:26 +#:contrib/admin/templates/admin/object_history.html:26 msgid "DATE_WITH_TIME_FULL" msgstr "j. N Y, H:i" -#: contrib/admin/templates/admin/object_history.html:36 +#: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 "" -"Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht " +msgstr "Dieses Objekt hat keine Änderungsgeschichte. Es wurde möglicherweise nicht " "über diese Verwaltungsseiten angelegt." -#: contrib/admin/templates/admin/pagination.html:10 +#:contrib/admin/templates/admin/pagination.html:10 msgid "Show all" msgstr "Zeige alle" -#: contrib/admin/templates/admin/search_form.html:8 +#:contrib/admin/templates/admin/search_form.html:8 msgid "Go" msgstr "Los" -#: contrib/admin/templates/admin/search_form.html:10 -#, python-format +#:contrib/admin/templates/admin/search_form.html:10 +#,python-format msgid "1 result" msgid_plural "%(counter)s results" msgstr[0] "Ein Ergebnis" msgstr[1] "%(counter)s Ergebnisse" -#: contrib/admin/templates/admin/search_form.html:10 -#, python-format +#:contrib/admin/templates/admin/search_form.html:10 +#,python-format msgid "%(full_result_count)s total" msgstr "%(full_result_count)s gesamt" -#: contrib/admin/templates/admin/submit_line.html:4 +#:contrib/admin/templates/admin/submit_line.html:4 msgid "Save as new" msgstr "Als neu sichern" -#: contrib/admin/templates/admin/submit_line.html:5 +#:contrib/admin/templates/admin/submit_line.html:5 msgid "Save and add another" msgstr "Sichern und neu hinzufügen" -#: contrib/admin/templates/admin/submit_line.html:6 +#:contrib/admin/templates/admin/submit_line.html:6 msgid "Save and continue editing" msgstr "Sichern und weiter bearbeiten" -#: contrib/admin/templates/admin/submit_line.html:7 +#:contrib/admin/templates/admin/submit_line.html:7 msgid "Save" msgstr "Sichern" -#: contrib/admin/templates/admin/auth/user/add_form.html:6 +#: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 "" -"Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere " +msgstr "Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere " "Optionen für den Benutzer geändert werden." -#: contrib/admin/templates/admin/auth/user/add_form.html:12 +#:contrib/admin/templates/admin/auth/user/add_form.html:12 msgid "Username" msgstr "Benutzername" -#: contrib/admin/templates/admin/auth/user/add_form.html:18 -#: contrib/admin/templates/admin/auth/user/change_password.html:34 +#:contrib/admin/templates/admin/auth/user/add_form.html:18 +#:contrib/admin/templates/admin/auth/user/change_password.html:34 msgid "Password" msgstr "Passwort" -#: contrib/admin/templates/admin/auth/user/add_form.html:23 -#: contrib/admin/templates/admin/auth/user/change_password.html:39 +#:contrib/admin/templates/admin/auth/user/add_form.html:23 +#:contrib/admin/templates/admin/auth/user/change_password.html:39 msgid "Password (again)" msgstr "Passwort (wiederholen)" -#: contrib/admin/templates/admin/auth/user/add_form.html:24 -#: contrib/admin/templates/admin/auth/user/change_password.html:40 +#: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." msgstr "Bitte das gleiche Passwort zur Überprüfung nochmal eingeben." -#: contrib/admin/templates/admin/auth/user/change_password.html:28 -#, python-format +#: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 "" -"Bitte geben Sie ein neues Passwort für den Benutzer <strong>%(username)s</" +msgstr "Bitte geben Sie ein neues Passwort für den Benutzer <strong>%(username)s</" "strong> ein." -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +#:contrib/admin/templates/admin_doc/bookmarklets.html:3 msgid "Bookmarklets" msgstr "Bookmarklets" -#: contrib/admin/templates/admin_doc/bookmarklets.html:5 +#:contrib/admin/templates/admin_doc/bookmarklets.html:5 msgid "Documentation bookmarklets" msgstr "Dokumentations-Bookmarklets" -#: contrib/admin/templates/admin_doc/bookmarklets.html:9 +#:contrib/admin/templates/admin_doc/bookmarklets.html:9 msgid "" "\n" "<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n" @@ -612,9 +611,9 @@ msgid "" "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\">Um Bookmarklets zu installieren, müssen diese Links in die\n" +msgstr "\n" +"<p class=\"help\">Um Bookmarklets zu installieren, müssen diese Links in " +"die\n" "Browser-Werkzeugleiste gezogen werden, oder mittels rechter Maustaste in " "die\n" "Bookmarks gespeichert werden. Danach können die Bookmarklets von jeder " @@ -830,7 +829,7 @@ msgid "" "Please enter a correct username and password. Note that both fields are case-" "sensitive." msgstr "" -"Bitte einen Benutzernamen und ein Passwort eingeben. Beide Felder " +"Bitte einen gültigen Benutzernamen und ein Passwort eingeben. Beide Felder " "berücksichtigen die Groß-/Kleinschreibung." #: contrib/admin/views/decorators.py:62 diff --git a/django/conf/locale/es/LC_MESSAGES/django.mo b/django/conf/locale/es/LC_MESSAGES/django.mo Binary files differindex 4b8254b95a..7beda77032 100644 --- a/django/conf/locale/es/LC_MESSAGES/django.mo +++ b/django/conf/locale/es/LC_MESSAGES/django.mo diff --git a/django/conf/locale/es/LC_MESSAGES/django.po b/django/conf/locale/es/LC_MESSAGES/django.po index 4dcc433098..424cce900d 100644 --- a/django/conf/locale/es/LC_MESSAGES/django.po +++ b/django/conf/locale/es/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-07-14 13:46-0500\n" +"POT-Creation-Date: 2007-08-13 11:29-0400\n" "PO-Revision-Date: 2007-07-14 13:00-0500\n" "Last-Translator: Mario Gonzalez <gonzalemario @t gmail.com>\n" "Language-Team: Castellano <Django-I18N@googlegroups.com>\n" @@ -25,78 +25,78 @@ msgstr "%(object)s de este %(type)s ya existen en este %(field)s." msgid "and" msgstr "y" -#: db/models/fields/related.py:55 -#, python-format -msgid "Please enter a valid %s." -msgstr "Por favor, introduzca un %s válido." - -#: db/models/fields/related.py:641 -msgid "Separate multiple IDs with commas." -msgstr "Separe múltiples IDs con comas." - -#: db/models/fields/related.py:643 -msgid "" -"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." -msgstr "" -"Mantenga presionado \"Control\", o \"Command\" en un Mac, para seleccionar " -"más de uno." - -#: db/models/fields/related.py:690 -#, 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] "" -"Por favor, introduzca IDs de %(self)s válidos. El valor %(value)r no es " -"válido." -msgstr[1] "" -"Por favor, introduzca IDs de %(self)s válidos. Los valores %(value)r no son " -"válidos." - -#: db/models/fields/__init__.py:47 +#: db/models/fields/__init__.py:49 #, python-format msgid "%(optname)s with this %(fieldname)s already exists." msgstr "Ya existe %(optname)s con este %(fieldname)s." -#: db/models/fields/__init__.py:127 db/models/fields/__init__.py:284 -#: db/models/fields/__init__.py:681 db/models/fields/__init__.py:692 -#: oldforms/__init__.py:369 newforms/fields.py:92 newforms/fields.py:440 -#: newforms/fields.py:516 newforms/fields.py:527 newforms/models.py:187 +#: db/models/fields/__init__.py:156 db/models/fields/__init__.py:313 +#: db/models/fields/__init__.py:721 db/models/fields/__init__.py:732 +#: newforms/fields.py:92 newforms/fields.py:490 newforms/fields.py:566 +#: newforms/fields.py:577 newforms/models.py:193 oldforms/__init__.py:373 msgid "This field is required." msgstr "Este campo es obligatorio." -#: db/models/fields/__init__.py:379 +#: db/models/fields/__init__.py:411 msgid "This value must be an integer." msgstr "Este valor debe ser un entero." -#: db/models/fields/__init__.py:414 +#: db/models/fields/__init__.py:446 msgid "This value must be either True or False." msgstr "Este valor debe ser Verdadero o Falso." -#: db/models/fields/__init__.py:435 +#: db/models/fields/__init__.py:467 msgid "This field cannot be null." msgstr "Este campo no puede estar vacío." -#: db/models/fields/__init__.py:469 core/validators.py:155 +#: db/models/fields/__init__.py:501 core/validators.py:155 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:538 core/validators.py:164 +#: db/models/fields/__init__.py:570 core/validators.py:164 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:598 +#: db/models/fields/__init__.py:631 msgid "This value must be a decimal number." msgstr "Este valor debe ser un entero." -#: db/models/fields/__init__.py:701 +#: db/models/fields/__init__.py:741 msgid "Enter a valid filename." msgstr "Introduzca un nombre de fichero válido" -#: db/models/fields/__init__.py:826 +#: db/models/fields/__init__.py:883 msgid "This value must be either None, True or False." msgstr "Este valor debe ser Verdadero o Falso." +#: db/models/fields/related.py:55 +#, python-format +msgid "Please enter a valid %s." +msgstr "Por favor, introduzca un %s válido." + +#: db/models/fields/related.py:661 +msgid "Separate multiple IDs with commas." +msgstr "Separe múltiples IDs con comas." + +#: db/models/fields/related.py:663 +msgid "" +"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +msgstr "" +"Mantenga presionado \"Control\", o \"Command\" en un Mac, para seleccionar " +"más de uno." + +#: db/models/fields/related.py:710 +#, 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] "" +"Por favor, introduzca IDs de %(self)s válidos. El valor %(value)r no es " +"válido." +msgstr[1] "" +"Por favor, introduzca IDs de %(self)s válidos. Los valores %(value)r no son " +"válidos." + #: conf/global_settings.py:38 msgid "Arabic" msgstr "Árabe" @@ -170,496 +170,634 @@ msgid "Hebrew" msgstr "Hebreo" #: conf/global_settings.py:56 +msgid "Croatian" +msgstr "Croata" + +#: conf/global_settings.py:57 msgid "Icelandic" msgstr "Islandés" -#: conf/global_settings.py:57 +#: conf/global_settings.py:58 msgid "Italian" msgstr "Italiano" -#: conf/global_settings.py:58 +#: conf/global_settings.py:59 msgid "Japanese" msgstr "Japonés" -#: conf/global_settings.py:59 +#: conf/global_settings.py:60 msgid "Korean" msgstr "Koreano" -#: conf/global_settings.py:60 +#: conf/global_settings.py:61 msgid "Kannada" msgstr "Kannada" -#: conf/global_settings.py:61 +#: conf/global_settings.py:62 msgid "Latvian" msgstr "Latvio" -#: conf/global_settings.py:62 +#: conf/global_settings.py:63 msgid "Macedonian" msgstr "Macedonio" -#: conf/global_settings.py:63 +#: conf/global_settings.py:64 msgid "Dutch" msgstr "Alemán" -#: conf/global_settings.py:64 +#: conf/global_settings.py:65 msgid "Norwegian" msgstr "Noruego" -#: conf/global_settings.py:65 +#: conf/global_settings.py:66 msgid "Polish" msgstr "Polaco" -#: conf/global_settings.py:66 +#: conf/global_settings.py:67 msgid "Portugese" msgstr "Portugés" -#: conf/global_settings.py:67 +#: conf/global_settings.py:68 msgid "Brazilian" msgstr "Brasileño" -#: conf/global_settings.py:68 +#: conf/global_settings.py:69 msgid "Romanian" msgstr "Rumano" -#: conf/global_settings.py:69 +#: conf/global_settings.py:70 msgid "Russian" msgstr "Ruso" -#: conf/global_settings.py:70 +#: conf/global_settings.py:71 msgid "Slovak" msgstr "Eslovaco" -#: conf/global_settings.py:71 +#: conf/global_settings.py:72 msgid "Slovenian" msgstr "Esloveno" -#: conf/global_settings.py:72 +#: conf/global_settings.py:73 msgid "Serbian" msgstr "Serbio" -#: conf/global_settings.py:73 +#: conf/global_settings.py:74 msgid "Swedish" msgstr "Sueco" -#: conf/global_settings.py:74 +#: conf/global_settings.py:75 msgid "Tamil" msgstr "Tamil" -#: conf/global_settings.py:75 +#: conf/global_settings.py:76 msgid "Telugu" msgstr "Telugu" -#: conf/global_settings.py:76 +#: conf/global_settings.py:77 msgid "Turkish" msgstr "Turco" -#: conf/global_settings.py:77 +#: conf/global_settings.py:78 msgid "Ukrainian" msgstr "Ucraniano" -#: conf/global_settings.py:78 +#: conf/global_settings.py:79 msgid "Simplified Chinese" msgstr "Chino simplificado" -#: conf/global_settings.py:79 +#: conf/global_settings.py:80 msgid "Traditional Chinese" msgstr "Chino tradicional" -#: core/validators.py:71 -msgid "This value must contain only letters, numbers and underscores." -msgstr "Este valor debe contener sólo letras, números y guiones bajos." +#: views/generic/create_update.py:43 +#, python-format +msgid "The %(verbose_name)s was created successfully." +msgstr "El %(verbose_name)s se ha creado correctamente." -#: core/validators.py:75 -msgid "" -"This value must contain only letters, numbers, underscores, dashes or " -"slashes." -msgstr "" -"Este valor debe contener letras, números, guiones bajos o barras solamente." +#: views/generic/create_update.py:117 +#, python-format +msgid "The %(verbose_name)s was updated successfully." +msgstr "Se actualizó con éxito el %(verbose_name)s." -#: core/validators.py:79 -msgid "This value must contain only letters, numbers, underscores or hyphens." -msgstr "Este valor debe contener sólo letras, números, guiones bajos o medios." +#: views/generic/create_update.py:184 +#, python-format +msgid "The %(verbose_name)s was deleted." +msgstr "El %(verbose_name)s ha sido eliminado." -#: core/validators.py:83 -msgid "Uppercase letters are not allowed here." -msgstr "No se admiten letras mayúsculas." +#: utils/dates.py:6 +msgid "Monday" +msgstr "Lunes" -#: core/validators.py:87 -msgid "Lowercase letters are not allowed here." -msgstr "No se admiten letras minúsculas." +#: utils/dates.py:6 +msgid "Tuesday" +msgstr "Martes" -#: core/validators.py:94 -msgid "Enter only digits separated by commas." -msgstr "Introduzca sólo dígitos separados por comas." +#: utils/dates.py:6 +msgid "Wednesday" +msgstr "Miércoles" -#: core/validators.py:106 -msgid "Enter valid e-mail addresses separated by commas." -msgstr "Introduzca direcciones de correo válidas separadas por comas." +#: utils/dates.py:6 +msgid "Thursday" +msgstr "Jueves" -#: core/validators.py:110 -msgid "Please enter a valid IP address." -msgstr "Por favor introduzca una dirección IP válida." +#: utils/dates.py:6 +msgid "Friday" +msgstr "Viernes" -#: core/validators.py:114 -msgid "Empty values are not allowed here." -msgstr "No se admiten valores vacíos." +#: utils/dates.py:7 +msgid "Saturday" +msgstr "Sábado" -#: core/validators.py:118 -msgid "Non-numeric characters aren't allowed here." -msgstr "No se admiten caracteres no numéricos." +#: utils/dates.py:7 +msgid "Sunday" +msgstr "Domingo" -#: core/validators.py:122 -msgid "This value can't be comprised solely of digits." -msgstr "Este valor no puede comprender sólo dígitos." +#: utils/dates.py:10 +msgid "Mon" +msgstr "Lun" -#: core/validators.py:127 newforms/fields.py:141 -msgid "Enter a whole number." -msgstr "Introduzca un número entero." +#: utils/dates.py:10 +msgid "Tue" +msgstr "Mar" -#: core/validators.py:131 -msgid "Only alphabetical characters are allowed here." -msgstr "Sólo se admiten caracteres alfabéticos." +#: utils/dates.py:10 +msgid "Wed" +msgstr "Mie" -#: core/validators.py:146 -msgid "Year must be 1900 or later." -msgstr "El año debe ser 1900 o posterior." +#: utils/dates.py:10 +msgid "Thu" +msgstr "Jue" -#: core/validators.py:150 -#, python-format -msgid "Invalid date: %s" -msgstr "Fecha no válida: %s" +#: utils/dates.py:10 +msgid "Fri" +msgstr "Vie" -#: core/validators.py:160 -msgid "Enter a valid time in HH:MM format." -msgstr "Introduzca una hora válida en formato HH:MM." +#: utils/dates.py:11 +msgid "Sat" +msgstr "Sab" -#: core/validators.py:169 newforms/fields.py:335 -msgid "Enter a valid e-mail address." -msgstr "Introduzca una dirección de correo electrónico válida" +#: utils/dates.py:11 +msgid "Sun" +msgstr "Dom" -#: core/validators.py:181 core/validators.py:461 oldforms/__init__.py:682 -msgid "No file was submitted. Check the encoding type on the form." -msgstr "" -"No se ha enviado ningún fichero. Compruebe el tipo de codificación en el " -"formulario." +#: utils/dates.py:18 +msgid "January" +msgstr "Enero" -#: core/validators.py:185 -msgid "" -"Upload a valid image. The file you uploaded was either not an image or a " -"corrupted image." -msgstr "" -"Envíe una imagen válida. El fichero que ha enviado no era una imagen o se " -"trataba de una imagen corrupta." +#: utils/dates.py:18 +msgid "February" +msgstr "Febrero" -#: core/validators.py:192 -#, python-format -msgid "The URL %s does not point to a valid image." -msgstr "La URL %s no apunta a una imagen válida." +#: utils/dates.py:18 utils/dates.py:31 +msgid "March" +msgstr "Marzo" -#: core/validators.py:196 -#, python-format -msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." -msgstr "" -"Los números de teléfono deben guardar el formato XXX-XXX-XXXX. \"%s\" no es " -"válido." +#: utils/dates.py:18 utils/dates.py:31 +msgid "April" +msgstr "Abril" -#: core/validators.py:204 -#, python-format -msgid "The URL %s does not point to a valid QuickTime video." -msgstr "La URL %s no apunta a un vídeo QuickTime válido." +#: utils/dates.py:18 utils/dates.py:31 +msgid "May" +msgstr "Mayo" -#: core/validators.py:208 -msgid "A valid URL is required." -msgstr "Se precisa una URL válida." +#: utils/dates.py:18 utils/dates.py:31 +msgid "June" +msgstr "Junio" -#: core/validators.py:222 -#, python-format -msgid "" -"Valid HTML is required. Specific errors are:\n" -"%s" -msgstr "" -"Se precisa HTML válido. Los errores específicos son:\n" -"%s" +#: utils/dates.py:19 utils/dates.py:31 +msgid "July" +msgstr "Julio" -#: core/validators.py:229 -#, python-format -msgid "Badly formed XML: %s" -msgstr "XML mal formado: %s" +#: utils/dates.py:19 +msgid "August" +msgstr "Agosto" -#: core/validators.py:246 -#, python-format -msgid "Invalid URL: %s" -msgstr "URL no válida: %s" +#: utils/dates.py:19 +msgid "September" +msgstr "Septiembre" -#: core/validators.py:251 core/validators.py:253 -#, python-format -msgid "The URL %s is a broken link." -msgstr "La URL %s es un enlace roto." +#: utils/dates.py:19 +msgid "October" +msgstr "Octubre" -#: core/validators.py:259 -msgid "Enter a valid U.S. state abbreviation." -msgstr "Introduzca una abreviatura válida de estado de los EEUU." +#: utils/dates.py:19 +msgid "November" +msgstr "Noviembre" -#: 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] "¡Cuida tu vocabulario! Aquí no admitimos la palabra %s." -msgstr[1] "¡Cuida tu vocabulario! Aquí no admitimos las palabras %s." +#: utils/dates.py:20 +msgid "December" +msgstr "Diciembre" -#: core/validators.py:280 -#, python-format -msgid "This field must match the '%s' field." -msgstr "Este campo debe concordar con el campo '%s'." +#: utils/dates.py:23 +msgid "jan" +msgstr "ene" -#: core/validators.py:299 -msgid "Please enter something for at least one field." -msgstr "Por favor, introduzca algo en al menos un campo." +#: utils/dates.py:23 +msgid "feb" +msgstr "feb" -#: core/validators.py:308 core/validators.py:319 -msgid "Please enter both fields or leave them both empty." -msgstr "Por favor, rellene ambos campos o deje ambos vacíos." +#: utils/dates.py:23 +msgid "mar" +msgstr "mar" -#: core/validators.py:327 -#, python-format -msgid "This field must be given if %(field)s is %(value)s" -msgstr "Se debe proporcionar este campo si %(field)s es %(value)s" +#: utils/dates.py:23 +msgid "apr" +msgstr "abr" -#: core/validators.py:340 -#, python-format -msgid "This field must be given if %(field)s is not %(value)s" -msgstr "Se debe proporcionar este campo si %(field)s no es %(value)s" +#: utils/dates.py:23 +msgid "may" +msgstr "may" -#: core/validators.py:359 -msgid "Duplicate values are not allowed." -msgstr "No se admiten valores duplicados." +#: utils/dates.py:23 +msgid "jun" +msgstr "jun" -#: core/validators.py:374 -#, python-format -msgid "This value must be between %(lower)s and %(upper)s." -msgstr "Este valor debe estar entre %(lower)s y %(upper)s." +#: utils/dates.py:24 +msgid "jul" +msgstr "jul" -#: core/validators.py:376 -#, python-format -msgid "This value must be at least %s." -msgstr "Este valor debe ser como mínimo %s." +#: utils/dates.py:24 +msgid "aug" +msgstr "ago" -#: core/validators.py:378 +#: utils/dates.py:24 +msgid "sep" +msgstr "sep" + +#: utils/dates.py:24 +msgid "oct" +msgstr "oct" + +#: utils/dates.py:24 +msgid "nov" +msgstr "nov" + +#: utils/dates.py:24 +msgid "dec" +msgstr "dic" + +#: utils/dates.py:31 +msgid "Jan." +msgstr "Ene." + +#: utils/dates.py:31 +msgid "Feb." +msgstr "Feb." + +#: utils/dates.py:32 +msgid "Aug." +msgstr "Ago." + +#: utils/dates.py:32 +msgid "Sept." +msgstr "Sept." + +#: utils/dates.py:32 +msgid "Oct." +msgstr "Oct." + +#: utils/dates.py:32 +msgid "Nov." +msgstr "Nov." + +#: utils/dates.py:32 +msgid "Dec." +msgstr "Dic." + +#: utils/timesince.py:12 +msgid "year" +msgid_plural "years" +msgstr[0] "año" +msgstr[1] "años" + +#: utils/timesince.py:13 +msgid "month" +msgid_plural "months" +msgstr[0] "mes" +msgstr[1] "meses" + +#: utils/timesince.py:14 +msgid "week" +msgid_plural "weeks" +msgstr[0] "semana" +msgstr[1] "semanas" + +#: utils/timesince.py:15 +msgid "day" +msgid_plural "days" +msgstr[0] "día" +msgstr[1] "días" + +#: utils/timesince.py:16 +msgid "hour" +msgid_plural "hours" +msgstr[0] "hora" +msgstr[1] "horas" + +#: utils/timesince.py:17 +msgid "minute" +msgid_plural "minutes" +msgstr[0] "minuto" +msgstr[1] "minutos" + +#: utils/timesince.py:39 #, python-format -msgid "This value must be no more than %s." -msgstr "Este valor no debe ser mayor que %s." +msgid "%(number)d %(type)s" +msgstr "%(number)d %(type)s" -#: core/validators.py:414 +#: utils/timesince.py:45 #, python-format -msgid "This value must be a power of %s." -msgstr "Este valor debe ser una potencia de %s." +msgid ", %(number)d %(type)s" +msgstr ", %(number)d %(type)s" -#: core/validators.py:424 -msgid "Please enter a valid decimal number." -msgstr "Por favor, introduzca un número decimal válido." +#: utils/dateformat.py:41 +msgid "p.m." +msgstr "p.m" -#: core/validators.py:431 -#, 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] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígito en " -"total." -msgstr[1] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígitos en " -"total." +#: utils/dateformat.py:42 +msgid "a.m." +msgstr "a.m" -#: core/validators.py:434 +#: utils/dateformat.py:47 +msgid "PM" +msgstr "PM" + +#: utils/dateformat.py:48 +msgid "AM" +msgstr "AM" + +#: utils/dateformat.py:97 +msgid "midnight" +msgstr "media noche" + +#: utils/dateformat.py:99 +msgid "noon" +msgstr "medio día" + +#: utils/translation/trans_real.py:391 +msgid "DATE_FORMAT" +msgstr "j N Y" + +#: utils/translation/trans_real.py:392 +msgid "DATETIME_FORMAT" +msgstr "j N Y P" + +#: utils/translation/trans_real.py:393 +msgid "TIME_FORMAT" +msgstr "P" + +#: utils/translation/trans_real.py:409 +msgid "YEAR_MONTH_FORMAT" +msgstr "F Y" + +#: utils/translation/trans_real.py:410 +msgid "MONTH_DAY_FORMAT" +msgstr "j \\de F" + +#: newforms/fields.py:116 #, 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] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígito en su " -"parte entera." -msgstr[1] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígitos en su " -"parte entera." +msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." +msgstr "" +"Asegúrese de que su texto tiene a lo más %(max)d caracteres (actualmente " +"tiene %(length)d)." -#: core/validators.py:437 +#: newforms/fields.py:118 #, 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] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígito " -"decimal." -msgstr[1] "" -"Por favor, introduzca un número decimal válido con a lo más %s dígitos " -"decimales." +msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." +msgstr "" +"Asegúrese de que su texto tiene al menos %(min)d caracteres (actualmente " +"tiene %(length)d)." -#: core/validators.py:445 -msgid "Please enter a valid floating point number." -msgstr "Por favor, introduzca un número decimal válido." +#: newforms/fields.py:142 core/validators.py:127 +msgid "Enter a whole number." +msgstr "Introduzca un número entero." -#: core/validators.py:454 +#: newforms/fields.py:144 newforms/fields.py:167 newforms/fields.py:197 #, python-format -msgid "Make sure your uploaded file is at least %s bytes big." -msgstr "Asegúrese de que el fichero que envía tiene al menos %s bytes." +msgid "Ensure this value is less than or equal to %s." +msgstr "Asegúrese de que este valor es menor o igual a %s." -#: core/validators.py:455 +#: newforms/fields.py:146 newforms/fields.py:169 newforms/fields.py:199 #, python-format -msgid "Make sure your uploaded file is at most %s bytes big." -msgstr "Asegúrese de que el fichero que envía tiene como máximo %s bytes." - -#: core/validators.py:472 -msgid "The format for this field is wrong." -msgstr "El formato de este campo es incorrecto." +msgid "Ensure this value is greater than or equal to %s." +msgstr "Asegúrese de que este valor es mayor o igual a %s." -#: core/validators.py:487 -msgid "This field is invalid." -msgstr "Este campo no es válido." +#: newforms/fields.py:165 newforms/fields.py:192 +msgid "Enter a number." +msgstr "Introduzca un número." -#: core/validators.py:523 +#: newforms/fields.py:201 #, python-format -msgid "Could not retrieve anything from %s." -msgstr "No pude obtener nada de %s." +msgid "Ensure that there are no more than %s digits in total." +msgstr "Asegúrese de que no hay más de %s dígitos en total." -#: core/validators.py:526 +#: newforms/fields.py:203 #, python-format -msgid "" -"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." -msgstr "" -"La URL %(url)s devolvió la cabecera Content-Type '%(contenttype)s', que no " -"es válida." +msgid "Ensure that there are no more than %s decimal places." +msgstr "Asegúrese de que no hay más de %s decimales." -#: core/validators.py:559 +#: newforms/fields.py:205 #, python-format -msgid "" -"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " -"\"%(start)s\".)" +msgid "Ensure that there are no more than %s digits before the decimal point." +msgstr "Asegúrese de que no hay más de %s dígitos antes del punto decimal." + +#: newforms/fields.py:238 newforms/fields.py:610 +msgid "Enter a valid date." +msgstr "Introduzca una fecha válida." + +#: newforms/fields.py:265 newforms/fields.py:612 +msgid "Enter a valid time." +msgstr "Introduzca una hora válida." + +#: newforms/fields.py:301 +msgid "Enter a valid date/time." +msgstr "Introduzca una fecha/hora válida." + +#: newforms/fields.py:314 +msgid "Enter a valid value." +msgstr "Introduzca un valor correcto." + +#: newforms/fields.py:336 core/validators.py:169 +msgid "Enter a valid e-mail address." +msgstr "Introduzca una dirección de correo electrónico válida" + +#: newforms/fields.py:376 oldforms/__init__.py:686 core/validators.py:181 +#: core/validators.py:461 +msgid "No file was submitted. Check the encoding type on the form." msgstr "" -"Por favor, cierre la etiqueta %(tag)s de la línea %(line)s. (La línea " -"empieza por \"%(start)s\".)" +"No se ha enviado ningún fichero. Compruebe el tipo de codificación en el " +"formulario." -#: core/validators.py:563 -#, python-format +#: newforms/fields.py:378 +msgid "No file was submitted." +msgstr "No se ha enviado ningún fichero" + +#: newforms/fields.py:380 oldforms/__init__.py:688 +msgid "The submitted file is empty." +msgstr "El fichero enviado está vacío." + +#: newforms/fields.py:397 core/validators.py:185 msgid "" -"Some text starting on line %(line)s is not allowed in that context. (Line " -"starts with \"%(start)s\".)" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." msgstr "" -"Parte del texto que comienza en la línea %(line)s no está permitido en ese " -"contexto. (La línea empieza por \"%(start)s\".)" +"Envíe una imagen válida. El fichero que ha enviado no era una imagen o se " +"trataba de una imagen corrupta." -#: core/validators.py:568 +#: newforms/fields.py:403 newforms/fields.py:425 +msgid "Enter a valid URL." +msgstr "Introduzca una URL válida." + +#: newforms/fields.py:427 +msgid "This URL appears to be a broken link." +msgstr "La URL parece ser un enlace roto." + +#: newforms/fields.py:478 newforms/models.py:180 +msgid "Select a valid choice. That choice is not one of the available choices." +msgstr "Escoja una opción válida. Esa opción no está entre las aceptadas." + +#: newforms/fields.py:494 newforms/fields.py:570 newforms/models.py:197 +msgid "Enter a list of values." +msgstr "Introduzca una lista de valores." + +#: newforms/fields.py:500 newforms/models.py:203 #, python-format -msgid "" -"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" -"(start)s\".)" -msgstr "" -"El \"%(attr)s\" de la línea %(line)s no es un atributo válido. (La línea " -"empieza por \"%(start)s\".)" +msgid "Select a valid choice. %s is not one of the available choices." +msgstr "Escoja una opción válida; '%s' no es una de las opciones disponibles." -#: core/validators.py:573 +#: newforms/widgets.py:188 contrib/admin/filterspecs.py:152 +#: oldforms/__init__.py:591 +msgid "Unknown" +msgstr "Desconocido" + +#: newforms/widgets.py:188 contrib/admin/filterspecs.py:145 +#: oldforms/__init__.py:591 +msgid "Yes" +msgstr "Sí" + +#: newforms/widgets.py:188 contrib/admin/filterspecs.py:145 +#: oldforms/__init__.py:591 +msgid "No" +msgstr "No" + +#: contrib/contenttypes/models.py:37 +msgid "python model class name" +msgstr "nombre de módulo python" + +#: contrib/contenttypes/models.py:40 +msgid "content type" +msgstr "tipo de contenido" + +#: contrib/contenttypes/models.py:41 +msgid "content types" +msgstr "tipos de contenido" + +#: contrib/humanize/templatetags/humanize.py:17 +msgid "th" +msgstr "th" + +#: contrib/humanize/templatetags/humanize.py:17 +msgid "st" +msgstr "st" + +#: contrib/humanize/templatetags/humanize.py:17 +msgid "nd" +msgstr "nd" + +#: contrib/humanize/templatetags/humanize.py:17 +msgid "rd" +msgstr "rd" + +#: contrib/humanize/templatetags/humanize.py:47 #, python-format -msgid "" -"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" -"(start)s\".)" -msgstr "" -"La \"<%(tag)s>\" de la línea %(line)s no es una etiqueta válida. (La línea " -"empieza por \"%(start)s\".)" +msgid "%(value).1f million" +msgid_plural "%(value).1f million" +msgstr[0] "%(value).1f millón" +msgstr[1] "%(value).1f millión" -#: core/validators.py:577 +#: contrib/humanize/templatetags/humanize.py:50 #, 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 línea %(line)s le faltan uno o más atributos " -"requeridos. (La línea empieza por \"%(start)s\".)" +msgid "%(value).1f billion" +msgid_plural "%(value).1f billion" +msgstr[0] "%(value).1f billión" +msgstr[1] "%(value).1f billión" -#: core/validators.py:582 +#: contrib/humanize/templatetags/humanize.py:53 #, python-format -msgid "" -"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " -"starts with \"%(start)s\".)" -msgstr "" -"El atributo \"%(attr)s\" de la línea %(line)s tiene un valor que no es " -"válido. (La línea empieza por \"%(start)s\".)" +msgid "%(value).1f trillion" +msgid_plural "%(value).1f trillion" +msgstr[0] "%(value).1f trillión" +msgstr[1] "%(value).1f trillión" -#: contrib/auth/forms.py:17 contrib/auth/forms.py:138 -msgid "The two password fields didn't match." -msgstr "Las dos contraseñas no coinciden." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "one" +msgstr "uno" -#: contrib/auth/forms.py:25 -msgid "A user with that username already exists." -msgstr "Ya existe un usuario con este nombre." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "two" +msgstr "dos" -#: contrib/auth/forms.py:53 -msgid "" -"Your Web browser doesn't appear to have cookies enabled. Cookies are " -"required for logging in." -msgstr "" -"Tu navegador de internet parece no tener las cookies habilitadas. Las " -"cookies se necesitan para poder ingresar." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "three" +msgstr "tres" -#: 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 "" -"Por favor, introduzca un correcto nombre de usuario y contraseña. Note que " -"ambos campos son sensibles a mayúsculas/minúsculas." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "four" +msgstr "cuatro" -#: contrib/auth/forms.py:62 -msgid "This account is inactive." -msgstr "Esta cuenta está inactiva." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "five" +msgstr "cinco" -#: contrib/auth/forms.py:84 -msgid "" -"That e-mail address doesn't have an associated user account. Are you sure " -"you've registered?" -msgstr "" -"Esta dirección de correo electrónico no tiene una cuenta de usuario " -"asociada. ¿Está seguro de que se ha registrado?" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "six" +msgstr "seis" -#: contrib/auth/forms.py:117 -msgid "The two 'new password' fields didn't match." -msgstr "" -"Las contraseñas introducidas en los campos 'nueva contraseña' no coinciden." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "seven" +msgstr "siete" -#: contrib/auth/forms.py:124 -msgid "Your old password was entered incorrectly. Please enter it again." -msgstr "" -"Tu contraseña antigua es incorrecta. Por favor, vuelve a introducirla " -"correctamente." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "eight" +msgstr "ocho" + +#: contrib/humanize/templatetags/humanize.py:68 +msgid "nine" +msgstr "nueve" + +#: contrib/auth/views.py:41 +msgid "Logged out" +msgstr "Sesión terminada" -#: contrib/auth/models.py:51 contrib/auth/models.py:71 +#: contrib/auth/models.py:53 contrib/auth/models.py:73 msgid "name" msgstr "nombre" -#: contrib/auth/models.py:53 +#: contrib/auth/models.py:55 msgid "codename" msgstr "nombre en código" -#: contrib/auth/models.py:56 +#: contrib/auth/models.py:58 msgid "permission" msgstr "permiso" -#: contrib/auth/models.py:57 contrib/auth/models.py:72 +#: contrib/auth/models.py:59 contrib/auth/models.py:74 msgid "permissions" msgstr "permisos" -#: contrib/auth/models.py:75 +#: contrib/auth/models.py:77 msgid "group" msgstr "grupo" -#: contrib/auth/models.py:76 contrib/auth/models.py:116 +#: contrib/auth/models.py:78 contrib/auth/models.py:121 msgid "groups" msgstr "grupos" -#: contrib/auth/models.py:106 +#: contrib/auth/models.py:111 msgid "username" msgstr "nombre de usuario" -#: contrib/auth/models.py:106 +#: contrib/auth/models.py:111 msgid "" "Required. 30 characters or fewer. Alphanumeric characters only (letters, " "digits and underscores)." @@ -667,23 +805,23 @@ msgstr "" "Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, " "dígitos y guiones bajos)." -#: contrib/auth/models.py:107 +#: contrib/auth/models.py:112 msgid "first name" msgstr "nombre" -#: contrib/auth/models.py:108 +#: contrib/auth/models.py:113 msgid "last name" msgstr "apellidos" -#: contrib/auth/models.py:109 +#: contrib/auth/models.py:114 msgid "e-mail address" msgstr "dirección de correo" -#: contrib/auth/models.py:110 +#: contrib/auth/models.py:115 msgid "password" msgstr "clave" -#: contrib/auth/models.py:110 +#: contrib/auth/models.py:115 msgid "" "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " "password form</a>." @@ -691,19 +829,19 @@ msgstr "" "Use'[algo]$[sal]$[hash hexadecimal]' o use <a href=\"password/\">el " "formulario para cambiar la contraseña</a>." -#: contrib/auth/models.py:111 +#: contrib/auth/models.py:116 msgid "staff status" msgstr "es staff" -#: contrib/auth/models.py:111 +#: contrib/auth/models.py:116 msgid "Designates whether the user can log into this admin site." msgstr "Indica si el usuario puede entrar en este sitio de administración." -#: contrib/auth/models.py:112 +#: contrib/auth/models.py:117 msgid "active" msgstr "activo" -#: contrib/auth/models.py:112 +#: contrib/auth/models.py:117 msgid "" "Designates whether this user can log into the Django admin. Unselect this " "instead of deleting accounts." @@ -711,11 +849,11 @@ msgstr "" "Indica si el usuario puede entrar en este sitio de administración. Desmarque " "esto en lugar de borrar la cuenta." -#: contrib/auth/models.py:113 +#: contrib/auth/models.py:118 msgid "superuser status" msgstr "es superusuario" -#: contrib/auth/models.py:113 +#: contrib/auth/models.py:118 msgid "" "Designates that this user has all permissions without explicitly assigning " "them." @@ -723,15 +861,15 @@ msgstr "" "Indica que este usuario tiene todos los permisos sin asignárselos " "explícitamente." -#: contrib/auth/models.py:114 +#: contrib/auth/models.py:119 msgid "last login" msgstr "Último registro" -#: contrib/auth/models.py:115 +#: contrib/auth/models.py:120 msgid "date joined" msgstr "fecha de creación" -#: contrib/auth/models.py:117 +#: contrib/auth/models.py:122 msgid "" "In addition to the permissions manually assigned, this user will also get " "all permissions granted to each group he/she is in." @@ -739,69 +877,536 @@ msgstr "" "Además de los permisos asignados manualmente, este usuario también tendrá " "todos los permisos de los grupos en los que esté." -#: contrib/auth/models.py:118 +#: contrib/auth/models.py:123 msgid "user permissions" msgstr "permisos" -#: contrib/auth/models.py:122 +#: contrib/auth/models.py:127 msgid "user" msgstr "usuario" -#: contrib/auth/models.py:123 +#: contrib/auth/models.py:128 msgid "users" msgstr "usuarios" -#: contrib/auth/models.py:129 +#: contrib/auth/models.py:134 msgid "Personal info" msgstr "Información personal" -#: contrib/auth/models.py:130 +#: contrib/auth/models.py:135 msgid "Permissions" msgstr "Permisos" -#: contrib/auth/models.py:131 +#: contrib/auth/models.py:136 msgid "Important dates" msgstr "Fechas importantes" -#: contrib/auth/models.py:132 +#: contrib/auth/models.py:137 msgid "Groups" msgstr "Grupos" -#: contrib/auth/models.py:274 +#: contrib/auth/models.py:287 msgid "message" msgstr "mensaje" -#: contrib/auth/views.py:41 -msgid "Logged out" -msgstr "Sesión terminada" +#: contrib/auth/forms.py:17 contrib/auth/forms.py:138 +msgid "The two password fields didn't match." +msgstr "Las dos contraseñas no coinciden." -#: contrib/admin/models.py:17 -msgid "action time" -msgstr "hora de acción" +#: contrib/auth/forms.py:25 +msgid "A user with that username already exists." +msgstr "Ya existe un usuario con este nombre." -#: contrib/admin/models.py:20 -msgid "object id" -msgstr "id de objeto" +#: contrib/auth/forms.py:53 +msgid "" +"Your Web browser doesn't appear to have cookies enabled. Cookies are " +"required for logging in." +msgstr "" +"Tu navegador de internet parece no tener las cookies habilitadas. Las " +"cookies se necesitan para poder ingresar." -#: contrib/admin/models.py:21 -msgid "object repr" -msgstr "repr de objeto" +#: 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 "" +"Por favor, introduzca un correcto nombre de usuario y contraseña. Note que " +"ambos campos son sensibles a mayúsculas/minúsculas." -#: contrib/admin/models.py:22 -msgid "action flag" -msgstr "marca de acción" +#: contrib/auth/forms.py:62 +msgid "This account is inactive." +msgstr "Esta cuenta está inactiva." -#: contrib/admin/models.py:23 -msgid "change message" -msgstr "mensaje de cambio" +#: contrib/auth/forms.py:84 +msgid "" +"That e-mail address doesn't have an associated user account. Are you sure " +"you've registered?" +msgstr "" +"Esta dirección de correo electrónico no tiene una cuenta de usuario " +"asociada. ¿Está seguro de que se ha registrado?" -#: contrib/admin/models.py:26 -msgid "log entry" -msgstr "entrada de registro" +#: contrib/auth/forms.py:117 +msgid "The two 'new password' fields didn't match." +msgstr "" +"Las contraseñas introducidas en los campos 'nueva contraseña' no coinciden." -#: contrib/admin/models.py:27 -msgid "log entries" -msgstr "entradas de registro" +#: contrib/auth/forms.py:124 +msgid "Your old password was entered incorrectly. Please enter it again." +msgstr "" +"Tu contraseña antigua es incorrecta. Por favor, vuelve a introducirla " +"correctamente." + +#: 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 "" +"Esta ruta debería ser absoluta, excluyendo el nombre de dominio. Ejeplo: '/" +"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 "" +"Esto puede ser bien una ruta absoluta (como antes) o una URL completa que " +"empiece con 'http://'." + +#: contrib/redirects/models.py:13 +msgid "redirect" +msgstr "redirección" + +#: contrib/redirects/models.py:14 +msgid "redirects" +msgstr "redirecciones" + +#: contrib/comments/models.py:67 contrib/comments/models.py:169 +msgid "object ID" +msgstr "ID de objeto" + +#: contrib/comments/models.py:68 +msgid "headline" +msgstr "encabezado" + +#: contrib/comments/models.py:69 contrib/comments/models.py:90 +#: contrib/comments/models.py:170 +msgid "comment" +msgstr "comentario" + +#: contrib/comments/models.py:70 +msgid "rating #1" +msgstr "calificación 1" + +#: contrib/comments/models.py:71 +msgid "rating #2" +msgstr "calificación 2" + +#: contrib/comments/models.py:72 +msgid "rating #3" +msgstr "calificación 3" + +#: contrib/comments/models.py:73 +msgid "rating #4" +msgstr "calificación 4" + +#: contrib/comments/models.py:74 +msgid "rating #5" +msgstr "calificación 5" + +#: contrib/comments/models.py:75 +msgid "rating #6" +msgstr "calificación 6" + +#: contrib/comments/models.py:76 +msgid "rating #7" +msgstr "calificación 7" + +#: contrib/comments/models.py:77 +msgid "rating #8" +msgstr "calificación 8" + +#: contrib/comments/models.py:82 +msgid "is valid rating" +msgstr "es calificación válida" + +#: contrib/comments/models.py:83 contrib/comments/models.py:172 +msgid "date/time submitted" +msgstr "fecha/hora de envío" + +#: contrib/comments/models.py:84 contrib/comments/models.py:173 +msgid "is public" +msgstr "es público" + +#: contrib/comments/models.py:85 contrib/admin/views/doc.py:306 +msgid "IP address" +msgstr "Dirección IP" + +#: contrib/comments/models.py:86 +msgid "is removed" +msgstr "está eliminado" + +#: 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 "" +"Marque esta caja si el comentario es inapropiado. En su lugar se mostrará " +"\"Este comentario ha sido eliminado\"." + +#: contrib/comments/models.py:91 +msgid "comments" +msgstr "comentarios" + +#: contrib/comments/models.py:134 contrib/comments/models.py:213 +msgid "Content object" +msgstr "Objeto contenido" + +#: contrib/comments/models.py:162 +#, python-format +msgid "" +"Posted by %(user)s at %(date)s\n" +"\n" +"%(comment)s\n" +"\n" +"http://%(domain)s%(url)s" +msgstr "" +"Enviado por %(user)s en %(date)s\n" +"\n" +"%(comment)s\n" +"\n" +"http://%(domain)s%(url)s" + +#: contrib/comments/models.py:171 +msgid "person's name" +msgstr "nombre de la persona" + +#: contrib/comments/models.py:174 +msgid "ip address" +msgstr "dirección ip" + +#: contrib/comments/models.py:176 +msgid "approved by staff" +msgstr "aprobado por el staff" + +#: contrib/comments/models.py:179 +msgid "free comment" +msgstr "comentario libre" + +#: contrib/comments/models.py:180 +msgid "free comments" +msgstr "comentarios libres" + +#: contrib/comments/models.py:239 +msgid "score" +msgstr "puntuación" + +#: contrib/comments/models.py:240 +msgid "score date" +msgstr "fecha de la puntuación" + +#: contrib/comments/models.py:243 +msgid "karma score" +msgstr "punto karma" + +#: contrib/comments/models.py:244 +msgid "karma scores" +msgstr "puntos karma" + +#: contrib/comments/models.py:248 +#, python-format +msgid "%(score)d rating by %(user)s" +msgstr "puntuado %(score)d por %(user)s" + +#: contrib/comments/models.py:264 +#, python-format +msgid "" +"This comment was flagged by %(user)s:\n" +"\n" +"%(text)s" +msgstr "" +"Este comentario fue marcado por %(user)s:\n" +"\n" +"%(text)s" + +#: contrib/comments/models.py:271 +msgid "flag date" +msgstr "fecha de la marca" + +#: contrib/comments/models.py:274 +msgid "user flag" +msgstr "marca de usuario" + +#: contrib/comments/models.py:275 +msgid "user flags" +msgstr "marcas de usuario" + +#: contrib/comments/models.py:279 +#, python-format +msgid "Flag by %r" +msgstr "Marca de %r" + +#: contrib/comments/models.py:284 +msgid "deletion date" +msgstr "fecha de eliminación" + +#: contrib/comments/models.py:286 +msgid "moderator deletion" +msgstr "eliminación de moderador" + +#: contrib/comments/models.py:287 +msgid "moderator deletions" +msgstr "eliminaciones de moderador" + +#: contrib/comments/models.py:291 +#, python-format +msgid "Moderator deletion by %r" +msgstr "Eliminación del moderador %r" + +#: contrib/comments/views/karma.py:20 +msgid "Anonymous users cannot vote" +msgstr "Los usuarios anónimos no pueden votar" + +#: contrib/comments/views/karma.py:24 +msgid "Invalid comment ID" +msgstr "ID de comentario no válido" + +#: contrib/comments/views/karma.py:26 +msgid "No voting for yourself" +msgstr "No puedes votarte tú mismo" + +#: contrib/comments/views/comments.py:28 +msgid "" +"This rating is required because you've entered at least one other rating." +msgstr "Se precisa esta puntuación porque ha introducido al menos otra más." + +#: contrib/comments/views/comments.py:112 +#, 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] "" +"Este comentario lo envió un usuario que ha enviado menos de %(count)s " +"comentario:\n" +"\n" +"%(text)s" +msgstr[1] "" +"Este comentario lo envió un usuario que ha enviado menos de %(count)s " +"comentarios:\n" +"\n" +"%(text)s" + +#: contrib/comments/views/comments.py:117 +#, python-format +msgid "" +"This comment was posted by a sketchy user:\n" +"\n" +"%(text)s" +msgstr "" +"Este comentario ha sido colocado por un usuario poco preciso: \n" +"\n" +"%(text)s" + +#: contrib/comments/views/comments.py:189 +#: contrib/comments/views/comments.py:281 +msgid "Only POSTs are allowed" +msgstr "Sólo se admite POST" + +#: contrib/comments/views/comments.py:193 +#: contrib/comments/views/comments.py:285 +msgid "One or more of the required fields wasn't submitted" +msgstr "No se proporcionó uno o más de los siguientes campos requeridos" + +#: contrib/comments/views/comments.py:197 +#: contrib/comments/views/comments.py:287 +msgid "Somebody tampered with the comment form (security violation)" +msgstr "" +"Alguien está jugando con el formulario de comentarios (violación de " +"seguridad)" + +#: contrib/comments/views/comments.py:207 +#: contrib/comments/views/comments.py:293 +msgid "" +"The comment form had an invalid 'target' parameter -- the object ID was " +"invalid" +msgstr "" +"El formulario de comentarios tiene un parámetro 'target' no válido (el ID de " +"objeto era inválido)" + +#: contrib/comments/views/comments.py:258 +#: contrib/comments/views/comments.py:322 +msgid "The comment form didn't provide either 'preview' or 'post'" +msgstr "El formulario de comentario no proporcionó 'previsualizar' ni 'enviar'" + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/comments/templates/comments/form.html:8 +#: contrib/admin/templates/admin/login.html:17 +msgid "Username:" +msgstr "Usuario:" + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/base.html:25 +#: 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/view_detail.html:4 +#: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_detail.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 +#: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 +#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 +msgid "Log out" +msgstr "Terminar sesión" + +#: contrib/comments/templates/comments/form.html:8 +#: contrib/admin/templates/admin/login.html:20 +msgid "Password:" +msgstr "Clave:" + +#: contrib/comments/templates/comments/form.html:8 +msgid "Forgotten your password?" +msgstr "¿Has olvidado tu contraseña?" + +#: contrib/comments/templates/comments/form.html:12 +msgid "Ratings" +msgstr "Calificaciones" + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Required" +msgstr "Requerido" + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Optional" +msgstr "Opcional" + +#: contrib/comments/templates/comments/form.html:23 +msgid "Post a photo" +msgstr "Postea una fotografía" + +#: contrib/comments/templates/comments/form.html:28 +#: contrib/comments/templates/comments/freeform.html:5 +msgid "Comment:" +msgstr "Comentario:" + +#: contrib/comments/templates/comments/form.html:35 +#: contrib/comments/templates/comments/freeform.html:10 +msgid "Preview comment" +msgstr "Previsualizar comentario" + +#: contrib/comments/templates/comments/freeform.html:4 +msgid "Your name:" +msgstr "Tu nombre:" + +#: contrib/flatpages/models.py:7 contrib/admin/views/doc.py:317 +msgid "URL" +msgstr "URL" + +#: contrib/flatpages/models.py:8 +msgid "" +"Example: '/about/contact/'. Make sure to have leading and trailing slashes." +msgstr "" +"Ejemplo: '/about/contact/'. Asegúrese de que pone barras al principio y al " +"final." + +#: contrib/flatpages/models.py:9 +msgid "title" +msgstr "título" + +#: contrib/flatpages/models.py:10 +msgid "content" +msgstr "contenido" + +#: contrib/flatpages/models.py:11 +msgid "enable comments" +msgstr "admitir comentarios" + +#: contrib/flatpages/models.py:12 +msgid "template name" +msgstr "nombre de 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 "" +"Ejemplo: 'flatpages/contact_page.html'. Si no es proporcionado, el sistema " +"usará 'flatpages/default.html'." + +#: contrib/flatpages/models.py:14 +msgid "registration required" +msgstr "debe estar registrado" + +#: contrib/flatpages/models.py:14 +msgid "If this is checked, only logged-in users will be able to view the page." +msgstr "Si está marcado, sólo los usuarios registrados podrán ver 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áginas estáticas" + +#: contrib/sessions/models.py:68 +msgid "session key" +msgstr "clave de sesión" + +#: contrib/sessions/models.py:69 +msgid "session data" +msgstr "datos de sesión" + +#: contrib/sessions/models.py:70 +msgid "expire date" +msgstr "fecha de caducidad" + +#: contrib/sessions/models.py:74 +msgid "session" +msgstr "sesión" + +#: contrib/sessions/models.py:75 +msgid "sessions" +msgstr "sesiones" + +#: contrib/sites/models.py:15 +msgid "domain name" +msgstr "nombre de dominio" + +#: contrib/sites/models.py:16 +msgid "display name" +msgstr "nombre para mostrar" + +#: contrib/sites/models.py:20 +msgid "site" +msgstr "sitio" + +#: contrib/sites/models.py:21 +msgid "sites" +msgstr "sitios" #: contrib/admin/filterspecs.py:42 #, python-format @@ -837,67 +1442,65 @@ msgstr "Este mes" msgid "This year" msgstr "Este año" -#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:587 -#: newforms/widgets.py:181 -msgid "Yes" -msgstr "Sí" - -#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:587 -#: newforms/widgets.py:181 -msgid "No" -msgstr "No" +#: contrib/admin/models.py:17 +msgid "action time" +msgstr "hora de acción" -#: contrib/admin/filterspecs.py:152 oldforms/__init__.py:587 -#: newforms/widgets.py:181 -msgid "Unknown" -msgstr "Desconocido" +#: contrib/admin/models.py:20 +msgid "object id" +msgstr "id de objeto" -#: contrib/admin/views/decorators.py:24 -#: contrib/admin/templates/admin/login.html:25 -msgid "Log in" -msgstr "Identificarse" +#: contrib/admin/models.py:21 +msgid "object repr" +msgstr "repr de objeto" -#: 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 "" -"Por favor, identifíquese de nuevo, porque su sesión ha caducado. No se " -"preocupe: se ha guardado su envío." +#: contrib/admin/models.py:22 +msgid "action flag" +msgstr "marca de acción" -#: 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 "" -"Parece que su navegador no está configurado para aceptar cookies. Actívelas " -"por favor, recargue esta página, e inténtelo de nuevo." +#: contrib/admin/models.py:23 +msgid "change message" +msgstr "mensaje de cambio" -#: contrib/admin/views/decorators.py:83 -msgid "Usernames cannot contain the '@' character." -msgstr "Los nombres de usuario no pueden contener el carácter '@'." +#: contrib/admin/models.py:26 +msgid "log entry" +msgstr "entrada de registro" -#: contrib/admin/views/decorators.py:85 -#, 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. Pruebe con '%s' en su " -"lugar." +#: contrib/admin/models.py:27 +msgid "log entries" +msgstr "entradas de registro" -#: contrib/admin/views/main.py:230 -msgid "Site administration" -msgstr "Sitio administrativo" +#: contrib/admin/templatetags/admin_list.py:254 +msgid "All dates" +msgstr "Todas las fechas" -#: contrib/admin/views/main.py:264 contrib/admin/views/auth.py:20 +#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:264 #, python-format msgid "The %(name)s \"%(obj)s\" was added successfully." msgstr "Se añadió con éxito el %(name)s \"%(obj)s\"." -#: contrib/admin/views/main.py:268 contrib/admin/views/main.py:354 -#: contrib/admin/views/auth.py:25 +#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:268 +#: contrib/admin/views/main.py:354 msgid "You may edit it again below." msgstr "Puede editarlo de nuevo abajo." +#: contrib/admin/views/auth.py:31 +msgid "Add user" +msgstr "Añadir usuario" + +#: contrib/admin/views/auth.py:58 +msgid "Password changed successfully." +msgstr "La clave se ha cambiado exitosamente." + +#: contrib/admin/views/auth.py:65 +#, python-format +msgid "Change password: %s" +msgstr "Cambiar clave: %s" + +#: contrib/admin/views/main.py:230 +msgid "Site administration" +msgstr "Sitio administrativo" + #: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363 #, python-format msgid "You may add another %s below." @@ -982,6 +1585,38 @@ msgstr "Escoja %s para modificar" msgid "Database error" msgstr "Erorr en la base de datos" +#: contrib/admin/views/decorators.py:24 +#: contrib/admin/templates/admin/login.html:25 +msgid "Log in" +msgstr "Identificarse" + +#: 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 "" +"Por favor, identifíquese de nuevo, porque su sesión ha caducado. No se " +"preocupe: se ha guardado su envío." + +#: 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 "" +"Parece que su navegador no está configurado para aceptar cookies. Actívelas " +"por favor, recargue esta página, e inténtelo de nuevo." + +#: contrib/admin/views/decorators.py:83 +msgid "Usernames cannot contain the '@' character." +msgstr "Los nombres de usuario no pueden contener el carácter '@'." + +#: contrib/admin/views/decorators.py:85 +#, 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. Pruebe con '%s' en su " +"lugar." + #: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49 #: contrib/admin/views/doc.py:51 msgid "tag:" @@ -1049,8 +1684,8 @@ msgstr "Booleano (Verdadero o Falso)" #: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313 #, python-format -msgid "String (up to %(maxlength)s)" -msgstr "Cadena (máximo %(maxlength)s)" +msgid "String (up to %(max_length)s)" +msgstr "Cadena (máximo %(max_length)s)" #: contrib/admin/views/doc.py:295 msgid "Comma-separated integers" @@ -1081,10 +1716,6 @@ msgstr "Ruta de fichero" msgid "Floating point number" msgstr "Número decimal" -#: contrib/admin/views/doc.py:306 contrib/comments/models.py:85 -msgid "IP address" -msgstr "Dirección IP" - #: contrib/admin/views/doc.py:308 msgid "Boolean (Either True, False or None)" msgstr "Booleano (Verdadero, Falso o Nulo)" @@ -1105,10 +1736,6 @@ msgstr "Texto" msgid "Time" msgstr "Hora" -#: contrib/admin/views/doc.py:317 contrib/flatpages/models.py:7 -msgid "URL" -msgstr "URL" - #: contrib/admin/views/doc.py:318 msgid "U.S. state (two uppercase letters)" msgstr "Estado de los EEUU (dos letras mayúsculas)" @@ -1122,231 +1749,88 @@ msgstr "Texto XML" msgid "%s does not appear to be a urlpattern object" msgstr "%s no parece ser un objeto urlpattern" -#: contrib/admin/views/auth.py:31 -msgid "Add user" -msgstr "Añadir usuario" - -#: contrib/admin/views/auth.py:58 -msgid "Password changed successfully." -msgstr "La clave se ha cambiado exitosamente." +#: contrib/admin/templates/widget/file.html:2 +msgid "Currently:" +msgstr "Actualmente:" -#: contrib/admin/views/auth.py:65 -#, python-format -msgid "Change password: %s" -msgstr "Cambiar clave: %s" +#: contrib/admin/templates/widget/file.html:3 +msgid "Change:" +msgstr "Modificar:" -#: contrib/admin/templatetags/admin_list.py:254 -msgid "All dates" -msgstr "Todas las fechas" +#: contrib/admin/templates/widget/date_time.html:3 +msgid "Date:" +msgstr "Fecha:" -#: contrib/admin/templates/admin/pagination.html:10 -msgid "Show all" -msgstr "Mostrarlo todo" +#: contrib/admin/templates/widget/date_time.html:4 +msgid "Time:" +msgstr "Hora:" -#: contrib/admin/templates/admin/delete_confirmation.html:3 -#: contrib/admin/templates/admin/change_form.html:10 #: contrib/admin/templates/admin/change_list.html:5 #: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.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 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 msgid "Documentation" msgstr "Documentación" -#: contrib/admin/templates/admin/delete_confirmation.html:3 -#: contrib/admin/templates/admin/change_form.html:10 #: contrib/admin/templates/admin/change_list.html:5 #: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.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/template_filter_index.html:5 +#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/view_detail.html:4 #: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_detail.html:4 #: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/model_detail.html:3 #: contrib/admin/templates/admin_doc/missing_docutils.html:4 -#: contrib/admin/templates/admin_doc/template_detail.html:4 #: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 #: contrib/admin/templates/admin_doc/model_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 -#: contrib/admin/templates/registration/password_change_form.html:3 -#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 msgid "Change password" msgstr "Cambiar clave" -#: contrib/admin/templates/admin/delete_confirmation.html:3 -#: contrib/admin/templates/admin/change_form.html:10 -#: contrib/admin/templates/admin/change_list.html:5 -#: 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/template_filter_index.html:5 -#: contrib/admin/templates/admin_doc/bookmarklets.html:4 -#: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/model_detail.html:3 -#: contrib/admin/templates/admin_doc/missing_docutils.html:4 -#: contrib/admin/templates/admin_doc/template_detail.html:4 -#: contrib/admin/templates/admin_doc/view_index.html:5 -#: contrib/admin/templates/admin_doc/model_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 -#: contrib/admin/templates/registration/password_change_form.html:3 -#: contrib/admin/templates/registration/password_change_done.html:3 -#: contrib/comments/templates/comments/form.html:6 -msgid "Log out" -msgstr "Terminar sesión" - -#: contrib/admin/templates/admin/delete_confirmation.html:6 -#: contrib/admin/templates/admin/change_form.html:13 #: contrib/admin/templates/admin/change_list.html:6 #: contrib/admin/templates/admin/object_history.html:5 #: 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/delete_confirmation.html:6 #: contrib/admin/templates/admin/base.html:30 #: contrib/admin/templates/admin/auth/user/change_password.html:12 -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +#: 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 #: 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/admin_doc/bookmarklets.html:3 msgid "Home" msgstr "Inicio" -#: contrib/admin/templates/admin/delete_confirmation.html:9 -#: contrib/admin/templates/admin/submit_line.html:3 -msgid "Delete" -msgstr "Eliminar" - -#: contrib/admin/templates/admin/delete_confirmation.html:14 -#, 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 %(object_name)s '%(escaped_object)s' provocaría la eliminación " -"de objetos relacionados, pero su cuenta no tiene permiso para borrar los " -"siguientes tipos de objetos:" - -#: contrib/admin/templates/admin/delete_confirmation.html:21 -#, 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á seguro de que quiere borrar los %(object_name)s \"%(escaped_object)s" -"\"? Se borrarán los siguientes objetos relacionados:" - -#: contrib/admin/templates/admin/delete_confirmation.html:26 -msgid "Yes, I'm sure" -msgstr "Sí, estoy seguro" - -#: contrib/admin/templates/admin/404.html:4 -#: contrib/admin/templates/admin/404.html:8 -msgid "Page not found" -msgstr "Página no encontrada" - -#: contrib/admin/templates/admin/404.html:10 -msgid "We're sorry, but the requested page could not be found." -msgstr "Lo sentimos, pero no se encuentra la página solicitada." - -#: contrib/admin/templates/admin/change_form.html:15 -#: contrib/admin/templates/admin/index.html:28 -msgid "Add" -msgstr "Agregar" - -#: contrib/admin/templates/admin/change_form.html:21 -#: contrib/admin/templates/admin/object_history.html:5 -msgid "History" -msgstr "Histórico" - -#: contrib/admin/templates/admin/change_form.html:22 -msgid "View on site" -msgstr "Ver en el sitio" - -#: 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] "Por favor, corrija el siguiente error." -msgstr[1] "Por favor, corrija los siguientes errores." - -#: contrib/admin/templates/admin/change_form.html:50 -msgid "Ordering" -msgstr "Ordenación" - -#: contrib/admin/templates/admin/change_form.html:53 -msgid "Order:" -msgstr "Orden:" - -#: contrib/admin/templates/admin/filter.html:2 -#, python-format -msgid " By %(filter_title)s " -msgstr " Por %(filter_title)s " - -#: contrib/admin/templates/admin/submit_line.html:4 -msgid "Save as new" -msgstr "Grabar como nuevo" - -#: contrib/admin/templates/admin/submit_line.html:5 -msgid "Save and add another" -msgstr "Grabar y añadir otro" - -#: contrib/admin/templates/admin/submit_line.html:6 -msgid "Save and continue editing" -msgstr "Grabar y continuar editando" - -#: contrib/admin/templates/admin/submit_line.html:7 -msgid "Save" -msgstr "Grabar" - #: contrib/admin/templates/admin/change_list.html:12 #, python-format msgid "Add %(name)s" msgstr "Agregar %(name)s" -#: contrib/admin/templates/admin/index.html:17 -#, python-format -msgid "Models available in the %(name)s application." -msgstr "Modelos disponibles en la aplicación %(name)s." - -#: contrib/admin/templates/admin/index.html:18 +#: contrib/admin/templates/admin/filter.html:2 #, python-format -msgid "%(name)s" -msgstr "%(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 tiene permiso para editar nada." - -#: contrib/admin/templates/admin/index.html:52 -msgid "Recent Actions" -msgstr "Acciones recientes" - -#: contrib/admin/templates/admin/index.html:53 -msgid "My Actions" -msgstr "Mis acciones" - -#: contrib/admin/templates/admin/index.html:57 -msgid "None available" -msgstr "Ninguno disponible" - -#: contrib/admin/templates/admin/base_site.html:4 -msgid "Django site admin" -msgstr "Sitio de administración de Django" +msgid " By %(filter_title)s " +msgstr " Por %(filter_title)s " -#: contrib/admin/templates/admin/base_site.html:7 -msgid "Django administration" -msgstr "Administración de Django" +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/change_form.html:21 +msgid "History" +msgstr "Histórico" #: contrib/admin/templates/admin/object_history.html:18 msgid "Date/time" @@ -1372,6 +1856,34 @@ msgstr "" "Este objeto no tiene histórico de cambios. Probablemente no fue añadido " "usando este sitio de administración." +#: contrib/admin/templates/admin/search_form.html:8 +msgid "Go" +msgstr "Buscar" + +#: contrib/admin/templates/admin/search_form.html:10 +#, python-format +msgid "1 result" +msgid_plural "%(counter)s results" +msgstr[0] "1 resultado" +msgstr[1] "%(counter)s resultados" + +#: contrib/admin/templates/admin/search_form.html:10 +#, python-format +msgid "%(full_result_count)s total" +msgstr "%(full_result_count)s total" + +#: contrib/admin/templates/admin/pagination.html:10 +msgid "Show all" +msgstr "Mostrarlo todo" + +#: contrib/admin/templates/admin/base_site.html:4 +msgid "Django site admin" +msgstr "Sitio de administración de Django" + +#: contrib/admin/templates/admin/base_site.html:7 +msgid "Django administration" +msgstr "Administración de Django" + #: contrib/admin/templates/admin/500.html:4 msgid "Server error" msgstr "Error del servidor" @@ -1403,41 +1915,122 @@ msgstr "" "necesarias han sido creadas, y que la base de datos puede ser leída por el " "usuario apropiado." -#: contrib/admin/templates/admin/search_form.html:8 -msgid "Go" -msgstr "Buscar" - -#: contrib/admin/templates/admin/search_form.html:10 +#: contrib/admin/templates/admin/index.html:17 #, python-format -msgid "1 result" -msgid_plural "%(counter)s results" -msgstr[0] "1 resultado" -msgstr[1] "%(counter)s resultados" +msgid "Models available in the %(name)s application." +msgstr "Modelos disponibles en la aplicación %(name)s." -#: contrib/admin/templates/admin/search_form.html:10 +#: contrib/admin/templates/admin/index.html:18 #, python-format -msgid "%(full_result_count)s total" -msgstr "%(full_result_count)s total" +msgid "%(name)s" +msgstr "%(name)s" + +#: contrib/admin/templates/admin/index.html:28 +#: contrib/admin/templates/admin/change_form.html:15 +msgid "Add" +msgstr "Agregar" + +#: 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 tiene permiso para editar nada." + +#: contrib/admin/templates/admin/index.html:52 +msgid "Recent Actions" +msgstr "Acciones recientes" + +#: contrib/admin/templates/admin/index.html:53 +msgid "My Actions" +msgstr "Mis acciones" + +#: contrib/admin/templates/admin/index.html:57 +msgid "None available" +msgstr "Ninguno disponible" + +#: contrib/admin/templates/admin/404.html:4 +#: contrib/admin/templates/admin/404.html:8 +msgid "Page not found" +msgstr "Página no encontrada" + +#: contrib/admin/templates/admin/404.html:10 +msgid "We're sorry, but the requested page could not be found." +msgstr "Lo sentimos, pero no se encuentra la página solicitada." #: contrib/admin/templates/admin/filters.html:4 msgid "Filter" msgstr "Filtro" -#: contrib/admin/templates/admin/login.html:17 -#: contrib/comments/templates/comments/form.html:6 -#: contrib/comments/templates/comments/form.html:8 -msgid "Username:" -msgstr "Usuario:" +#: contrib/admin/templates/admin/change_form.html:22 +msgid "View on site" +msgstr "Ver en el sitio" -#: contrib/admin/templates/admin/login.html:20 -#: contrib/comments/templates/comments/form.html:8 -msgid "Password:" -msgstr "Clave:" +#: 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] "Por favor, corrija el siguiente error." +msgstr[1] "Por favor, corrija los siguientes errores." + +#: contrib/admin/templates/admin/change_form.html:50 +msgid "Ordering" +msgstr "Ordenación" + +#: contrib/admin/templates/admin/change_form.html:53 +msgid "Order:" +msgstr "Orden:" + +#: contrib/admin/templates/admin/delete_confirmation.html:9 +#: contrib/admin/templates/admin/submit_line.html:3 +msgid "Delete" +msgstr "Eliminar" + +#: contrib/admin/templates/admin/delete_confirmation.html:14 +#, 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 %(object_name)s '%(escaped_object)s' provocaría la eliminación " +"de objetos relacionados, pero su cuenta no tiene permiso para borrar los " +"siguientes tipos de objetos:" + +#: contrib/admin/templates/admin/delete_confirmation.html:21 +#, 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á seguro de que quiere borrar los %(object_name)s \"%(escaped_object)s" +"\"? Se borrarán los siguientes objetos relacionados:" + +#: contrib/admin/templates/admin/delete_confirmation.html:26 +msgid "Yes, I'm sure" +msgstr "Sí, estoy seguro" #: contrib/admin/templates/admin/base.html:25 msgid "Welcome," msgstr "Bienvenido," +#: contrib/admin/templates/admin/submit_line.html:4 +msgid "Save as new" +msgstr "Grabar como nuevo" + +#: contrib/admin/templates/admin/submit_line.html:5 +msgid "Save and add another" +msgstr "Grabar y añadir otro" + +#: contrib/admin/templates/admin/submit_line.html:6 +msgid "Save and continue editing" +msgstr "Grabar y continuar editando" + +#: contrib/admin/templates/admin/submit_line.html:7 +msgid "Save" +msgstr "Grabar" + #: 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 " @@ -1472,91 +2065,21 @@ msgstr "" "Introduzca una nueva contraseña para el usuario <strong>%(username)s</" "strong>." -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 -msgid "Bookmarklets" -msgstr "Bookmarklets" - -#: contrib/admin/templates/admin_doc/bookmarklets.html:5 -msgid "Documentation bookmarklets" -msgstr "Bookmarklets de documentación" - -#: 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\">Para instalar bookmarklets, arrastre el enlace a su barra\n" -"de favoritos, o pulse con el botón derecho el enlace y añádalo a sus " -"favoritos.\n" -"Ahora puede escoger el bookmarklet desde cualquier página en el sitio.\n" -"Observer que algunos de estos bookmarklets precisan que esté viendo\n" -"el sitio desde un computador señalado como \"interno\" (hable\n" -"con su administrador de sistemas si no está seguro de si el suyo lo es).</" -"p>\n" - -#: contrib/admin/templates/admin_doc/bookmarklets.html:19 -msgid "Documentation for this page" -msgstr "Documentación de esta 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 "" -"Le lleva desde cualquier página a la documentación de la vista que la genera." - -#: contrib/admin/templates/admin_doc/bookmarklets.html:22 -msgid "Show object ID" -msgstr "Mostrar ID de objeto" - -#: contrib/admin/templates/admin_doc/bookmarklets.html:23 -msgid "" -"Shows the content-type and unique ID for pages that represent a single " -"object." -msgstr "" -"Muestra el tipo de contenido e ID unívoco de las páginas que representan un " -"único objeto." - -#: contrib/admin/templates/admin_doc/bookmarklets.html:25 -msgid "Edit this object (current window)" -msgstr "Editar este objeto (ventana actual)" - -#: contrib/admin/templates/admin_doc/bookmarklets.html:26 -msgid "Jumps to the admin page for pages that represent a single object." -msgstr "" -"Le lleva a la página de administración de páginas que representan un único " -"objeto." - -#: contrib/admin/templates/admin_doc/bookmarklets.html:28 -msgid "Edit this object (new window)" -msgstr "Editar este objeto (nueva ventana)" - -#: contrib/admin/templates/admin_doc/bookmarklets.html:29 -msgid "As above, but opens the admin page in a new window." -msgstr "" -"Como antes, pero abre la página de administración en una nueva ventana." - -#: contrib/admin/templates/widget/date_time.html:3 -msgid "Date:" -msgstr "Fecha:" - -#: contrib/admin/templates/widget/date_time.html:4 -msgid "Time:" -msgstr "Hora:" +#: 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 +#: contrib/admin/templates/registration/password_change_form.html:10 +msgid "Password change" +msgstr "Cambio de clave" -#: contrib/admin/templates/widget/file.html:2 -msgid "Currently:" -msgstr "Actualmente:" +#: contrib/admin/templates/registration/password_change_done.html:6 +#: contrib/admin/templates/registration/password_change_done.html:10 +msgid "Password change successful" +msgstr "Cambio de clave exitoso" -#: contrib/admin/templates/widget/file.html:3 -msgid "Change:" -msgstr "Modificar:" +#: contrib/admin/templates/registration/password_change_done.html:12 +msgid "Your password was changed." +msgstr "Su clave ha sido cambiada." #: contrib/admin/templates/registration/password_reset_form.html:4 #: contrib/admin/templates/registration/password_reset_form.html:6 @@ -1581,37 +2104,6 @@ msgstr "Dirección de correo electrónico:" msgid "Reset my password" msgstr "Recuperar mi clave" -#: contrib/admin/templates/registration/password_reset_email.html:2 -msgid "You're receiving this e-mail because you requested a password reset" -msgstr "Está recibiendo este mensaje debido a que solicitó recuperar la clave" - -#: contrib/admin/templates/registration/password_reset_email.html:3 -#, python-format -msgid "for your user account at %(site_name)s" -msgstr "de su cuenta de usuario en %(site_name)s." - -#: contrib/admin/templates/registration/password_reset_email.html:5 -#, python-format -msgid "Your new password is: %(new_password)s" -msgstr "Su nueva clave es: %(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 "Puede cambiarla accediendo a esta página:" - -#: contrib/admin/templates/registration/password_reset_email.html:11 -msgid "Your username, in case you've forgotten:" -msgstr "Su nombre de usuario, en caso de haberlo olvidado:" - -#: contrib/admin/templates/registration/password_reset_email.html:13 -msgid "Thanks for using our site!" -msgstr "¡Gracias por usar nuestro sitio!" - -#: contrib/admin/templates/registration/password_reset_email.html:15 -#, python-format -msgid "The %(site_name)s team" -msgstr "El equipo de %(site_name)s" - #: contrib/admin/templates/registration/logged_out.html:8 msgid "Thanks for spending some quality time with the Web site today." msgstr "Gracias por el tiempo que ha dedicado al sitio web hoy." @@ -1633,13 +2125,6 @@ msgstr "" "Le hemos enviado una clave nueva a la dirección que ha suministrado. Debería " "recibirla en breve." -#: contrib/admin/templates/registration/password_change_form.html:4 -#: contrib/admin/templates/registration/password_change_form.html:6 -#: contrib/admin/templates/registration/password_change_form.html:10 -#: contrib/admin/templates/registration/password_change_done.html:4 -msgid "Password change" -msgstr "Cambio de clave" - #: contrib/admin/templates/registration/password_change_form.html:12 msgid "" "Please enter your old password, for security's sake, and then enter your new " @@ -1664,482 +2149,309 @@ msgstr "Confirme clave:" msgid "Change my password" msgstr "Cambiar mi clave" -#: contrib/admin/templates/registration/password_change_done.html:6 -#: contrib/admin/templates/registration/password_change_done.html:10 -msgid "Password change successful" -msgstr "Cambio de clave exitoso" - -#: contrib/admin/templates/registration/password_change_done.html:12 -msgid "Your password was changed." -msgstr "Su clave ha sido cambiada." - -#: contrib/sites/models.py:15 -msgid "domain name" -msgstr "nombre de dominio" - -#: contrib/sites/models.py:16 -msgid "display name" -msgstr "nombre para mostrar" - -#: contrib/sites/models.py:20 -msgid "site" -msgstr "sitio" - -#: contrib/sites/models.py:21 -msgid "sites" -msgstr "sitios" - -#: contrib/humanize/templatetags/humanize.py:17 -msgid "th" -msgstr "th" - -#: contrib/humanize/templatetags/humanize.py:17 -msgid "st" -msgstr "st" - -#: contrib/humanize/templatetags/humanize.py:17 -msgid "nd" -msgstr "nd" - -#: contrib/humanize/templatetags/humanize.py:17 -msgid "rd" -msgstr "rd" - -#: contrib/humanize/templatetags/humanize.py:47 -#, python-format -msgid "%(value).1f million" -msgid_plural "%(value).1f million" -msgstr[0] "%(value).1f millón" -msgstr[1] "%(value).1f millión" +#: contrib/admin/templates/registration/password_reset_email.html:2 +msgid "You're receiving this e-mail because you requested a password reset" +msgstr "Está recibiendo este mensaje debido a que solicitó recuperar la clave" -#: contrib/humanize/templatetags/humanize.py:50 +#: contrib/admin/templates/registration/password_reset_email.html:3 #, python-format -msgid "%(value).1f billion" -msgid_plural "%(value).1f billion" -msgstr[0] "%(value).1f billión" -msgstr[1] "%(value).1f billión" +msgid "for your user account at %(site_name)s" +msgstr "de su cuenta de usuario en %(site_name)s." -#: contrib/humanize/templatetags/humanize.py:53 +#: contrib/admin/templates/registration/password_reset_email.html:5 #, python-format -msgid "%(value).1f trillion" -msgid_plural "%(value).1f trillion" -msgstr[0] "%(value).1f trillión" -msgstr[1] "%(value).1f trillión" - -#: contrib/humanize/templatetags/humanize.py:68 -msgid "one" -msgstr "uno" - -#: contrib/humanize/templatetags/humanize.py:68 -msgid "two" -msgstr "dos" - -#: contrib/humanize/templatetags/humanize.py:68 -msgid "three" -msgstr "tres" +msgid "Your new password is: %(new_password)s" +msgstr "Su nueva clave es: %(new_password)s" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "four" -msgstr "cuatro" +#: contrib/admin/templates/registration/password_reset_email.html:7 +msgid "Feel free to change this password by going to this page:" +msgstr "Puede cambiarla accediendo a esta página:" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "five" -msgstr "cinco" +#: contrib/admin/templates/registration/password_reset_email.html:11 +msgid "Your username, in case you've forgotten:" +msgstr "Su nombre de usuario, en caso de haberlo olvidado:" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "six" -msgstr "seis" +#: contrib/admin/templates/registration/password_reset_email.html:13 +msgid "Thanks for using our site!" +msgstr "¡Gracias por usar nuestro sitio!" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "seven" -msgstr "siete" +#: contrib/admin/templates/registration/password_reset_email.html:15 +#, python-format +msgid "The %(site_name)s team" +msgstr "El equipo de %(site_name)s" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "eight" -msgstr "ocho" +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Bookmarklets" +msgstr "Bookmarklets" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "nine" -msgstr "nueve" +#: contrib/admin/templates/admin_doc/bookmarklets.html:5 +msgid "Documentation bookmarklets" +msgstr "Bookmarklets de documentación" -#: contrib/flatpages/models.py:8 +#: contrib/admin/templates/admin_doc/bookmarklets.html:9 msgid "" -"Example: '/about/contact/'. Make sure to have leading and trailing slashes." +"\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 "" -"Ejemplo: '/about/contact/'. Asegúrese de que pone barras al principio y al " -"final." - -#: contrib/flatpages/models.py:9 -msgid "title" -msgstr "título" - -#: contrib/flatpages/models.py:10 -msgid "content" -msgstr "contenido" - -#: contrib/flatpages/models.py:11 -msgid "enable comments" -msgstr "admitir comentarios" +"\n" +"<p class=\"help\">Para instalar bookmarklets, arrastre el enlace a su barra\n" +"de favoritos, o pulse con el botón derecho el enlace y añádalo a sus " +"favoritos.\n" +"Ahora puede escoger el bookmarklet desde cualquier página en el sitio.\n" +"Observer que algunos de estos bookmarklets precisan que esté viendo\n" +"el sitio desde un computador señalado como \"interno\" (hable\n" +"con su administrador de sistemas si no está seguro de si el suyo lo es).</" +"p>\n" -#: contrib/flatpages/models.py:12 -msgid "template name" -msgstr "nombre de plantilla" +#: contrib/admin/templates/admin_doc/bookmarklets.html:19 +msgid "Documentation for this page" +msgstr "Documentación de esta página" -#: contrib/flatpages/models.py:13 +#: contrib/admin/templates/admin_doc/bookmarklets.html:20 msgid "" -"Example: 'flatpages/contact_page.html'. If this isn't provided, the system " -"will use 'flatpages/default.html'." +"Jumps you from any page to the documentation for the view that generates " +"that page." msgstr "" -"Ejemplo: 'flatpages/contact_page.html'. Si no es proporcionado, el sistema " -"usará 'flatpages/default.html'." - -#: contrib/flatpages/models.py:14 -msgid "registration required" -msgstr "debe estar registrado" - -#: contrib/flatpages/models.py:14 -msgid "If this is checked, only logged-in users will be able to view the page." -msgstr "Si está marcado, sólo los usuarios registrados podrán ver 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áginas estáticas" +"Le lleva desde cualquier página a la documentación de la vista que la genera." -#: contrib/redirects/models.py:7 -msgid "redirect from" -msgstr "redirigir desde" +#: contrib/admin/templates/admin_doc/bookmarklets.html:22 +msgid "Show object ID" +msgstr "Mostrar ID de objeto" -#: contrib/redirects/models.py:8 +#: contrib/admin/templates/admin_doc/bookmarklets.html:23 msgid "" -"This should be an absolute path, excluding the domain name. Example: '/" -"events/search/'." +"Shows the content-type and unique ID for pages that represent a single " +"object." msgstr "" -"Esta ruta debería ser absoluta, excluyendo el nombre de dominio. Ejeplo: '/" -"events/search/'." +"Muestra el tipo de contenido e ID unívoco de las páginas que representan un " +"único objeto." -#: contrib/redirects/models.py:9 -msgid "redirect to" -msgstr "redirigir a" +#: contrib/admin/templates/admin_doc/bookmarklets.html:25 +msgid "Edit this object (current window)" +msgstr "Editar este objeto (ventana actual)" -#: contrib/redirects/models.py:10 -msgid "" -"This can be either an absolute path (as above) or a full URL starting with " -"'http://'." +#: contrib/admin/templates/admin_doc/bookmarklets.html:26 +msgid "Jumps to the admin page for pages that represent a single object." msgstr "" -"Esto puede ser bien una ruta absoluta (como antes) o una URL completa que " -"empiece con 'http://'." - -#: contrib/redirects/models.py:13 -msgid "redirect" -msgstr "redirección" - -#: contrib/redirects/models.py:14 -msgid "redirects" -msgstr "redirecciones" - -#: contrib/comments/models.py:67 contrib/comments/models.py:166 -msgid "object ID" -msgstr "ID de objeto" - -#: contrib/comments/models.py:68 -msgid "headline" -msgstr "encabezado" - -#: contrib/comments/models.py:69 contrib/comments/models.py:90 -#: contrib/comments/models.py:167 -msgid "comment" -msgstr "comentario" - -#: contrib/comments/models.py:70 -msgid "rating #1" -msgstr "calificación 1" - -#: contrib/comments/models.py:71 -msgid "rating #2" -msgstr "calificación 2" - -#: contrib/comments/models.py:72 -msgid "rating #3" -msgstr "calificación 3" +"Le lleva a la página de administración de páginas que representan un único " +"objeto." -#: contrib/comments/models.py:73 -msgid "rating #4" -msgstr "calificación 4" +#: contrib/admin/templates/admin_doc/bookmarklets.html:28 +msgid "Edit this object (new window)" +msgstr "Editar este objeto (nueva ventana)" -#: contrib/comments/models.py:74 -msgid "rating #5" -msgstr "calificación 5" +#: contrib/admin/templates/admin_doc/bookmarklets.html:29 +msgid "As above, but opens the admin page in a new window." +msgstr "" +"Como antes, pero abre la página de administración en una nueva ventana." -#: contrib/comments/models.py:75 -msgid "rating #6" -msgstr "calificación 6" +#: contrib/localflavor/uk/forms.py:18 +msgid "Enter a postcode. A space is required between the two postcode parts." +msgstr "" +"Introduzca un código postal. Se necesita un espacio entre las dos partes del " +"código." -#: contrib/comments/models.py:76 -msgid "rating #7" -msgstr "calificación 7" +#: contrib/localflavor/fr/forms.py:17 contrib/localflavor/fi/forms.py:14 +#: contrib/localflavor/de/forms.py:16 +msgid "Enter a zip code in the format XXXXX." +msgstr "Introduzca un código postal en el formato XXXXX." -#: contrib/comments/models.py:77 -msgid "rating #8" -msgstr "calificación 8" +#: contrib/localflavor/jp/jp_prefectures.py:4 +msgid "Hokkaido" +msgstr "Hokkaido" -#: contrib/comments/models.py:82 -msgid "is valid rating" -msgstr "es calificación válida" +#: contrib/localflavor/jp/jp_prefectures.py:5 +msgid "Aomori" +msgstr "Aomori" -#: contrib/comments/models.py:83 contrib/comments/models.py:169 -msgid "date/time submitted" -msgstr "fecha/hora de envío" +#: contrib/localflavor/jp/jp_prefectures.py:6 +msgid "Iwate" +msgstr "Iwate" -#: contrib/comments/models.py:84 contrib/comments/models.py:170 -msgid "is public" -msgstr "es público" +#: contrib/localflavor/jp/jp_prefectures.py:7 +msgid "Miyagi" +msgstr "Miyagi" -#: contrib/comments/models.py:86 -msgid "is removed" -msgstr "está eliminado" +#: contrib/localflavor/jp/jp_prefectures.py:8 +msgid "Akita" +msgstr "Akita" -#: 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 "" -"Marque esta caja si el comentario es inapropiado. En su lugar se mostrará " -"\"Este comentario ha sido eliminado\"." +#: contrib/localflavor/jp/jp_prefectures.py:9 +msgid "Yamagata" +msgstr "Yamagata" -#: contrib/comments/models.py:91 -msgid "comments" -msgstr "comentarios" +#: contrib/localflavor/jp/jp_prefectures.py:10 +msgid "Fukushima" +msgstr "Fukushima" -#: contrib/comments/models.py:131 contrib/comments/models.py:207 -msgid "Content object" -msgstr "Objeto contenido" +#: contrib/localflavor/jp/jp_prefectures.py:11 +msgid "Ibaraki" +msgstr "Ibaraki" -#: contrib/comments/models.py:159 -#, python-format -msgid "" -"Posted by %(user)s at %(date)s\n" -"\n" -"%(comment)s\n" -"\n" -"http://%(domain)s%(url)s" -msgstr "" -"Enviado por %(user)s en %(date)s\n" -"\n" -"%(comment)s\n" -"\n" -"http://%(domain)s%(url)s" +#: contrib/localflavor/jp/jp_prefectures.py:12 +msgid "Tochigi" +msgstr "Tochigi" -#: contrib/comments/models.py:168 -msgid "person's name" -msgstr "nombre de la persona" +#: contrib/localflavor/jp/jp_prefectures.py:13 +msgid "Gunma" +msgstr "Gunma" -#: contrib/comments/models.py:171 -msgid "ip address" -msgstr "dirección ip" +#: contrib/localflavor/jp/jp_prefectures.py:14 +msgid "Saitama" +msgstr "Saitama" -#: contrib/comments/models.py:173 -msgid "approved by staff" -msgstr "aprobado por el staff" +#: contrib/localflavor/jp/jp_prefectures.py:15 +msgid "Chiba" +msgstr "Chiba" -#: contrib/comments/models.py:176 -msgid "free comment" -msgstr "comentario libre" +#: contrib/localflavor/jp/jp_prefectures.py:16 +msgid "Tokyo" +msgstr "Tokyo" -#: contrib/comments/models.py:177 -msgid "free comments" -msgstr "comentarios libres" +#: contrib/localflavor/jp/jp_prefectures.py:17 +msgid "Kanagawa" +msgstr "Kanagawa" -#: contrib/comments/models.py:233 -msgid "score" -msgstr "puntuación" +#: contrib/localflavor/jp/jp_prefectures.py:18 +msgid "Yamanashi" +msgstr "Yamanashi" -#: contrib/comments/models.py:234 -msgid "score date" -msgstr "fecha de la puntuación" +#: contrib/localflavor/jp/jp_prefectures.py:19 +msgid "Nagano" +msgstr "Nagano" -#: contrib/comments/models.py:237 -msgid "karma score" -msgstr "punto karma" +#: contrib/localflavor/jp/jp_prefectures.py:20 +msgid "Niigata" +msgstr "Niigata" -#: contrib/comments/models.py:238 -msgid "karma scores" -msgstr "puntos karma" +#: contrib/localflavor/jp/jp_prefectures.py:21 +msgid "Toyama" +msgstr "Toyama" -#: contrib/comments/models.py:242 -#, python-format -msgid "%(score)d rating by %(user)s" -msgstr "puntuado %(score)d por %(user)s" +#: contrib/localflavor/jp/jp_prefectures.py:22 +msgid "Ishikawa" +msgstr "Ishikawa" -#: contrib/comments/models.py:258 -#, python-format -msgid "" -"This comment was flagged by %(user)s:\n" -"\n" -"%(text)s" -msgstr "" -"Este comentario fue marcado por %(user)s:\n" -"\n" -"%(text)s" +#: contrib/localflavor/jp/jp_prefectures.py:23 +msgid "Fukui" +msgstr "Fukui" -#: contrib/comments/models.py:265 -msgid "flag date" -msgstr "fecha de la marca" +#: contrib/localflavor/jp/jp_prefectures.py:24 +msgid "Gifu" +msgstr "Gifu" -#: contrib/comments/models.py:268 -msgid "user flag" -msgstr "marca de usuario" +#: contrib/localflavor/jp/jp_prefectures.py:25 +msgid "Shizuoka" +msgstr "Shizuoka" -#: contrib/comments/models.py:269 -msgid "user flags" -msgstr "marcas de usuario" +#: contrib/localflavor/jp/jp_prefectures.py:26 +msgid "Aichi" +msgstr "Aichi" -#: contrib/comments/models.py:273 -#, python-format -msgid "Flag by %r" -msgstr "Marca de %r" +#: contrib/localflavor/jp/jp_prefectures.py:27 +msgid "Mie" +msgstr "Mie" -#: contrib/comments/models.py:278 -msgid "deletion date" -msgstr "fecha de eliminación" +#: contrib/localflavor/jp/jp_prefectures.py:28 +msgid "Shiga" +msgstr "Shiga" -#: contrib/comments/models.py:280 -msgid "moderator deletion" -msgstr "eliminación de moderador" +#: contrib/localflavor/jp/jp_prefectures.py:29 +msgid "Kyoto" +msgstr "Kyoto" -#: contrib/comments/models.py:281 -msgid "moderator deletions" -msgstr "eliminaciones de moderador" +#: contrib/localflavor/jp/jp_prefectures.py:30 +msgid "Osaka" +msgstr "Osaka" -#: contrib/comments/models.py:285 -#, python-format -msgid "Moderator deletion by %r" -msgstr "Eliminación del moderador %r" +#: contrib/localflavor/jp/jp_prefectures.py:31 +msgid "Hyogo" +msgstr "Hyogo" -#: contrib/comments/views/karma.py:20 -msgid "Anonymous users cannot vote" -msgstr "Los usuarios anónimos no pueden votar" +#: contrib/localflavor/jp/jp_prefectures.py:32 +msgid "Nara" +msgstr "Nara" -#: contrib/comments/views/karma.py:24 -msgid "Invalid comment ID" -msgstr "ID de comentario no válido" +#: contrib/localflavor/jp/jp_prefectures.py:33 +msgid "Wakayama" +msgstr "Wakayama" -#: contrib/comments/views/karma.py:26 -msgid "No voting for yourself" -msgstr "No puedes votarte tú mismo" +#: contrib/localflavor/jp/jp_prefectures.py:34 +msgid "Tottori" +msgstr "Tottori" -#: contrib/comments/views/comments.py:28 -msgid "" -"This rating is required because you've entered at least one other rating." -msgstr "Se precisa esta puntuación porque ha introducido al menos otra más." +#: contrib/localflavor/jp/jp_prefectures.py:35 +msgid "Shimane" +msgstr "Shimane" -#: contrib/comments/views/comments.py:112 -#, 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] "" -"Este comentario lo envió un usuario que ha enviado menos de %(count)s " -"comentario:\n" -"\n" -"%(text)s" -msgstr[1] "" -"Este comentario lo envió un usuario que ha enviado menos de %(count)s " -"comentarios:\n" -"\n" -"%(text)s" +#: contrib/localflavor/jp/jp_prefectures.py:36 +msgid "Okayama" +msgstr "Okayama" -#: contrib/comments/views/comments.py:117 -#, python-format -msgid "" -"This comment was posted by a sketchy user:\n" -"\n" -"%(text)s" -msgstr "" -"Este comentario ha sido colocado por un usuario poco preciso: \n" -"\n" -"%(text)s" +#: contrib/localflavor/jp/jp_prefectures.py:37 +msgid "Hiroshima" +msgstr "Hiroshima" -#: contrib/comments/views/comments.py:189 -#: contrib/comments/views/comments.py:281 -msgid "Only POSTs are allowed" -msgstr "Sólo se admite POST" +#: contrib/localflavor/jp/jp_prefectures.py:38 +msgid "Yamaguchi" +msgstr "Yamaguchi" -#: contrib/comments/views/comments.py:193 -#: contrib/comments/views/comments.py:285 -msgid "One or more of the required fields wasn't submitted" -msgstr "No se proporcionó uno o más de los siguientes campos requeridos" +#: contrib/localflavor/jp/jp_prefectures.py:39 +msgid "Tokushima" +msgstr "Tokushima" -#: contrib/comments/views/comments.py:197 -#: contrib/comments/views/comments.py:287 -msgid "Somebody tampered with the comment form (security violation)" -msgstr "" -"Alguien está jugando con el formulario de comentarios (violación de " -"seguridad)" +#: contrib/localflavor/jp/jp_prefectures.py:40 +msgid "Kagawa" +msgstr "Kagawa" -#: contrib/comments/views/comments.py:207 -#: contrib/comments/views/comments.py:293 -msgid "" -"The comment form had an invalid 'target' parameter -- the object ID was " -"invalid" -msgstr "" -"El formulario de comentarios tiene un parámetro 'target' no válido (el ID de " -"objeto era inválido)" +#: contrib/localflavor/jp/jp_prefectures.py:41 +msgid "Ehime" +msgstr "Ehime" -#: contrib/comments/views/comments.py:258 -#: contrib/comments/views/comments.py:322 -msgid "The comment form didn't provide either 'preview' or 'post'" -msgstr "El formulario de comentario no proporcionó 'previsualizar' ni 'enviar'" +#: contrib/localflavor/jp/jp_prefectures.py:42 +msgid "Kochi" +msgstr "Kochi" -#: contrib/comments/templates/comments/form.html:8 -msgid "Forgotten your password?" -msgstr "¿Has olvidado tu contraseña?" +#: contrib/localflavor/jp/jp_prefectures.py:43 +msgid "Fukuoka" +msgstr "Fukuoka" -#: contrib/comments/templates/comments/form.html:12 -msgid "Ratings" -msgstr "Calificaciones" +#: contrib/localflavor/jp/jp_prefectures.py:44 +msgid "Saga" +msgstr "Saga" -#: contrib/comments/templates/comments/form.html:12 -#: contrib/comments/templates/comments/form.html:23 -msgid "Required" -msgstr "Requerido" +#: contrib/localflavor/jp/jp_prefectures.py:45 +msgid "Nagasaki" +msgstr "Nagasaki" -#: contrib/comments/templates/comments/form.html:12 -#: contrib/comments/templates/comments/form.html:23 -msgid "Optional" -msgstr "Opcional" +#: contrib/localflavor/jp/jp_prefectures.py:46 +msgid "Kumamoto" +msgstr "Kumamoto" -#: contrib/comments/templates/comments/form.html:23 -msgid "Post a photo" -msgstr "Postea una fotografía" +#: contrib/localflavor/jp/jp_prefectures.py:47 +msgid "Oita" +msgstr "Oita" -#: contrib/comments/templates/comments/form.html:28 -#: contrib/comments/templates/comments/freeform.html:5 -msgid "Comment:" -msgstr "Comentario:" +#: contrib/localflavor/jp/jp_prefectures.py:48 +msgid "Miyazaki" +msgstr "Miyazaki" -#: contrib/comments/templates/comments/form.html:35 -#: contrib/comments/templates/comments/freeform.html:10 -msgid "Preview comment" -msgstr "Previsualizar comentario" +#: contrib/localflavor/jp/jp_prefectures.py:49 +msgid "Kagoshima" +msgstr "Kagoshima" -#: contrib/comments/templates/comments/freeform.html:4 -msgid "Your name:" -msgstr "Tu nombre:" +#: contrib/localflavor/jp/jp_prefectures.py:50 +msgid "Okinawa" +msgstr "Okinawa" -#: contrib/localflavor/au/forms.py:18 -msgid "Enter a 4 digit post code." -msgstr "Introduzca un código postal de 4 dígitos." +#: 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 el formato XXXXX o XXXX-XXXX." #: contrib/localflavor/br/forms.py:18 msgid "Enter a zip code in the format XXXXX-XXX." @@ -2169,15 +2481,133 @@ msgstr "Este campo necesita 14 dígitos como máximo" msgid "Invalid CNPJ number." msgstr "Número CNPJ inválido" -#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:14 +#: contrib/localflavor/it/forms.py:16 +msgid "Enter a valid zip code." +msgstr "Introduzca un código postal válido." + +#: contrib/localflavor/it/forms.py:41 +msgid "Enter a valid Social Security number." +msgstr "Introduzca un número de Seguro Social válido." + +#: contrib/localflavor/it/forms.py:68 +msgid "Enter a valid VAT number." +msgstr "Introduzca un número VAT válido." + +#: contrib/localflavor/no/forms.py:14 contrib/localflavor/ch/forms.py:18 msgid "Enter a zip code in the format XXXX." msgstr "Introduzca un código postal en el formato XXXX." -#: contrib/localflavor/ch/forms.py:90 +#: contrib/localflavor/no/forms.py:35 +msgid "Enter a valid Norwegian social security number." +msgstr "Introduzca un número de seguro social de Noruega válido." + +#: 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 seguro social finlandés válido." + +#: contrib/localflavor/de/de_states.py:5 +msgid "Baden-Wuerttemberg" +msgstr "Baden-Wuerttemberg" + +#: contrib/localflavor/de/de_states.py:6 +msgid "Bavaria" +msgstr "Bavaria" + +#: contrib/localflavor/de/de_states.py:7 +msgid "Berlin" +msgstr "Berlín" + +#: contrib/localflavor/de/de_states.py:8 +msgid "Brandenburg" +msgstr "Brandenburg" + +#: contrib/localflavor/de/de_states.py:9 +msgid "Bremen" +msgstr "Bremen" + +#: contrib/localflavor/de/de_states.py:10 +msgid "Hamburg" +msgstr "Hamburg" + +#: contrib/localflavor/de/de_states.py:11 +msgid "Hessen" +msgstr "Hessen" + +#: contrib/localflavor/de/de_states.py:12 +msgid "Mecklenburg-Western Pomerania" +msgstr "Mecklenburg-Western Pomerania" + +#: 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/de/forms.py:60 msgid "" -"Enter a valid Swiss identity or passport card number in X1234567<0 or " -"1234567890 format." +"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X " +"format." msgstr "" +"Introduzca un número de tarjeta de identidad de Alemania válida en el " +"formato XXXXXXXXXXX-XXXXXXX-XXXXXXX-X." + +#: contrib/localflavor/au/forms.py:18 +msgid "Enter a 4 digit post code." +msgstr "Introduzca un código postal de 4 dígitos." + +#: contrib/localflavor/us/forms.py:18 +msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX." +msgstr "Introduzca un código postal en el formato XXXXX o XXXX-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 Seguro Social de EEUU válido en el formato XXX-XX-XXXX" + +#: contrib/localflavor/is_/forms.py:17 +msgid "" +"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX." +msgstr "" +"Introduzca un número de identificación de Islandia válido. El formato es " +"XXXXXX-XXXX." + +#: contrib/localflavor/is_/forms.py:31 +msgid "The Icelandic identification number is not valid." +msgstr "El número de identificación de Islandia no es válido." + +#: contrib/localflavor/cl/forms.py:32 +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:37 +msgid "Enter valid a Chilean RUT" +msgstr "Introduzca un RUT chileno válido" #: contrib/localflavor/ch/ch_states.py:5 msgid "Aargau" @@ -2283,780 +2713,717 @@ msgstr "Zug" msgid "Zurich" msgstr "Zurich" -#: contrib/localflavor/cl/forms.py:32 -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.XXXX-X." +#: contrib/localflavor/ch/forms.py:90 +msgid "" +"Enter a valid Swiss identity or passport card number in X1234567<0 or " +"1234567890 format." +msgstr "" +"Introduzca una identificación suiza válida o un número de pasaporte en el " +"formato X1234567<0 or 1234567890." -#: contrib/localflavor/cl/forms.py:37 -msgid "Enter valid a Chilean RUT" -msgstr "Introduzca un RUT chileno válido" +#: contrib/localflavor/sk/sk_regions.py:8 +msgid "Banska Bystrica region" +msgstr "Región de Banska Bystrica" -#: contrib/localflavor/de/forms.py:16 contrib/localflavor/fi/forms.py:14 -#: contrib/localflavor/fr/forms.py:17 -msgid "Enter a zip code in the format XXXXX." -msgstr "Introduzca un código postal en el formato XXXXX." +#: contrib/localflavor/sk/sk_regions.py:9 +msgid "Bratislava region" +msgstr "Región de Bratislava" -#: 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 de Alemania válida en el " -"formato XXXXXXXXXXX-XXXXXXX-XXXXXXX-X." +#: contrib/localflavor/sk/sk_regions.py:10 +msgid "Kosice region" +msgstr "Región de Kosice" -#: contrib/localflavor/de/de_states.py:5 -msgid "Baden-Wuerttemberg" -msgstr "Baden-Wuerttemberg" +#: contrib/localflavor/sk/sk_regions.py:11 +msgid "Nitra region" +msgstr "Región de Nitra" -#: contrib/localflavor/de/de_states.py:6 -msgid "Bavaria" -msgstr "Bavaria" +#: contrib/localflavor/sk/sk_regions.py:12 +msgid "Presov region" +msgstr "Región de Presov" -#: contrib/localflavor/de/de_states.py:7 -msgid "Berlin" -msgstr "Berlín" +#: contrib/localflavor/sk/sk_regions.py:13 +msgid "Trencin region" +msgstr "Región de Trencin" -#: contrib/localflavor/de/de_states.py:8 -msgid "Brandenburg" -msgstr "Brandenburg" +#: contrib/localflavor/sk/sk_regions.py:14 +msgid "Trnava region" +msgstr "Región de Trnava" -#: contrib/localflavor/de/de_states.py:9 -msgid "Bremen" -msgstr "Bremen" +#: contrib/localflavor/sk/sk_regions.py:15 +msgid "Zilina region" +msgstr "Región de Zilina" -#: contrib/localflavor/de/de_states.py:10 -msgid "Hamburg" -msgstr "Hamburg" +#: contrib/localflavor/sk/sk_districts.py:8 +msgid "Banska Bystrica" +msgstr "Región de Bystrica" -#: contrib/localflavor/de/de_states.py:11 -msgid "Hessen" -msgstr "Hessen" +#: contrib/localflavor/sk/sk_districts.py:9 +msgid "Banska Stiavnica" +msgstr "Región de Banska Stiavnica" -#: contrib/localflavor/de/de_states.py:12 -msgid "Mecklenburg-Western Pomerania" -msgstr "Mecklenburg-Western Pomerania" +#: contrib/localflavor/sk/sk_districts.py:10 +msgid "Bardejov" +msgstr "Región de Bardejov" -#: contrib/localflavor/de/de_states.py:13 -msgid "Lower Saxony" -msgstr "Lower Saxony" +#: contrib/localflavor/sk/sk_districts.py:11 +msgid "Banovce nad Bebravou" +msgstr "Región de Banovce nad Bebravou" -#: contrib/localflavor/de/de_states.py:14 -msgid "North Rhine-Westphalia" -msgstr "North Rhine-Westphalia" +#: contrib/localflavor/sk/sk_districts.py:12 +msgid "Brezno" +msgstr "Región de Brezno" -#: contrib/localflavor/de/de_states.py:15 -msgid "Rhineland-Palatinate" -msgstr "Rhineland-Palatinate" +#: contrib/localflavor/sk/sk_districts.py:13 +msgid "Bratislava I" +msgstr "Región de Bratislava I" -#: contrib/localflavor/de/de_states.py:16 -msgid "Saarland" -msgstr "Saarland" +#: contrib/localflavor/sk/sk_districts.py:14 +msgid "Bratislava II" +msgstr "Región de Bratislava II" -#: contrib/localflavor/de/de_states.py:17 -msgid "Saxony" -msgstr "Saxony" +#: contrib/localflavor/sk/sk_districts.py:15 +msgid "Bratislava III" +msgstr "Región de Bratislava III" -#: contrib/localflavor/de/de_states.py:18 -msgid "Saxony-Anhalt" -msgstr "Saxony-Anhalt" +#: contrib/localflavor/sk/sk_districts.py:16 +msgid "Bratislava IV" +msgstr "Región de Bratislava IV" -#: contrib/localflavor/de/de_states.py:19 -msgid "Schleswig-Holstein" -msgstr "Schleswig-Holstein" +#: contrib/localflavor/sk/sk_districts.py:17 +msgid "Bratislava V" +msgstr "Región de Bratislava V" -#: contrib/localflavor/de/de_states.py:20 -msgid "Thuringia" -msgstr "Thuringia" +#: contrib/localflavor/sk/sk_districts.py:18 +msgid "Bytca" +msgstr "Región de Bytca" -#: 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 seguro social finlandés válido." +#: contrib/localflavor/sk/sk_districts.py:19 +msgid "Cadca" +msgstr "Región de Cadca" -#: contrib/localflavor/it/forms.py:16 -msgid "Enter a valid zip code." -msgstr "Introduzca un código postal válido." +#: contrib/localflavor/sk/sk_districts.py:20 +msgid "Detva" +msgstr "Región de Detva" -#: contrib/localflavor/it/forms.py:41 -msgid "Enter a valid Social Security number." -msgstr "Introduzca un número de Seguro Social válido." +#: contrib/localflavor/sk/sk_districts.py:21 +msgid "Dolny Kubin" +msgstr "Región de Dolny Kubin" -#: contrib/localflavor/it/forms.py:68 -msgid "Enter a valid VAT number." -msgstr "Introduzca un número VAT válido." +#: contrib/localflavor/sk/sk_districts.py:22 +msgid "Dunajska Streda" +msgstr "Región de Dunajska Streda" -#: 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 el formato XXXXX o XXXX-XXXX." +#: contrib/localflavor/sk/sk_districts.py:23 +msgid "Galanta" +msgstr "Galanta" -#: contrib/localflavor/jp/jp_prefectures.py:4 -msgid "Hokkaido" -msgstr "Hokkaido" +#: contrib/localflavor/sk/sk_districts.py:24 +msgid "Gelnica" +msgstr "Gelnica" -#: contrib/localflavor/jp/jp_prefectures.py:5 -msgid "Aomori" -msgstr "Aomori" +#: contrib/localflavor/sk/sk_districts.py:25 +msgid "Hlohovec" +msgstr "Hlohovec" -#: contrib/localflavor/jp/jp_prefectures.py:6 -msgid "Iwate" -msgstr "Iwate" +#: contrib/localflavor/sk/sk_districts.py:26 +msgid "Humenne" +msgstr "Humenne" -#: contrib/localflavor/jp/jp_prefectures.py:7 -msgid "Miyagi" -msgstr "Miyagi" +#: contrib/localflavor/sk/sk_districts.py:27 +msgid "Ilava" +msgstr "Ilava" -#: contrib/localflavor/jp/jp_prefectures.py:8 -msgid "Akita" -msgstr "Akita" +#: contrib/localflavor/sk/sk_districts.py:28 +msgid "Kezmarok" +msgstr "Kezmarok" -#: contrib/localflavor/jp/jp_prefectures.py:9 -msgid "Yamagata" -msgstr "Yamagata" +#: contrib/localflavor/sk/sk_districts.py:29 +msgid "Komarno" +msgstr "Komarno" -#: contrib/localflavor/jp/jp_prefectures.py:10 -msgid "Fukushima" -msgstr "Fukushima" +#: contrib/localflavor/sk/sk_districts.py:30 +msgid "Kosice I" +msgstr "Kosice I" -#: contrib/localflavor/jp/jp_prefectures.py:11 -msgid "Ibaraki" -msgstr "Ibaraki" +#: contrib/localflavor/sk/sk_districts.py:31 +msgid "Kosice II" +msgstr "Kosice II" -#: contrib/localflavor/jp/jp_prefectures.py:12 -msgid "Tochigi" -msgstr "Tochigi" +#: contrib/localflavor/sk/sk_districts.py:32 +msgid "Kosice III" +msgstr "Kosice III" -#: contrib/localflavor/jp/jp_prefectures.py:13 -msgid "Gunma" -msgstr "Gunma" +#: contrib/localflavor/sk/sk_districts.py:33 +msgid "Kosice IV" +msgstr "Kosice IV" -#: contrib/localflavor/jp/jp_prefectures.py:14 -msgid "Saitama" -msgstr "Saitama" +#: contrib/localflavor/sk/sk_districts.py:34 +msgid "Kosice - okolie" +msgstr "Kosice - okolie" -#: contrib/localflavor/jp/jp_prefectures.py:15 -msgid "Chiba" -msgstr "Chiba" +#: contrib/localflavor/sk/sk_districts.py:35 +msgid "Krupina" +msgstr "Krupina" -#: contrib/localflavor/jp/jp_prefectures.py:16 -msgid "Tokyo" -msgstr "Tokyo" +#: contrib/localflavor/sk/sk_districts.py:36 +msgid "Kysucke Nove Mesto" +msgstr "Kysucke Nove Mesto" -#: contrib/localflavor/jp/jp_prefectures.py:17 -msgid "Kanagawa" -msgstr "Kanagawa" +#: contrib/localflavor/sk/sk_districts.py:37 +msgid "Levice" +msgstr "Levice" -#: contrib/localflavor/jp/jp_prefectures.py:18 -msgid "Yamanashi" -msgstr "Yamanashi" +#: contrib/localflavor/sk/sk_districts.py:38 +msgid "Levoca" +msgstr "Levoca" -#: contrib/localflavor/jp/jp_prefectures.py:19 -msgid "Nagano" -msgstr "Nagano" +#: contrib/localflavor/sk/sk_districts.py:39 +msgid "Liptovsky Mikulas" +msgstr "Liptovsky Mikulas" -#: contrib/localflavor/jp/jp_prefectures.py:20 -msgid "Niigata" -msgstr "Niigata" +#: contrib/localflavor/sk/sk_districts.py:40 +msgid "Lucenec" +msgstr "Lucenec" -#: contrib/localflavor/jp/jp_prefectures.py:21 -msgid "Toyama" -msgstr "Toyama" +#: contrib/localflavor/sk/sk_districts.py:41 +msgid "Malacky" +msgstr "Malacky" -#: contrib/localflavor/jp/jp_prefectures.py:22 -msgid "Ishikawa" -msgstr "Ishikawa" +#: contrib/localflavor/sk/sk_districts.py:42 +msgid "Martin" +msgstr "Martin" -#: contrib/localflavor/jp/jp_prefectures.py:23 -msgid "Fukui" -msgstr "Fukui" +#: contrib/localflavor/sk/sk_districts.py:43 +msgid "Medzilaborce" +msgstr "Medzilaborce" -#: contrib/localflavor/jp/jp_prefectures.py:24 -msgid "Gifu" -msgstr "Gifu" +#: contrib/localflavor/sk/sk_districts.py:44 +msgid "Michalovce" +msgstr "Michalovce" -#: contrib/localflavor/jp/jp_prefectures.py:25 -msgid "Shizuoka" -msgstr "Shizuoka" +#: contrib/localflavor/sk/sk_districts.py:45 +msgid "Myjava" +msgstr "Myjava" -#: contrib/localflavor/jp/jp_prefectures.py:26 -msgid "Aichi" -msgstr "Aichi" +#: contrib/localflavor/sk/sk_districts.py:46 +msgid "Namestovo" +msgstr "Namestovo" -#: contrib/localflavor/jp/jp_prefectures.py:27 -msgid "Mie" -msgstr "Mie" +#: contrib/localflavor/sk/sk_districts.py:47 +msgid "Nitra" +msgstr "Nitra" -#: contrib/localflavor/jp/jp_prefectures.py:28 -msgid "Shiga" -msgstr "Shiga" +#: contrib/localflavor/sk/sk_districts.py:48 +msgid "Nove Mesto nad Vahom" +msgstr "Nove Mesto nad Vahom" -#: contrib/localflavor/jp/jp_prefectures.py:29 -msgid "Kyoto" -msgstr "Kyoto" +#: contrib/localflavor/sk/sk_districts.py:49 +msgid "Nove Zamky" +msgstr "Nove Zamky" -#: contrib/localflavor/jp/jp_prefectures.py:30 -msgid "Osaka" -msgstr "Osaka" +#: contrib/localflavor/sk/sk_districts.py:50 +msgid "Partizanske" +msgstr "Partizanske" -#: contrib/localflavor/jp/jp_prefectures.py:31 -msgid "Hyogo" -msgstr "Hyogo" +#: contrib/localflavor/sk/sk_districts.py:51 +msgid "Pezinok" +msgstr "Pezinok" -#: contrib/localflavor/jp/jp_prefectures.py:32 -msgid "Nara" -msgstr "Nara" +#: contrib/localflavor/sk/sk_districts.py:52 +msgid "Piestany" +msgstr "Piestany" -#: contrib/localflavor/jp/jp_prefectures.py:33 -msgid "Wakayama" -msgstr "Wakayama" +#: contrib/localflavor/sk/sk_districts.py:53 +msgid "Poltar" +msgstr "Poltar" -#: contrib/localflavor/jp/jp_prefectures.py:34 -msgid "Tottori" -msgstr "Tottori" +#: contrib/localflavor/sk/sk_districts.py:54 +msgid "Poprad" +msgstr "Poprad" -#: contrib/localflavor/jp/jp_prefectures.py:35 -msgid "Shimane" -msgstr "Shimane" +#: contrib/localflavor/sk/sk_districts.py:55 +msgid "Povazska Bystrica" +msgstr "Povazska Bystrica" -#: contrib/localflavor/jp/jp_prefectures.py:36 -msgid "Okayama" -msgstr "Okayama" +#: contrib/localflavor/sk/sk_districts.py:56 +msgid "Presov" +msgstr "Presov" -#: contrib/localflavor/jp/jp_prefectures.py:37 -msgid "Hiroshima" -msgstr "Hiroshima" +#: contrib/localflavor/sk/sk_districts.py:57 +msgid "Prievidza" +msgstr "Prievidza" -#: contrib/localflavor/jp/jp_prefectures.py:38 -msgid "Yamaguchi" -msgstr "Yamaguchi" +#: contrib/localflavor/sk/sk_districts.py:58 +msgid "Puchov" +msgstr "Puchov" -#: contrib/localflavor/jp/jp_prefectures.py:39 -msgid "Tokushima" -msgstr "Tokushima" +#: contrib/localflavor/sk/sk_districts.py:59 +msgid "Revuca" +msgstr "Revuca" -#: contrib/localflavor/jp/jp_prefectures.py:40 -msgid "Kagawa" -msgstr "Kagawa" +#: contrib/localflavor/sk/sk_districts.py:60 +msgid "Rimavska Sobota" +msgstr "Rimavska Sobota" -#: contrib/localflavor/jp/jp_prefectures.py:41 -msgid "Ehime" -msgstr "Ehime" +#: contrib/localflavor/sk/sk_districts.py:61 +msgid "Roznava" +msgstr "Roznava" -#: contrib/localflavor/jp/jp_prefectures.py:42 -msgid "Kochi" -msgstr "Kochi" +#: contrib/localflavor/sk/sk_districts.py:62 +msgid "Ruzomberok" +msgstr "Ruzomberok" -#: contrib/localflavor/jp/jp_prefectures.py:43 -msgid "Fukuoka" -msgstr "Fukuoka" +#: contrib/localflavor/sk/sk_districts.py:63 +msgid "Sabinov" +msgstr "Sabinov" -#: contrib/localflavor/jp/jp_prefectures.py:44 -msgid "Saga" -msgstr "Saga" +#: contrib/localflavor/sk/sk_districts.py:64 +msgid "Senec" +msgstr "Senec" -#: contrib/localflavor/jp/jp_prefectures.py:45 -msgid "Nagasaki" -msgstr "Nagasaki" +#: contrib/localflavor/sk/sk_districts.py:65 +msgid "Senica" +msgstr "Senica" -#: contrib/localflavor/jp/jp_prefectures.py:46 -msgid "Kumamoto" -msgstr "Kumamoto" +#: contrib/localflavor/sk/sk_districts.py:66 +msgid "Skalica" +msgstr "Skalica" -#: contrib/localflavor/jp/jp_prefectures.py:47 -msgid "Oita" -msgstr "Oita" +#: contrib/localflavor/sk/sk_districts.py:67 +msgid "Snina" +msgstr "Snina" -#: contrib/localflavor/jp/jp_prefectures.py:48 -msgid "Miyazaki" -msgstr "Miyazaki" +#: contrib/localflavor/sk/sk_districts.py:68 +msgid "Sobrance" +msgstr "Sobrance" -#: contrib/localflavor/jp/jp_prefectures.py:49 -msgid "Kagoshima" -msgstr "Kagoshima" +#: contrib/localflavor/sk/sk_districts.py:69 +msgid "Spisska Nova Ves" +msgstr "Spisska Nova Ves" -#: contrib/localflavor/jp/jp_prefectures.py:50 -msgid "Okinawa" -msgstr "Okinawa" +#: contrib/localflavor/sk/sk_districts.py:70 +msgid "Stara Lubovna" +msgstr "Stara Lubovna" -#: contrib/localflavor/no/forms.py:35 -msgid "Enter a valid Norwegian social security number." -msgstr "Introduzca un número de seguro social de Noruega válido." +#: contrib/localflavor/sk/sk_districts.py:71 +msgid "Stropkov" +msgstr "Stropkov" -#: contrib/localflavor/uk/forms.py:18 -msgid "Enter a postcode. A space is required between the two postcode parts." -msgstr "" -"Introduzca un código postal. Se necesita un espacio entre las dos partes del " -"código." +#: contrib/localflavor/sk/sk_districts.py:72 +msgid "Svidnik" +msgstr "Svidnik" -#: contrib/localflavor/us/forms.py:18 -msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX." -msgstr "Introduzca un código postal en el formato XXXXX o XXXX-XXXX." +#: contrib/localflavor/sk/sk_districts.py:73 +msgid "Sala" +msgstr "Sala" -#: 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 Seguro Social de EEUU válido en el formato XXX-XX-XXXX" +#: contrib/localflavor/sk/sk_districts.py:74 +msgid "Topolcany" +msgstr "Topolcany" -#: contrib/localflavor/is_/forms.py:17 -msgid "" -"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX." -msgstr "" -"Introduzca un número de identificación de Islandia válido. El formato es " -"XXXXXX-XXXX." +#: contrib/localflavor/sk/sk_districts.py:75 +msgid "Trebisov" +msgstr "Trebisov" -#: contrib/localflavor/is_/forms.py:31 -msgid "The Icelandic identification number is not valid." -msgstr "El número de identificación de Islandia no es válido." +#: contrib/localflavor/sk/sk_districts.py:76 +msgid "Trencin" +msgstr "Trencin" -#: contrib/sessions/models.py:68 -msgid "session key" -msgstr "clave de sesión" +#: contrib/localflavor/sk/sk_districts.py:77 +msgid "Trnava" +msgstr "Trnava" -#: contrib/sessions/models.py:69 -msgid "session data" -msgstr "datos de sesión" +#: contrib/localflavor/sk/sk_districts.py:78 +msgid "Turcianske Teplice" +msgstr "Turcianske Teplice" -#: contrib/sessions/models.py:70 -msgid "expire date" -msgstr "fecha de caducidad" +#: contrib/localflavor/sk/sk_districts.py:79 +msgid "Tvrdosin" +msgstr "Tvrdosin" -#: contrib/sessions/models.py:74 -msgid "session" -msgstr "sesión" +#: contrib/localflavor/sk/sk_districts.py:80 +msgid "Velky Krtis" +msgstr "Velky Krtis" -#: contrib/sessions/models.py:75 -msgid "sessions" -msgstr "sesiones" +#: contrib/localflavor/sk/sk_districts.py:81 +msgid "Vranov nad Toplou" +msgstr "Vranov nad Toplou" -#: contrib/contenttypes/models.py:37 -msgid "python model class name" -msgstr "nombre de módulo python" +#: contrib/localflavor/sk/sk_districts.py:82 +msgid "Zlate Moravce" +msgstr "Zlate Moravce" -#: contrib/contenttypes/models.py:40 -msgid "content type" -msgstr "tipo de contenido" +#: contrib/localflavor/sk/sk_districts.py:83 +msgid "Zvolen" +msgstr "Zvolen" -#: contrib/contenttypes/models.py:41 -msgid "content types" -msgstr "tipos de contenido" +#: contrib/localflavor/sk/sk_districts.py:84 +msgid "Zarnovica" +msgstr "Zarnovica" + +#: contrib/localflavor/sk/sk_districts.py:85 +msgid "Ziar nad Hronom" +msgstr "Ziar nad Hronom" + +#: contrib/localflavor/sk/sk_districts.py:86 +msgid "Zilina" +msgstr "Zilina" + +#: contrib/localflavor/sk/forms.py:32 +msgid "Enter a postal code in the format XXXXX or XXX XX." +msgstr "Introduzca un código postal en el formato XXXXX o XXX XX." + +#: contrib/localflavor/in_/forms.py:16 +msgid "Enter a zip code in the format XXXXXXX." +msgstr "Introduzca un código postal en el formato XXXXXXX." + +#: template/defaultfilters.py:485 +msgid "yes,no,maybe" +msgstr "sí,no,tal vez" + +#: template/defaultfilters.py:514 +#, python-format +msgid "%(size)d byte" +msgid_plural "%(size)d bytes" +msgstr[0] "%(size)d byte" +msgstr[1] "%(size)d bytes" -#: oldforms/__init__.py:404 +#: template/defaultfilters.py:516 +#, python-format +msgid "%.1f KB" +msgstr "%.1f KB" + +#: template/defaultfilters.py:518 +#, python-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: template/defaultfilters.py:519 +#, python-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: oldforms/__init__.py:408 #, python-format msgid "Ensure your text is less than %s character." msgid_plural "Ensure your text is less than %s characters." msgstr[0] "Asegúrese de que su texto tiene menos de %s carácter." msgstr[1] "Asegúrese de que su texto tiene menos de %s caracteres." -#: oldforms/__init__.py:409 +#: oldforms/__init__.py:413 msgid "Line breaks are not allowed here." msgstr "No se permiten saltos de línea." -#: oldforms/__init__.py:507 oldforms/__init__.py:581 oldforms/__init__.py:620 +#: oldforms/__init__.py:511 oldforms/__init__.py:585 oldforms/__init__.py:624 #, python-format msgid "Select a valid choice; '%(data)s' is not in %(choices)s." msgstr "Escoja una opción válida; '%(data)s' no está en %(choices)s." -#: oldforms/__init__.py:684 -msgid "The submitted file is empty." -msgstr "El fichero enviado está vacío." - -#: oldforms/__init__.py:740 +#: oldforms/__init__.py:744 msgid "Enter a whole number between -32,768 and 32,767." msgstr "Introduzca un número entero entre -32,768 y 32,767." -#: oldforms/__init__.py:750 +#: oldforms/__init__.py:754 msgid "Enter a positive number." msgstr "Introduzca un número positivo." -#: oldforms/__init__.py:760 +#: oldforms/__init__.py:764 msgid "Enter a whole number between 0 and 32,767." 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 "El %(verbose_name)s se ha creado correctamente." - -#: views/generic/create_update.py:117 -#, python-format -msgid "The %(verbose_name)s was updated successfully." -msgstr "Se actualizó con éxito el %(verbose_name)s." - -#: views/generic/create_update.py:184 -#, python-format -msgid "The %(verbose_name)s was deleted." -msgstr "El %(verbose_name)s ha sido eliminado." - -#: utils/dates.py:6 -msgid "Monday" -msgstr "Lunes" - -#: utils/dates.py:6 -msgid "Tuesday" -msgstr "Martes" - -#: utils/dates.py:6 -msgid "Wednesday" -msgstr "Miércoles" - -#: utils/dates.py:6 -msgid "Thursday" -msgstr "Jueves" - -#: utils/dates.py:6 -msgid "Friday" -msgstr "Viernes" - -#: utils/dates.py:7 -msgid "Saturday" -msgstr "Sábado" - -#: utils/dates.py:7 -msgid "Sunday" -msgstr "Domingo" - -#: utils/dates.py:10 -msgid "Mon" -msgstr "Lun" - -#: utils/dates.py:10 -msgid "Tue" -msgstr "Mar" - -#: utils/dates.py:10 -msgid "Wed" -msgstr "Mie" - -#: utils/dates.py:10 -msgid "Thu" -msgstr "Jue" - -#: utils/dates.py:10 -msgid "Fri" -msgstr "Vie" - -#: utils/dates.py:11 -msgid "Sat" -msgstr "Sab" - -#: utils/dates.py:11 -msgid "Sun" -msgstr "Dom" - -#: utils/dates.py:18 -msgid "January" -msgstr "Enero" - -#: utils/dates.py:18 -msgid "February" -msgstr "Febrero" - -#: utils/dates.py:18 utils/dates.py:31 -msgid "March" -msgstr "Marzo" - -#: utils/dates.py:18 utils/dates.py:31 -msgid "April" -msgstr "Abril" - -#: utils/dates.py:18 utils/dates.py:31 -msgid "May" -msgstr "Mayo" - -#: utils/dates.py:18 utils/dates.py:31 -msgid "June" -msgstr "Junio" - -#: utils/dates.py:19 utils/dates.py:31 -msgid "July" -msgstr "Julio" - -#: utils/dates.py:19 -msgid "August" -msgstr "Agosto" - -#: utils/dates.py:19 -msgid "September" -msgstr "Septiembre" - -#: utils/dates.py:19 -msgid "October" -msgstr "Octubre" +#: core/validators.py:71 +msgid "This value must contain only letters, numbers and underscores." +msgstr "Este valor debe contener sólo letras, números y guiones bajos." -#: utils/dates.py:19 -msgid "November" -msgstr "Noviembre" +#: core/validators.py:75 +msgid "" +"This value must contain only letters, numbers, underscores, dashes or " +"slashes." +msgstr "" +"Este valor debe contener letras, números, guiones bajos o barras solamente." -#: utils/dates.py:20 -msgid "December" -msgstr "Diciembre" +#: core/validators.py:79 +msgid "This value must contain only letters, numbers, underscores or hyphens." +msgstr "Este valor debe contener sólo letras, números, guiones bajos o medios." -#: utils/dates.py:23 -msgid "jan" -msgstr "ene" +#: core/validators.py:83 +msgid "Uppercase letters are not allowed here." +msgstr "No se admiten letras mayúsculas." -#: utils/dates.py:23 -msgid "feb" -msgstr "feb" +#: core/validators.py:87 +msgid "Lowercase letters are not allowed here." +msgstr "No se admiten letras minúsculas." -#: utils/dates.py:23 -msgid "mar" -msgstr "mar" +#: core/validators.py:94 +msgid "Enter only digits separated by commas." +msgstr "Introduzca sólo dígitos separados por comas." -#: utils/dates.py:23 -msgid "apr" -msgstr "abr" +#: core/validators.py:106 +msgid "Enter valid e-mail addresses separated by commas." +msgstr "Introduzca direcciones de correo válidas separadas por comas." -#: utils/dates.py:23 -msgid "may" -msgstr "may" +#: core/validators.py:110 +msgid "Please enter a valid IP address." +msgstr "Por favor introduzca una dirección IP válida." -#: utils/dates.py:23 -msgid "jun" -msgstr "jun" +#: core/validators.py:114 +msgid "Empty values are not allowed here." +msgstr "No se admiten valores vacíos." -#: utils/dates.py:24 -msgid "jul" -msgstr "jul" +#: core/validators.py:118 +msgid "Non-numeric characters aren't allowed here." +msgstr "No se admiten caracteres no numéricos." -#: utils/dates.py:24 -msgid "aug" -msgstr "ago" +#: core/validators.py:122 +msgid "This value can't be comprised solely of digits." +msgstr "Este valor no puede comprender sólo dígitos." -#: utils/dates.py:24 -msgid "sep" -msgstr "sep" +#: core/validators.py:131 +msgid "Only alphabetical characters are allowed here." +msgstr "Sólo se admiten caracteres alfabéticos." -#: utils/dates.py:24 -msgid "oct" -msgstr "oct" +#: core/validators.py:146 +msgid "Year must be 1900 or later." +msgstr "El año debe ser 1900 o posterior." -#: utils/dates.py:24 -msgid "nov" -msgstr "nov" +#: core/validators.py:150 +#, python-format +msgid "Invalid date: %s" +msgstr "Fecha no válida: %s" -#: utils/dates.py:24 -msgid "dec" -msgstr "dic" +#: core/validators.py:160 +msgid "Enter a valid time in HH:MM format." +msgstr "Introduzca una hora válida en formato HH:MM." -#: utils/dates.py:31 -msgid "Jan." -msgstr "Ene." +#: core/validators.py:192 +#, python-format +msgid "The URL %s does not point to a valid image." +msgstr "La URL %s no apunta a una imagen válida." -#: utils/dates.py:31 -msgid "Feb." -msgstr "Feb." +#: core/validators.py:196 +#, python-format +msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." +msgstr "" +"Los números de teléfono deben guardar el formato XXX-XXX-XXXX. \"%s\" no es " +"válido." -#: utils/dates.py:32 -msgid "Aug." -msgstr "Ago." +#: core/validators.py:204 +#, python-format +msgid "The URL %s does not point to a valid QuickTime video." +msgstr "La URL %s no apunta a un vídeo QuickTime válido." -#: utils/dates.py:32 -msgid "Sept." -msgstr "Sept." +#: core/validators.py:208 +msgid "A valid URL is required." +msgstr "Se precisa una URL válida." -#: utils/dates.py:32 -msgid "Oct." -msgstr "Oct." +#: core/validators.py:222 +#, python-format +msgid "" +"Valid HTML is required. Specific errors are:\n" +"%s" +msgstr "" +"Se precisa HTML válido. Los errores específicos son:\n" +"%s" -#: utils/dates.py:32 -msgid "Nov." -msgstr "Nov." +#: core/validators.py:229 +#, python-format +msgid "Badly formed XML: %s" +msgstr "XML mal formado: %s" -#: utils/dates.py:32 -msgid "Dec." -msgstr "Dic." +#: core/validators.py:246 +#, python-format +msgid "Invalid URL: %s" +msgstr "URL no válida: %s" -#: utils/timesince.py:12 -msgid "year" -msgid_plural "years" -msgstr[0] "año" -msgstr[1] "años" +#: core/validators.py:251 core/validators.py:253 +#, python-format +msgid "The URL %s is a broken link." +msgstr "La URL %s es un enlace roto." -#: utils/timesince.py:13 -msgid "month" -msgid_plural "months" -msgstr[0] "mes" -msgstr[1] "meses" +#: core/validators.py:259 +msgid "Enter a valid U.S. state abbreviation." +msgstr "Introduzca una abreviatura válida de estado de los EEUU." -#: utils/timesince.py:14 -msgid "week" -msgid_plural "weeks" -msgstr[0] "semana" -msgstr[1] "semanas" +#: 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] "¡Cuida tu vocabulario! Aquí no admitimos la palabra %s." +msgstr[1] "¡Cuida tu vocabulario! Aquí no admitimos las palabras %s." -#: utils/timesince.py:15 -msgid "day" -msgid_plural "days" -msgstr[0] "día" -msgstr[1] "días" +#: core/validators.py:280 +#, python-format +msgid "This field must match the '%s' field." +msgstr "Este campo debe concordar con el campo '%s'." -#: utils/timesince.py:16 -msgid "hour" -msgid_plural "hours" -msgstr[0] "hora" -msgstr[1] "horas" +#: core/validators.py:299 +msgid "Please enter something for at least one field." +msgstr "Por favor, introduzca algo en al menos un campo." -#: utils/timesince.py:17 -msgid "minute" -msgid_plural "minutes" -msgstr[0] "minuto" -msgstr[1] "minutos" +#: core/validators.py:308 core/validators.py:319 +msgid "Please enter both fields or leave them both empty." +msgstr "Por favor, rellene ambos campos o deje ambos vacíos." -#: utils/timesince.py:39 +#: core/validators.py:327 #, python-format -msgid "%(number)d %(type)s" -msgstr "%(number)d %(type)s" +msgid "This field must be given if %(field)s is %(value)s" +msgstr "Se debe proporcionar este campo si %(field)s es %(value)s" -#: utils/timesince.py:45 +#: core/validators.py:340 #, python-format -msgid ", %(number)d %(type)s" -msgstr ", %(number)d %(type)s" - -#: utils/dateformat.py:41 -msgid "p.m." -msgstr "p.m" - -#: utils/dateformat.py:42 -msgid "a.m." -msgstr "a.m" +msgid "This field must be given if %(field)s is not %(value)s" +msgstr "Se debe proporcionar este campo si %(field)s no es %(value)s" -#: utils/dateformat.py:47 -msgid "PM" -msgstr "PM" +#: core/validators.py:359 +msgid "Duplicate values are not allowed." +msgstr "No se admiten valores duplicados." -#: utils/dateformat.py:48 -msgid "AM" -msgstr "AM" +#: core/validators.py:374 +#, python-format +msgid "This value must be between %(lower)s and %(upper)s." +msgstr "Este valor debe estar entre %(lower)s y %(upper)s." -#: utils/dateformat.py:97 -msgid "midnight" -msgstr "media noche" +#: core/validators.py:376 +#, python-format +msgid "This value must be at least %s." +msgstr "Este valor debe ser como mínimo %s." -#: utils/dateformat.py:99 -msgid "noon" -msgstr "medio día" +#: core/validators.py:378 +#, python-format +msgid "This value must be no more than %s." +msgstr "Este valor no debe ser mayor que %s." -#: utils/translation/trans_real.py:391 -msgid "DATE_FORMAT" -msgstr "j N Y" +#: core/validators.py:414 +#, python-format +msgid "This value must be a power of %s." +msgstr "Este valor debe ser una potencia de %s." -#: utils/translation/trans_real.py:392 -msgid "DATETIME_FORMAT" -msgstr "j N Y P" +#: core/validators.py:424 +msgid "Please enter a valid decimal number." +msgstr "Por favor, introduzca un número decimal válido." -#: utils/translation/trans_real.py:393 -msgid "TIME_FORMAT" -msgstr "P" +#: core/validators.py:431 +#, 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] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígito en " +"total." +msgstr[1] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígitos en " +"total." -#: utils/translation/trans_real.py:409 -msgid "YEAR_MONTH_FORMAT" -msgstr "F Y" +#: core/validators.py:434 +#, 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] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígito en su " +"parte entera." +msgstr[1] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígitos en su " +"parte entera." -#: utils/translation/trans_real.py:410 -msgid "MONTH_DAY_FORMAT" -msgstr "j \\de F" +#: core/validators.py:437 +#, 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] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígito " +"decimal." +msgstr[1] "" +"Por favor, introduzca un número decimal válido con a lo más %s dígitos " +"decimales." -#: template/defaultfilters.py:485 -msgid "yes,no,maybe" -msgstr "sí,no,tal vez" +#: core/validators.py:445 +msgid "Please enter a valid floating point number." +msgstr "Por favor, introduzca un número decimal válido." -#: template/defaultfilters.py:514 +#: core/validators.py:454 #, python-format -msgid "%(size)d byte" -msgid_plural "%(size)d bytes" -msgstr[0] "%(size)d byte" -msgstr[1] "%(size)d bytes" +msgid "Make sure your uploaded file is at least %s bytes big." +msgstr "Asegúrese de que el fichero que envía tiene al menos %s bytes." -#: template/defaultfilters.py:516 +#: core/validators.py:455 #, python-format -msgid "%.1f KB" -msgstr "%.1f KB" +msgid "Make sure your uploaded file is at most %s bytes big." +msgstr "Asegúrese de que el fichero que envía tiene como máximo %s bytes." -#: template/defaultfilters.py:518 -#, python-format -msgid "%.1f MB" -msgstr "%.1f MB" +#: core/validators.py:472 +msgid "The format for this field is wrong." +msgstr "El formato de este campo es incorrecto." -#: template/defaultfilters.py:519 -#, python-format -msgid "%.1f GB" -msgstr "%.1f GB" +#: core/validators.py:487 +msgid "This field is invalid." +msgstr "Este campo no es válido." -#: newforms/fields.py:116 +#: core/validators.py:523 #, python-format -msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." -msgstr "" -"Asegúrese de que su texto tiene a lo más %(max)d caracteres (actualmente " -"tiene %(length)d)." +msgid "Could not retrieve anything from %s." +msgstr "No pude obtener nada de %s." -#: newforms/fields.py:118 +#: core/validators.py:526 #, python-format -msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." +msgid "" +"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." msgstr "" -"Asegúrese de que su texto tiene al menos %(min)d caracteres (actualmente " -"tiene %(length)d)." +"La URL %(url)s devolvió la cabecera Content-Type '%(contenttype)s', que no " +"es válida." -#: newforms/fields.py:143 newforms/fields.py:166 newforms/fields.py:196 +#: core/validators.py:559 #, python-format -msgid "Ensure this value is less than or equal to %s." -msgstr "Asegúrese de que este valor es menor o igual a %s." +msgid "" +"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " +"\"%(start)s\".)" +msgstr "" +"Por favor, cierre la etiqueta %(tag)s de la línea %(line)s. (La línea " +"empieza por \"%(start)s\".)" -#: newforms/fields.py:145 newforms/fields.py:168 newforms/fields.py:198 +#: core/validators.py:563 #, python-format -msgid "Ensure this value is greater than or equal to %s." -msgstr "Asegúrese de que este valor es mayor o igual a %s." - -#: newforms/fields.py:164 newforms/fields.py:191 -msgid "Enter a number." -msgstr "Introduzca un número." +msgid "" +"Some text starting on line %(line)s is not allowed in that context. (Line " +"starts with \"%(start)s\".)" +msgstr "" +"Parte del texto que comienza en la línea %(line)s no está permitido en ese " +"contexto. (La línea empieza por \"%(start)s\".)" -#: newforms/fields.py:200 +#: core/validators.py:568 #, python-format -msgid "Ensure that there are no more than %s digits in total." -msgstr "Asegúrese de que no hay más de %s dígitos en total." +msgid "" +"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" +"(start)s\".)" +msgstr "" +"El \"%(attr)s\" de la línea %(line)s no es un atributo válido. (La línea " +"empieza por \"%(start)s\".)" -#: newforms/fields.py:202 +#: core/validators.py:573 #, python-format -msgid "Ensure that there are no more than %s decimal places." -msgstr "Asegúrese de que no hay más de %s decimales." +msgid "" +"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" +"(start)s\".)" +msgstr "" +"La \"<%(tag)s>\" de la línea %(line)s no es una etiqueta válida. (La línea " +"empieza por \"%(start)s\".)" -#: newforms/fields.py:204 +#: core/validators.py:577 #, python-format -msgid "Ensure that there are no more than %s digits before the decimal point." -msgstr "Asegúrese de que no hay más de %s dígitos antes del punto decimal." - -#: newforms/fields.py:237 newforms/fields.py:560 -msgid "Enter a valid date." -msgstr "Introduzca una fecha válida." - -#: newforms/fields.py:264 newforms/fields.py:562 -msgid "Enter a valid time." -msgstr "Introduzca una hora válida." - -#: newforms/fields.py:300 -msgid "Enter a valid date/time." -msgstr "Introduzca una fecha/hora válida." - -#: newforms/fields.py:313 -msgid "Enter a valid value." -msgstr "Introduzca un valor correcto." - -#: newforms/fields.py:353 newforms/fields.py:375 -msgid "Enter a valid URL." -msgstr "Introduzca una URL válida." - -#: newforms/fields.py:377 -msgid "This URL appears to be a broken link." -msgstr "La URL parece ser un enlace roto." - -#: newforms/fields.py:428 newforms/models.py:174 -msgid "Select a valid choice. That choice is not one of the available choices." -msgstr "Escoja una opción válida. Esa opción no está entre las aceptadas." - -#: newforms/fields.py:444 newforms/fields.py:520 newforms/models.py:191 -msgid "Enter a list of values." -msgstr "Introduzca una lista de valores." +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 línea %(line)s le faltan uno o más atributos " +"requeridos. (La línea empieza por \"%(start)s\".)" -#: newforms/fields.py:450 newforms/models.py:197 +#: core/validators.py:582 #, python-format -msgid "Select a valid choice. %s is not one of the available choices." -msgstr "Escoja una opción válida; '%s' no es una de las opciones disponibles." +msgid "" +"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " +"starts with \"%(start)s\".)" +msgstr "" +"El atributo \"%(attr)s\" de la línea %(line)s tiene un valor que no es " +"válido. (La línea empieza por \"%(start)s\".)" diff --git a/django/conf/locale/fr/LC_MESSAGES/django.mo b/django/conf/locale/fr/LC_MESSAGES/django.mo Binary files differindex 32b009440f..55e4e57f5a 100644 --- a/django/conf/locale/fr/LC_MESSAGES/django.mo +++ b/django/conf/locale/fr/LC_MESSAGES/django.mo diff --git a/django/conf/locale/fr/LC_MESSAGES/django.po b/django/conf/locale/fr/LC_MESSAGES/django.po index c64130e4dd..ba335f5eae 100644 --- a/django/conf/locale/fr/LC_MESSAGES/django.po +++ b/django/conf/locale/fr/LC_MESSAGES/django.po @@ -2862,7 +2862,7 @@ msgstr "jul" #: utils/dates.py:24 msgid "aug" -msgstr "aout" +msgstr "août" #: utils/dates.py:24 msgid "sep" @@ -2890,7 +2890,7 @@ msgstr "Fév." #: utils/dates.py:32 msgid "Aug." -msgstr "Aôut" +msgstr "Août" #: utils/dates.py:32 msgid "Sept." diff --git a/django/conf/locale/fr/LC_MESSAGES/djangojs.mo b/django/conf/locale/fr/LC_MESSAGES/djangojs.mo Binary files differindex 34f4c78529..44f04e3b7e 100644 --- a/django/conf/locale/fr/LC_MESSAGES/djangojs.mo +++ b/django/conf/locale/fr/LC_MESSAGES/djangojs.mo diff --git a/django/conf/locale/fr/LC_MESSAGES/djangojs.po b/django/conf/locale/fr/LC_MESSAGES/djangojs.po index 1841be20c8..3d6a2aaca3 100644 --- a/django/conf/locale/fr/LC_MESSAGES/djangojs.po +++ b/django/conf/locale/fr/LC_MESSAGES/djangojs.po @@ -35,7 +35,7 @@ msgstr "Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi" #: contrib/admin/media/js/SelectFilter2.js:33 #, perl-format msgid "Available %s" -msgstr "Disponible %s" +msgstr "%s disponible(s)" #: contrib/admin/media/js/SelectFilter2.js:41 msgid "Choose all" @@ -52,7 +52,7 @@ msgstr "Enlever" #: contrib/admin/media/js/SelectFilter2.js:53 #, perl-format msgid "Chosen %s" -msgstr "Choisi %s" +msgstr "%s choisi(es)" #: contrib/admin/media/js/SelectFilter2.js:54 msgid "Select your choice(s) and click " diff --git a/django/conf/locale/hr/LC_MESSAGES/django.mo b/django/conf/locale/hr/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 0000000000..e7f4d6bf2f --- /dev/null +++ b/django/conf/locale/hr/LC_MESSAGES/django.mo diff --git a/django/conf/locale/hr/LC_MESSAGES/django.po b/django/conf/locale/hr/LC_MESSAGES/django.po new file mode 100644 index 0000000000..79850d176e --- /dev/null +++ b/django/conf/locale/hr/LC_MESSAGES/django.po @@ -0,0 +1,3282 @@ +# translation of django.po to Hrvatski jezik +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +msgid "" +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" +"Last-Translator: Aljosa Mohorovic <aljosa.mohorovic@gmail.com>\n" +"Language-Team: Hrvatski jezik\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" +"X-Generator: KBabel 1.11.4\n" + +#: oldforms/__init__.py:373 db/models/fields/__init__.py:156 +#: db/models/fields/__init__.py:313 db/models/fields/__init__.py:721 +#: db/models/fields/__init__.py:732 newforms/models.py:193 +#: newforms/fields.py:92 newforms/fields.py:490 newforms/fields.py:566 +#: newforms/fields.py:577 +msgid "This field is required." +msgstr "Unos za ovo polje je obavezan." + +#: oldforms/__init__.py:408 +#, 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[1] "Uneseni tekst mora sadržavati manje od %s znakova." + +#: oldforms/__init__.py:413 +msgid "Line breaks are not allowed here." +msgstr "Unos u novi red ovdje nije dozvoljen." + +#: oldforms/__init__.py:511 oldforms/__init__.py:585 oldforms/__init__.py:624 +#, python-format +msgid "Select a valid choice; '%(data)s' is not in %(choices)s." +msgstr "Odaberite iz ponuđenog; '%(data)s' nije u %(choices)s." + +#: oldforms/__init__.py:591 newforms/widgets.py:188 +#: contrib/admin/filterspecs.py:152 +msgid "Unknown" +msgstr "Nepoznat pojam." + +#: oldforms/__init__.py:591 newforms/widgets.py:188 +#: contrib/admin/filterspecs.py:145 +msgid "Yes" +msgstr "Da" + +#: oldforms/__init__.py:591 newforms/widgets.py:188 +#: contrib/admin/filterspecs.py:145 +msgid "No" +msgstr "Ne" + +#: oldforms/__init__.py:686 core/validators.py:181 core/validators.py:461 +#: newforms/fields.py:376 +msgid "No file was submitted. Check the encoding type on the form." +msgstr "Datoteka nije poslana. Provjerite 'encoding type' forme." + +#: oldforms/__init__.py:688 newforms/fields.py:380 +msgid "The submitted file is empty." +msgstr "Poslana datoteka je prazna." + +#: oldforms/__init__.py:744 +msgid "Enter a whole number between -32,768 and 32,767." +msgstr "Unesite cijeli broj između -32,768 i 32,767." + +#: oldforms/__init__.py:754 +msgid "Enter a positive number." +msgstr "Unesite pozitivan broj." + +#: oldforms/__init__.py:764 +msgid "Enter a whole number between 0 and 32,767." +msgstr "Unesite cijeli broj između 0 i 32,767." + +#: db/models/manipulators.py:309 +#, python-format +msgid "%(object)s with this %(type)s already exists for the given %(field)s." +msgstr "%(object)s sa %(type)s već postoji za navedeno %(field)s." + +#: db/models/manipulators.py:310 contrib/admin/views/main.py:342 +#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346 +msgid "and" +msgstr "i" + +#: db/models/fields/__init__.py:49 +#, python-format +msgid "%(optname)s with this %(fieldname)s already exists." +msgstr "%(optname)s sa navedenim %(fieldname)s već postoji." + +#: db/models/fields/__init__.py:411 +msgid "This value must be an integer." +msgstr "Vrijednost mora biti interger." + +#: db/models/fields/__init__.py:446 +msgid "This value must be either True or False." +msgstr "Vrijednost mora biti True ili False." + +#: db/models/fields/__init__.py:467 +msgid "This field cannot be null." +msgstr "Ovo polje ne može biti null." + +#: db/models/fields/__init__.py:501 core/validators.py:155 +msgid "Enter a valid date in YYYY-MM-DD format." +msgstr "Unesite validan datum u formatu YYYY-MM-DD." + +#: db/models/fields/__init__.py:570 core/validators.py:164 +msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." +msgstr "Unesite validan datum/vrijeme u formatu YYYY-MM-DD HH:MM." + +#: db/models/fields/__init__.py:631 +msgid "This value must be a decimal number." +msgstr "Vrijednost mora biti decimalan broj." + +#: db/models/fields/__init__.py:741 +msgid "Enter a valid filename." +msgstr "Unesite ime datoteke koja postoji." + +#: db/models/fields/__init__.py:883 +msgid "This value must be either None, True or False." +msgstr "Vrijednost mora biti None, True ili False." + +#: db/models/fields/related.py:55 +#, python-format +msgid "Please enter a valid %s." +msgstr "Molim unesite validan %s." + +#: db/models/fields/related.py:661 +msgid "Separate multiple IDs with commas." +msgstr "Odvojite više ID-a zarezom." + +#: db/models/fields/related.py:663 +msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +msgstr "Držite \"Control\", ili \"Command\" na Mac-u, da bi odabravili više od jednog objekta." + +#: db/models/fields/related.py:710 +#, 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] "Molim unesite ispravan %(self)s ID. Vrijednost %(value)r je neispravna." +msgstr[1] "" + +#: conf/global_settings.py:38 +msgid "Arabic" +msgstr "" + +#: conf/global_settings.py:39 +msgid "Bengali" +msgstr "" + +#: conf/global_settings.py:40 +msgid "Bulgarian" +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 "Persian" +msgstr "" + +#: conf/global_settings.py:51 +msgid "Finnish" +msgstr "" + +#: conf/global_settings.py:52 +msgid "French" +msgstr "" + +#: conf/global_settings.py:53 +msgid "Galician" +msgstr "" + +#: conf/global_settings.py:54 +msgid "Hungarian" +msgstr "" + +#: conf/global_settings.py:55 +msgid "Hebrew" +msgstr "" + +#: conf/global_settings.py:56 +msgid "Icelandic" +msgstr "" + +#: conf/global_settings.py:57 +msgid "Italian" +msgstr "" + +#: conf/global_settings.py:58 +msgid "Japanese" +msgstr "" + +#: conf/global_settings.py:59 +msgid "Korean" +msgstr "" + +#: conf/global_settings.py:60 +msgid "Kannada" +msgstr "" + +#: conf/global_settings.py:61 +msgid "Latvian" +msgstr "" + +#: conf/global_settings.py:62 +msgid "Macedonian" +msgstr "" + +#: conf/global_settings.py:63 +msgid "Dutch" +msgstr "" + +#: conf/global_settings.py:64 +msgid "Norwegian" +msgstr "" + +#: conf/global_settings.py:65 +msgid "Polish" +msgstr "" + +#: conf/global_settings.py:66 +msgid "Portugese" +msgstr "" + +#: conf/global_settings.py:67 +msgid "Brazilian" +msgstr "" + +#: conf/global_settings.py:68 +msgid "Romanian" +msgstr "" + +#: conf/global_settings.py:69 +msgid "Russian" +msgstr "" + +#: conf/global_settings.py:70 +msgid "Slovak" +msgstr "" + +#: conf/global_settings.py:71 +msgid "Slovenian" +msgstr "" + +#: conf/global_settings.py:72 +msgid "Serbian" +msgstr "" + +#: conf/global_settings.py:73 +msgid "Swedish" +msgstr "" + +#: conf/global_settings.py:74 +msgid "Tamil" +msgstr "" + +#: conf/global_settings.py:75 +msgid "Telugu" +msgstr "" + +#: conf/global_settings.py:76 +msgid "Turkish" +msgstr "" + +#: conf/global_settings.py:77 +msgid "Ukrainian" +msgstr "" + +#: conf/global_settings.py:78 +msgid "Simplified Chinese" +msgstr "" + +#: conf/global_settings.py:79 +msgid "Traditional Chinese" +msgstr "" + +#: core/validators.py:71 +msgid "This value must contain only letters, numbers and underscores." +msgstr "Ova vrijednost može sadržavati samo slova, brojeve i povlaku." + +#: core/validators.py:75 +msgid "" +"This value must contain only letters, numbers, underscores, dashes or " +"slashes." +msgstr "" +"Ova vrijednost može sadržavati samo slova, brojeve, povlaku, crtice ili " +"slashes (/)." + +#: core/validators.py:79 +msgid "This value must contain only letters, numbers, underscores or hyphens." +msgstr "Ova vrijednost može sadržavati samo slova, brojeve, povlake ili hyphens." + +#: core/validators.py:83 +msgid "Uppercase letters are not allowed here." +msgstr "Velika slova ovdje nisu dopuštena." + +#: core/validators.py:87 +msgid "Lowercase letters are not allowed here." +msgstr "Mala slova ovdje nisu dopuštena" + +#: core/validators.py:94 +msgid "Enter only digits separated by commas." +msgstr "Unesite samo brojeve razdvojene zarezom." + +#: core/validators.py:106 +msgid "Enter valid e-mail addresses separated by commas." +msgstr "Unesite ispravne e-mail adrese odvojene zarezom." + +#: core/validators.py:110 +msgid "Please enter a valid IP address." +msgstr "Unesite ispravnu IP adresu." + +#: core/validators.py:114 +msgid "Empty values are not allowed here." +msgstr "Prazne vrijednosti nisu ispravne ovdje." + +#: core/validators.py:118 +msgid "Non-numeric characters aren't allowed here." +msgstr "Dozvoljeni su samo numerički znakovi." + +#: core/validators.py:122 +msgid "This value can't be comprised solely of digits." +msgstr "Ova vrijednost ne može sadržavati samo brojeve." + +#: core/validators.py:127 newforms/fields.py:142 +msgid "Enter a whole number." +msgstr "Unesite cijeli broj." + +#: core/validators.py:131 +msgid "Only alphabetical characters are allowed here." +msgstr "Dozvoljena su samo slova abecede." + +#: core/validators.py:146 +msgid "Year must be 1900 or later." +msgstr "Godina mora biti poslije 1900." + +#: core/validators.py:150 +#, python-format +msgid "Invalid date: %s" +msgstr "Neispravan datum: %s" + +#: core/validators.py:160 +msgid "Enter a valid time in HH:MM format." +msgstr "Unesite ispravno vrijeme u HH:MM formatu." + +#: core/validators.py:169 newforms/fields.py:336 +msgid "Enter a valid e-mail address." +msgstr "Unesite ispravnu e-mail adresu." + +#: core/validators.py:185 newforms/fields.py:397 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "Upload-ajte ispravnu sliku. Datoteka koju ste upload-ali ili nije slika ili je oštečena." + +#: core/validators.py:192 +#, python-format +msgid "The URL %s does not point to a valid image." +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 "" + +#: core/validators.py:204 +#, python-format +msgid "The URL %s does not point to a valid QuickTime video." +msgstr "" + +#: core/validators.py:208 +msgid "A valid URL is required." +msgstr "" + +#: core/validators.py:222 +#, python-format +msgid "" +"Valid HTML is required. Specific errors are:\n" +"%s" +msgstr "" + +#: core/validators.py:229 +#, python-format +msgid "Badly formed XML: %s" +msgstr "" + +#: core/validators.py:246 +#, python-format +msgid "Invalid URL: %s" +msgstr "" + +#: core/validators.py:251 core/validators.py:253 +#, python-format +msgid "The URL %s is a broken link." +msgstr "" + +#: core/validators.py:259 +msgid "Enter a valid U.S. state abbreviation." +msgstr "" + +#: 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] "" + +#: core/validators.py:280 +#, python-format +msgid "This field must match the '%s' field." +msgstr "" + +#: core/validators.py:299 +msgid "Please enter something for at least one field." +msgstr "" + +#: core/validators.py:308 core/validators.py:319 +msgid "Please enter both fields or leave them both empty." +msgstr "" + +#: core/validators.py:327 +#, python-format +msgid "This field must be given if %(field)s is %(value)s" +msgstr "" + +#: core/validators.py:340 +#, python-format +msgid "This field must be given if %(field)s is not %(value)s" +msgstr "" + +#: core/validators.py:359 +msgid "Duplicate values are not allowed." +msgstr "" + +#: core/validators.py:374 +#, python-format +#, fuzzy +msgid "This value must be between %(lower)s and %(upper)s." +msgstr "i." + +#: core/validators.py:376 +#, python-format +msgid "This value must be at least %s." +msgstr "" + +#: core/validators.py:378 +#, python-format +msgid "This value must be no more than %s." +msgstr "" + +#: core/validators.py:414 +#, python-format +msgid "This value must be a power of %s." +msgstr "" + +#: core/validators.py:424 +msgid "Please enter a valid decimal number." +msgstr "" + +#: core/validators.py:431 +#, 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] "" +msgstr[1] "" + +#: core/validators.py:434 +#, 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] "" +msgstr[1] "" + +#: core/validators.py:437 +#, 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] "" +msgstr[1] "" + +#: core/validators.py:445 +msgid "Please enter a valid floating point number." +msgstr "" + +#: core/validators.py:454 +#, python-format +msgid "Make sure your uploaded file is at least %s bytes big." +msgstr "" + +#: core/validators.py:455 +#, python-format +msgid "Make sure your uploaded file is at most %s bytes big." +msgstr "" + +#: core/validators.py:472 +msgid "The format for this field is wrong." +msgstr "" + +#: core/validators.py:487 +msgid "This field is invalid." +msgstr "" + +#: core/validators.py:523 +#, python-format +msgid "Could not retrieve anything from %s." +msgstr "" + +#: core/validators.py:526 +#, python-format +msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." +msgstr "" + +#: core/validators.py:559 +#, python-format +msgid "" +"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " +"\"%(start)s\".)" +msgstr "" + +#: core/validators.py:563 +#, python-format +msgid "" +"Some text starting on line %(line)s is not allowed in that context. (Line " +"starts with \"%(start)s\".)" +msgstr "" + +#: core/validators.py:568 +#, python-format +msgid "" +"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" +"(start)s\".)" +msgstr "" + +#: core/validators.py:573 +#, python-format +msgid "" +"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" +"(start)s\".)" +msgstr "" + +#: core/validators.py:577 +#, python-format +msgid "" +"A tag on line %(line)s is missing one or more required attributes. (Line " +"starts with \"%(start)s\".)" +msgstr "" + +#: core/validators.py:582 +#, python-format +msgid "" +"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " +"starts with \"%(start)s\".)" +msgstr "" + +#: views/generic/create_update.py:43 +#, python-format +msgid "The %(verbose_name)s was created successfully." +msgstr "" + +#: views/generic/create_update.py:117 +#, python-format +msgid "The %(verbose_name)s was updated successfully." +msgstr "" + +#: views/generic/create_update.py:184 +#, python-format +msgid "The %(verbose_name)s was deleted." +msgstr "" + +#: newforms/models.py:180 newforms/fields.py:478 +msgid "Select a valid choice. That choice is not one of the available choices." +msgstr "" + +#: newforms/models.py:197 newforms/fields.py:494 newforms/fields.py:570 +msgid "Enter a list of values." +msgstr "" + +#: newforms/models.py:203 newforms/fields.py:500 +#, python-format +msgid "Select a valid choice. %s is not one of the available choices." +msgstr "" + +#: newforms/fields.py:116 +#, python-format +msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." +msgstr "" + +#: newforms/fields.py:118 +#, python-format +msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." +msgstr "" + +#: newforms/fields.py:144 newforms/fields.py:167 newforms/fields.py:197 +#, python-format +msgid "Ensure this value is less than or equal to %s." +msgstr "" + +#: newforms/fields.py:146 newforms/fields.py:169 newforms/fields.py:199 +#, python-format +msgid "Ensure this value is greater than or equal to %s." +msgstr "" + +#: newforms/fields.py:165 newforms/fields.py:192 +msgid "Enter a number." +msgstr "" + +#: newforms/fields.py:201 +#, python-format +msgid "Ensure that there are no more than %s digits in total." +msgstr "" + +#: newforms/fields.py:203 +#, python-format +msgid "Ensure that there are no more than %s decimal places." +msgstr "" + +#: newforms/fields.py:205 +#, python-format +msgid "Ensure that there are no more than %s digits before the decimal point." +msgstr "" + +#: newforms/fields.py:238 newforms/fields.py:610 +msgid "Enter a valid date." +msgstr "" + +#: newforms/fields.py:265 newforms/fields.py:612 +msgid "Enter a valid time." +msgstr "" + +#: newforms/fields.py:301 +msgid "Enter a valid date/time." +msgstr "" + +#: newforms/fields.py:314 +msgid "Enter a valid value." +msgstr "" + +#: newforms/fields.py:378 +#, fuzzy +msgid "No file was submitted." +msgstr "Ne." + +#: newforms/fields.py:403 newforms/fields.py:425 +msgid "Enter a valid URL." +msgstr "" + +#: newforms/fields.py:427 +msgid "This URL appears to be a broken link." +msgstr "" + +#: 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] "" +msgstr[1] "" + +#: contrib/humanize/templatetags/humanize.py:50 +#, python-format +msgid "%(value).1f billion" +msgid_plural "%(value).1f billion" +msgstr[0] "" +msgstr[1] "" + +#: contrib/humanize/templatetags/humanize.py:53 +#, python-format +msgid "%(value).1f trillion" +msgid_plural "%(value).1f trillion" +msgstr[0] "" +msgstr[1] "" + +#: 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 "" + +#: 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 "" + +#: 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 "" + +#: contrib/comments/models.py:68 +msgid "headline" +msgstr "" + +#: contrib/comments/models.py:69 contrib/comments/models.py:90 +#: contrib/comments/models.py:167 +msgid "comment" +msgstr "" + +#: contrib/comments/models.py:70 +msgid "rating #1" +msgstr "" + +#: contrib/comments/models.py:71 +msgid "rating #2" +msgstr "" + +#: contrib/comments/models.py:72 +msgid "rating #3" +msgstr "" + +#: contrib/comments/models.py:73 +msgid "rating #4" +msgstr "" + +#: contrib/comments/models.py:74 +msgid "rating #5" +msgstr "" + +#: contrib/comments/models.py:75 +msgid "rating #6" +msgstr "" + +#: contrib/comments/models.py:76 +msgid "rating #7" +msgstr "" + +#: contrib/comments/models.py:77 +msgid "rating #8" +msgstr "" + +#: contrib/comments/models.py:82 +msgid "is valid rating" +msgstr "" + +#: 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 +msgid "is public" +msgstr "" + +#: contrib/comments/models.py:85 contrib/admin/views/doc.py:306 +msgid "IP address" +msgstr "" + +#: contrib/comments/models.py:86 +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 "" + +#: contrib/comments/models.py:91 +msgid "comments" +msgstr "" + +#: contrib/comments/models.py:131 contrib/comments/models.py:207 +msgid "Content object" +msgstr "" + +#: contrib/comments/models.py:159 +#, python-format +msgid "" +"Posted by %(user)s at %(date)s\n" +"\n" +"%(comment)s\n" +"\n" +"http://%(domain)s%(url)s" +msgstr "" + +#: contrib/comments/models.py:168 +msgid "person's name" +msgstr "" + +#: contrib/comments/models.py:171 +msgid "ip address" +msgstr "" + +#: contrib/comments/models.py:173 +msgid "approved by staff" +msgstr "" + +#: contrib/comments/models.py:176 +msgid "free comment" +msgstr "" + +#: contrib/comments/models.py:177 +msgid "free comments" +msgstr "" + +#: contrib/comments/models.py:233 +msgid "score" +msgstr "" + +#: contrib/comments/models.py:234 +msgid "score date" +msgstr "" + +#: contrib/comments/models.py:237 +msgid "karma score" +msgstr "" + +#: contrib/comments/models.py:238 +msgid "karma scores" +msgstr "" + +#: contrib/comments/models.py:242 +#, python-format +msgid "%(score)d rating by %(user)s" +msgstr "" + +#: contrib/comments/models.py:258 +#, python-format +msgid "" +"This comment was flagged by %(user)s:\n" +"\n" +"%(text)s" +msgstr "" + +#: contrib/comments/models.py:265 +msgid "flag date" +msgstr "" + +#: contrib/comments/models.py:268 +msgid "user flag" +msgstr "" + +#: contrib/comments/models.py:269 +msgid "user flags" +msgstr "" + +#: contrib/comments/models.py:273 +#, python-format +msgid "Flag by %r" +msgstr "" + +#: contrib/comments/models.py:278 +msgid "deletion date" +msgstr "" + +#: contrib/comments/models.py:280 +msgid "moderator deletion" +msgstr "" + +#: contrib/comments/models.py:281 +msgid "moderator deletions" +msgstr "" + +#: contrib/comments/models.py:285 +#, python-format +msgid "Moderator deletion by %r" +msgstr "" + +#: contrib/comments/views/karma.py:20 +msgid "Anonymous users cannot vote" +msgstr "" + +#: contrib/comments/views/karma.py:24 +msgid "Invalid comment ID" +msgstr "" + +#: contrib/comments/views/karma.py:26 +#, fuzzy +msgid "No voting for yourself" +msgstr "Ne" + +#: 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:112 +#, 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] "" +msgstr[1] "" + +#: contrib/comments/views/comments.py:117 +#, python-format +msgid "" +"This comment was posted by a sketchy user:\n" +"\n" +"%(text)s" +msgstr "" + +#: contrib/comments/views/comments.py:189 +#: contrib/comments/views/comments.py:281 +msgid "Only POSTs are allowed" +msgstr "" + +#: contrib/comments/views/comments.py:193 +#: contrib/comments/views/comments.py:285 +msgid "One or more of the required fields wasn't submitted" +msgstr "" + +#: contrib/comments/views/comments.py:197 +#: contrib/comments/views/comments.py:287 +msgid "Somebody tampered with the comment form (security violation)" +msgstr "" + +#: contrib/comments/views/comments.py:207 +#: contrib/comments/views/comments.py:293 +msgid "" +"The comment form had an invalid 'target' parameter -- the object ID was " +"invalid" +msgstr "" + +#: contrib/comments/views/comments.py:258 +#: contrib/comments/views/comments.py:322 +msgid "The comment form didn't provide either 'preview' or 'post'" +msgstr "" + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/comments/templates/comments/form.html:8 +#: contrib/admin/templates/admin/login.html:17 +msgid "Username:" +msgstr "" + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/base.html:25 +#: 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/view_detail.html:4 +#: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_detail.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 +#: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 +#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 +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 "" + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Required" +msgstr "" + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Optional" +msgstr "" + +#: contrib/comments/templates/comments/form.html:23 +msgid "Post a photo" +msgstr "" + +#: contrib/comments/templates/comments/form.html:28 +#: contrib/comments/templates/comments/freeform.html:5 +msgid "Comment:" +msgstr "" + +#: contrib/comments/templates/comments/form.html:35 +#: contrib/comments/templates/comments/freeform.html:10 +msgid "Preview comment" +msgstr "" + +#: contrib/comments/templates/comments/freeform.html:4 +msgid "Your name:" +msgstr "" + +#: contrib/sites/models.py:15 +msgid "domain name" +msgstr "" + +#: contrib/sites/models.py:16 +msgid "display name" +msgstr "" + +#: contrib/sites/models.py:20 +msgid "site" +msgstr "" + +#: contrib/sites/models.py:21 +msgid "sites" +msgstr "" + +#: contrib/admin/filterspecs.py:42 +#, python-format +msgid "" +"<h3>By %s:</h3>\n" +"<ul>\n" +msgstr "" + +#: contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90 +#: contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171 +msgid "All" +msgstr "" + +#: contrib/admin/filterspecs.py:111 +msgid "Any date" +msgstr "" + +#: contrib/admin/filterspecs.py:112 +msgid "Today" +msgstr "" + +#: contrib/admin/filterspecs.py:115 +msgid "Past 7 days" +msgstr "" + +#: contrib/admin/filterspecs.py:117 +msgid "This month" +msgstr "" + +#: contrib/admin/filterspecs.py:119 +msgid "This year" +msgstr "" + +#: contrib/admin/models.py:17 +msgid "action time" +msgstr "" + +#: contrib/admin/models.py:20 +msgid "object id" +msgstr "" + +#: contrib/admin/models.py:21 +msgid "object repr" +msgstr "" + +#: contrib/admin/models.py:22 +msgid "action flag" +msgstr "" + +#: contrib/admin/models.py:23 +msgid "change message" +msgstr "" + +#: contrib/admin/models.py:26 +msgid "log entry" +msgstr "" + +#: contrib/admin/models.py:27 +msgid "log entries" +msgstr "" + +#: contrib/admin/templatetags/admin_list.py:254 +msgid "All dates" +msgstr "" + +#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:264 +#, python-format +msgid "The %(name)s \"%(obj)s\" was added successfully." +msgstr "" + +#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:268 +#: contrib/admin/views/main.py:354 +msgid "You may edit it again below." +msgstr "" + +#: contrib/admin/views/auth.py:31 +msgid "Add user" +msgstr "" + +#: contrib/admin/views/auth.py:58 +msgid "Password changed successfully." +msgstr "" + +#: contrib/admin/views/auth.py:65 +#, python-format +msgid "Change password: %s" +msgstr "" + +#: contrib/admin/views/main.py:230 +msgid "Site administration" +msgstr "" + +#: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363 +#, python-format +msgid "You may add another %s below." +msgstr "" + +#: contrib/admin/views/main.py:296 +#, python-format +msgid "Add %s" +msgstr "" + +#: contrib/admin/views/main.py:342 +#, python-format +msgid "Added %s." +msgstr "" + +#: contrib/admin/views/main.py:344 +#, python-format +msgid "Changed %s." +msgstr "" + +#: contrib/admin/views/main.py:346 +#, python-format +msgid "Deleted %s." +msgstr "" + +#: contrib/admin/views/main.py:349 +#, fuzzy +msgid "No fields changed." +msgstr "Ne." + +#: contrib/admin/views/main.py:352 +#, python-format +msgid "The %(name)s \"%(obj)s\" was changed successfully." +msgstr "" + +#: contrib/admin/views/main.py:360 +#, python-format +msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below." +msgstr "" + +#: contrib/admin/views/main.py:398 +#, python-format +msgid "Change %s" +msgstr "" + +#: contrib/admin/views/main.py:483 +#, python-format +msgid "One or more %(fieldname)s in %(name)s: %(obj)s" +msgstr "" + +#: contrib/admin/views/main.py:488 +#, python-format +msgid "One or more %(fieldname)s in %(name)s:" +msgstr "" + +#: contrib/admin/views/main.py:520 +#, python-format +msgid "The %(name)s \"%(obj)s\" was deleted successfully." +msgstr "" + +#: contrib/admin/views/main.py:523 +msgid "Are you sure?" +msgstr "" + +#: contrib/admin/views/main.py:545 +#, python-format +msgid "Change history: %s" +msgstr "" + +#: contrib/admin/views/main.py:579 +#, python-format +msgid "Select %s" +msgstr "" + +#: contrib/admin/views/main.py:579 +#, python-format +msgid "Select %s to change" +msgstr "" + +#: contrib/admin/views/main.py:780 +msgid "Database error" +msgstr "" + +#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60 +#, fuzzy +msgid "" +"Please enter a correct username and password. Note that both fields are case-" +"sensitive." +msgstr "i." + +#: contrib/admin/views/decorators.py:24 +#: contrib/admin/templates/admin/login.html:25 +msgid "Log in" +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:69 +#, fuzzy +msgid "" +"Looks like your browser isn't configured to accept cookies. Please enable " +"cookies, reload this page, and try again." +msgstr "i." + +#: contrib/admin/views/decorators.py:83 +msgid "Usernames cannot contain the '@' character." +msgstr "" + +#: contrib/admin/views/decorators.py:85 +#, python-format +msgid "Your e-mail address is not your username. Try '%s' instead." +msgstr "" + +#: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49 +#: contrib/admin/views/doc.py:51 +msgid "tag:" +msgstr "" + +#: contrib/admin/views/doc.py:78 contrib/admin/views/doc.py:80 +#: contrib/admin/views/doc.py:82 +msgid "filter:" +msgstr "" + +#: contrib/admin/views/doc.py:136 contrib/admin/views/doc.py:138 +#: contrib/admin/views/doc.py:140 +msgid "view:" +msgstr "" + +#: contrib/admin/views/doc.py:165 +#, python-format +msgid "App %r not found" +msgstr "" + +#: contrib/admin/views/doc.py:172 +#, python-format +msgid "Model %(name)r not found in app %(label)r" +msgstr "" + +#: contrib/admin/views/doc.py:184 +#, python-format +msgid "the related `%(label)s.%(type)s` object" +msgstr "" + +#: contrib/admin/views/doc.py:184 contrib/admin/views/doc.py:206 +#: contrib/admin/views/doc.py:220 contrib/admin/views/doc.py:225 +msgid "model:" +msgstr "" + +#: contrib/admin/views/doc.py:215 +#, python-format +msgid "related `%(label)s.%(name)s` objects" +msgstr "" + +#: contrib/admin/views/doc.py:220 +#, python-format +msgid "all %s" +msgstr "" + +#: contrib/admin/views/doc.py:225 +#, python-format +msgid "number of %s" +msgstr "" + +#: contrib/admin/views/doc.py:230 +#, python-format +msgid "Fields on %s objects" +msgstr "" + +#: contrib/admin/views/doc.py:292 contrib/admin/views/doc.py:303 +#: contrib/admin/views/doc.py:305 contrib/admin/views/doc.py:311 +#: contrib/admin/views/doc.py:312 contrib/admin/views/doc.py:314 +msgid "Integer" +msgstr "" + +#: contrib/admin/views/doc.py:293 +msgid "Boolean (Either True or False)" +msgstr "" + +#: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313 +#, python-format +msgid "String (up to %(max_length)s)" +msgstr "" + +#: contrib/admin/views/doc.py:295 +msgid "Comma-separated integers" +msgstr "" + +#: contrib/admin/views/doc.py:296 +msgid "Date (without time)" +msgstr "" + +#: contrib/admin/views/doc.py:297 +msgid "Date (with time)" +msgstr "" + +#: contrib/admin/views/doc.py:298 +msgid "Decimal number" +msgstr "" + +#: contrib/admin/views/doc.py:299 +msgid "E-mail address" +msgstr "" + +#: contrib/admin/views/doc.py:300 contrib/admin/views/doc.py:301 +#: contrib/admin/views/doc.py:304 +msgid "File path" +msgstr "" + +#: contrib/admin/views/doc.py:302 +msgid "Floating point number" +msgstr "" + +#: contrib/admin/views/doc.py:308 +msgid "Boolean (Either True, False or None)" +msgstr "" + +#: contrib/admin/views/doc.py:309 +msgid "Relation to parent model" +msgstr "" + +#: contrib/admin/views/doc.py:310 +msgid "Phone number" +msgstr "" + +#: contrib/admin/views/doc.py:315 +msgid "Text" +msgstr "" + +#: contrib/admin/views/doc.py:316 +msgid "Time" +msgstr "" + +#: contrib/admin/views/doc.py:317 contrib/flatpages/models.py:7 +msgid "URL" +msgstr "" + +#: contrib/admin/views/doc.py:318 +msgid "U.S. state (two uppercase letters)" +msgstr "" + +#: contrib/admin/views/doc.py:319 +msgid "XML text" +msgstr "" + +#: contrib/admin/views/doc.py:345 +#, python-format +msgid "%s does not appear to be a urlpattern object" +msgstr "" + +#: 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/change_list.html:5 +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/base.html:25 +#: 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 +msgid "Documentation" +msgstr "" + +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/admin/delete_confirmation.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/registration/password_change_done.html:3 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/view_detail.html:4 +#: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_detail.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 +#: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 +#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 +msgid "Change password" +msgstr "" + +#: contrib/admin/templates/admin/change_list.html:6 +#: contrib/admin/templates/admin/object_history.html:5 +#: 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/delete_confirmation.html:6 +#: contrib/admin/templates/admin/base.html:30 +#: 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 +#: contrib/admin/templates/registration/password_reset_done.html:4 +#: contrib/admin/templates/registration/password_change_form.html:4 +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Home" +msgstr "" + +#: contrib/admin/templates/admin/change_list.html:12 +#, python-format +msgid "Add %(name)s" +msgstr "" + +#: contrib/admin/templates/admin/filter.html:2 +#, python-format +msgid " By %(filter_title)s " +msgstr "" + +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/change_form.html:21 +msgid "History" +msgstr "" + +#: contrib/admin/templates/admin/object_history.html:18 +msgid "Date/time" +msgstr "" + +#: contrib/admin/templates/admin/object_history.html:19 +msgid "User" +msgstr "" + +#: contrib/admin/templates/admin/object_history.html:20 +msgid "Action" +msgstr "" + +#: contrib/admin/templates/admin/object_history.html:26 +msgid "DATE_WITH_TIME_FULL" +msgstr "" + +#: 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 "" + +#: 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] "" +msgstr[1] "" + +#: contrib/admin/templates/admin/search_form.html:10 +#, python-format +msgid "%(full_result_count)s total" +msgstr "" + +#: contrib/admin/templates/admin/pagination.html:10 +msgid "Show all" +msgstr "" + +#: contrib/admin/templates/admin/base_site.html:4 +msgid "Django site admin" +msgstr "" + +#: contrib/admin/templates/admin/base_site.html:7 +msgid "Django administration" +msgstr "" + +#: contrib/admin/templates/admin/500.html:4 +msgid "Server error" +msgstr "" + +#: contrib/admin/templates/admin/500.html:6 +msgid "Server error (500)" +msgstr "" + +#: contrib/admin/templates/admin/500.html:9 +msgid "Server Error <em>(500)</em>" +msgstr "" + +#: contrib/admin/templates/admin/500.html:10 +#, fuzzy +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 "i." + +#: contrib/admin/templates/admin/invalid_setup.html:8 +#, fuzzy +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 "i." + +#: contrib/admin/templates/admin/index.html:17 +#, python-format +msgid "Models available in the %(name)s application." +msgstr "" + +#: contrib/admin/templates/admin/index.html:18 +#, python-format +msgid "%(name)s" +msgstr "" + +#: contrib/admin/templates/admin/index.html:28 +#: contrib/admin/templates/admin/change_form.html:15 +msgid "Add" +msgstr "" + +#: contrib/admin/templates/admin/index.html:34 +msgid "Change" +msgstr "" + +#: contrib/admin/templates/admin/index.html:44 +msgid "You don't have permission to edit anything." +msgstr "" + +#: contrib/admin/templates/admin/index.html:52 +msgid "Recent Actions" +msgstr "" + +#: contrib/admin/templates/admin/index.html:53 +msgid "My Actions" +msgstr "" + +#: contrib/admin/templates/admin/index.html:57 +msgid "None available" +msgstr "" + +#: contrib/admin/templates/admin/404.html:4 +#: contrib/admin/templates/admin/404.html:8 +msgid "Page not found" +msgstr "" + +#: contrib/admin/templates/admin/404.html:10 +msgid "We're sorry, but the requested page could not be found." +msgstr "" + +#: contrib/admin/templates/admin/filters.html:4 +msgid "Filter" +msgstr "" + +#: contrib/admin/templates/admin/change_form.html:22 +msgid "View on site" +msgstr "" + +#: 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] "" + +#: 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/delete_confirmation.html:9 +#: contrib/admin/templates/admin/submit_line.html:3 +msgid "Delete" +msgstr "" + +#: contrib/admin/templates/admin/delete_confirmation.html:14 +#, 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 "" + +#: contrib/admin/templates/admin/delete_confirmation.html:21 +#, 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 "" + +#: contrib/admin/templates/admin/delete_confirmation.html:26 +#, fuzzy +msgid "Yes, I'm sure" +msgstr "Da" + +#: contrib/admin/templates/admin/base.html:25 +msgid "Welcome," +msgstr "" + +#: contrib/admin/templates/admin/submit_line.html:4 +msgid "Save as new" +msgstr "" + +#: contrib/admin/templates/admin/submit_line.html:5 +#, fuzzy +msgid "Save and add another" +msgstr "i" + +#: contrib/admin/templates/admin/submit_line.html:6 +#, fuzzy +msgid "Save and continue editing" +msgstr "i" + +#: contrib/admin/templates/admin/submit_line.html:7 +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 "" + +#: 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 +#, fuzzy +msgid "" +"First, enter a username and password. Then, you'll be able to edit more user " +"options." +msgstr "i." + +#: 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 +#: contrib/admin/templates/registration/password_change_form.html:10 +msgid "Password change" +msgstr "" + +#: contrib/admin/templates/registration/password_change_done.html:6 +#: contrib/admin/templates/registration/password_change_done.html:10 +msgid "Password change successful" +msgstr "" + +#: contrib/admin/templates/registration/password_change_done.html:12 +msgid "Your password was changed." +msgstr "" + +#: 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 "" + +#: contrib/admin/templates/registration/password_reset_form.html:12 +#, fuzzy +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 "i i." + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "E-mail address:" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "Reset my password" +msgstr "" + +#: contrib/admin/templates/registration/logged_out.html:8 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" + +#: contrib/admin/templates/registration/logged_out.html:10 +msgid "Log in again" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_done.html:6 +#: contrib/admin/templates/registration/password_reset_done.html:10 +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 "" + +#: contrib/admin/templates/registration/password_change_form.html:12 +#, fuzzy +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 "i." + +#: contrib/admin/templates/registration/password_change_form.html:17 +msgid "Old password:" +msgstr "" + +#: contrib/admin/templates/registration/password_change_form.html:19 +msgid "New password:" +msgstr "" + +#: contrib/admin/templates/registration/password_change_form.html:21 +msgid "Confirm password:" +msgstr "" + +#: contrib/admin/templates/registration/password_change_form.html:23 +msgid "Change my password" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:2 +msgid "You're receiving this e-mail because you requested a password reset" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:3 +#, python-format +msgid "for your user account at %(site_name)s" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:5 +#, python-format +msgid "Your new password is: %(new_password)s" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:7 +msgid "Feel free to change this password by going to this page:" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:11 +msgid "Your username, in case you've forgotten:" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:13 +msgid "Thanks for using our site!" +msgstr "" + +#: contrib/admin/templates/registration/password_reset_email.html:15 +#, python-format +msgid "The %(site_name)s team" +msgstr "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Bookmarklets" +msgstr "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:5 +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" +"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\"> i</p>" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:19 +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 "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:22 +msgid "Show object ID" +msgstr "" + +#: 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." + +#: contrib/admin/templates/admin_doc/bookmarklets.html:25 +msgid "Edit this object (current window)" +msgstr "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:26 +msgid "Jumps to the admin page for pages that represent a single object." +msgstr "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:28 +msgid "Edit this object (new window)" +msgstr "" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:29 +msgid "As above, but opens the admin page in a new window." +msgstr "" + +#: contrib/contenttypes/models.py:37 +msgid "python model class name" +msgstr "" + +#: contrib/contenttypes/models.py:40 +msgid "content type" +msgstr "" + +#: contrib/contenttypes/models.py:41 +msgid "content types" +msgstr "" + +#: contrib/auth/views.py:41 +msgid "Logged out" +msgstr "" + +#: contrib/auth/models.py:53 contrib/auth/models.py:73 +msgid "name" +msgstr "" + +#: contrib/auth/models.py:55 +msgid "codename" +msgstr "" + +#: contrib/auth/models.py:58 +msgid "permission" +msgstr "" + +#: contrib/auth/models.py:59 contrib/auth/models.py:74 +msgid "permissions" +msgstr "" + +#: contrib/auth/models.py:77 +msgid "group" +msgstr "" + +#: contrib/auth/models.py:78 contrib/auth/models.py:121 +msgid "groups" +msgstr "" + +#: contrib/auth/models.py:111 +msgid "username" +msgstr "" + +#: contrib/auth/models.py:111 +#, fuzzy +msgid "" +"Required. 30 characters or fewer. Alphanumeric characters only (letters, " +"digits and underscores)." +msgstr "i." + +#: contrib/auth/models.py:112 +msgid "first name" +msgstr "" + +#: contrib/auth/models.py:113 +msgid "last name" +msgstr "" + +#: contrib/auth/models.py:114 +msgid "e-mail address" +msgstr "" + +#: contrib/auth/models.py:115 +msgid "password" +msgstr "" + +#: contrib/auth/models.py:115 +msgid "" +"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " +"password form</a>." +msgstr "" + +#: contrib/auth/models.py:116 +msgid "staff status" +msgstr "" + +#: contrib/auth/models.py:116 +msgid "Designates whether the user can log into this admin site." +msgstr "" + +#: contrib/auth/models.py:117 +msgid "active" +msgstr "" + +#: contrib/auth/models.py:117 +msgid "" +"Designates whether this user can log into the Django admin. Unselect this " +"instead of deleting accounts." +msgstr "" + +#: contrib/auth/models.py:118 +msgid "superuser status" +msgstr "" + +#: contrib/auth/models.py:118 +msgid "" +"Designates that this user has all permissions without explicitly assigning " +"them." +msgstr "" + +#: contrib/auth/models.py:119 +msgid "last login" +msgstr "" + +#: contrib/auth/models.py:120 +msgid "date joined" +msgstr "" + +#: contrib/auth/models.py:122 +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:123 +msgid "user permissions" +msgstr "" + +#: contrib/auth/models.py:127 +msgid "user" +msgstr "" + +#: contrib/auth/models.py:128 +msgid "users" +msgstr "" + +#: contrib/auth/models.py:134 +msgid "Personal info" +msgstr "" + +#: contrib/auth/models.py:135 +msgid "Permissions" +msgstr "" + +#: contrib/auth/models.py:136 +msgid "Important dates" +msgstr "" + +#: contrib/auth/models.py:137 +msgid "Groups" +msgstr "" + +#: contrib/auth/models.py:287 +msgid "message" +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 "" + +#: contrib/auth/forms.py:62 +msgid "This account is inactive." +msgstr "" + +#: contrib/auth/forms.py:84 +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/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 "" + +#: contrib/localflavor/br/forms.py:30 +msgid "Phone numbers must be in XX-XXXX-XXXX format." +msgstr "" + +#: 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 "" + +#: contrib/localflavor/br/forms.py:84 +msgid "Invalid CPF number." +msgstr "" + +#: contrib/localflavor/br/forms.py:106 +msgid "This field requires at least 14 digits" +msgstr "" + +#: contrib/localflavor/br/forms.py:116 +msgid "Invalid CNPJ number." +msgstr "" + +#: contrib/localflavor/au/forms.py:18 +msgid "Enter a 4 digit post code." +msgstr "" + +#: 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 "" + +#: 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 +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 "" + +#: 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 "" + +#: 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/ch/forms.py:18 contrib/localflavor/no/forms.py:14 +msgid "Enter a zip code in the format XXXX." +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/localflavor/is_/forms.py:17 +msgid "Enter a valid Icelandic identification number. The format is XXXXXX-XXXX." +msgstr "" + +#: contrib/localflavor/is_/forms.py:31 +msgid "The Icelandic identification number is not valid." +msgstr "" + +#: contrib/localflavor/it/forms.py:16 +msgid "Enter a valid zip code." +msgstr "" + +#: contrib/localflavor/it/forms.py:41 +msgid "Enter a valid Social Security number." +msgstr "" + +#: contrib/localflavor/it/forms.py:68 +msgid "Enter a valid VAT number." +msgstr "" + +#: contrib/localflavor/no/forms.py:35 +msgid "Enter a valid Norwegian social security number." +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:8 +msgid "Banska Bystrica region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:9 +msgid "Bratislava region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:10 +msgid "Kosice region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:11 +msgid "Nitra region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:12 +msgid "Presov region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:13 +msgid "Trencin region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:14 +msgid "Trnava region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:15 +msgid "Zilina region" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:8 +msgid "Banska Bystrica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:9 +msgid "Banska Stiavnica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:10 +msgid "Bardejov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:11 +msgid "Banovce nad Bebravou" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:12 +msgid "Brezno" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:13 +msgid "Bratislava I" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:14 +msgid "Bratislava II" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:15 +msgid "Bratislava III" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:16 +msgid "Bratislava IV" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:17 +msgid "Bratislava V" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:18 +msgid "Bytca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:19 +msgid "Cadca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:20 +msgid "Detva" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:21 +msgid "Dolny Kubin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:22 +msgid "Dunajska Streda" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:23 +msgid "Galanta" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:24 +msgid "Gelnica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:25 +msgid "Hlohovec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:26 +msgid "Humenne" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:27 +msgid "Ilava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:28 +msgid "Kezmarok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:29 +msgid "Komarno" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:30 +msgid "Kosice I" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:31 +msgid "Kosice II" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:32 +msgid "Kosice III" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:33 +msgid "Kosice IV" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:34 +msgid "Kosice - okolie" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:35 +msgid "Krupina" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:36 +msgid "Kysucke Nove Mesto" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:37 +msgid "Levice" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:38 +msgid "Levoca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:39 +msgid "Liptovsky Mikulas" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:40 +msgid "Lucenec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:41 +msgid "Malacky" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:42 +msgid "Martin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:43 +msgid "Medzilaborce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:44 +msgid "Michalovce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:45 +msgid "Myjava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:46 +msgid "Namestovo" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:47 +msgid "Nitra" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:48 +msgid "Nove Mesto nad Vahom" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:49 +msgid "Nove Zamky" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:50 +msgid "Partizanske" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:51 +msgid "Pezinok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:52 +msgid "Piestany" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:53 +msgid "Poltar" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:54 +msgid "Poprad" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:55 +msgid "Povazska Bystrica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:56 +msgid "Presov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:57 +msgid "Prievidza" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:58 +msgid "Puchov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:59 +msgid "Revuca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:60 +msgid "Rimavska Sobota" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:61 +msgid "Roznava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:62 +msgid "Ruzomberok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:63 +msgid "Sabinov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:64 +msgid "Senec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:65 +msgid "Senica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:66 +msgid "Skalica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:67 +msgid "Snina" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:68 +msgid "Sobrance" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:69 +msgid "Spisska Nova Ves" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:70 +msgid "Stara Lubovna" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:71 +msgid "Stropkov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:72 +msgid "Svidnik" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:73 +msgid "Sala" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:74 +msgid "Topolcany" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:75 +msgid "Trebisov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:76 +msgid "Trencin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:77 +msgid "Trnava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:78 +msgid "Turcianske Teplice" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:79 +msgid "Tvrdosin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:80 +msgid "Velky Krtis" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:81 +msgid "Vranov nad Toplou" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:82 +msgid "Zlate Moravce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:83 +msgid "Zvolen" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:84 +msgid "Zarnovica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:85 +msgid "Ziar nad Hronom" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:86 +msgid "Zilina" +msgstr "" + +#: contrib/localflavor/sk/forms.py:32 +msgid "Enter a postal code in the format XXXXX or XXX XX." +msgstr "" + +#: contrib/localflavor/cl/forms.py:32 +msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X." +msgstr "" + +#: contrib/localflavor/cl/forms.py:37 +msgid "Enter valid a Chilean RUT" +msgstr "" + +#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45 +msgid "Enter a valid Finnish social security number." +msgstr "" + +#: contrib/sessions/models.py:68 +msgid "session key" +msgstr "" + +#: contrib/sessions/models.py:69 +msgid "session data" +msgstr "" + +#: contrib/sessions/models.py:70 +msgid "expire date" +msgstr "" + +#: contrib/sessions/models.py:74 +msgid "session" +msgstr "" + +#: contrib/sessions/models.py:75 +msgid "sessions" +msgstr "" + +#: contrib/flatpages/models.py:8 +#, fuzzy +msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes." +msgstr "i." + +#: 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.html'. If this isn't provided, the system " +"will use 'flatpages/default.html'." +msgstr "" + +#: 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" +msgstr "" + +#: utils/dates.py:6 +msgid "Tuesday" +msgstr "" + +#: utils/dates.py:6 +msgid "Wednesday" +msgstr "" + +#: utils/dates.py:6 +msgid "Thursday" +msgstr "" + +#: utils/dates.py:6 +msgid "Friday" +msgstr "" + +#: utils/dates.py:7 +msgid "Saturday" +msgstr "" + +#: utils/dates.py:7 +msgid "Sunday" +msgstr "" + +#: utils/dates.py:10 +msgid "Mon" +msgstr "" + +#: utils/dates.py:10 +msgid "Tue" +msgstr "" + +#: utils/dates.py:10 +msgid "Wed" +msgstr "" + +#: utils/dates.py:10 +msgid "Thu" +msgstr "" + +#: utils/dates.py:10 +msgid "Fri" +msgstr "" + +#: utils/dates.py:11 +msgid "Sat" +msgstr "" + +#: utils/dates.py:11 +msgid "Sun" +msgstr "" + +#: utils/dates.py:18 +msgid "January" +msgstr "" + +#: utils/dates.py:18 +msgid "February" +msgstr "" + +#: utils/dates.py:18 utils/dates.py:31 +msgid "March" +msgstr "" + +#: utils/dates.py:18 utils/dates.py:31 +msgid "April" +msgstr "" + +#: utils/dates.py:18 utils/dates.py:31 +msgid "May" +msgstr "" + +#: utils/dates.py:18 utils/dates.py:31 +msgid "June" +msgstr "" + +#: utils/dates.py:19 utils/dates.py:31 +msgid "July" +msgstr "" + +#: utils/dates.py:19 +msgid "August" +msgstr "" + +#: utils/dates.py:19 +msgid "September" +msgstr "" + +#: utils/dates.py:19 +msgid "October" +msgstr "" + +#: utils/dates.py:19 +msgid "November" +msgstr "" + +#: utils/dates.py:20 +msgid "December" +msgstr "" + +#: utils/dates.py:23 +msgid "jan" +msgstr "" + +#: utils/dates.py:23 +msgid "feb" +msgstr "" + +#: utils/dates.py:23 +msgid "mar" +msgstr "" + +#: utils/dates.py:23 +msgid "apr" +msgstr "" + +#: utils/dates.py:23 +msgid "may" +msgstr "" + +#: utils/dates.py:23 +msgid "jun" +msgstr "" + +#: utils/dates.py:24 +msgid "jul" +msgstr "" + +#: utils/dates.py:24 +msgid "aug" +msgstr "" + +#: utils/dates.py:24 +msgid "sep" +msgstr "" + +#: utils/dates.py:24 +msgid "oct" +msgstr "" + +#: utils/dates.py:24 +msgid "nov" +msgstr "" + +#: utils/dates.py:24 +msgid "dec" +msgstr "" + +#: utils/dates.py:31 +msgid "Jan." +msgstr "" + +#: utils/dates.py:31 +msgid "Feb." +msgstr "" + +#: utils/dates.py:32 +msgid "Aug." +msgstr "" + +#: utils/dates.py:32 +msgid "Sept." +msgstr "" + +#: utils/dates.py:32 +msgid "Oct." +msgstr "" + +#: utils/dates.py:32 +msgid "Nov." +msgstr "" + +#: utils/dates.py:32 +msgid "Dec." +msgstr "" + +#: utils/timesince.py:12 +msgid "year" +msgid_plural "years" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:13 +msgid "month" +msgid_plural "months" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:14 +msgid "week" +msgid_plural "weeks" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:15 +msgid "day" +msgid_plural "days" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:16 +msgid "hour" +msgid_plural "hours" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:17 +msgid "minute" +msgid_plural "minutes" +msgstr[0] "" +msgstr[1] "" + +#: utils/timesince.py:39 +#, python-format +msgid "%(number)d %(type)s" +msgstr "" + +#: utils/timesince.py:45 +#, python-format +msgid ", %(number)d %(type)s" +msgstr "" + +#: utils/dateformat.py:41 +msgid "p.m." +msgstr "" + +#: utils/dateformat.py:42 +msgid "a.m." +msgstr "" + +#: utils/dateformat.py:47 +msgid "PM" +msgstr "" + +#: utils/dateformat.py:48 +msgid "AM" +msgstr "" + +#: utils/dateformat.py:97 +msgid "midnight" +msgstr "" + +#: utils/dateformat.py:99 +msgid "noon" +msgstr "" + +#: utils/translation/trans_real.py:391 +msgid "DATE_FORMAT" +msgstr "" + +#: utils/translation/trans_real.py:392 +msgid "DATETIME_FORMAT" +msgstr "" + +#: utils/translation/trans_real.py:393 +msgid "TIME_FORMAT" +msgstr "" + +#: utils/translation/trans_real.py:409 +msgid "YEAR_MONTH_FORMAT" +msgstr "" + +#: utils/translation/trans_real.py:410 +msgid "MONTH_DAY_FORMAT" +msgstr "" + +#: template/defaultfilters.py:485 +msgid "yes,no,maybe" +msgstr "" + +#: template/defaultfilters.py:514 +#, python-format +msgid "%(size)d byte" +msgid_plural "%(size)d bytes" +msgstr[0] "" +msgstr[1] "" + +#: template/defaultfilters.py:516 +#, python-format +msgid "%.1f KB" +msgstr "" + +#: template/defaultfilters.py:518 +#, python-format +msgid "%.1f MB" +msgstr "" + +#: template/defaultfilters.py:519 +#, python-format +msgid "%.1f GB" +msgstr "" + diff --git a/django/conf/locale/hr/LC_MESSAGES/djangojs.mo b/django/conf/locale/hr/LC_MESSAGES/djangojs.mo Binary files differnew file mode 100644 index 0000000000..823d8dbf10 --- /dev/null +++ b/django/conf/locale/hr/LC_MESSAGES/djangojs.mo diff --git a/django/conf/locale/hr/LC_MESSAGES/djangojs.po b/django/conf/locale/hr/LC_MESSAGES/djangojs.po new file mode 100644 index 0000000000..7fd1654913 --- /dev/null +++ b/django/conf/locale/hr/LC_MESSAGES/djangojs.po @@ -0,0 +1,118 @@ +# SOME DESCRIPTIVE TITLE. +# 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. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-08-13 11:13+1000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: contrib/admin/media/js/SelectFilter2.js:33 +#, perl-format +msgid "Available %s" +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:41 +msgid "Choose all" +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:46 +msgid "Add" +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:48 +msgid "Remove" +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:53 +#, perl-format +msgid "Chosen %s" +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:54 +msgid "Select your choice(s) and click " +msgstr "" + +#: contrib/admin/media/js/SelectFilter2.js:59 +msgid "Clear all" +msgstr "" + +#: contrib/admin/media/js/dateparse.js:32 +#: contrib/admin/media/js/calendar.js:24 +msgid "" +"January February March April May June July August September October November " +"December" +msgstr "" + +#: contrib/admin/media/js/dateparse.js:33 +msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" +msgstr "" + +#: contrib/admin/media/js/calendar.js:25 +msgid "S M T W T F S" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47 +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81 +msgid "Now" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51 +msgid "Clock" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78 +msgid "Choose a time" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82 +msgid "Midnight" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83 +msgid "6 a.m." +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84 +msgid "Noon" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88 +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183 +msgid "Cancel" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128 +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177 +msgid "Today" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132 +msgid "Calendar" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175 +msgid "Yesterday" +msgstr "" + +#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179 +msgid "Tomorrow" +msgstr "" + +#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34 +#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72 +msgid "Show" +msgstr "" + +#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63 +msgid "Hide" +msgstr "" diff --git a/django/conf/locale/it/LC_MESSAGES/django.mo b/django/conf/locale/it/LC_MESSAGES/django.mo Binary files differindex e0d5e0442d..42f69d30bf 100644 --- a/django/conf/locale/it/LC_MESSAGES/django.mo +++ b/django/conf/locale/it/LC_MESSAGES/django.mo diff --git a/django/conf/locale/it/LC_MESSAGES/django.po b/django/conf/locale/it/LC_MESSAGES/django.po index 2c9060a076..96ca9650d6 100644 --- a/django/conf/locale/it/LC_MESSAGES/django.po +++ b/django/conf/locale/it/LC_MESSAGES/django.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-04-11 17:39+0200\n" -"PO-Revision-Date: 2007-03-14 19:29+0100\n" -"Last-Translator: Flavio Curella <flavio.curella@gmail.com>\n" +"POT-Creation-Date: 2007-08-11 19:17+0200\n" +"PO-Revision-Date: 2007-08-11 19:39+0100\n" +"Last-Translator: Nicola Larosa <nico@tekNico.net>\n" "Language-Team: Italiano\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,13 +17,97 @@ msgstr "" "X-Generator: KBabel 1.11.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: conf/global_settings.py:39 +#: db/models/manipulators.py:309 +#, python-format +msgid "%(object)s with this %(type)s already exists for the given %(field)s." +msgstr "Un %(object)s·con questo·%(type)s·esiste già per questo·%(field)s." + +#: db/models/manipulators.py:310 contrib/admin/views/main.py:342 +#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346 +msgid "and" +msgstr "e" + +#: db/models/fields/related.py:55 +#, python-format +msgid "Please enter a valid %s." +msgstr "Inserire un %s valido." + +#: db/models/fields/related.py:661 +msgid "Separate multiple IDs with commas." +msgstr "Separare gli ID multipli con virgole." + +#: db/models/fields/related.py:663 +msgid "" +"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +msgstr "" +"Tenere premuto \"Control\", o \"Command\" su Mac, per selezionarne più di " +"uno." + +#: db/models/fields/related.py:710 +#, 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] "" +"Inserire un ID valido per %(self)s. Il valore %(value)r non è valido." +msgstr[1] "" +"Inserire ID validi per %(self)s. I valori %(value)r non sono validi." + +#: db/models/fields/__init__.py:49 +#, python-format +msgid "%(optname)s with this %(fieldname)s already exists." +msgstr "Un %(optname)s·con questo·%(fieldname)s·esiste già." + +#: db/models/fields/__init__.py:156 db/models/fields/__init__.py:313 +#: db/models/fields/__init__.py:721 db/models/fields/__init__.py:732 +#: oldforms/__init__.py:373 newforms/fields.py:92 newforms/fields.py:490 +#: newforms/fields.py:566 newforms/fields.py:577 newforms/models.py:193 +msgid "This field is required." +msgstr "Questo campo è obbligatorio." + +#: db/models/fields/__init__.py:411 +msgid "This value must be an integer." +msgstr "Questo valore deve essere un intero." + +#: db/models/fields/__init__.py:446 +msgid "This value must be either True or False." +msgstr "Questo valore deve essere True o False." + +#: db/models/fields/__init__.py:467 +msgid "This field cannot be null." +msgstr "Questo campo non può essere nullo." + +#: db/models/fields/__init__.py:501 core/validators.py:155 +msgid "Enter a valid date in YYYY-MM-DD format." +msgstr "Inserire una data valida in formato AAAA-MM-GG." + +#: db/models/fields/__init__.py:570 core/validators.py:164 +msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." +msgstr "Inserire una data/ora valida in formato AAAA-MM-GG OO:MM." + +#: db/models/fields/__init__.py:631 +msgid "This value must be a decimal number." +msgstr "Questo valore deve essere un numero decimale." + +#: db/models/fields/__init__.py:741 +msgid "Enter a valid filename." +msgstr "Inserire un nome di file valido." + +#: db/models/fields/__init__.py:883 +msgid "This value must be either None, True or False." +msgstr "Questo valore deve essere None, True o False." + +#: conf/global_settings.py:38 msgid "Arabic" msgstr "Arabo" -#: conf/global_settings.py:40 +#: conf/global_settings.py:39 msgid "Bengali" -msgstr "Bengali" +msgstr "" + +#: conf/global_settings.py:40 +msgid "Bulgarian" +msgstr "Bulgaro" #: conf/global_settings.py:41 msgid "Catalan" @@ -62,313 +146,1105 @@ msgid "Argentinean Spanish" msgstr "Spagnolo argentino" #: conf/global_settings.py:50 +msgid "Persian" +msgstr "Persiano" + +#: conf/global_settings.py:51 msgid "Finnish" msgstr "Finlandese" -#: conf/global_settings.py:51 +#: conf/global_settings.py:52 msgid "French" msgstr "Francese" -#: conf/global_settings.py:52 +#: conf/global_settings.py:53 msgid "Galician" msgstr "Galiziano" -#: conf/global_settings.py:53 +#: conf/global_settings.py:54 msgid "Hungarian" msgstr "Ungherese" -#: conf/global_settings.py:54 +#: conf/global_settings.py:55 msgid "Hebrew" msgstr "Ebraico" -#: conf/global_settings.py:55 +#: conf/global_settings.py:56 msgid "Icelandic" msgstr "Islandese" -#: 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 "Giapponese" -#: conf/global_settings.py:58 -#, fuzzy +#: conf/global_settings.py:59 msgid "Korean" -msgstr "Norvegese" +msgstr "Coreano" -#: conf/global_settings.py:59 +#: conf/global_settings.py:60 msgid "Kannada" -msgstr "Kannada" +msgstr "" -#: conf/global_settings.py:60 +#: conf/global_settings.py:61 msgid "Latvian" msgstr "Lettone" -#: conf/global_settings.py:61 +#: conf/global_settings.py:62 msgid "Macedonian" msgstr "Macedone" -#: conf/global_settings.py:62 +#: conf/global_settings.py:63 msgid "Dutch" msgstr "Olandese" -#: conf/global_settings.py:63 +#: conf/global_settings.py:64 msgid "Norwegian" msgstr "Norvegese" -#: conf/global_settings.py:64 +#: conf/global_settings.py:65 msgid "Polish" msgstr "Polacco" -#: conf/global_settings.py:65 +#: conf/global_settings.py:66 msgid "Portugese" msgstr "Portoghese" -#: conf/global_settings.py:66 +#: conf/global_settings.py:67 msgid "Brazilian" msgstr "Brasiliano" -#: conf/global_settings.py:67 +#: conf/global_settings.py:68 msgid "Romanian" msgstr "Rumeno" -#: conf/global_settings.py:68 +#: conf/global_settings.py:69 msgid "Russian" msgstr "Russo" -#: conf/global_settings.py:69 +#: conf/global_settings.py:70 msgid "Slovak" msgstr "Slovacco" -#: conf/global_settings.py:70 +#: conf/global_settings.py:71 msgid "Slovenian" msgstr "Sloveno" -#: conf/global_settings.py:71 +#: conf/global_settings.py:72 msgid "Serbian" msgstr "Serbo" -#: conf/global_settings.py:72 +#: conf/global_settings.py:73 msgid "Swedish" msgstr "Svedese" -#: conf/global_settings.py:73 +#: conf/global_settings.py:74 msgid "Tamil" -msgstr "Tamil" +msgstr "" -#: conf/global_settings.py:74 +#: conf/global_settings.py:75 msgid "Telugu" msgstr "" -#: conf/global_settings.py:75 +#: conf/global_settings.py:76 msgid "Turkish" msgstr "Turco" -#: conf/global_settings.py:76 +#: conf/global_settings.py:77 msgid "Ukrainian" msgstr "Ucraino" -#: conf/global_settings.py:77 +#: conf/global_settings.py:78 msgid "Simplified Chinese" msgstr "Cinese semplificato" -#: conf/global_settings.py:78 +#: conf/global_settings.py:79 msgid "Traditional Chinese" msgstr "Cinese tradizionale" -#: contrib/admin/filterspecs.py:40 +#: core/validators.py:71 +msgid "This value must contain only letters, numbers and underscores." +msgstr "Questo valore può contenere solo lettere, cifre e sottolineati." + +#: core/validators.py:75 +msgid "" +"This value must contain only letters, numbers, underscores, dashes or " +"slashes." +msgstr "" +"Questo valore può contenere solo lettere, cifre, sottolineati, trattini e " +"barre diagonali." + +#: core/validators.py:79 +msgid "This value must contain only letters, numbers, underscores or hyphens." +msgstr "" +"Questo valore può contenere solo lettere, cifre, sottolineati e trattini." + +#: core/validators.py:83 +msgid "Uppercase letters are not allowed here." +msgstr "Non sono ammesse lettere maiuscole." + +#: core/validators.py:87 +msgid "Lowercase letters are not allowed here." +msgstr "Non sono ammesse lettere minuscole." + +#: core/validators.py:94 +msgid "Enter only digits separated by commas." +msgstr "Inserire solo cifre separate da virgole." + +#: core/validators.py:106 +msgid "Enter valid e-mail addresses separated by commas." +msgstr "Inserire indirizzi e-mail validi separati da virgole." + +#: core/validators.py:110 +msgid "Please enter a valid IP address." +msgstr "Inserire un indirizzo IP valido." + +#: core/validators.py:114 +msgid "Empty values are not allowed here." +msgstr "È necessario inserire un valore." + +#: core/validators.py:118 +msgid "Non-numeric characters aren't allowed here." +msgstr "Sono ammessi soltanto caratteri numerici." + +#: core/validators.py:122 +msgid "This value can't be comprised solely of digits." +msgstr "Questo valore non può essere composto solo da cifre." + +#: core/validators.py:127 newforms/fields.py:142 +msgid "Enter a whole number." +msgstr "Inserire un numero intero." + +#: core/validators.py:131 +msgid "Only alphabetical characters are allowed here." +msgstr "Sono ammessi solo caratteri alfabetici." + +#: core/validators.py:146 +msgid "Year must be 1900 or later." +msgstr "L'anno deve essere 1900 o successivo." + +#: core/validators.py:150 +#, python-format +msgid "Invalid date: %s" +msgstr "Data non valida: %s" + +#: core/validators.py:160 +msgid "Enter a valid time in HH:MM format." +msgstr "Inserire un ora valida in formato OO:MM." + +#: core/validators.py:169 newforms/fields.py:336 +msgid "Enter a valid e-mail address." +msgstr "Inserire un indirizzo e-mail valido." + +#: core/validators.py:181 core/validators.py:461 oldforms/__init__.py:686 +#: newforms/fields.py:376 +msgid "No file was submitted. Check the encoding type on the form." +msgstr "" +"Non è stato inviato alcun file. Verificare il tipo di codifica della form." + +#: core/validators.py:185 newforms/fields.py:397 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" +"Caricare un'immagine valida. Il file caricato non è un'immagine o è corrotto." + +#: core/validators.py:192 +#, python-format +msgid "The URL %s does not point to a valid image." +msgstr "La URL %s non punta ad un'immagine valida." + +#: core/validators.py:196 +#, python-format +msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." +msgstr "" +"I numeri di telefono devono essere in formato XXX-XXX-XXXX . \"%s\" non è " +"valido." + +#: core/validators.py:204 +#, python-format +msgid "The URL %s does not point to a valid QuickTime video." +msgstr "La URL %s non punta ad un video QuickTime valido." + +#: core/validators.py:208 +msgid "A valid URL is required." +msgstr "Inserire una URL valida." + +#: core/validators.py:222 +#, python-format +msgid "" +"Valid HTML is required. Specific errors are:\n" +"%s" +msgstr "" +"È richiesto HTML valido. Gli errori sono i seguenti:\n" +"%s" + +#: core/validators.py:229 +#, python-format +msgid "Badly formed XML: %s" +msgstr "XML malformato: %s" + +#: core/validators.py:246 +#, python-format +msgid "Invalid URL: %s" +msgstr "URL non valida: %s" + +#: core/validators.py:251 core/validators.py:253 +#, python-format +msgid "The URL %s is a broken link." +msgstr "La URL %s è un link non funzionante." + +#: core/validators.py:259 +msgid "Enter a valid U.S. state abbreviation." +msgstr "Inserire un valido nome di stato USA abbreviato." + +#: 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] "Moderare i termini: la parola %s non è ammessa." +msgstr[1] "Moderare i termini: le parole %s non sono ammesse." + +#: core/validators.py:280 +#, python-format +msgid "This field must match the '%s' field." +msgstr "Questo campo deve corrispondere al campo '%s'." + +#: core/validators.py:299 +msgid "Please enter something for at least one field." +msgstr "Inserire qualcosa in almeno un campo." + +#: core/validators.py:308 core/validators.py:319 +msgid "Please enter both fields or leave them both empty." +msgstr "Inserire entrambi i campi o lasciarli entrambi vuoti." + +#: core/validators.py:327 +#, python-format +msgid "This field must be given if %(field)s is %(value)s" +msgstr "Questo campo è obbligatorio se %(field)s è %(value)s" + +#: core/validators.py:340 +#, python-format +msgid "This field must be given if %(field)s is not %(value)s" +msgstr "Questo campo è obbligatorio se %(field)s non è %(value)s" + +#: core/validators.py:359 +msgid "Duplicate values are not allowed." +msgstr "Non sono ammessi valori duplicati." + +#: core/validators.py:374 +#, fuzzy, python-format +msgid "This value must be between %(lower)s and %(upper)s." +msgstr "Questo valore deve essere compreso tra %s e %s." + +#: core/validators.py:376 +#, python-format +msgid "This value must be at least %s." +msgstr "Questo valore deve essere almeno pari a %s." + +#: core/validators.py:378 +#, python-format +msgid "This value must be no more than %s." +msgstr "Questo valore non deve essere maggiore di %s." + +#: core/validators.py:414 +#, python-format +msgid "This value must be a power of %s." +msgstr "Questo valore deve essere una potenza di %s." + +#: core/validators.py:424 +msgid "Please enter a valid decimal number." +msgstr "Inserire un numero decimale valido." + +#: core/validators.py:431 +#, 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] "Inserire un numero decimale con non più di %s cifra in totale." +msgstr[1] "Inserire un numero decimale con non più di %s cifre in totale." + +#: core/validators.py:434 +#, 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] "" +"Inserire un numero decimale la cui parte intera sia composta da non più di " +"%s cifra." +msgstr[1] "" +"Inserire un numero decimale la cui parte intera sia composta da non più di " +"%s cifre." + +#: core/validators.py:437 +#, 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] "Inserire un decimale con non più di %s cifra decimale." +msgstr[1] "Inserire un decimale con non più di %s cifre decimali." + +#: core/validators.py:445 +msgid "Please enter a valid floating point number." +msgstr "Inserire un numero decimale valido." + +#: core/validators.py:454 +#, python-format +msgid "Make sure your uploaded file is at least %s bytes big." +msgstr "Verificare che il file caricato sia grande almeno %s byte." + +#: core/validators.py:455 +#, python-format +msgid "Make sure your uploaded file is at most %s bytes big." +msgstr "Verificare che il file caricato non sia più grande di %s byte." + +#: core/validators.py:472 +msgid "The format for this field is wrong." +msgstr "Il formato di questo campo non è valido." + +#: core/validators.py:487 +msgid "This field is invalid." +msgstr "Questo campo non è valido." + +#: core/validators.py:523 +#, python-format +msgid "Could not retrieve anything from %s." +msgstr "Impossibile recuperare alcunché da %s." + +#: core/validators.py:526 +#, python-format +msgid "" +"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." +msgstr "" +"La URL %(url)s ha restituito un header Content-Type non valido: " +"'%(contenttype)s'." + +#: core/validators.py:559 +#, python-format +msgid "" +"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " +"\"%(start)s\".)" +msgstr "" +"Chiudere il tag %(tag)s a linea %(line)s. (La linea inizia con \"%(start)s" +"\".)" + +#: core/validators.py:563 +#, python-format +msgid "" +"Some text starting on line %(line)s is not allowed in that context. (Line " +"starts with \"%(start)s\".)" +msgstr "" +"Il testo che comincia a linea %(line)s non e' ammesso in quel contesto. " +"(La linea comincia con \"%(start)s\".)" + +#: core/validators.py:568 +#, python-format +msgid "" +"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" +"(start)s\".)" +msgstr "" +"\"%(attr)s\" a linea %(line)s non è un attributo valido. (La linea comincia " +"con \"%(start)s\".)" + +#: core/validators.py:573 +#, python-format +msgid "" +"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" +"(start)s\".)" +msgstr "" +"\"<%(tag)s>\" a linea %(line)s non è un tag valido. (La linea comincia con " +"\"%(start)s\".)" + +#: core/validators.py:577 +#, python-format +msgid "" +"A tag on line %(line)s is missing one or more required attributes. (Line " +"starts with \"%(start)s\".)" +msgstr "" +"Un tag a linea %(line)s manca di uno o più attributi richiesti. (La linea " +"comincia con \"%(start)s\".)" + +#: core/validators.py:582 +#, python-format +msgid "" +"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " +"starts with \"%(start)s\".)" +msgstr "" +"L'attributo \"%(attr)s\" a linea %(line)s ha un valore non valido. (La linea " +"comincia con \"%(start)s\".)" + +#: contrib/auth/forms.py:17 contrib/auth/forms.py:138 +msgid "The two password fields didn't match." +msgstr "I due campi password non corrispondono." + +#: contrib/auth/forms.py:25 +msgid "A user with that username already exists." +msgstr "Un utente con questo nome·è già presente." + +#: contrib/auth/forms.py:53 +msgid "" +"Your Web browser doesn't appear to have cookies enabled. Cookies are " +"required for logging in." +msgstr "" +"Il browser web sembra non avere i cookie abilitati. I cookie sono necessari " +"per poter accedere." + +#: 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 "" +"Inserire nome utente e password corretti. Entrambi i campi sono case " +"sensitive." + +#: contrib/auth/forms.py:62 +msgid "This account is inactive." +msgstr "Questo account non è attivo." + +#: contrib/auth/forms.py:84 +msgid "" +"That e-mail address doesn't have an associated user account. Are you sure " +"you've registered?" +msgstr "" +"Questo indirizzo email non è associato ad alcun account utente. Sei sicuro " +"di esserti registrato?" + +#: contrib/auth/forms.py:117 +msgid "The two 'new password' fields didn't match." +msgstr "I due campi 'nuova password' non corrispondono." + +#: contrib/auth/forms.py:124 +msgid "Your old password was entered incorrectly. Please enter it again." +msgstr "" +"La vecchia password non è stata inserita correttamente: va inserita di nuovo." + +#: contrib/auth/models.py:53 contrib/auth/models.py:73 +msgid "name" +msgstr "nome" + +#: contrib/auth/models.py:55 +msgid "codename" +msgstr "nome in codice" + +#: contrib/auth/models.py:58 +msgid "permission" +msgstr "permesso" + +#: contrib/auth/models.py:59 contrib/auth/models.py:74 +msgid "permissions" +msgstr "permessi" + +#: contrib/auth/models.py:77 +msgid "group" +msgstr "gruppo" + +#: contrib/auth/models.py:78 contrib/auth/models.py:121 +msgid "groups" +msgstr "gruppi" + +#: contrib/auth/models.py:111 +msgid "username" +msgstr "nome utente" + +#: contrib/auth/models.py:111 +msgid "" +"Required. 30 characters or fewer. Alphanumeric characters only (letters, " +"digits and underscores)." +msgstr "" +"Obbligatorio. 30 caratteri o meno. Solo caratteri alfanumerici (lettere, " +"cifre e sottolineati)." + +#: contrib/auth/models.py:112 +msgid "first name" +msgstr "nome" + +#: contrib/auth/models.py:113 +msgid "last name" +msgstr "cognome" + +#: contrib/auth/models.py:114 +msgid "e-mail address" +msgstr "indirizzo e-mail" + +#: contrib/auth/models.py:115 +msgid "password" +msgstr "password" + +#: contrib/auth/models.py:115 +msgid "" +"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " +"password form</a>." +msgstr "" +"Usare '[algo]$[salt]$[hexdigest]' oppure la <a href=\"password/\">maschera " +"di cambio password</a>." + +#: contrib/auth/models.py:116 +msgid "staff status" +msgstr "privilegi di staff" + +#: contrib/auth/models.py:116 +msgid "Designates whether the user can log into this admin site." +msgstr "Indica se l'utente può accedere a questo sito di amministrazione." + +#: contrib/auth/models.py:117 +msgid "active" +msgstr "attivo" + +#: contrib/auth/models.py:117 +msgid "" +"Designates whether this user can log into the Django admin. Unselect this " +"instead of deleting accounts." +msgstr "" +"Indica se l'utente può accedere all'amministrazione di Django. Deselezionare " +"qui, piuttosto che cancellare gli account." + +#: contrib/auth/models.py:118 +msgid "superuser status" +msgstr "privilegi di superutente" + +#: contrib/auth/models.py:118 +msgid "" +"Designates that this user has all permissions without explicitly assigning " +"them." +msgstr "" +"Indica che l'utente ha tutti i privilegi, senza che siano stati assegnati " +"esplicitamente." + +#: contrib/auth/models.py:119 +msgid "last login" +msgstr "ultimo accesso" + +#: contrib/auth/models.py:120 +msgid "date joined" +msgstr "iscritto in data" + +#: contrib/auth/models.py:122 +msgid "" +"In addition to the permissions manually assigned, this user will also get " +"all permissions granted to each group he/she is in." +msgstr "" +"In aggiunta ai privilegi assegnati manualmente, l'utente riceverà anche " +"tutti i privilegi assegnati ad ogni gruppo cui appartiene." + +#: contrib/auth/models.py:123 +msgid "user permissions" +msgstr "privilegi utente" + +#: contrib/auth/models.py:127 +msgid "user" +msgstr "utente" + +#: contrib/auth/models.py:128 +msgid "users" +msgstr "utenti" + +#: contrib/auth/models.py:134 +msgid "Personal info" +msgstr "Informazioni personali" + +#: contrib/auth/models.py:135 +msgid "Permissions" +msgstr "Permessi" + +#: contrib/auth/models.py:136 +msgid "Important dates" +msgstr "Date importanti" + +#: contrib/auth/models.py:137 +msgid "Groups" +msgstr "Gruppi" + +#: contrib/auth/models.py:287 +msgid "message" +msgstr "messaggio" + +#: contrib/auth/views.py:41 +msgid "Logged out" +msgstr "Accesso annullato" + +#: contrib/admin/models.py:17 +msgid "action time" +msgstr "momento dell'azione" + +#: contrib/admin/models.py:20 +msgid "object id" +msgstr "id dell'oggetto" + +#: contrib/admin/models.py:21 +msgid "object repr" +msgstr "rappresentazione dell'oggetto" + +#: contrib/admin/models.py:22 +msgid "action flag" +msgstr "flag di azione" + +#: contrib/admin/models.py:23 +msgid "change message" +msgstr "messaggio di modifica" + +#: contrib/admin/models.py:26 +msgid "log entry" +msgstr "voce di log" + +#: contrib/admin/models.py:27 +msgid "log entries" +msgstr "voci di log" + +#: contrib/admin/filterspecs.py:42 #, python-format msgid "" "<h3>By %s:</h3>\n" "<ul>\n" msgstr "" -"<h3>Da %s:</h3>\n" +"<h3>Di %s:</h3>\n" "<ul>\n" -#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88 -#: contrib/admin/filterspecs.py:143 contrib/admin/filterspecs.py:169 +#: contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90 +#: contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171 msgid "All" msgstr "Tutti" -#: contrib/admin/filterspecs.py:109 +#: contrib/admin/filterspecs.py:111 msgid "Any date" msgstr "Qualsiasi data" -#: contrib/admin/filterspecs.py:110 +#: contrib/admin/filterspecs.py:112 msgid "Today" msgstr "Oggi" -#: contrib/admin/filterspecs.py:113 +#: contrib/admin/filterspecs.py:115 msgid "Past 7 days" msgstr "Ultimi 7 giorni" -#: contrib/admin/filterspecs.py:115 +#: contrib/admin/filterspecs.py:117 msgid "This month" msgstr "Questo mese" -#: contrib/admin/filterspecs.py:117 +#: contrib/admin/filterspecs.py:119 msgid "This year" msgstr "Quest'anno" -#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:591 +#: newforms/widgets.py:188 msgid "Yes" msgstr "Sì" -#: contrib/admin/filterspecs.py:143 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:591 +#: newforms/widgets.py:188 msgid "No" msgstr "No" -#: contrib/admin/filterspecs.py:150 newforms/widgets.py:180 -#: oldforms/__init__.py:577 +#: contrib/admin/filterspecs.py:152 oldforms/__init__.py:591 +#: newforms/widgets.py:188 msgid "Unknown" msgstr "Sconosciuto" -#: contrib/admin/models.py:16 -msgid "action time" -msgstr "data azione" +#: contrib/admin/views/decorators.py:24 +#: contrib/admin/templates/admin/login.html:25 +msgid "Log in" +msgstr "Accedi" -#: contrib/admin/models.py:19 -msgid "object id" -msgstr "ID oggetto" +#: 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 "" +"La sessione è scaduta: occorre accedere nuovamente. I dati inseriti sono " +"stati comunque salvati." -#: contrib/admin/models.py:20 -msgid "object repr" -msgstr "rappresentazione oggetto" +#: 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 "" +"Il browser non sembra configurato per accettare i cookie. Una volta " +"abilitati, ricaricare la pagina e riprovare." -#: contrib/admin/models.py:21 -msgid "action flag" -msgstr "flag azione" +#: contrib/admin/views/decorators.py:83 +msgid "Usernames cannot contain the '@' character." +msgstr "I nomi utente non possono contenere il carattere '@'." -#: contrib/admin/models.py:22 -msgid "change message" -msgstr "messaggio di modifica" +#: contrib/admin/views/decorators.py:85 +#, python-format +msgid "Your e-mail address is not your username. Try '%s' instead." +msgstr "" +"Il nome utente non è costituito dall'indirizzo e-mail. Provare con '%s'." -#: contrib/admin/models.py:25 -msgid "log entry" -msgstr "voce di log" +#: contrib/admin/views/main.py:230 +msgid "Site administration" +msgstr "Amministrazione sito" -#: contrib/admin/models.py:26 -msgid "log entries" -msgstr "voci di log" +#: contrib/admin/views/main.py:264 contrib/admin/views/auth.py:20 +#, python-format +msgid "The %(name)s \"%(obj)s\" was added successfully." +msgstr "Lo %(name)s \"%(obj)s\" è stato aggiunto correttamente." -#: contrib/admin/templates/admin/404.html:4 -#: contrib/admin/templates/admin/404.html:8 -msgid "Page not found" -msgstr "Pagina non trovata" +#: contrib/admin/views/main.py:268 contrib/admin/views/main.py:354 +#: contrib/admin/views/auth.py:25 +msgid "You may edit it again below." +msgstr "È possibile modificarlo nuovamente qui sotto." -#: contrib/admin/templates/admin/404.html:10 -msgid "We're sorry, but the requested page could not be found." -msgstr "Spiacenti, ma la pagina richiesta non è stata trovata." +#: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363 +#, python-format +msgid "You may add another %s below." +msgstr "È possibile aggiungere un altro %s qui sotto." -#: contrib/admin/templates/admin/500.html:4 -#: contrib/admin/templates/admin/base.html:30 -#: contrib/admin/templates/admin/change_form.html:13 -#: contrib/admin/templates/admin/change_list.html:6 -#: contrib/admin/templates/admin/delete_confirmation.html:6 -#: contrib/admin/templates/admin/invalid_setup.html:4 -#: contrib/admin/templates/admin/object_history.html:5 -#: contrib/admin/templates/admin/auth/user/change_password.html:12 -#: contrib/admin/templates/admin_doc/bookmarklets.html:3 -#: contrib/admin/templates/registration/logged_out.html:4 -#: contrib/admin/templates/registration/password_change_done.html:4 -#: contrib/admin/templates/registration/password_change_form.html:4 -#: contrib/admin/templates/registration/password_reset_done.html:4 -#: contrib/admin/templates/registration/password_reset_form.html:4 -msgid "Home" -msgstr "Pagina iniziale" +#: contrib/admin/views/main.py:296 +#, python-format +msgid "Add %s" +msgstr "Aggiungi %s" -#: contrib/admin/templates/admin/500.html:4 -msgid "Server error" -msgstr "Errore del server" +#: contrib/admin/views/main.py:342 +#, python-format +msgid "Added %s." +msgstr "%s aggiunto." -#: contrib/admin/templates/admin/500.html:6 -msgid "Server error (500)" -msgstr "Errore del server (500)" +#: contrib/admin/views/main.py:344 +#, python-format +msgid "Changed %s." +msgstr "%s modificato." -#: contrib/admin/templates/admin/500.html:9 -msgid "Server Error <em>(500)</em>" -msgstr "Errore del server <em>(500)</em>" +#: contrib/admin/views/main.py:346 +#, python-format +msgid "Deleted %s." +msgstr "%s cancellato." -#: contrib/admin/templates/admin/500.html:10 +#: contrib/admin/views/main.py:349 +msgid "No fields changed." +msgstr "Nessun campo modificato." + +#: contrib/admin/views/main.py:352 +#, python-format +msgid "The %(name)s \"%(obj)s\" was changed successfully." +msgstr "Lo %(name)s \"%(obj)s\" è stato modificato correttamente." + +#: contrib/admin/views/main.py:360 +#, fuzzy, python-format 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." +"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below." msgstr "" -"Si è verificato un errore. È stato riportato agli amministratori del sito " -"via e-mail e verrà corretto a breve. Grazie per la tua pazienza." +"%Lo (name)s \"%(obj)s\" è stato aggiunto correttamente. È possibile " +"modificarlo nuovamente qui sotto." -#: contrib/admin/templates/admin/base.html:25 -msgid "Welcome," -msgstr "Benvenuto," +#: contrib/admin/views/main.py:398 +#, python-format +msgid "Change %s" +msgstr "Modifica %s" -#: contrib/admin/templates/admin/base.html:25 +#: contrib/admin/views/main.py:483 +#, python-format +msgid "One or more %(fieldname)s in %(name)s: %(obj)s" +msgstr "Uno o più %(fieldname)s in %(name)s: %(obj)s" + +#: contrib/admin/views/main.py:488 +#, python-format +msgid "One or more %(fieldname)s in %(name)s:" +msgstr "Uno o più %(fieldname)s in %(name)s:" + +#: contrib/admin/views/main.py:520 +#, python-format +msgid "The %(name)s \"%(obj)s\" was deleted successfully." +msgstr "Lo %(name)s \"%(obj)s\" è stato cancellato correttamente." + +#: contrib/admin/views/main.py:523 +msgid "Are you sure?" +msgstr "Sei sicuro?" + +#: contrib/admin/views/main.py:545 +#, python-format +msgid "Change history: %s" +msgstr "Tracciato delle modifiche: %s" + +#: contrib/admin/views/main.py:579 +#, python-format +msgid "Select %s" +msgstr "Scegli %s" + +#: contrib/admin/views/main.py:579 +#, python-format +msgid "Select %s to change" +msgstr "Scegli %s da modificare" + +#: contrib/admin/views/main.py:780 +msgid "Database error" +msgstr "Errore nel database" + +#: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49 +#: contrib/admin/views/doc.py:51 +msgid "tag:" +msgstr "tag:" + +#: contrib/admin/views/doc.py:78 contrib/admin/views/doc.py:80 +#: contrib/admin/views/doc.py:82 +msgid "filter:" +msgstr "filtro:" + +#: contrib/admin/views/doc.py:136 contrib/admin/views/doc.py:138 +#: contrib/admin/views/doc.py:140 +msgid "view:" +msgstr "view:" + +#: contrib/admin/views/doc.py:165 +#, python-format +msgid "App %r not found" +msgstr "Appl. %r non trovata" + +#: contrib/admin/views/doc.py:172 +#, python-format +msgid "Model %(name)r not found in app %(label)r" +msgstr "Modello %(name)r non trovato nell'appl. %(label)r" + +#: contrib/admin/views/doc.py:184 +#, python-format +msgid "the related `%(label)s.%(type)s` object" +msgstr "l'oggetto `%(label)s.%(type)s` collegato" + +#: contrib/admin/views/doc.py:184 contrib/admin/views/doc.py:206 +#: contrib/admin/views/doc.py:220 contrib/admin/views/doc.py:225 +msgid "model:" +msgstr "modello:" + +#: contrib/admin/views/doc.py:215 +#, python-format +msgid "related `%(label)s.%(name)s` objects" +msgstr "oggetti `%(label)s.%(name)s` collegati" + +#: contrib/admin/views/doc.py:220 +#, python-format +msgid "all %s" +msgstr "tutti %s" + +#: contrib/admin/views/doc.py:225 +#, python-format +msgid "number of %s" +msgstr "numero di %s" + +#: contrib/admin/views/doc.py:230 +#, python-format +msgid "Fields on %s objects" +msgstr "Campi sugli oggetti %s" + +#: contrib/admin/views/doc.py:292 contrib/admin/views/doc.py:303 +#: contrib/admin/views/doc.py:305 contrib/admin/views/doc.py:311 +#: contrib/admin/views/doc.py:312 contrib/admin/views/doc.py:314 +msgid "Integer" +msgstr "Intero" + +#: contrib/admin/views/doc.py:293 +msgid "Boolean (Either True or False)" +msgstr "Booleano (True o False)" + +#: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313 +#, python-format +msgid "String (up to %(max_length)s)" +msgstr "Stringa (fino a %(max_length)s)" + +#: contrib/admin/views/doc.py:295 +msgid "Comma-separated integers" +msgstr "Interi separati da virgola" + +#: contrib/admin/views/doc.py:296 +msgid "Date (without time)" +msgstr "Data (senza ora)" + +#: contrib/admin/views/doc.py:297 +msgid "Date (with time)" +msgstr "Data (con ora)" + +#: contrib/admin/views/doc.py:298 +msgid "Decimal number" +msgstr "Numero decimale" + +#: contrib/admin/views/doc.py:299 +msgid "E-mail address" +msgstr "Indirizzo e-mail" + +#: contrib/admin/views/doc.py:300 contrib/admin/views/doc.py:301 +#: contrib/admin/views/doc.py:304 +msgid "File path" +msgstr "Percorso di file" + +#: contrib/admin/views/doc.py:302 +msgid "Floating point number" +msgstr "Numero decimale" + +#: contrib/admin/views/doc.py:306 contrib/comments/models.py:85 +msgid "IP address" +msgstr "indirizzo IP" + +#: contrib/admin/views/doc.py:308 +msgid "Boolean (Either True, False or None)" +msgstr "Booleano (True, False o None)" + +#: contrib/admin/views/doc.py:309 +msgid "Relation to parent model" +msgstr "Collegamento a modello padre" + +#: contrib/admin/views/doc.py:310 +msgid "Phone number" +msgstr "Numero di telefono" + +#: contrib/admin/views/doc.py:315 +msgid "Text" +msgstr "Testo" + +#: contrib/admin/views/doc.py:316 +msgid "Time" +msgstr "Ora" + +#: contrib/admin/views/doc.py:317 contrib/flatpages/models.py:7 +msgid "URL" +msgstr "URL" + +#: contrib/admin/views/doc.py:318 +msgid "U.S. state (two uppercase letters)" +msgstr "Stato USA (due lettere maiuscole)" + +#: contrib/admin/views/doc.py:319 +msgid "XML text" +msgstr "Testo XML" + +#: contrib/admin/views/doc.py:345 +#, python-format +msgid "%s does not appear to be a urlpattern object" +msgstr "%s non sembra essere un oggetto urlpattern" + +#: contrib/admin/views/auth.py:31 +msgid "Add user" +msgstr "Aggiungi utente" + +#: contrib/admin/views/auth.py:58 +msgid "Password changed successfully." +msgstr "La password è stata cambiata correttamente." + +#: contrib/admin/views/auth.py:65 +#, python-format +msgid "Change password: %s" +msgstr "Cambia la password: %s" + +#: contrib/admin/templatetags/admin_list.py:254 +msgid "All dates" +msgstr "Tutte le date" + +#: contrib/admin/templates/admin/pagination.html:10 +msgid "Show all" +msgstr "Mostra tutto" + +#: contrib/admin/templates/admin/delete_confirmation.html:3 #: 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_done.html:3 #: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/registration/password_change_done.html:3 msgid "Documentation" msgstr "Documentazione" -#: contrib/admin/templates/admin/base.html:25 +#: contrib/admin/templates/admin/delete_confirmation.html:3 #: 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/template_filter_index.html:5 #: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 #: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/missing_docutils.html:4 #: contrib/admin/templates/admin_doc/model_detail.html:3 -#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 #: contrib/admin/templates/admin_doc/template_detail.html:4 -#: contrib/admin/templates/admin_doc/template_filter_index.html:5 -#: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 #: contrib/admin/templates/admin_doc/view_index.html:5 -#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/view_detail.html:4 #: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/registration/password_change_done.html:3 msgid "Change password" msgstr "Cambia la password" -#: contrib/admin/templates/admin/base.html:25 +#: contrib/admin/templates/admin/delete_confirmation.html:3 #: 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/template_filter_index.html:5 #: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 #: contrib/admin/templates/admin_doc/index.html:4 -#: contrib/admin/templates/admin_doc/missing_docutils.html:4 #: contrib/admin/templates/admin_doc/model_detail.html:3 -#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 #: contrib/admin/templates/admin_doc/template_detail.html:4 -#: contrib/admin/templates/admin_doc/template_filter_index.html:5 -#: contrib/admin/templates/admin_doc/template_tag_index.html:5 -#: contrib/admin/templates/admin_doc/view_detail.html:4 #: contrib/admin/templates/admin_doc/view_index.html:5 -#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/admin_doc/model_index.html:5 +#: contrib/admin/templates/admin_doc/view_detail.html:4 #: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/registration/password_change_done.html:3 #: contrib/comments/templates/comments/form.html:6 msgid "Log out" msgstr "Esci" -#: contrib/admin/templates/admin/base_site.html:4 -msgid "Django site admin" -msgstr "Amministrazione sito Django" +#: contrib/admin/templates/admin/delete_confirmation.html:6 +#: contrib/admin/templates/admin/change_form.html:13 +#: contrib/admin/templates/admin/change_list.html:6 +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/500.html:4 +#: contrib/admin/templates/admin/invalid_setup.html:4 +#: contrib/admin/templates/admin/base.html:30 +#: 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/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 +msgid "Home" +msgstr "Pagina iniziale" -#: contrib/admin/templates/admin/base_site.html:7 -msgid "Django administration" -msgstr "Amministrazione Django" +#: contrib/admin/templates/admin/delete_confirmation.html:9 +#: contrib/admin/templates/admin/submit_line.html:3 +msgid "Delete" +msgstr "Cancella" + +#: contrib/admin/templates/admin/delete_confirmation.html:14 +#, 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 "" +"La cancellazione di %(object_name)s '%(escaped_object)s' causerebbe la " +"cancellazione di oggetti collegati, ma questo account non ha i permessi per " +"cancellare gli oggetti dei seguenti tipi:" + +#: contrib/admin/templates/admin/delete_confirmation.html:21 +#, 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 "" +"Sei sicuro di voler cancellare gli %(object_name)s \"%(escaped_object)s\"? " +"Tutti i seguenti oggetti collegati saranno cancellati:" + +#: contrib/admin/templates/admin/delete_confirmation.html:26 +msgid "Yes, I'm sure" +msgstr "Sì, sono sicuro" + +#: contrib/admin/templates/admin/404.html:4 +#: contrib/admin/templates/admin/404.html:8 +msgid "Page not found" +msgstr "Pagina non trovata" + +#: contrib/admin/templates/admin/404.html:10 +msgid "We're sorry, but the requested page could not be found." +msgstr "Spiacenti, ma la pagina richiesta non è stata trovata." #: contrib/admin/templates/admin/change_form.html:15 #: contrib/admin/templates/admin/index.html:28 @@ -399,48 +1275,31 @@ msgstr "Ordinamento" msgid "Order:" msgstr "Ordine:" -#: contrib/admin/templates/admin/change_list.html:12 +#: contrib/admin/templates/admin/filter.html:2 #, python-format -msgid "Add %(name)s" -msgstr "Aggiungi %(name)s" +msgid " By %(filter_title)s " +msgstr " Per %(filter_title)s " -#: contrib/admin/templates/admin/delete_confirmation.html:9 -#: contrib/admin/templates/admin/submit_line.html:3 -msgid "Delete" -msgstr "Cancella" +#: contrib/admin/templates/admin/submit_line.html:4 +msgid "Save as new" +msgstr "Salva come nuovo" -#: contrib/admin/templates/admin/delete_confirmation.html:14 -#, 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 "" -"La cancellazione di %(object_name)s '%(escaped_object)s' causerebbe la " -"cancellazione di oggetti collegati, ma questo account non ha i permessi per " -"cancellare gli oggetti dei seguenti tipi:" +#: contrib/admin/templates/admin/submit_line.html:5 +msgid "Save and add another" +msgstr "Salva e aggiungi un altro" -#: contrib/admin/templates/admin/delete_confirmation.html:21 -#, 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 "" -"Sei sicuro di voler rimuovere %(object_name)s \"%(escaped_object)s\"? Tutti " -"i seguenti oggetti collegati saranno cancellati:" +#: contrib/admin/templates/admin/submit_line.html:6 +msgid "Save and continue editing" +msgstr "Salva e continua le modifiche" -#: contrib/admin/templates/admin/delete_confirmation.html:26 -msgid "Yes, I'm sure" -msgstr "Sì, sono sicuro" +#: contrib/admin/templates/admin/submit_line.html:7 +msgid "Save" +msgstr "Salva" -#: contrib/admin/templates/admin/filter.html:2 +#: contrib/admin/templates/admin/change_list.html:12 #, python-format -msgid " By %(filter_title)s " -msgstr " Per %(filter_title)s " - -#: contrib/admin/templates/admin/filters.html:4 -msgid "Filter" -msgstr "Filtro" +msgid "Add %(name)s" +msgstr "Aggiungi %(name)s" #: contrib/admin/templates/admin/index.html:17 #, python-format @@ -472,35 +1331,17 @@ msgstr "Azioni Proprie" msgid "None available" msgstr "Nessuno disponibile" -#: 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 "" -"Ci sono problemi nell'installazione del database. Assicurarsi che le tabelle " -"appropriate del database siano state create, e che il database sia leggibile " -"dall'utente appropriato." - -#: contrib/admin/templates/admin/login.html:17 -#: contrib/comments/templates/comments/form.html:6 -#: contrib/comments/templates/comments/form.html:8 -msgid "Username:" -msgstr "Nome utente:" - -#: contrib/admin/templates/admin/login.html:20 -#: contrib/comments/templates/comments/form.html:8 -msgid "Password:" -msgstr "Password:" +#: contrib/admin/templates/admin/base_site.html:4 +msgid "Django site admin" +msgstr "Amministrazione sito Django" -#: contrib/admin/templates/admin/login.html:25 -#: contrib/admin/views/decorators.py:24 -msgid "Log in" -msgstr "Accedi" +#: contrib/admin/templates/admin/base_site.html:7 +msgid "Django administration" +msgstr "Amministrazione Django" #: contrib/admin/templates/admin/object_history.html:18 msgid "Date/time" -msgstr "Data/orario" +msgstr "Data/ora" #: contrib/admin/templates/admin/object_history.html:19 msgid "User" @@ -522,9 +1363,35 @@ msgstr "" "Questo oggetto non ha cambiamenti registrati. Probabilmente non è stato " "creato con questo sito di amministrazione." -#: contrib/admin/templates/admin/pagination.html:10 -msgid "Show all" -msgstr "Mostra tutto" +#: contrib/admin/templates/admin/500.html:4 +msgid "Server error" +msgstr "Errore del server" + +#: contrib/admin/templates/admin/500.html:6 +msgid "Server error (500)" +msgstr "Errore del server (500)" + +#: contrib/admin/templates/admin/500.html:9 +msgid "Server Error <em>(500)</em>" +msgstr "Errore del server <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 "" +"Si è verificato un errore. È stato riportato agli amministratori del sito " +"via e-mail e verrà corretto a breve. Grazie per la tua pazienza." + +#: 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 "" +"Ci sono problemi nell'installazione del database. Assicurarsi che le tabelle " +"appropriate del database siano state create, e che il database sia leggibile " +"dall'utente appropriato." #: contrib/admin/templates/admin/search_form.html:8 msgid "Go" @@ -542,21 +1409,24 @@ msgstr[1] "%(counter)s risultati" msgid "%(full_result_count)s total" msgstr "%(full_result_count)s totali" -#: contrib/admin/templates/admin/submit_line.html:4 -msgid "Save as new" -msgstr "Salva come nuovo" +#: contrib/admin/templates/admin/filters.html:4 +msgid "Filter" +msgstr "Filtro" -#: contrib/admin/templates/admin/submit_line.html:5 -msgid "Save and add another" -msgstr "Salva e aggiungi un altro" +#: contrib/admin/templates/admin/login.html:17 +#: contrib/comments/templates/comments/form.html:6 +#: contrib/comments/templates/comments/form.html:8 +msgid "Username:" +msgstr "Nome utente:" -#: contrib/admin/templates/admin/submit_line.html:6 -msgid "Save and continue editing" -msgstr "Salva e continua le modifiche" +#: contrib/admin/templates/admin/login.html:20 +#: contrib/comments/templates/comments/form.html:8 +msgid "Password:" +msgstr "Password:" -#: contrib/admin/templates/admin/submit_line.html:7 -msgid "Save" -msgstr "Salva" +#: contrib/admin/templates/admin/base.html:25 +msgid "Welcome," +msgstr "Benvenuto," #: contrib/admin/templates/admin/auth/user/add_form.html:6 msgid "" @@ -614,7 +1484,7 @@ msgstr "" "barra \n" "dei bookmark, o cliccare il link con il tasto destro e aggiungerlo ai " "bookmark.\n" -"Sarà quindi possibile selezionare un bookmarklet in qualsiasi pagina del " +"Sarà quindi possibile scegliere un bookmarklet in qualsiasi pagina del " "sito.\n" "Si noti che alcuni di questi bookmarklet richiedono l'accesso al sito " "tramite un\n" @@ -664,73 +1534,44 @@ msgid "As above, but opens the admin page in a new window." msgstr "" "Come sopra, ma apre la pagina di amministrazione in una nuova finestra." -#: contrib/admin/templates/registration/logged_out.html:8 -msgid "Thanks for spending some quality time with the Web site today." -msgstr "Grazie per aver speso il tuo tempo prezioso su questo sito oggi." - -#: contrib/admin/templates/registration/logged_out.html:10 -msgid "Log in again" -msgstr "Accedi di nuovo" - -#: 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 -#: contrib/admin/templates/registration/password_change_form.html:10 -msgid "Password change" -msgstr "Cambio password" - -#: contrib/admin/templates/registration/password_change_done.html:6 -#: contrib/admin/templates/registration/password_change_done.html:10 -msgid "Password change successful" -msgstr "Cambio di password avvenuto correttamente" - -#: contrib/admin/templates/registration/password_change_done.html:12 -msgid "Your password was changed." -msgstr "La password è stata cambiata." - -#: 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 "" -"Inserire l'attuale password, per ragioni di sicurezza, e poi la nuova " -"password due volte, per verificare di averla scritta correttamente." - -#: contrib/admin/templates/registration/password_change_form.html:17 -msgid "Old password:" -msgstr "Password attuale:" +#: contrib/admin/templates/widget/date_time.html:3 +msgid "Date:" +msgstr "Data:" -#: contrib/admin/templates/registration/password_change_form.html:19 -msgid "New password:" -msgstr "Nuova password:" +#: contrib/admin/templates/widget/date_time.html:4 +msgid "Time:" +msgstr "Ora:" -#: contrib/admin/templates/registration/password_change_form.html:21 -msgid "Confirm password:" -msgstr "Confermare la password:" +#: contrib/admin/templates/widget/file.html:2 +msgid "Currently:" +msgstr "Attualmente:" -#: contrib/admin/templates/registration/password_change_form.html:23 -msgid "Change my password" -msgstr "Modifica la mia password" +#: contrib/admin/templates/widget/file.html:3 +msgid "Change:" +msgstr "Modifica:" -#: 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 "Reimposta la password" -#: contrib/admin/templates/registration/password_reset_done.html:6 -#: contrib/admin/templates/registration/password_reset_done.html:10 -msgid "Password reset successful" -msgstr "Password reimpostata correttamente" - -#: contrib/admin/templates/registration/password_reset_done.html:12 +#: contrib/admin/templates/registration/password_reset_form.html:12 msgid "" -"We've e-mailed a new password to the e-mail address you submitted. You " -"should be receiving it shortly." +"Forgotten your password? Enter your e-mail address below, and we'll reset " +"your password and e-mail the new one to you." msgstr "" -"La nuova password è stata inviata all'indirizzo e-mail inserito. Arriverà a " -"breve." +"Dimenticata la password? Inserire il proprio indirizzo e-mail qui sotto: la " +"password sarà reimpostata, e la nuova ti verrà inviata per e-mail." + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "E-mail address:" +msgstr "Indirizzo e-mail:" + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "Reset my password" +msgstr "Reimposta la mia password" #: contrib/admin/templates/registration/password_reset_email.html:2 msgid "You're receiving this e-mail because you requested a password reset" @@ -764,511 +1605,238 @@ msgstr "Grazie per aver usato il nostro sito!" msgid "The %(site_name)s team" msgstr "Il team di %(site_name)s" -#: 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 "" -"Dimenticata la password? Inserire il proprio indirizzo e-mail qui sotto: la " -"password sarà reimpostata, e la nuova ti verrà inviata per e-mail." - -#: contrib/admin/templates/registration/password_reset_form.html:16 -msgid "E-mail address:" -msgstr "Indirizzo e-mail:" - -#: contrib/admin/templates/registration/password_reset_form.html:16 -msgid "Reset my password" -msgstr "Reimposta la mia password" - -#: contrib/admin/templates/widget/date_time.html:3 -msgid "Date:" -msgstr "Data:" - -#: contrib/admin/templates/widget/date_time.html:4 -msgid "Time:" -msgstr "Orario:" - -#: contrib/admin/templates/widget/file.html:2 -msgid "Currently:" -msgstr "Attualmente:" - -#: contrib/admin/templates/widget/file.html:3 -msgid "Change:" -msgstr "Modifica:" - -#: contrib/admin/templatetags/admin_list.py:247 -msgid "All dates" -msgstr "Tutte le date" - -#: 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\" è stato aggiunto correttamente." - -#: 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 "È possibile modificarlo nuovamente qui sotto." - -#: contrib/admin/views/auth.py:30 -msgid "Add user" -msgstr "Aggiungi utente" +#: contrib/admin/templates/registration/logged_out.html:8 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "Grazie per aver speso il tuo tempo prezioso su questo sito oggi." -#: contrib/admin/views/auth.py:57 -msgid "Password changed successfully." -msgstr "La password è stata cambiata correttamente." +#: contrib/admin/templates/registration/logged_out.html:10 +msgid "Log in again" +msgstr "Accedi di nuovo" -#: contrib/admin/views/auth.py:64 -#, python-format -msgid "Change password: %s" -msgstr "Cambia la password: %s" +#: contrib/admin/templates/registration/password_reset_done.html:6 +#: contrib/admin/templates/registration/password_reset_done.html:10 +msgid "Password reset successful" +msgstr "Password reimpostata correttamente" -#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60 +#: contrib/admin/templates/registration/password_reset_done.html:12 msgid "" -"Please enter a correct username and password. Note that both fields are case-" -"sensitive." +"We've e-mailed a new password to the e-mail address you submitted. You " +"should be receiving it shortly." msgstr "" -"Inserire nome utente e password corretti. Entrambi i campi sono case " -"sensitive." +"La nuova password è stata inviata all'indirizzo e-mail inserito. Arriverà a " +"breve." -#: 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 "" -"La sessione è scaduta: occorre accedere nuovamente. I dati inseriti sono " -"stati comunquesalvati." +#: contrib/admin/templates/registration/password_change_form.html:4 +#: contrib/admin/templates/registration/password_change_form.html:6 +#: contrib/admin/templates/registration/password_change_form.html:10 +#: contrib/admin/templates/registration/password_change_done.html:4 +msgid "Password change" +msgstr "Cambio password" -#: contrib/admin/views/decorators.py:69 +#: contrib/admin/templates/registration/password_change_form.html:12 msgid "" -"Looks like your browser isn't configured to accept cookies. Please enable " -"cookies, reload this page, and try again." -msgstr "" -"Il browser non sembra configurato per accettare i cookie. Una volta " -"abilitati, ricaricare la pagina e riprovare." - -#: contrib/admin/views/decorators.py:83 -msgid "Usernames cannot contain the '@' character." -msgstr "I nomi utente non possono contenere il carattere '@'." - -#: contrib/admin/views/decorators.py:85 -#, python-format -msgid "Your e-mail address is not your username. Try '%s' instead." +"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 "" -"Il nome utente non è costituito dall'indirizzo e-mail. Provare con '%s'." - -#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48 -#: contrib/admin/views/doc.py:50 -msgid "tag:" -msgstr "tag:" - -#: contrib/admin/views/doc.py:77 contrib/admin/views/doc.py:79 -#: contrib/admin/views/doc.py:81 -msgid "filter:" -msgstr "filtro:" - -#: 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 "Appl. %r non trovata" - -#: contrib/admin/views/doc.py:171 -#, fuzzy, python-format -msgid "Model %(name)r not found in app %(label)r" -msgstr "Modello %r non trovato nell'appl. %r" - -#: contrib/admin/views/doc.py:183 -#, fuzzy, python-format -msgid "the related `%(label)s.%(type)s` object" -msgstr "l'oggetto `%s.%s` collegato" - -#: 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 "modello:" - -#: contrib/admin/views/doc.py:214 -#, fuzzy, python-format -msgid "related `%(label)s.%(name)s` objects" -msgstr "oggetti `%s.%s` collegati" - -#: contrib/admin/views/doc.py:219 -#, python-format -msgid "all %s" -msgstr "tutti %s" - -#: contrib/admin/views/doc.py:224 -#, python-format -msgid "number of %s" -msgstr "numero di %s" - -#: contrib/admin/views/doc.py:229 -#, python-format -msgid "Fields on %s objects" -msgstr "Campi sugli oggetti %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 "Intero" - -#: contrib/admin/views/doc.py:292 -msgid "Boolean (Either True or False)" -msgstr "Booleano (True o False)" - -#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:311 -#, python-format -msgid "String (up to %(maxlength)s)" -msgstr "Stringa (fino a %(maxlength)s caratteri)" - -#: contrib/admin/views/doc.py:294 -msgid "Comma-separated integers" -msgstr "Interi separati da virgola" - -#: contrib/admin/views/doc.py:295 -msgid "Date (without time)" -msgstr "Data (senza orario)" - -#: contrib/admin/views/doc.py:296 -msgid "Date (with time)" -msgstr "Data (con orario)" - -#: contrib/admin/views/doc.py:297 -msgid "E-mail address" -msgstr "Indirizzo e-mail" - -#: contrib/admin/views/doc.py:298 contrib/admin/views/doc.py:299 -#: contrib/admin/views/doc.py:302 -msgid "File path" -msgstr "Percorso di file" - -#: contrib/admin/views/doc.py:300 -msgid "Decimal number" -msgstr "Numero decimale" - -#: contrib/admin/views/doc.py:304 contrib/comments/models.py:85 -msgid "IP address" -msgstr "indirizzo IP" - -#: contrib/admin/views/doc.py:306 -msgid "Boolean (Either True, False or None)" -msgstr "Booleano (True, False o None)" - -#: contrib/admin/views/doc.py:307 -msgid "Relation to parent model" -msgstr "Collegamento a modello padre" - -#: contrib/admin/views/doc.py:308 -msgid "Phone number" -msgstr "Numero di telefono" - -#: contrib/admin/views/doc.py:313 -msgid "Text" -msgstr "Testo" - -#: contrib/admin/views/doc.py:314 -msgid "Time" -msgstr "Orario" - -#: contrib/admin/views/doc.py:315 contrib/flatpages/models.py:7 -msgid "URL" -msgstr "URL" +"Inserire l'attuale password, per ragioni di sicurezza, e poi la nuova " +"password due volte, per verificare di averla scritta correttamente." -#: contrib/admin/views/doc.py:316 -msgid "U.S. state (two uppercase letters)" -msgstr "Stato USA (due lettere maiuscole)" +#: contrib/admin/templates/registration/password_change_form.html:17 +msgid "Old password:" +msgstr "Password attuale:" -#: contrib/admin/views/doc.py:317 -msgid "XML text" -msgstr "Testo XML" +#: contrib/admin/templates/registration/password_change_form.html:19 +msgid "New password:" +msgstr "Nuova password:" -#: contrib/admin/views/doc.py:343 -#, python-format -msgid "%s does not appear to be a urlpattern object" -msgstr "%s non sembra essere un oggetto urlpattern" +#: contrib/admin/templates/registration/password_change_form.html:21 +msgid "Confirm password:" +msgstr "Confermare la password:" -#: contrib/admin/views/main.py:223 -msgid "Site administration" -msgstr "Amministrazione sito" +#: contrib/admin/templates/registration/password_change_form.html:23 +msgid "Change my password" +msgstr "Modifica la mia password" -#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356 -#, python-format -msgid "You may add another %s below." -msgstr "È possibile aggiungere un altro %s qui sotto." +#: contrib/admin/templates/registration/password_change_done.html:6 +#: contrib/admin/templates/registration/password_change_done.html:10 +msgid "Password change successful" +msgstr "Cambio di password avvenuto correttamente" -#: contrib/admin/views/main.py:289 -#, python-format -msgid "Add %s" -msgstr "Aggiungere %s" +#: contrib/admin/templates/registration/password_change_done.html:12 +msgid "Your password was changed." +msgstr "La password è stata cambiata." -#: contrib/admin/views/main.py:335 -#, python-format -msgid "Added %s." -msgstr "Aggiunto %s" +#: contrib/sites/models.py:15 +msgid "domain name" +msgstr "nome di dominio" -#: 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 "e" +#: contrib/sites/models.py:16 +msgid "display name" +msgstr "nome visualizzato" -#: contrib/admin/views/main.py:337 -#, python-format -msgid "Changed %s." -msgstr "Modificato %s." +#: contrib/sites/models.py:20 +msgid "site" +msgstr "sito" -#: contrib/admin/views/main.py:339 -#, python-format -msgid "Deleted %s." -msgstr "Cancellato %s" +#: contrib/sites/models.py:21 +msgid "sites" +msgstr "siti" -#: contrib/admin/views/main.py:342 -msgid "No fields changed." -msgstr "Nessun campo modificato." +#: contrib/humanize/templatetags/humanize.py:17 +msgid "th" +msgstr "º" -#: contrib/admin/views/main.py:345 -#, python-format -msgid "The %(name)s \"%(obj)s\" was changed successfully." -msgstr "%(name)s \"%(obj)s\" è stato modificato correttamente." +#: contrib/humanize/templatetags/humanize.py:17 +msgid "st" +msgstr "º" -#: 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\" è stato aggiunto correttamente. È possibile modificarlo " -"nuovamente qui sotto." +#: contrib/humanize/templatetags/humanize.py:17 +msgid "nd" +msgstr "º" -#: contrib/admin/views/main.py:391 -#, python-format -msgid "Change %s" -msgstr "Modificare %s" +#: contrib/humanize/templatetags/humanize.py:17 +msgid "rd" +msgstr "º" -#: contrib/admin/views/main.py:476 +#: contrib/humanize/templatetags/humanize.py:47 #, python-format -msgid "One or more %(fieldname)s in %(name)s: %(obj)s" -msgstr "Uno o più %(fieldname)s in %(name)s: %(obj)s" +msgid "%(value).1f million" +msgid_plural "%(value).1f million" +msgstr[0] "%(value).1f milione" +msgstr[1] "%(value).1f milioni" -#: contrib/admin/views/main.py:481 +#: contrib/humanize/templatetags/humanize.py:50 #, python-format -msgid "One or more %(fieldname)s in %(name)s:" -msgstr "Uno o più %(fieldname)s in %(name)s:" +msgid "%(value).1f billion" +msgid_plural "%(value).1f billion" +msgstr[0] "%(value).1f miliardo" +msgstr[1] "%(value).1f miliardi" -#: contrib/admin/views/main.py:514 +#: contrib/humanize/templatetags/humanize.py:53 #, python-format -msgid "The %(name)s \"%(obj)s\" was deleted successfully." -msgstr "%(name)s \"%(obj)s\" è stato cancellato correttamente." +msgid "%(value).1f trillion" +msgid_plural "%(value).1f trillion" +msgstr[0] "%(value).1f migliaio di miliardi" +msgstr[1] "%(value).1f migliaia di miliardi" -#: contrib/admin/views/main.py:517 -msgid "Are you sure?" -msgstr "Sei sicuro?" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "one" +msgstr "uno" -#: contrib/admin/views/main.py:539 -#, python-format -msgid "Change history: %s" -msgstr "Tracciato delle modifiche: %s" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "two" +msgstr "due" -#: contrib/admin/views/main.py:573 -#, python-format -msgid "Select %s" -msgstr "Seleziona %s" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "three" +msgstr "tre" -#: contrib/admin/views/main.py:573 -#, python-format -msgid "Select %s to change" -msgstr "Seleziona %s per modificare" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "four" +msgstr "quattro" -#: contrib/admin/views/main.py:768 -msgid "Database error" -msgstr "Errore nel database" +#: contrib/humanize/templatetags/humanize.py:68 +msgid "five" +msgstr "cinque" -#: contrib/auth/forms.py:17 contrib/auth/forms.py:138 -msgid "The two password fields didn't match." -msgstr "I due campi password non corrispondono." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "six" +msgstr "sei" -#: contrib/auth/forms.py:25 -msgid "A user with that username already exists." -msgstr "Un utente con questo nome·è già presente." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "seven" +msgstr "sette" -#: contrib/auth/forms.py:53 -msgid "" -"Your Web browser doesn't appear to have cookies enabled. Cookies are " -"required for logging in." -msgstr "" -"Il browser web sembra non avere i cookie abilitati. I cookie sono necessari " -"per poter accedere." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "eight" +msgstr "otto" -#: contrib/auth/forms.py:62 -msgid "This account is inactive." -msgstr "Questo account non è attivo." +#: contrib/humanize/templatetags/humanize.py:68 +msgid "nine" +msgstr "nove" -#: contrib/auth/forms.py:85 +#: contrib/flatpages/models.py:8 msgid "" -"That e-mail address doesn't have an associated user account. Are you sure " -"you've registered?" -msgstr "" -"Questo indirizzo email non è associato ad alcun account utente. Sei sicuro " -"di esserti registrato?" - -#: contrib/auth/forms.py:117 -msgid "The two 'new password' fields didn't match." -msgstr "I due campi 'nuova password' non corrispondono." - -#: contrib/auth/forms.py:124 -msgid "Your old password was entered incorrectly. Please enter it again." +"Example: '/about/contact/'. Make sure to have leading and trailing slashes." msgstr "" -"La vecchia password non è stata inserita correttamente: va inserita di nuovo." - -#: contrib/auth/models.py:38 contrib/auth/models.py:58 -msgid "name" -msgstr "nome" - -#: contrib/auth/models.py:40 -msgid "codename" -msgstr "nome in codice" - -#: contrib/auth/models.py:43 -msgid "permission" -msgstr "permesso" +"Esempio: '/about/contact/'. Assicurarsi di inserire le barre diagonali " +"iniziali e finali." -#: contrib/auth/models.py:44 contrib/auth/models.py:59 -msgid "permissions" -msgstr "permessi" +#: contrib/flatpages/models.py:9 +msgid "title" +msgstr "titolo" -#: contrib/auth/models.py:62 -msgid "group" -msgstr "gruppo" +#: contrib/flatpages/models.py:10 +msgid "content" +msgstr "contenuto" -#: contrib/auth/models.py:63 contrib/auth/models.py:103 -msgid "groups" -msgstr "gruppi" +#: contrib/flatpages/models.py:11 +msgid "enable comments" +msgstr "abilita commenti" -#: contrib/auth/models.py:93 -msgid "username" -msgstr "nome utente" +#: contrib/flatpages/models.py:12 +msgid "template name" +msgstr "nome modello" -#: contrib/auth/models.py:93 +#: contrib/flatpages/models.py:13 msgid "" -"Required. 30 characters or fewer. Alphanumeric characters only (letters, " -"digits and underscores)." +"Example: 'flatpages/contact_page.html'. If this isn't provided, the system " +"will use 'flatpages/default.html'." msgstr "" -"Obbligatorio. 30 caratteri o meno. Solo caratteri alfanumerici (lettere, " -"cifre e sottolineature)." - -#: contrib/auth/models.py:94 -msgid "first name" -msgstr "nome" - -#: contrib/auth/models.py:95 -msgid "last name" -msgstr "cognome" - -#: contrib/auth/models.py:96 -msgid "e-mail address" -msgstr "indirizzo e-mail" +"Esempio: 'flatpages/contact_page.html'. Se non specificato, il sistema userà " +"'flatpages/default.html'." -#: contrib/auth/models.py:97 -msgid "password" -msgstr "password" +#: contrib/flatpages/models.py:14 +msgid "registration required" +msgstr "registrazione obbligatoria" -#: contrib/auth/models.py:97 -msgid "" -"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " -"password form</a>." +#: contrib/flatpages/models.py:14 +msgid "If this is checked, only logged-in users will be able to view the page." msgstr "" -"Usare '[algo]$[salt]$[hexdigest]' oppure la maschera di <a href=\"password/" -"\">cambio password</a>." - -#: contrib/auth/models.py:98 -msgid "staff status" -msgstr "privilegi di staff" - -#: contrib/auth/models.py:98 -msgid "Designates whether the user can log into this admin site." -msgstr "Indica se l'utente può accedere a questo sito di amministrazione." +"Se selezionato, solo gli utenti che hanno effettuato l'accesso potranno " +"vedere la pagina." -#: contrib/auth/models.py:99 -msgid "active" -msgstr "attivo" +#: contrib/flatpages/models.py:18 +msgid "flat page" +msgstr "pagina statica" -#: contrib/auth/models.py:99 -msgid "" -"Designates whether this user can log into the Django admin. Unselect this " -"instead of deleting accounts." -msgstr "" -"Indica se l'utente può accedere all'amministrazione di Django. Deselezionare " -"qui, piuttosto che cancellare gli account." +#: contrib/flatpages/models.py:19 +msgid "flat pages" +msgstr "pagine statiche" -#: contrib/auth/models.py:100 -msgid "superuser status" -msgstr "privilegi di superutente" +#: contrib/redirects/models.py:7 +msgid "redirect from" +msgstr "redirezione da" -#: contrib/auth/models.py:100 +#: contrib/redirects/models.py:8 msgid "" -"Designates that this user has all permissions without explicitly assigning " -"them." +"This should be an absolute path, excluding the domain name. Example: '/" +"events/search/'." msgstr "" -"Indica che l'utente ha tutti i privilegi, senza che siano stati assegnati " -"esplicitamente." - -#: contrib/auth/models.py:101 -msgid "last login" -msgstr "ultimo accesso" +"Deve essere un percorso assoluto, senza nome di dominio. Esempio: '/events/" +"search/'." -#: contrib/auth/models.py:102 -msgid "date joined" -msgstr "iscritto in data" +#: contrib/redirects/models.py:9 +msgid "redirect to" +msgstr "redirezione verso" -#: contrib/auth/models.py:104 +#: contrib/redirects/models.py:10 msgid "" -"In addition to the permissions manually assigned, this user will also get " -"all permissions granted to each group he/she is in." +"This can be either an absolute path (as above) or a full URL starting with " +"'http://'." msgstr "" -"In aggiunta ai privilegi assegnati manualmente, l'utente riceverà anche " -"tutti i privilegi assegnati ad ogni gruppo cui appartiene." - -#: contrib/auth/models.py:105 -msgid "user permissions" -msgstr "privilegi utente" - -#: contrib/auth/models.py:109 -msgid "user" -msgstr "utente" - -#: contrib/auth/models.py:110 -msgid "users" -msgstr "utenti" - -#: contrib/auth/models.py:116 -msgid "Personal info" -msgstr "Informazioni personali" - -#: contrib/auth/models.py:117 -msgid "Permissions" -msgstr "Privilegi" - -#: contrib/auth/models.py:118 -msgid "Important dates" -msgstr "Date importanti" - -#: contrib/auth/models.py:119 -msgid "Groups" -msgstr "Gruppi" +"Può essere un percorso assoluto (come sopra) o una URL completa che inizia " +"con 'http://'." -#: contrib/auth/models.py:263 -msgid "message" -msgstr "messaggio" +#: contrib/redirects/models.py:13 +msgid "redirect" +msgstr "redirezione" -#: contrib/auth/views.py:39 -msgid "Logged out" -msgstr "Accesso annullato" +#: contrib/redirects/models.py:14 +msgid "redirects" +msgstr "redirezioni" -#: contrib/comments/models.py:67 contrib/comments/models.py:166 +#: contrib/comments/models.py:67 contrib/comments/models.py:169 msgid "object ID" msgstr "ID dell'oggetto" @@ -1277,7 +1845,7 @@ msgid "headline" msgstr "intestazione" #: contrib/comments/models.py:69 contrib/comments/models.py:90 -#: contrib/comments/models.py:167 +#: contrib/comments/models.py:170 msgid "comment" msgstr "commento" @@ -1317,11 +1885,11 @@ msgstr "valutazione #8" msgid "is valid rating" msgstr "è una valutazione valida" -#: contrib/comments/models.py:83 contrib/comments/models.py:169 +#: contrib/comments/models.py:83 contrib/comments/models.py:172 msgid "date/time submitted" -msgstr "data/orario di inserimento" +msgstr "data/ora di inserimento" -#: contrib/comments/models.py:84 contrib/comments/models.py:170 +#: contrib/comments/models.py:84 contrib/comments/models.py:173 msgid "is public" msgstr "è pubblico" @@ -1341,11 +1909,11 @@ msgstr "" msgid "comments" msgstr "commenti" -#: contrib/comments/models.py:131 contrib/comments/models.py:207 +#: contrib/comments/models.py:134 contrib/comments/models.py:213 msgid "Content object" msgstr "Oggetto con contenuto" -#: contrib/comments/models.py:159 +#: contrib/comments/models.py:162 #, python-format msgid "" "Posted by %(user)s at %(date)s\n" @@ -1360,48 +1928,48 @@ msgstr "" "\n" "http://%(domain)s%(url)s" -#: contrib/comments/models.py:168 +#: contrib/comments/models.py:171 msgid "person's name" msgstr "nome della persona" -#: contrib/comments/models.py:171 +#: contrib/comments/models.py:174 msgid "ip address" msgstr "indirizzo IP" -#: contrib/comments/models.py:173 +#: contrib/comments/models.py:176 msgid "approved by staff" msgstr "approvato dallo staff" -#: contrib/comments/models.py:176 +#: contrib/comments/models.py:179 msgid "free comment" msgstr "commento libero" -#: contrib/comments/models.py:177 +#: contrib/comments/models.py:180 msgid "free comments" msgstr "commenti liberi" -#: contrib/comments/models.py:233 +#: contrib/comments/models.py:239 msgid "score" msgstr "punteggio" -#: contrib/comments/models.py:234 +#: contrib/comments/models.py:240 msgid "score date" msgstr "data punteggio" -#: contrib/comments/models.py:237 +#: contrib/comments/models.py:243 msgid "karma score" msgstr "livello karma" -#: contrib/comments/models.py:238 +#: contrib/comments/models.py:244 msgid "karma scores" msgstr "livelli karma" -#: contrib/comments/models.py:242 +#: contrib/comments/models.py:248 #, python-format msgid "%(score)d rating by %(user)s" msgstr "valutazione: %(score)d da %(user)s" -#: contrib/comments/models.py:258 +#: contrib/comments/models.py:264 #, python-format msgid "" "This comment was flagged by %(user)s:\n" @@ -1412,84 +1980,60 @@ msgstr "" "\n" "%(text)s" -#: contrib/comments/models.py:265 +#: contrib/comments/models.py:271 msgid "flag date" msgstr "data flag" -#: contrib/comments/models.py:268 +#: contrib/comments/models.py:274 msgid "user flag" msgstr "flag utente" -#: contrib/comments/models.py:269 +#: contrib/comments/models.py:275 msgid "user flags" msgstr "flag utente" -#: contrib/comments/models.py:273 +#: contrib/comments/models.py:279 #, python-format msgid "Flag by %r" msgstr "Flag da %r" -#: contrib/comments/models.py:278 +#: contrib/comments/models.py:284 msgid "deletion date" msgstr "data cancellazione" -#: contrib/comments/models.py:280 +#: contrib/comments/models.py:286 msgid "moderator deletion" msgstr "cancellazione da moderatore" -#: contrib/comments/models.py:281 +#: contrib/comments/models.py:287 msgid "moderator deletions" msgstr "cancellazioni da moderatore" -#: contrib/comments/models.py:285 +#: contrib/comments/models.py:291 #, python-format msgid "Moderator deletion by %r" msgstr "Cancellazione da moderatore %r" -#: contrib/comments/templates/comments/form.html:8 -msgid "Forgotten your password?" -msgstr "Hai dimenticato la password?" - -#: contrib/comments/templates/comments/form.html:12 -msgid "Ratings" -msgstr "Valutazioni" - -#: contrib/comments/templates/comments/form.html:12 -#: contrib/comments/templates/comments/form.html:23 -msgid "Required" -msgstr "Obbligatorio" - -#: contrib/comments/templates/comments/form.html:12 -#: contrib/comments/templates/comments/form.html:23 -msgid "Optional" -msgstr "Facoltativo" - -#: contrib/comments/templates/comments/form.html:23 -msgid "Post a photo" -msgstr "Invia una foto" - -#: contrib/comments/templates/comments/form.html:28 -#: contrib/comments/templates/comments/freeform.html:5 -msgid "Comment:" -msgstr "Commento:" +#: contrib/comments/views/karma.py:20 +msgid "Anonymous users cannot vote" +msgstr "Gli utenti anonimi non possono votare" -#: contrib/comments/templates/comments/form.html:35 -#: contrib/comments/templates/comments/freeform.html:10 -msgid "Preview comment" -msgstr "Anteprima commento" +#: contrib/comments/views/karma.py:24 +msgid "Invalid comment ID" +msgstr "ID commento non valido" -#: contrib/comments/templates/comments/freeform.html:4 -msgid "Your name:" -msgstr "Il suo nome:" +#: contrib/comments/views/karma.py:26 +msgid "No voting for yourself" +msgstr "Impossibile votare per se stessi" -#: contrib/comments/views/comments.py:27 +#: contrib/comments/views/comments.py:28 msgid "" "This rating is required because you've entered at least one other rating." msgstr "" "Questa valutazione è obbligatoria perché hai inserito almeno un'altra " "valutazione." -#: contrib/comments/views/comments.py:111 +#: contrib/comments/views/comments.py:112 #, python-format msgid "" "This comment was posted by a user who has posted fewer than %(count)s " @@ -1512,7 +2056,7 @@ msgstr[1] "" "\n" "%(text)s" -#: contrib/comments/views/comments.py:116 +#: contrib/comments/views/comments.py:117 #, python-format msgid "" "This comment was posted by a sketchy user:\n" @@ -1523,23 +2067,23 @@ msgstr "" "\n" "%(text)s" -#: contrib/comments/views/comments.py:188 -#: contrib/comments/views/comments.py:280 +#: contrib/comments/views/comments.py:189 +#: contrib/comments/views/comments.py:281 msgid "Only POSTs are allowed" msgstr "Sono ammessi solo POST" -#: contrib/comments/views/comments.py:192 -#: contrib/comments/views/comments.py:284 +#: contrib/comments/views/comments.py:193 +#: contrib/comments/views/comments.py:285 msgid "One or more of the required fields wasn't submitted" msgstr "Uno o più campi richiesti non sono stati inseriti" -#: contrib/comments/views/comments.py:196 -#: contrib/comments/views/comments.py:286 +#: contrib/comments/views/comments.py:197 +#: contrib/comments/views/comments.py:287 msgid "Somebody tampered with the comment form (security violation)" msgstr "Qualcuno ha alterato il modulo di commento (violazione di sicurezza)" -#: contrib/comments/views/comments.py:206 -#: contrib/comments/views/comments.py:292 +#: contrib/comments/views/comments.py:207 +#: contrib/comments/views/comments.py:293 msgid "" "The comment form had an invalid 'target' parameter -- the object ID was " "invalid" @@ -1547,176 +2091,215 @@ msgstr "" "Il modulo di commento ha un parametro 'target' non valido -- l'ID " "dell'oggetto non è valido" -#: contrib/comments/views/comments.py:257 -#: contrib/comments/views/comments.py:321 +#: contrib/comments/views/comments.py:258 +#: contrib/comments/views/comments.py:322 msgid "The comment form didn't provide either 'preview' or 'post'" msgstr "Il modulo di commento non fornisce né 'anteprima' né 'invia'" -#: contrib/comments/views/karma.py:19 -msgid "Anonymous users cannot vote" -msgstr "Gli utenti anonimi non possono votare" +#: contrib/comments/templates/comments/form.html:8 +msgid "Forgotten your password?" +msgstr "Hai dimenticato la password?" -#: contrib/comments/views/karma.py:23 -msgid "Invalid comment ID" -msgstr "ID commento non valido" +#: contrib/comments/templates/comments/form.html:12 +msgid "Ratings" +msgstr "Valutazioni" -#: contrib/comments/views/karma.py:25 -msgid "No voting for yourself" -msgstr "Impossibile votare per se stessi" +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Required" +msgstr "Obbligatorio" -#: contrib/contenttypes/models.py:36 -msgid "python model class name" -msgstr "nome della classe modello in Python" +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Optional" +msgstr "Facoltativo" -#: contrib/contenttypes/models.py:39 -msgid "content type" -msgstr "content type" +#: contrib/comments/templates/comments/form.html:23 +msgid "Post a photo" +msgstr "Inserisci una foto" -#: contrib/contenttypes/models.py:40 -msgid "content types" -msgstr "content type" +#: contrib/comments/templates/comments/form.html:28 +#: contrib/comments/templates/comments/freeform.html:5 +msgid "Comment:" +msgstr "Commento:" -#: contrib/flatpages/models.py:8 -msgid "" -"Example: '/about/contact/'. Make sure to have leading and trailing slashes." -msgstr "" -"Esempio: '/about/contact/'. Assicurarsi di inserire le barre diagonali " -"iniziali e finali." +#: contrib/comments/templates/comments/form.html:35 +#: contrib/comments/templates/comments/freeform.html:10 +msgid "Preview comment" +msgstr "Anteprima commento" -#: contrib/flatpages/models.py:9 -msgid "title" -msgstr "titolo" +#: contrib/comments/templates/comments/freeform.html:4 +msgid "Your name:" +msgstr "Il tuo nome:" -#: contrib/flatpages/models.py:10 -msgid "content" -msgstr "contenuto" +#: contrib/localflavor/au/forms.py:18 +msgid "Enter a 4 digit post code." +msgstr "Inserire un codice postale di 4 cifre." -#: contrib/flatpages/models.py:11 -msgid "enable comments" -msgstr "abilita commenti" +#: contrib/localflavor/br/forms.py:18 +msgid "Enter a zip code in the format XXXXX-XXX." +msgstr "Inserire un codice postale nel formato XXXXX-XXX ." -#: contrib/flatpages/models.py:12 -msgid "template name" -msgstr "nome modello" +#: contrib/localflavor/br/forms.py:30 +msgid "Phone numbers must be in XX-XXXX-XXXX format." +msgstr "I numeri di telefono devono essere in formato XX-XXXX-XXXX ." -#: contrib/flatpages/models.py:13 +#: contrib/localflavor/br/forms.py:72 +msgid "This field requires only numbers." +msgstr "In questo campo possono essere solo presenti numeri." + +#: contrib/localflavor/br/forms.py:74 +msgid "This field requires at most 11 digits or 14 characters." +msgstr "Questo campo richiede non più di 11 cifre, o 14 caratteri." + +#: contrib/localflavor/br/forms.py:84 +msgid "Invalid CPF number." +msgstr "Numero CPF non valido." + +#: contrib/localflavor/br/forms.py:106 +msgid "This field requires at least 14 digits" +msgstr "Questo campo richiede almeno 14 cifre." + +#: contrib/localflavor/br/forms.py:116 +msgid "Invalid CNPJ number." +msgstr "Numero CNPJ non valido." + +#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:14 +msgid "Enter a zip code in the format XXXX." +msgstr "Inserire un codice postale nel formato XXXXX ." + +#: contrib/localflavor/ch/forms.py:90 msgid "" -"Example: 'flatpages/contact_page.html'. If this isn't provided, the system " -"will use 'flatpages/default.html'." +"Enter a valid Swiss identity or passport card number in X1234567<0 or " +"1234567890 format." msgstr "" -"Esempio: 'flatpages/contact_page.html'. Se non specificato, il sistema userà " -"'flatpages/default.html'." +"Inserire un numero di carta d'identità o passaporto svizzeri validi, in " +"formato X1234567<0 o 1234567890 ." -#: contrib/flatpages/models.py:14 -msgid "registration required" -msgstr "registrazione obbligatoria" +#: contrib/localflavor/ch/ch_states.py:5 +msgid "Aargau" +msgstr "" -#: contrib/flatpages/models.py:14 -msgid "If this is checked, only logged-in users will be able to view the page." +#: contrib/localflavor/ch/ch_states.py:6 +msgid "Appenzell Innerrhoden" msgstr "" -"Se selezionato, solo gli utenti che hanno effettuato l'accesso potranno " -"vedere la pagina." -#: contrib/flatpages/models.py:18 -msgid "flat page" -msgstr "pagina statica" +#: contrib/localflavor/ch/ch_states.py:7 +msgid "Appenzell Ausserrhoden" +msgstr "" -#: contrib/flatpages/models.py:19 -msgid "flat pages" -msgstr "pagine statiche" +#: contrib/localflavor/ch/ch_states.py:8 +msgid "Basel-Stadt" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:17 -msgid "th" +#: contrib/localflavor/ch/ch_states.py:9 +msgid "Basel-Land" msgstr "" -#: contrib/humanize/templatetags/humanize.py:17 -#, fuzzy -msgid "st" -msgstr "º" +#: contrib/localflavor/ch/ch_states.py:10 +msgid "Berne" +msgstr "Berna" -#: contrib/humanize/templatetags/humanize.py:17 -#, fuzzy -msgid "nd" -msgstr "º" +#: contrib/localflavor/ch/ch_states.py:11 +msgid "Fribourg" +msgstr "Friburgo" -#: contrib/humanize/templatetags/humanize.py:17 -msgid "rd" -msgstr "º" +#: contrib/localflavor/ch/ch_states.py:12 +msgid "Geneva" +msgstr "Ginevra" -#: contrib/humanize/templatetags/humanize.py:47 -#, python-format -msgid "%(value).1f million" -msgid_plural "%(value).1f million" -msgstr[0] "%(value).1f milione" -msgstr[1] "%(value).1f milioni" +#: contrib/localflavor/ch/ch_states.py:13 +msgid "Glarus" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:50 -#, python-format -msgid "%(value).1f billion" -msgid_plural "%(value).1f billion" -msgstr[0] "%(value).1f miliardo" -msgstr[1] "%(value).1f miliardi" +#: contrib/localflavor/ch/ch_states.py:14 +msgid "Graubuenden" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:53 -#, python-format -msgid "%(value).1f trillion" -msgid_plural "%(value).1f trillion" -msgstr[0] "" -msgstr[1] "" +#: contrib/localflavor/ch/ch_states.py:15 +msgid "Jura" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "one" +#: contrib/localflavor/ch/ch_states.py:16 +msgid "Lucerne" +msgstr "Lucerna" + +#: contrib/localflavor/ch/ch_states.py:17 +msgid "Neuchatel" msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "two" -msgstr "due" +#: contrib/localflavor/ch/ch_states.py:18 +msgid "Nidwalden" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "three" -msgstr "tre" +#: contrib/localflavor/ch/ch_states.py:19 +msgid "Obwalden" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -#, fuzzy -msgid "four" -msgstr "quattro" +#: contrib/localflavor/ch/ch_states.py:20 +msgid "Schaffhausen" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "five" -msgstr "cinque" +#: contrib/localflavor/ch/ch_states.py:21 +msgid "Schwyz" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "six" -msgstr "sei" +#: contrib/localflavor/ch/ch_states.py:22 +msgid "Solothurn" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "seven" -msgstr "sette" +#: contrib/localflavor/ch/ch_states.py:23 +msgid "St. Gallen" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "eight" -msgstr "otto" +#: contrib/localflavor/ch/ch_states.py:24 +msgid "Thurgau" +msgstr "" -#: contrib/humanize/templatetags/humanize.py:68 -msgid "nine" -msgstr "nove" +#: contrib/localflavor/ch/ch_states.py:25 +msgid "Ticino" +msgstr "" -#: contrib/localflavor/au/forms.py:18 -#, fuzzy -msgid "Enter a 4 digit post code." -msgstr "Inserire una codici postale di 4 cifre." +#: contrib/localflavor/ch/ch_states.py:26 +msgid "Uri" +msgstr "" -#: contrib/localflavor/br/forms.py:18 -#, fuzzy -msgid "Enter a zip code in the format XXXXX-XXX." -msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX." +#: contrib/localflavor/ch/ch_states.py:27 +msgid "Valais" +msgstr "" -#: contrib/localflavor/br/forms.py:30 -#, fuzzy -msgid "Phone numbers must be in XX-XXXX-XXXX format." +#: contrib/localflavor/ch/ch_states.py:28 +msgid "Vaud" msgstr "" -"I numeri di telefono devono essere in formato XXX-XXX-XXXX. \"%s\" non è " -"valido." + +#: contrib/localflavor/ch/ch_states.py:29 +msgid "Zug" +msgstr "" + +#: contrib/localflavor/ch/ch_states.py:30 +msgid "Zurich" +msgstr "Zurigo" + +#: contrib/localflavor/cl/forms.py:32 +msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X." +msgstr "Inserire un RUT cileno valido. Il formato è XX.XXX.XXX-X ." + +#: contrib/localflavor/cl/forms.py:37 +msgid "Enter valid a Chilean RUT" +msgstr "Inserire un RUT cileno valido." + +#: contrib/localflavor/de/forms.py:16 contrib/localflavor/fi/forms.py:14 +#: contrib/localflavor/fr/forms.py:17 +msgid "Enter a zip code in the format XXXXX." +msgstr "Inserire un codice postale nel formato XXXXX ." + +#: contrib/localflavor/de/forms.py:60 +msgid "" +"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X " +"format." +msgstr "" +"Inserire un numero di carta d'identità tedesco valido nel formato " +"XXXXXXXXXXX-XXXXXXX-XXXXXXX-X ." #: contrib/localflavor/de/de_states.py:5 msgid "Baden-Wuerttemberg" @@ -1724,10 +2307,9 @@ msgstr "" #: contrib/localflavor/de/de_states.py:6 msgid "Bavaria" -msgstr "" +msgstr "Baviera" #: contrib/localflavor/de/de_states.py:7 -#, fuzzy msgid "Berlin" msgstr "Berlino" @@ -1744,7 +2326,6 @@ msgid "Hamburg" msgstr "Amburgo" #: contrib/localflavor/de/de_states.py:11 -#, fuzzy msgid "Hessen" msgstr "" @@ -1765,7 +2346,6 @@ msgid "Rhineland-Palatinate" msgstr "" #: contrib/localflavor/de/de_states.py:16 -#, fuzzy msgid "Saarland" msgstr "" @@ -1785,27 +2365,25 @@ msgstr "" msgid "Thuringia" msgstr "" -#: contrib/localflavor/de/forms.py:16 contrib/localflavor/fi/forms.py:14 -#: contrib/localflavor/fr/forms.py:17 contrib/localflavor/it/forms.py:14 -#, fuzzy -msgid "Enter a zip code in the format XXXXX." -msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX." - -#: contrib/localflavor/de/forms.py:60 -msgid "" -"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X " -"format." -msgstr "Inserire un numero tedesco di carta d'identità valido nel formato XXXXXXXXXXX-XXXXXXX-XXXXXXX-X." - #: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45 -#, fuzzy msgid "Enter a valid Finnish social security number." -msgstr "Inserire un numero valido di assisstenza sociale finlandese." +msgstr "Inserire un numero di assistenza sociale finlandese valido." + +#: contrib/localflavor/it/forms.py:16 +msgid "Enter a valid zip code." +msgstr "Inserire un codice postale valido." + +#: contrib/localflavor/it/forms.py:41 +msgid "Enter a valid Social Security number." +msgstr "Inserire un numero di assistenza sociale valido." + +#: contrib/localflavor/it/forms.py:68 +msgid "Enter a valid VAT number." +msgstr "Inserire una partita IVA valida." #: contrib/localflavor/jp/forms.py:21 -#, fuzzy msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX." -msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX." +msgstr "Inserire un codice postale nel formato XXXXXXX o XXX-XXXX ." #: contrib/localflavor/jp/jp_prefectures.py:4 msgid "Hokkaido" @@ -1860,9 +2438,8 @@ msgid "Tokyo" msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:17 -#, fuzzy msgid "Kanagawa" -msgstr "Kannada" +msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:18 msgid "Yamanashi" @@ -1933,9 +2510,8 @@ msgid "Tottori" msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:35 -#, fuzzy msgid "Shimane" -msgstr "Modifica" +msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:36 msgid "Okayama" @@ -1954,14 +2530,12 @@ msgid "Tokushima" msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:40 -#, fuzzy msgid "Kagawa" -msgstr "Kannada" +msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:41 -#, fuzzy msgid "Ehime" -msgstr "Orario" +msgstr "" #: contrib/localflavor/jp/jp_prefectures.py:42 msgid "Kochi" @@ -1999,595 +2573,467 @@ msgstr "" msgid "Okinawa" msgstr "" -#: contrib/localflavor/no/forms.py:15 -#, fuzzy -msgid "Enter a zip code in the format XXXX." -msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX." - -#: contrib/localflavor/no/forms.py:36 -#, fuzzy +#: contrib/localflavor/no/forms.py:35 msgid "Enter a valid Norwegian social security number." -msgstr "Inserire un numero decimale valido." +msgstr "Inserire un numero di assistenza sociale norvegese valido." -#: contrib/localflavor/uk/forms.py:18 -msgid "Enter a postcode. A space is required between the two postcode parts." +#: contrib/localflavor/sk/forms.py:32 +msgid "Enter a postal code in the format XXXXX or XXX XX." +msgstr "Inserire un codice postale nel formato XXXXX o XXX XX ." + +#: contrib/localflavor/sk/sk_districts.py:8 +msgid "Banska Bystrica" msgstr "" -"Inserire un codice postale. È obbligatorio uno spazio tra le due parti del " -"codice postale." -#: contrib/localflavor/us/forms.py:18 -msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX." -msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX." +#: contrib/localflavor/sk/sk_districts.py:9 +msgid "Banska Stiavnica" +msgstr "" -#: contrib/localflavor/us/forms.py:51 -msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format." -msgstr "Inserire un numero di assistenza sociale statunitense valido, nel formato XXX-XX-XXXX." +#: contrib/localflavor/sk/sk_districts.py:10 +msgid "Bardejov" +msgstr "" -#: contrib/redirects/models.py:7 -msgid "redirect from" -msgstr "redirigi da" +#: contrib/localflavor/sk/sk_districts.py:11 +msgid "Banovce nad Bebravou" +msgstr "" -#: contrib/redirects/models.py:8 -msgid "" -"This should be an absolute path, excluding the domain name. Example: '/" -"events/search/'." +#: contrib/localflavor/sk/sk_districts.py:12 +msgid "Brezno" msgstr "" -"Deve essere un percorso assoluto, senza nome di dominio. Esempio: '/events/" -"search/'." -#: contrib/redirects/models.py:9 -msgid "redirect to" -msgstr "redirigi verso" +#: contrib/localflavor/sk/sk_districts.py:13 +msgid "Bratislava I" +msgstr "" -#: contrib/redirects/models.py:10 -msgid "" -"This can be either an absolute path (as above) or a full URL starting with " -"'http://'." +#: contrib/localflavor/sk/sk_districts.py:14 +msgid "Bratislava II" msgstr "" -"Può essere un percorso assoluto (come sopra) o una URL completa che inizia " -"con 'http://'." -#: contrib/redirects/models.py:13 -msgid "redirect" -msgstr "redirezione" +#: contrib/localflavor/sk/sk_districts.py:15 +msgid "Bratislava III" +msgstr "" -#: contrib/redirects/models.py:14 -msgid "redirects" -msgstr "redirezioni" +#: contrib/localflavor/sk/sk_districts.py:16 +msgid "Bratislava IV" +msgstr "" -#: contrib/sessions/models.py:68 -msgid "session key" -msgstr "chiave di sessione" +#: contrib/localflavor/sk/sk_districts.py:17 +msgid "Bratislava V" +msgstr "" -#: contrib/sessions/models.py:69 -msgid "session data" -msgstr "dati di sessione" +#: contrib/localflavor/sk/sk_districts.py:18 +msgid "Bytca" +msgstr "" -#: contrib/sessions/models.py:70 -msgid "expire date" -msgstr "data di scadenza" +#: contrib/localflavor/sk/sk_districts.py:19 +msgid "Cadca" +msgstr "" -#: contrib/sessions/models.py:74 -msgid "session" -msgstr "sessione" +#: contrib/localflavor/sk/sk_districts.py:20 +msgid "Detva" +msgstr "" -#: contrib/sessions/models.py:75 -msgid "sessions" -msgstr "sessioni" +#: contrib/localflavor/sk/sk_districts.py:21 +msgid "Dolny Kubin" +msgstr "" -#: contrib/sites/models.py:10 -msgid "domain name" -msgstr "nome di dominio" +#: contrib/localflavor/sk/sk_districts.py:22 +msgid "Dunajska Streda" +msgstr "" -#: contrib/sites/models.py:11 -msgid "display name" -msgstr "nome visualizzato" +#: contrib/localflavor/sk/sk_districts.py:23 +msgid "Galanta" +msgstr "" -#: contrib/sites/models.py:15 -msgid "site" -msgstr "sito" +#: contrib/localflavor/sk/sk_districts.py:24 +msgid "Gelnica" +msgstr "" -#: contrib/sites/models.py:16 -msgid "sites" -msgstr "siti" +#: contrib/localflavor/sk/sk_districts.py:25 +msgid "Hlohovec" +msgstr "" -#: core/validators.py:64 -msgid "This value must contain only letters, numbers and underscores." -msgstr "Questo valore può contenere solo lettere, cifre e sottolineature." +#: contrib/localflavor/sk/sk_districts.py:26 +msgid "Humenne" +msgstr "" -#: core/validators.py:68 -msgid "" -"This value must contain only letters, numbers, underscores, dashes or " -"slashes." +#: contrib/localflavor/sk/sk_districts.py:27 +msgid "Ilava" msgstr "" -"Questo valore può contenere solo lettere, cifre, sottolineature, trattini e " -"barre diagonali." -#: core/validators.py:72 -msgid "This value must contain only letters, numbers, underscores or hyphens." +#: contrib/localflavor/sk/sk_districts.py:28 +msgid "Kezmarok" msgstr "" -"Questo valore può contenere solo lettere, cifre, sottolineature e trattini." -#: core/validators.py:76 -msgid "Uppercase letters are not allowed here." -msgstr "Non sono ammesse lettere maiuscole." +#: contrib/localflavor/sk/sk_districts.py:29 +msgid "Komarno" +msgstr "" -#: core/validators.py:80 -msgid "Lowercase letters are not allowed here." -msgstr "Non sono ammesse lettere minuscole." +#: contrib/localflavor/sk/sk_districts.py:30 +msgid "Kosice I" +msgstr "" -#: core/validators.py:87 -msgid "Enter only digits separated by commas." -msgstr "Inserire solo cifre separate da virgole." +#: contrib/localflavor/sk/sk_districts.py:31 +msgid "Kosice II" +msgstr "" -#: core/validators.py:99 -msgid "Enter valid e-mail addresses separated by commas." -msgstr "Inserire indirizzi e-mail validi separati da virgole." +#: contrib/localflavor/sk/sk_districts.py:32 +msgid "Kosice III" +msgstr "" -#: core/validators.py:103 -msgid "Please enter a valid IP address." -msgstr "Inserire un indirizzo IP valido." +#: contrib/localflavor/sk/sk_districts.py:33 +msgid "Kosice IV" +msgstr "" -#: core/validators.py:107 -msgid "Empty values are not allowed here." -msgstr "È necessario inserire un valore." +#: contrib/localflavor/sk/sk_districts.py:34 +msgid "Kosice - okolie" +msgstr "" -#: core/validators.py:111 -msgid "Non-numeric characters aren't allowed here." -msgstr "Sono ammessi soltanto caratteri numerici." +#: contrib/localflavor/sk/sk_districts.py:35 +msgid "Krupina" +msgstr "" -#: core/validators.py:115 -msgid "This value can't be comprised solely of digits." -msgstr "Questo valore non può essere composto solo da cifre." +#: contrib/localflavor/sk/sk_districts.py:36 +msgid "Kysucke Nove Mesto" +msgstr "" -#: core/validators.py:120 newforms/fields.py:128 -msgid "Enter a whole number." -msgstr "Inserire un numero intero." +#: contrib/localflavor/sk/sk_districts.py:37 +msgid "Levice" +msgstr "" -#: core/validators.py:124 -msgid "Only alphabetical characters are allowed here." -msgstr "Sono ammessi solo caratteri alfabetici." +#: contrib/localflavor/sk/sk_districts.py:38 +msgid "Levoca" +msgstr "" -#: core/validators.py:139 -msgid "Year must be 1900 or later." -msgstr "L'anno deve essere 1900 o successivo." +#: contrib/localflavor/sk/sk_districts.py:39 +msgid "Liptovsky Mikulas" +msgstr "" -#: core/validators.py:143 -#, fuzzy, python-format -msgid "Invalid date: %s" -msgstr "Data non valida: %s." +#: contrib/localflavor/sk/sk_districts.py:40 +msgid "Lucenec" +msgstr "" -#: core/validators.py:148 db/models/fields/__init__.py:457 -msgid "Enter a valid date in YYYY-MM-DD format." -msgstr "Inserire una data valida in formato AAAA-MM-GG." +#: contrib/localflavor/sk/sk_districts.py:41 +msgid "Malacky" +msgstr "" -#: core/validators.py:153 -msgid "Enter a valid time in HH:MM format." -msgstr "Inserire un orario valido in formato OO:MM." +#: contrib/localflavor/sk/sk_districts.py:42 +msgid "Martin" +msgstr "" -#: core/validators.py:157 db/models/fields/__init__.py:526 -msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." -msgstr "Inserire una data/ora valida in formato AAAA-MM-GG OO:MM." +#: contrib/localflavor/sk/sk_districts.py:43 +msgid "Medzilaborce" +msgstr "" -#: core/validators.py:162 newforms/fields.py:271 -msgid "Enter a valid e-mail address." -msgstr "Inserire un indirizzo e-mail valido." +#: contrib/localflavor/sk/sk_districts.py:44 +msgid "Michalovce" +msgstr "" -#: core/validators.py:174 core/validators.py:445 oldforms/__init__.py:672 -msgid "No file was submitted. Check the encoding type on the form." +#: contrib/localflavor/sk/sk_districts.py:45 +msgid "Myjava" msgstr "" -"Non è stato inviato alcun file. Verificare il tipo di codifica della form." -#: core/validators.py:178 -msgid "" -"Upload a valid image. The file you uploaded was either not an image or a " -"corrupted image." +#: contrib/localflavor/sk/sk_districts.py:46 +msgid "Namestovo" msgstr "" -"Caricare un'immagine valida. Il file caricato non è un'immagine o è corrotto." -#: core/validators.py:185 -#, python-format -msgid "The URL %s does not point to a valid image." -msgstr "La URL %s non punta ad un'immagine valida." +#: contrib/localflavor/sk/sk_districts.py:47 +msgid "Nitra" +msgstr "" -#: core/validators.py:189 -#, python-format -msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." +#: contrib/localflavor/sk/sk_districts.py:48 +msgid "Nove Mesto nad Vahom" msgstr "" -"I numeri di telefono devono essere in formato XXX-XXX-XXXX. \"%s\" non è " -"valido." -#: core/validators.py:197 -#, python-format -msgid "The URL %s does not point to a valid QuickTime video." -msgstr "La URL %s non punta ad un video QuickTime valido." +#: contrib/localflavor/sk/sk_districts.py:49 +msgid "Nove Zamky" +msgstr "" -#: core/validators.py:201 -msgid "A valid URL is required." -msgstr "Inserire una URL valida." +#: contrib/localflavor/sk/sk_districts.py:50 +msgid "Partizanske" +msgstr "" -#: core/validators.py:215 -#, python-format -msgid "" -"Valid HTML is required. Specific errors are:\n" -"%s" +#: contrib/localflavor/sk/sk_districts.py:51 +msgid "Pezinok" msgstr "" -"È richiesto HTML valido. Gli errori sono i seguenti:\n" -"%s" -#: core/validators.py:222 -#, python-format -msgid "Badly formed XML: %s" -msgstr "XML malformato: %s" +#: contrib/localflavor/sk/sk_districts.py:52 +msgid "Piestany" +msgstr "" -#: core/validators.py:239 -#, python-format -msgid "Invalid URL: %s" -msgstr "URL non valida: %s" +#: contrib/localflavor/sk/sk_districts.py:53 +msgid "Poltar" +msgstr "" -#: core/validators.py:244 core/validators.py:246 -#, python-format -msgid "The URL %s is a broken link." -msgstr "La URL %s è un link non funzionante." +#: contrib/localflavor/sk/sk_districts.py:54 +msgid "Poprad" +msgstr "" -#: core/validators.py:252 -msgid "Enter a valid U.S. state abbreviation." -msgstr "Inserire un valido nome di stato USA abbreviato." +#: contrib/localflavor/sk/sk_districts.py:55 +msgid "Povazska Bystrica" +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] "Moderare i termini: la parola %s non è ammessa." -msgstr[1] "Moderare i termini: le parole %s non sono ammesse." +#: contrib/localflavor/sk/sk_districts.py:56 +msgid "Presov" +msgstr "" -#: core/validators.py:273 -#, python-format -msgid "This field must match the '%s' field." -msgstr "Questo campo deve corrispondere al campo '%s'." +#: contrib/localflavor/sk/sk_districts.py:57 +msgid "Prievidza" +msgstr "" -#: core/validators.py:292 -msgid "Please enter something for at least one field." -msgstr "Inserire qualcosa in almeno un campo." +#: contrib/localflavor/sk/sk_districts.py:58 +msgid "Puchov" +msgstr "" -#: core/validators.py:301 core/validators.py:312 -msgid "Please enter both fields or leave them both empty." -msgstr "Inserire entrambi i campi o lasciarli entrambi vuoti." +#: contrib/localflavor/sk/sk_districts.py:59 +msgid "Revuca" +msgstr "" -#: core/validators.py:320 -#, python-format -msgid "This field must be given if %(field)s is %(value)s" -msgstr "Questo campo è obbligatorio se %(field)s è %(value)s" +#: contrib/localflavor/sk/sk_districts.py:60 +msgid "Rimavska Sobota" +msgstr "" -#: core/validators.py:333 -#, python-format -msgid "This field must be given if %(field)s is not %(value)s" -msgstr "Questo campo è obbligatorio se %(field)s non è %(value)s" +#: contrib/localflavor/sk/sk_districts.py:61 +msgid "Roznava" +msgstr "" -#: core/validators.py:352 -msgid "Duplicate values are not allowed." -msgstr "Non sono ammessi valori duplicati." +#: contrib/localflavor/sk/sk_districts.py:62 +msgid "Ruzomberok" +msgstr "" -#: core/validators.py:367 -#, fuzzy, python-format -msgid "This value must be between %(lower)s and %(upper)s." -msgstr "Questo valore deve essere compreso tra %s e %s." +#: contrib/localflavor/sk/sk_districts.py:63 +msgid "Sabinov" +msgstr "" -#: core/validators.py:369 -#, python-format -msgid "This value must be at least %s." -msgstr "Questo valore deve essere almeno pari a %s." +#: contrib/localflavor/sk/sk_districts.py:64 +msgid "Senec" +msgstr "" -#: core/validators.py:371 -#, python-format -msgid "This value must be no more than %s." -msgstr "Questo valore non deve essere maggiore di %s." +#: contrib/localflavor/sk/sk_districts.py:65 +msgid "Senica" +msgstr "" -#: core/validators.py:407 -#, python-format -msgid "This value must be a power of %s." -msgstr "Questo valore deve essere una potenza di %s." +#: contrib/localflavor/sk/sk_districts.py:66 +msgid "Skalica" +msgstr "" -#: core/validators.py:418 -msgid "Please enter a valid decimal number." -msgstr "Inserire un numero decimale valido." +#: contrib/localflavor/sk/sk_districts.py:67 +msgid "Snina" +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] "Inserire un numero decimale con non più di %s cifra in totale." -msgstr[1] "Inserire un numero decimale con non più di %s cifre in totale." +#: contrib/localflavor/sk/sk_districts.py:68 +msgid "Sobrance" +msgstr "" -#: 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] "" -"Inserire un numero decimale la cui parte intera sia composta da non più di %" -"s cifra." -msgstr[1] "" -"Inserire un numero decimale la cui parte intera sia composta da non più di %" -"s cifre." +#: contrib/localflavor/sk/sk_districts.py:69 +msgid "Spisska Nova Ves" +msgstr "" -#: 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] "Inserire un decimale con non più di %s cifra decimale." -msgstr[1] "Inserire un decimale con non più di %s cifre decimali." +#: contrib/localflavor/sk/sk_districts.py:70 +msgid "Stara Lubovna" +msgstr "" -#: core/validators.py:438 -#, python-format -msgid "Make sure your uploaded file is at least %s bytes big." -msgstr "Verificare che il file caricato sia grande almeno %s byte." +#: contrib/localflavor/sk/sk_districts.py:71 +msgid "Stropkov" +msgstr "" -#: core/validators.py:439 -#, python-format -msgid "Make sure your uploaded file is at most %s bytes big." -msgstr "Verificare che il file caricato non sia più grande di %s byte." +#: contrib/localflavor/sk/sk_districts.py:72 +msgid "Svidnik" +msgstr "" -#: core/validators.py:456 -msgid "The format for this field is wrong." -msgstr "Il formato di questo campo non è valido." +#: contrib/localflavor/sk/sk_districts.py:73 +msgid "Sala" +msgstr "" -#: core/validators.py:471 -msgid "This field is invalid." -msgstr "Questo campo non è valido." +#: contrib/localflavor/sk/sk_districts.py:74 +msgid "Topolcany" +msgstr "" -#: core/validators.py:507 -#, python-format -msgid "Could not retrieve anything from %s." -msgstr "Impossibile recuperare alcunché da %s." +#: contrib/localflavor/sk/sk_districts.py:75 +msgid "Trebisov" +msgstr "" -#: core/validators.py:510 -#, python-format -msgid "" -"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." +#: contrib/localflavor/sk/sk_districts.py:76 +msgid "Trencin" msgstr "" -"La URL %(url)s ha restituito un header Content-Type non valido: '%" -"(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\".)" +#: contrib/localflavor/sk/sk_districts.py:77 +msgid "Trnava" msgstr "" -"Chiudere il tag %(tag)s a linea %(line)s. (La linea inizia con \"%(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\".)" +#: contrib/localflavor/sk/sk_districts.py:78 +msgid "Turcianske Teplice" msgstr "" -"Il testo che comincia a linea %(line)s non e' ammesso in questo contesto. " -"(La linea comincia con \"%(start)s\".)" -#: core/validators.py:552 -#, python-format -msgid "" -"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" -"(start)s\".)" +#: contrib/localflavor/sk/sk_districts.py:79 +msgid "Tvrdosin" msgstr "" -"\"%(attr)s\" a linea %(line)s non è un attributo valido. (La linea comincia " -"con \"%(start)s\".)" -#: core/validators.py:557 -#, python-format -msgid "" -"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" -"(start)s\".)" +#: contrib/localflavor/sk/sk_districts.py:80 +msgid "Velky Krtis" msgstr "" -"\"<%(tag)s>\" a linea %(line)s non è un tag valido. (La linea comincia con " -"\"%(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\".)" +#: contrib/localflavor/sk/sk_districts.py:81 +msgid "Vranov nad Toplou" msgstr "" -"Un tag a linea %(line)s manca di uno o più attributi richiesti. (La linea " -"comincia con \"%(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\".)" +#: contrib/localflavor/sk/sk_districts.py:82 +msgid "Zlate Moravce" msgstr "" -"L'attributo \"%(attr)s\" a linea %(line)s ha un valore non valido. (La linea " -"comincia con \"%(start)s\".)" -#: db/models/manipulators.py:307 -#, python-format -msgid "%(object)s with this %(type)s already exists for the given %(field)s." -msgstr "%(object)s·con questo·%(type)s·esiste già per questo·%(field)s." +#: contrib/localflavor/sk/sk_districts.py:83 +msgid "Zvolen" +msgstr "" -#: db/models/fields/__init__.py:42 -#, python-format -msgid "%(optname)s with this %(fieldname)s already exists." -msgstr "%(optname)s·con questo·%(fieldname)s·esiste già." +#: contrib/localflavor/sk/sk_districts.py:84 +msgid "Zarnovica" +msgstr "" -#: db/models/fields/__init__.py:117 db/models/fields/__init__.py:274 -#: db/models/fields/__init__.py:610 db/models/fields/__init__.py:621 -#: newforms/fields.py:80 newforms/fields.py:376 newforms/fields.py:452 -#: newforms/fields.py:463 newforms/models.py:178 oldforms/__init__.py:357 -msgid "This field is required." -msgstr "Questo campo è obbligatorio." +#: contrib/localflavor/sk/sk_districts.py:85 +msgid "Ziar nad Hronom" +msgstr "" -#: db/models/fields/__init__.py:367 -msgid "This value must be an integer." -msgstr "Questo valore deve essere un intero." +#: contrib/localflavor/sk/sk_districts.py:86 +msgid "Zilina" +msgstr "" -#: db/models/fields/__init__.py:402 -msgid "This value must be either True or False." -msgstr "Questo valore deve essere True o False." +#: contrib/localflavor/sk/sk_regions.py:8 +msgid "Banska Bystrica region" +msgstr "" -#: db/models/fields/__init__.py:423 -msgid "This field cannot be null." -msgstr "Questo campo non può essere nullo." +#: contrib/localflavor/sk/sk_regions.py:9 +msgid "Bratislava region" +msgstr "" -#: db/models/fields/__init__.py:630 -msgid "Enter a valid filename." -msgstr "Inserire un nome file valido." +#: contrib/localflavor/sk/sk_regions.py:10 +msgid "Kosice region" +msgstr "" -#: db/models/fields/__init__.py:751 -#, fuzzy -msgid "This value must be either None, True or False." -msgstr "Questo valore deve essere True o False." +#: contrib/localflavor/sk/sk_regions.py:11 +msgid "Nitra region" +msgstr "" -#: db/models/fields/related.py:53 -#, python-format -msgid "Please enter a valid %s." -msgstr "Inserire un %s valido." +#: contrib/localflavor/sk/sk_regions.py:12 +msgid "Presov region" +msgstr "" -#: db/models/fields/related.py:642 -msgid "Separate multiple IDs with commas." -msgstr "Separare ID multipli con virgole." +#: contrib/localflavor/sk/sk_regions.py:13 +msgid "Trencin region" +msgstr "" -#: db/models/fields/related.py:644 -msgid "" -"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +#: contrib/localflavor/sk/sk_regions.py:14 +msgid "Trnava region" msgstr "" -"Tenere premuto \"Control\", o \"Command\" su Mac, per selezionarne più di " -"uno." -#: 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] "" -"Inserire un ID validi per %(self)s. Il valore %(value)r non è valido." -msgstr[1] "" -"Inserire un ID validi per %(self)s. I valori %(value)r non sono validi." +#: contrib/localflavor/sk/sk_regions.py:15 +msgid "Zilina region" +msgstr "" -#: newforms/fields.py:103 newforms/fields.py:256 -#, python-format -msgid "Ensure this value has at most %d characters." -msgstr "Assicurarsi che questo valore non contenga più di %d caratteri." +#: contrib/localflavor/uk/forms.py:18 +msgid "Enter a postcode. A space is required between the two postcode parts." +msgstr "" +"Inserire un codice postale. È obbligatorio uno spazio tra le due parti del " +"codice postale." -#: newforms/fields.py:105 newforms/fields.py:258 -#, python-format -msgid "Ensure this value has at least %d characters." -msgstr "Assicurarsi che questo valore contenga almeno %d caratteri." +#: contrib/localflavor/us/forms.py:18 +msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX." +msgstr "Inserire un codice postale nel formato XXXXX o XXXXX-XXXX ." -#: newforms/fields.py:130 -#, python-format -msgid "Ensure this value is less than or equal to %s." -msgstr "Assicurarsi che questo valore sia minore o uguale a %s." +#: contrib/localflavor/us/forms.py:51 +msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format." +msgstr "" +"Inserire un numero di assistenza sociale statunitense valido, nel formato " +"XXX-XX-XXXX ." -#: newforms/fields.py:132 -#, python-format -msgid "Ensure this value is greater than or equal to %s." -msgstr "Assicurarsi che questo valore sia maggiore o uguale a %s." +#: contrib/localflavor/is_/forms.py:17 +msgid "" +"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX." +msgstr "" +"Inserire un numero di identificazione islandese valido. Il formato è XXXXXX-" +"XXXX ." -#: newforms/fields.py:165 -msgid "Enter a valid date." -msgstr "Inserire una data valida." +#: contrib/localflavor/is_/forms.py:31 +msgid "The Icelandic identification number is not valid." +msgstr "Il numero di identificazione islandese non è valido." -#: newforms/fields.py:192 -msgid "Enter a valid time." -msgstr "Inserire un orario valido." +#: contrib/sessions/models.py:68 +msgid "session key" +msgstr "chiave di sessione" -#: newforms/fields.py:228 -msgid "Enter a valid date/time." -msgstr "Inserire una coppia data/orario valida." +#: contrib/sessions/models.py:69 +msgid "session data" +msgstr "dati di sessione" -#: newforms/fields.py:242 -msgid "Enter a valid value." -msgstr "Inserire un valore valido." +#: contrib/sessions/models.py:70 +msgid "expire date" +msgstr "data di scadenza" -#: newforms/fields.py:289 newforms/fields.py:311 -msgid "Enter a valid URL." -msgstr "Inserire una URL valida." +#: contrib/sessions/models.py:74 +msgid "session" +msgstr "sessione" -#: newforms/fields.py:313 -msgid "This URL appears to be a broken link." -msgstr "Questa URL non sembra funzionare." +#: contrib/sessions/models.py:75 +msgid "sessions" +msgstr "sessioni" -#: newforms/fields.py:362 newforms/models.py:165 -msgid "Select a valid choice. That choice is not one of the available choices." -msgstr "" -"Selezionare un'opzione valida. La scelta effettuata non compare tra quelle " -"disponibili." +#: contrib/contenttypes/models.py:37 +msgid "python model class name" +msgstr "nome della classe del modello Python" -#: newforms/fields.py:380 newforms/fields.py:456 newforms/models.py:182 -msgid "Enter a list of values." -msgstr "Inserire una lista di valori." +#: contrib/contenttypes/models.py:40 +msgid "content type" +msgstr "content type" -#: newforms/fields.py:389 newforms/models.py:188 -#, python-format -msgid "Select a valid choice. %s is not one of the available choices." -msgstr "Selezionare un'opzione valida;'%s non compare tra quelle disponibili." +#: contrib/contenttypes/models.py:41 +msgid "content types" +msgstr "content type" -#: oldforms/__init__.py:392 +#: oldforms/__init__.py:408 #, python-format msgid "Ensure your text is less than %s character." msgid_plural "Ensure your text is less than %s characters." msgstr[0] "Assicurarsi che il testo sia più corto di %s carattere." msgstr[1] "Assicurarsi che il testo sia più corto di %s caratteri." -#: oldforms/__init__.py:397 +#: oldforms/__init__.py:413 msgid "Line breaks are not allowed here." -msgstr "Non sono ammessi a capo manuali." +msgstr "Non sono ammessi a capo manuali qui." -#: oldforms/__init__.py:498 oldforms/__init__.py:571 oldforms/__init__.py:610 +#: oldforms/__init__.py:511 oldforms/__init__.py:585 oldforms/__init__.py:624 #, python-format msgid "Select a valid choice; '%(data)s' is not in %(choices)s." -msgstr "Selezionare un'opzione valida; '%(data)s' non presente in %(choices)s." +msgstr "Scegliere un'opzione valida; '%(data)s' non presente in %(choices)s." -#: oldforms/__init__.py:674 +#: oldforms/__init__.py:688 newforms/fields.py:380 msgid "The submitted file is empty." msgstr "Il file inviato è vuoto." -#: oldforms/__init__.py:730 +#: oldforms/__init__.py:744 msgid "Enter a whole number between -32,768 and 32,767." -msgstr "Inserire un numero intero compreso tra -32.768 e 32.767." +msgstr "Inserire un numero intero compreso tra -32.768 e 32.767 ." -#: oldforms/__init__.py:740 +#: oldforms/__init__.py:754 msgid "Enter a positive number." msgstr "Inserire un numero positivo." -#: oldforms/__init__.py:750 +#: oldforms/__init__.py:764 msgid "Enter a whole number between 0 and 32,767." -msgstr "Inserire un numero intero compreso tra 0 e 32.767." - -#: template/defaultfilters.py:491 -msgid "yes,no,maybe" -msgstr "sì,no,forse" +msgstr "Inserire un numero intero compreso tra 0 e 32.767 ." -#: utils/dateformat.py:40 -msgid "p.m." -msgstr "" - -#: utils/dateformat.py:41 -msgid "a.m." -msgstr "" - -#: utils/dateformat.py:46 -msgid "PM" -msgstr "" - -#: utils/dateformat.py:47 -msgid "AM" -msgstr "" +#: views/generic/create_update.py:43 +#, python-format +msgid "The %(verbose_name)s was created successfully." +msgstr "%(verbose_name)s è stato creato correttamente." -#: utils/dateformat.py:95 -msgid "midnight" -msgstr "mezzanotte" +#: views/generic/create_update.py:117 +#, python-format +msgid "The %(verbose_name)s was updated successfully." +msgstr "%(verbose_name)s è stato aggiornato correttamente." -#: utils/dateformat.py:97 -msgid "noon" -msgstr "mezzogiorno" +#: views/generic/create_update.py:184 +#, python-format +msgid "The %(verbose_name)s was deleted." +msgstr "%(verbose_name)s è stato cancellato." #: utils/dates.py:6 msgid "Monday" @@ -2617,127 +3063,155 @@ msgstr "Sabato" msgid "Sunday" msgstr "Domenica" -#: utils/dates.py:14 +#: utils/dates.py:10 +msgid "Mon" +msgstr "Lun" + +#: utils/dates.py:10 +msgid "Tue" +msgstr "Mar" + +#: utils/dates.py:10 +msgid "Wed" +msgstr "Mer" + +#: utils/dates.py:10 +msgid "Thu" +msgstr "Gio" + +#: utils/dates.py:10 +msgid "Fri" +msgstr "Ven" + +#: utils/dates.py:11 +msgid "Sat" +msgstr "Sab" + +#: utils/dates.py:11 +msgid "Sun" +msgstr "Dom" + +#: utils/dates.py:18 msgid "January" msgstr "Gennaio" -#: utils/dates.py:14 +#: utils/dates.py:18 msgid "February" msgstr "Febbraio" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "March" msgstr "Marzo" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "April" msgstr "Aprile" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "May" msgstr "Maggio" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "June" msgstr "Giugno" -#: utils/dates.py:15 utils/dates.py:27 +#: utils/dates.py:19 utils/dates.py:31 msgid "July" msgstr "Luglio" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "August" msgstr "Agosto" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "September" msgstr "Settembre" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "October" msgstr "Ottobre" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "November" msgstr "Novembre" -#: utils/dates.py:16 +#: utils/dates.py:20 msgid "December" msgstr "Dicembre" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "jan" msgstr "gen" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "feb" msgstr "feb" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "mar" msgstr "mar" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "apr" msgstr "apr" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "may" msgstr "mag" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "jun" msgstr "giu" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "jul" msgstr "lug" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "aug" msgstr "ago" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "sep" msgstr "set" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "oct" msgstr "ott" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "nov" msgstr "nov" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "dec" msgstr "dic" -#: utils/dates.py:27 +#: utils/dates.py:31 msgid "Jan." msgstr "Gen." -#: utils/dates.py:27 +#: utils/dates.py:31 msgid "Feb." msgstr "Feb." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Aug." msgstr "Ago." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Sept." msgstr "Set." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Oct." msgstr "Ott." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Nov." msgstr "Nov." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Dec." msgstr "Dic." @@ -2777,40 +3251,168 @@ msgid_plural "minutes" msgstr[0] "minuto" msgstr[1] "minuti" -#: utils/translation/trans_real.py:358 +#: utils/timesince.py:39 +#, python-format +msgid "%(number)d %(type)s" +msgstr "%(number)d %(type)s" + +#: utils/timesince.py:45 +#, python-format +msgid ", %(number)d %(type)s" +msgstr ", %(number)d %(type)s" + +#: utils/dateformat.py:41 +msgid "p.m." +msgstr "" + +#: utils/dateformat.py:42 +msgid "a.m." +msgstr "" + +#: utils/dateformat.py:47 +msgid "PM" +msgstr "" + +#: utils/dateformat.py:48 +msgid "AM" +msgstr "" + +#: utils/dateformat.py:97 +msgid "midnight" +msgstr "mezzanotte" + +#: utils/dateformat.py:99 +msgid "noon" +msgstr "mezzogiorno" + +#: utils/translation/trans_real.py:391 msgid "DATE_FORMAT" msgstr "j F Y" -#: utils/translation/trans_real.py:359 +#: utils/translation/trans_real.py:392 msgid "DATETIME_FORMAT" msgstr "j F Y, H:i" -#: utils/translation/trans_real.py:360 +#: utils/translation/trans_real.py:393 msgid "TIME_FORMAT" msgstr "H:i" -#: utils/translation/trans_real.py:376 +#: utils/translation/trans_real.py:409 msgid "YEAR_MONTH_FORMAT" msgstr "Y F" -#: utils/translation/trans_real.py:377 +#: utils/translation/trans_real.py:410 msgid "MONTH_DAY_FORMAT" msgstr "F j" -#: views/generic/create_update.py:43 +#: template/defaultfilters.py:485 +msgid "yes,no,maybe" +msgstr "sì,no,forse" + +#: template/defaultfilters.py:514 #, python-format -msgid "The %(verbose_name)s was created successfully." -msgstr "%(verbose_name)s è stato creato correttamente." +msgid "%(size)d byte" +msgid_plural "%(size)d bytes" +msgstr[0] "%(size)d byte" +msgstr[1] "%(size)d byte" -#: views/generic/create_update.py:117 +#: template/defaultfilters.py:516 #, python-format -msgid "The %(verbose_name)s was updated successfully." -msgstr "%(verbose_name)s è stato aggiornato correttamente." +msgid "%.1f KB" +msgstr "" -#: views/generic/create_update.py:184 +#: template/defaultfilters.py:518 #, python-format -msgid "The %(verbose_name)s was deleted." -msgstr "%(verbose_name)s è stato cancellato." +msgid "%.1f MB" +msgstr "" + +#: template/defaultfilters.py:519 +#, python-format +msgid "%.1f GB" +msgstr "" + +#: newforms/fields.py:116 +#, fuzzy, python-format +msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." +msgstr "" +"Assicurarsi che questo valore non contenga più di %(max)d caratteri (ne ha " +"%(length))." + +#: newforms/fields.py:118 +#, fuzzy, python-format +msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." +msgstr "" +"Assicurarsi che questo valore contenga almeno %(min)d caratteri (ne ha " +"%(length))." + +#: newforms/fields.py:144 newforms/fields.py:167 newforms/fields.py:197 +#, python-format +msgid "Ensure this value is less than or equal to %s." +msgstr "Assicurarsi che questo valore sia minore o uguale a %s." -#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?" -#~ msgstr "Hai <a href=\"/password_reset/\">dimenticato la password</a>?" +#: newforms/fields.py:146 newforms/fields.py:169 newforms/fields.py:199 +#, python-format +msgid "Ensure this value is greater than or equal to %s." +msgstr "Assicurarsi che questo valore sia maggiore o uguale a %s." + +#: newforms/fields.py:165 newforms/fields.py:192 +msgid "Enter a number." +msgstr "Inserire un numero." + +#: newforms/fields.py:201 +#, python-format +msgid "Ensure that there are no more than %s digits in total." +msgstr "Assicurarsi che non vi siano più di %s cifre in totale." + +#: newforms/fields.py:203 +#, python-format +msgid "Ensure that there are no more than %s decimal places." +msgstr "Assicurarsi che non vi siano più di %s cifre decimali." + +#: newforms/fields.py:205 +#, python-format +msgid "Ensure that there are no more than %s digits before the decimal point." +msgstr "Assicurarsi che non vi siano più di %s cifre prima della virgola." + +#: newforms/fields.py:238 newforms/fields.py:610 +msgid "Enter a valid date." +msgstr "Inserire una data valida." + +#: newforms/fields.py:265 newforms/fields.py:612 +msgid "Enter a valid time." +msgstr "Inserire un ora valida." + +#: newforms/fields.py:301 +msgid "Enter a valid date/time." +msgstr "Inserire una coppia data/ora valida." + +#: newforms/fields.py:314 +msgid "Enter a valid value." +msgstr "Inserire un valore valido." + +#: newforms/fields.py:378 +msgid "No file was submitted." +msgstr "Nessun file è stato inviato." + +#: newforms/fields.py:403 newforms/fields.py:425 +msgid "Enter a valid URL." +msgstr "Inserire una URL valida." + +#: newforms/fields.py:427 +msgid "This URL appears to be a broken link." +msgstr "Questa URL non sembra funzionare." + +#: newforms/fields.py:478 newforms/models.py:180 +msgid "Select a valid choice. That choice is not one of the available choices." +msgstr "" +"Scegliere un'opzione valida. La scelta effettuata non compare tra quelle " +"disponibili." + +#: newforms/fields.py:494 newforms/fields.py:570 newforms/models.py:197 +msgid "Enter a list of values." +msgstr "Inserire una lista di valori." + +#: newforms/fields.py:500 newforms/models.py:203 +#, python-format +msgid "Select a valid choice. %s is not one of the available choices." +msgstr "Scegliere un'opzione valida. '%s non compare tra quelle disponibili." diff --git a/django/conf/locale/it/LC_MESSAGES/djangojs.mo b/django/conf/locale/it/LC_MESSAGES/djangojs.mo Binary files differindex c34009f148..49620a7942 100644 --- a/django/conf/locale/it/LC_MESSAGES/djangojs.mo +++ b/django/conf/locale/it/LC_MESSAGES/djangojs.mo diff --git a/django/conf/locale/it/LC_MESSAGES/djangojs.po b/django/conf/locale/it/LC_MESSAGES/djangojs.po index 4f01cd04a0..7c8d438855 100644 --- a/django/conf/locale/it/LC_MESSAGES/djangojs.po +++ b/django/conf/locale/it/LC_MESSAGES/djangojs.po @@ -38,7 +38,7 @@ msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato" #: contrib/admin/media/js/SelectFilter2.js:33 #, perl-format msgid "Available %s" -msgstr "Disponibile %s" +msgstr "%s disponibili" #: contrib/admin/media/js/SelectFilter2.js:41 msgid "Choose all" @@ -55,11 +55,11 @@ msgstr "Rimuovi" #: contrib/admin/media/js/SelectFilter2.js:53 #, perl-format msgid "Chosen %s" -msgstr "Scelto %s" +msgstr "%s scelti" #: contrib/admin/media/js/SelectFilter2.js:54 msgid "Select your choice(s) and click " -msgstr "Seleziona le tue scelte e clicca " +msgstr "Fai le tue scelte e clicca " #: contrib/admin/media/js/SelectFilter2.js:59 msgid "Clear all" diff --git a/django/conf/locale/sk/LC_MESSAGES/django.mo b/django/conf/locale/sk/LC_MESSAGES/django.mo Binary files differindex 9c8cfd3cd6..169f270969 100644 --- a/django/conf/locale/sk/LC_MESSAGES/django.mo +++ b/django/conf/locale/sk/LC_MESSAGES/django.mo diff --git a/django/conf/locale/sk/LC_MESSAGES/django.po b/django/conf/locale/sk/LC_MESSAGES/django.po index 98cc44579c..89dd4897bb 100644 --- a/django/conf/locale/sk/LC_MESSAGES/django.po +++ b/django/conf/locale/sk/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-23 18:09-0400\n" +"POT-Creation-Date: 2007-07-24 09:56-0400\n" "PO-Revision-Date: 2007-06-22 20:54-0400\n" "Last-Translator: Vlado <vlado@labath.org>\n" "Language-Team: Slovak <sk@li.org>\n" @@ -15,130 +15,130 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" -#: oldforms/__init__.py:361 db/models/fields/__init__.py:121 -#: db/models/fields/__init__.py:278 db/models/fields/__init__.py:675 -#: db/models/fields/__init__.py:686 newforms/models.py:185 -#: newforms/fields.py:87 newforms/fields.py:444 newforms/fields.py:520 -#: newforms/fields.py:531 +#: oldforms/__init__.py:369 db/models/fields/__init__.py:152 +#: db/models/fields/__init__.py:309 db/models/fields/__init__.py:706 +#: db/models/fields/__init__.py:717 newforms/models.py:187 +#: newforms/fields.py:92 newforms/fields.py:440 newforms/fields.py:516 +#: newforms/fields.py:527 msgid "This field is required." msgstr "Toto pole je povinné." -#: oldforms/__init__.py:396 +#: oldforms/__init__.py:404 #, python-format msgid "Ensure your text is less than %s character." msgid_plural "Ensure your text is less than %s characters." msgstr[0] "Uisite sa, že text je kratší ako %s znak." msgstr[1] "Uisite sa, že text je kratší ako %s znakov." -#: oldforms/__init__.py:401 +#: oldforms/__init__.py:409 msgid "Line breaks are not allowed here." msgstr "Zalomenia riadkov nie sú povolené." -#: oldforms/__init__.py:502 oldforms/__init__.py:575 oldforms/__init__.py:614 +#: oldforms/__init__.py:507 oldforms/__init__.py:581 oldforms/__init__.py:620 #, python-format msgid "Select a valid choice; '%(data)s' is not in %(choices)s." msgstr "Vyberte platnú možnosť; '%(data)s' nie je v %(choices)s." -#: oldforms/__init__.py:581 newforms/widgets.py:182 -#: contrib/admin/filterspecs.py:150 +#: oldforms/__init__.py:587 newforms/widgets.py:181 +#: contrib/admin/filterspecs.py:152 msgid "Unknown" msgstr "Neznámy" -#: oldforms/__init__.py:581 newforms/widgets.py:182 -#: contrib/admin/filterspecs.py:143 +#: oldforms/__init__.py:587 newforms/widgets.py:181 +#: contrib/admin/filterspecs.py:145 msgid "Yes" msgstr "Áno" -#: oldforms/__init__.py:581 newforms/widgets.py:182 -#: contrib/admin/filterspecs.py:143 +#: oldforms/__init__.py:587 newforms/widgets.py:181 +#: contrib/admin/filterspecs.py:145 msgid "No" msgstr "Nie" -#: oldforms/__init__.py:676 core/validators.py:175 core/validators.py:453 +#: oldforms/__init__.py:682 core/validators.py:181 core/validators.py:461 msgid "No file was submitted. Check the encoding type on the form." msgstr "" "Súbor nebol odoslaný. Skontrolujte atribút 'enctype' encoding vo formulári." -#: oldforms/__init__.py:678 +#: oldforms/__init__.py:684 msgid "The submitted file is empty." msgstr "Odoslaný súbor je prázdný." -#: oldforms/__init__.py:734 +#: oldforms/__init__.py:740 msgid "Enter a whole number between -32,768 and 32,767." msgstr "Zadajte celé číslo s hodnotou medzi -32768 a 32767." -#: oldforms/__init__.py:744 +#: oldforms/__init__.py:750 msgid "Enter a positive number." msgstr "Zadajte celé kladné číslo." -#: oldforms/__init__.py:754 +#: oldforms/__init__.py:760 msgid "Enter a whole number between 0 and 32,767." msgstr "Zadajte celé číslo s hodnotou medzi 0 a 32767." -#: db/models/manipulators.py:307 +#: db/models/manipulators.py:309 #, python-format msgid "%(object)s with this %(type)s already exists for the given %(field)s." msgstr "%(object)s s %(type)s už existuje pre prvok %(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 +#: db/models/manipulators.py:310 contrib/admin/views/main.py:342 +#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346 msgid "and" msgstr "a" -#: db/models/fields/__init__.py:46 +#: db/models/fields/__init__.py:48 #, python-format msgid "%(optname)s with this %(fieldname)s already exists." msgstr "%(optname)s s %(fieldname)s už existuje." -#: db/models/fields/__init__.py:373 +#: db/models/fields/__init__.py:404 msgid "This value must be an integer." msgstr "Táto hodnota musí byť celé číslo." -#: db/models/fields/__init__.py:408 +#: db/models/fields/__init__.py:439 msgid "This value must be either True or False." msgstr "Táto hodnota musí byť True alebo False." -#: db/models/fields/__init__.py:429 +#: db/models/fields/__init__.py:460 msgid "This field cannot be null." msgstr "Toto pole nemôže obsahovať null." -#: db/models/fields/__init__.py:463 core/validators.py:149 +#: db/models/fields/__init__.py:494 core/validators.py:155 msgid "Enter a valid date in YYYY-MM-DD format." msgstr "Zadajte platný dátum vo formáte RRRR-MM-DD." -#: db/models/fields/__init__.py:532 core/validators.py:158 +#: db/models/fields/__init__.py:563 core/validators.py:164 msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." msgstr "Zadajte platný dátum a čas vo formáte RRRR-MM-DD HH:MM." -#: db/models/fields/__init__.py:592 +#: db/models/fields/__init__.py:623 msgid "This value must be a decimal number." msgstr "Táto hodnota musí byť desiatkove číslo." -#: db/models/fields/__init__.py:695 +#: db/models/fields/__init__.py:726 msgid "Enter a valid filename." msgstr "Zadajte platný názov súboru." -#: db/models/fields/__init__.py:818 +#: db/models/fields/__init__.py:851 msgid "This value must be either None, True or False." msgstr "Táto hodnota musí byť buď None, True alebo False." -#: db/models/fields/related.py:53 +#: db/models/fields/related.py:55 #, python-format msgid "Please enter a valid %s." msgstr "Prosím, zadajte platné %s." -#: db/models/fields/related.py:642 +#: db/models/fields/related.py:661 msgid "Separate multiple IDs with commas." msgstr "Oddeľte viacnásobné ID čiarkami." -#: db/models/fields/related.py:644 +#: db/models/fields/related.py:663 msgid "" "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgstr "" "Ak chcete vybrať viacero možností, podržte \"Control\" alebo \"Command\" na " "Mac-u." -#: db/models/fields/related.py:691 +#: db/models/fields/related.py:710 #, python-format msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." msgid_plural "" @@ -147,54 +147,58 @@ msgstr[0] "Prosím, vložte platné %(self)s ID. Hodnota %(value)r je neplatná. msgstr[1] "" "Prosím, vložte platné %(self)s ID-čka. Hodnoty %(value)r sú neplatné." -#: conf/global_settings.py:39 +#: conf/global_settings.py:38 msgid "Arabic" msgstr "Arabsky" -#: conf/global_settings.py:40 +#: conf/global_settings.py:39 msgid "Bengali" msgstr "Bengálsky" -#: conf/global_settings.py:41 +#: conf/global_settings.py:40 msgid "Bulgarian" msgstr "Bulharský" -#: conf/global_settings.py:42 +#: conf/global_settings.py:41 msgid "Catalan" msgstr "Katalánsky" -#: conf/global_settings.py:43 +#: conf/global_settings.py:42 msgid "Czech" msgstr "Česky" -#: conf/global_settings.py:44 +#: conf/global_settings.py:43 msgid "Welsh" msgstr "Welšsky" -#: conf/global_settings.py:45 +#: conf/global_settings.py:44 msgid "Danish" msgstr "Dánsky" -#: conf/global_settings.py:46 +#: conf/global_settings.py:45 msgid "German" msgstr "Nemecky" -#: conf/global_settings.py:47 +#: conf/global_settings.py:46 msgid "Greek" msgstr "Grécky" -#: conf/global_settings.py:48 +#: conf/global_settings.py:47 msgid "English" msgstr "Anglicky" -#: conf/global_settings.py:49 +#: conf/global_settings.py:48 msgid "Spanish" msgstr "Španielsky" -#: conf/global_settings.py:50 +#: conf/global_settings.py:49 msgid "Argentinean Spanish" msgstr "Argentínska španielčina" +#: conf/global_settings.py:50 +msgid "Persian" +msgstr "Perzský" + #: conf/global_settings.py:51 msgid "Finnish" msgstr "Fínsky" @@ -311,11 +315,11 @@ msgstr "Čínsky (zjednodušene)" msgid "Traditional Chinese" msgstr "Čínsky (tradične)" -#: core/validators.py:65 +#: core/validators.py:71 msgid "This value must contain only letters, numbers and underscores." msgstr "Táto hodnota môže obsahovať len písmená, číslice a podčiarkovníky." -#: core/validators.py:69 +#: core/validators.py:75 msgid "" "This value must contain only letters, numbers, underscores, dashes or " "slashes." @@ -323,69 +327,69 @@ msgstr "" "Táto hodnota môže obsahovať len písmena, číslice, podčiarkovniky, pomlčky a " "lomítka." -#: core/validators.py:73 +#: core/validators.py:79 msgid "This value must contain only letters, numbers, underscores or hyphens." msgstr "" "Táto hodnota môže obsahovať len písmená, číslice, počiarkovníky a pomlčky." -#: core/validators.py:77 +#: core/validators.py:83 msgid "Uppercase letters are not allowed here." msgstr "Veľké písmená nie sú povolené." -#: core/validators.py:81 +#: core/validators.py:87 msgid "Lowercase letters are not allowed here." msgstr "Malé písmena nie sú povolené." -#: core/validators.py:88 +#: core/validators.py:94 msgid "Enter only digits separated by commas." msgstr "Zadávajte len číslice oddelené čiarkami." -#: core/validators.py:100 +#: core/validators.py:106 msgid "Enter valid e-mail addresses separated by commas." msgstr "Zadajte platné e-mailové adresy oddelené čiarkami." -#: core/validators.py:104 +#: core/validators.py:110 msgid "Please enter a valid IP address." msgstr "Prosím, zadajte platnú IP adresu." -#: core/validators.py:108 +#: core/validators.py:114 msgid "Empty values are not allowed here." msgstr "Prázdne hodnoty tu nie sú povolené." -#: core/validators.py:112 +#: core/validators.py:118 msgid "Non-numeric characters aren't allowed here." msgstr "Iné ako numerické znaky tu nie sú povolené." -#: core/validators.py:116 +#: core/validators.py:122 msgid "This value can't be comprised solely of digits." msgstr "Táto hodnota nemôže byť čisto numerická." -#: core/validators.py:121 newforms/fields.py:135 +#: core/validators.py:127 newforms/fields.py:141 msgid "Enter a whole number." msgstr "Zadajte celé číslo." -#: core/validators.py:125 +#: core/validators.py:131 msgid "Only alphabetical characters are allowed here." msgstr "Tu sú povolené len alfanumerické znaky." -#: core/validators.py:140 +#: core/validators.py:146 msgid "Year must be 1900 or later." msgstr "Rok musí byť 1900 alebo neskôr." -#: core/validators.py:144 +#: core/validators.py:150 #, python-format msgid "Invalid date: %s" msgstr "Neplatný dátum: %s" -#: core/validators.py:154 +#: core/validators.py:160 msgid "Enter a valid time in HH:MM format." msgstr "Zadajte platný čas vo formáte HH:MM." -#: core/validators.py:163 newforms/fields.py:339 +#: core/validators.py:169 newforms/fields.py:335 msgid "Enter a valid e-mail address." msgstr "Zadajte platnú e-mailovú adresu." -#: core/validators.py:179 +#: core/validators.py:185 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." @@ -393,27 +397,27 @@ msgstr "" "Nahrajte platný obrázok. Súbor, ktorý ste odoslali nebol obrázkový formát " "alebo bol poškodený." -#: core/validators.py:186 +#: core/validators.py:192 #, python-format msgid "The URL %s does not point to a valid image." msgstr "URL %s neodkazuje na platný obrázok." -#: core/validators.py:190 +#: core/validators.py:196 #, python-format msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." msgstr "" "Telefónne číslo musí mať formát XXX-XXX-XXXX. Číslo \"%s\" je neplatné." -#: core/validators.py:198 +#: core/validators.py:204 #, python-format msgid "The URL %s does not point to a valid QuickTime video." msgstr "URL %s neodkazuje na platné QuickTime video." -#: core/validators.py:202 +#: core/validators.py:208 msgid "A valid URL is required." msgstr "Je požadovaná platná adresa URL." -#: core/validators.py:216 +#: core/validators.py:222 #, python-format msgid "" "Valid HTML is required. Specific errors are:\n" @@ -422,84 +426,84 @@ msgstr "" "HTML kód musí zodpovedať špecifikácii. Zistené chyby sú:\n" "%s" -#: core/validators.py:223 +#: core/validators.py:229 #, python-format msgid "Badly formed XML: %s" msgstr "Chybné XML nezodpovedajúce definícii: %s" -#: core/validators.py:240 +#: core/validators.py:246 #, python-format msgid "Invalid URL: %s" msgstr "Neplatná adresa URL: %s" -#: core/validators.py:245 core/validators.py:247 +#: core/validators.py:251 core/validators.py:253 #, python-format msgid "The URL %s is a broken link." msgstr "Odkaz na URL %s je neplatný." -#: core/validators.py:253 +#: core/validators.py:259 msgid "Enter a valid U.S. state abbreviation." msgstr "Zadajte platnú skratku štátu USA." -#: core/validators.py:267 +#: 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] "Vyjadrujte sa slušne! Slovo %s tu nie je dovolené použivať." msgstr[1] "Vyjadrujte sa slušne! Slová %s tu nie je dovolené použivať." -#: core/validators.py:274 +#: core/validators.py:280 #, python-format msgid "This field must match the '%s' field." msgstr "Toto pole sa musí zhodovať s poľom '%s'. " -#: core/validators.py:293 +#: core/validators.py:299 msgid "Please enter something for at least one field." msgstr "Prosím, vyplňte aspoň jedno pole." -#: core/validators.py:302 core/validators.py:313 +#: core/validators.py:308 core/validators.py:319 msgid "Please enter both fields or leave them both empty." msgstr "Prosím, vyplňte buď obidve polia, alebo ich nechajte prázdne." -#: core/validators.py:321 +#: core/validators.py:327 #, python-format msgid "This field must be given if %(field)s is %(value)s" msgstr "Toto pole musí byť vyplnené ak, %(field)s je %(value)s" -#: core/validators.py:334 +#: core/validators.py:340 #, python-format msgid "This field must be given if %(field)s is not %(value)s" msgstr "Toto pole musí byť vyplnené, ak %(field)s nie je %(value)s" -#: core/validators.py:353 +#: core/validators.py:359 msgid "Duplicate values are not allowed." msgstr "Duplicitné hodnoty nie sú povolené." -#: core/validators.py:368 +#: core/validators.py:374 #, python-format msgid "This value must be between %(lower)s and %(upper)s." msgstr "Táto hodnota musí byť medzi %(lower)s a %(upper)s." -#: core/validators.py:370 +#: core/validators.py:376 #, python-format msgid "This value must be at least %s." msgstr "Táto hodnota musí byť prinajmenšom %s." -#: core/validators.py:372 +#: core/validators.py:378 #, python-format msgid "This value must be no more than %s." msgstr "Táto hodnota musí byť väčšia ako %s." -#: core/validators.py:408 +#: core/validators.py:414 #, python-format msgid "This value must be a power of %s." msgstr "Táto hodnota musí byť mocninou %s." -#: core/validators.py:417 +#: core/validators.py:424 msgid "Please enter a valid decimal number." msgstr "Prosím, vložte platné desatinné číslo. " -#: core/validators.py:423 +#: core/validators.py:431 #, python-format msgid "Please enter a valid decimal number with at most %s total digit." msgid_plural "" @@ -507,7 +511,7 @@ msgid_plural "" msgstr[0] "Prosím, vložte platné desatinné číslo. " msgstr[1] "Prosím, vložte platné desatinné čísla. " -#: core/validators.py:426 +#: core/validators.py:434 #, python-format msgid "" "Please enter a valid decimal number with a whole part of at most %s digit." @@ -516,7 +520,7 @@ msgid_plural "" msgstr[0] "Prosím vlož platné desatinné číslo s najviac %s číslicou. " msgstr[1] "Prosím vlož platné desatinné číslo s najviac %s číslicami." -#: core/validators.py:429 +#: core/validators.py:437 #, python-format msgid "Please enter a valid decimal number with at most %s decimal place." msgid_plural "" @@ -526,34 +530,34 @@ msgstr[0] "" msgstr[1] "" "Prosím, vložte platné desatinné číslo s najviac %s desatinnými miestamy. " -#: core/validators.py:437 +#: core/validators.py:445 msgid "Please enter a valid floating point number." msgstr "Prosím, vložte platné číslo s pohyblivou desatinnou čiarkou. " -#: core/validators.py:446 +#: core/validators.py:454 #, python-format msgid "Make sure your uploaded file is at least %s bytes big." msgstr "Uistite sa, že posielaný súbor nemá menej ako %s bajtov." -#: core/validators.py:447 +#: core/validators.py:455 #, python-format msgid "Make sure your uploaded file is at most %s bytes big." msgstr "Uistite sa, že posielaný súbor nemá viac ako %s bajtov." -#: core/validators.py:464 +#: core/validators.py:472 msgid "The format for this field is wrong." msgstr "Formát pre toto pole je chybný." -#: core/validators.py:479 +#: core/validators.py:487 msgid "This field is invalid." msgstr "Toto pole nie je platné." -#: core/validators.py:515 +#: core/validators.py:523 #, python-format msgid "Could not retrieve anything from %s." msgstr "Z %s nič neprišlo." -#: core/validators.py:518 +#: core/validators.py:526 #, python-format msgid "" "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." @@ -561,7 +565,7 @@ msgstr "" "Adresa URL %(url)s vrátila v hlavičke neplatný Content-Type '%(contenttype)" "s'." -#: core/validators.py:551 +#: core/validators.py:559 #, python-format msgid "" "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " @@ -570,7 +574,7 @@ msgstr "" "Prosím, uzatvorte tag %(tag)s na riadku %(line)s. (Riadok začína s \"%(start)" "s\".)" -#: core/validators.py:555 +#: core/validators.py:563 #, python-format msgid "" "Some text starting on line %(line)s is not allowed in that context. (Line " @@ -579,7 +583,7 @@ msgstr "" "Text začínajúci na riadku %(line)s nie je povolený v tomto kontexte. (Riadok " "začína s \"%(start)s\".)" -#: core/validators.py:560 +#: core/validators.py:568 #, python-format msgid "" "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" @@ -588,7 +592,7 @@ msgstr "" "\"%(attr)s\" na riadku %(line)s je neplatný atribút. (Riadok začína s \"%" "(start)s\".)" -#: core/validators.py:565 +#: core/validators.py:573 #, python-format msgid "" "\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" @@ -597,7 +601,7 @@ msgstr "" "\"<%(tag)s>\" na riadku %(line)s je neplatný tag. (Riadok začína s \"%(start)" "s\".)" -#: core/validators.py:569 +#: core/validators.py:577 #, python-format msgid "" "A tag on line %(line)s is missing one or more required attributes. (Line " @@ -606,7 +610,7 @@ msgstr "" "V tagu na riadku %(line)s chýba jeden alebo viac atribútov. (Riadok začína s " "\"%(start)s\".)" -#: core/validators.py:574 +#: core/validators.py:582 #, python-format msgid "" "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " @@ -630,79 +634,77 @@ msgstr "Objekt %(verbose_name)s bol úspešne zmenený." msgid "The %(verbose_name)s was deleted." msgstr "Objekt %(verbose_name)s bol zmazaný." -#: newforms/models.py:172 newforms/fields.py:432 +#: newforms/models.py:174 newforms/fields.py:428 msgid "Select a valid choice. That choice is not one of the available choices." msgstr "Vyberte platnú možnosť. Vybraná položka nepatrí medzi platné možnosti." -#: newforms/models.py:189 newforms/fields.py:448 newforms/fields.py:524 +#: newforms/models.py:191 newforms/fields.py:444 newforms/fields.py:520 msgid "Enter a list of values." msgstr "Vložte zoznam hodnôt." -#: newforms/models.py:195 newforms/fields.py:457 +#: newforms/models.py:197 newforms/fields.py:450 #, python-format msgid "Select a valid choice. %s is not one of the available choices." msgstr "Vyberte platnú možnost. %s nepatrí medzi dostupné možnosti." -#: newforms/fields.py:110 newforms/fields.py:324 -#, python-format -msgid "Ensure this value has at most %d characters." -msgstr "Uistite sa, že hodnota má najviac %d znakov." +#: newforms/fields.py:116 +msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." +msgstr "Uistite sa, že hodnota má najviac %d znakov( teraz má %(length)d)." -#: newforms/fields.py:112 newforms/fields.py:326 -#, python-format -msgid "Ensure this value has at least %d characters." -msgstr "Uistite sa, že zadaná hodnota má menej ako %d znakov." +#: newforms/fields.py:118 +msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." +msgstr "Uistite sa, že zadaná hodnota nemá menej ako %d znakov ( teraz má %(length)d)." -#: newforms/fields.py:137 newforms/fields.py:160 newforms/fields.py:192 +#: newforms/fields.py:143 newforms/fields.py:166 newforms/fields.py:196 #, python-format msgid "Ensure this value is less than or equal to %s." msgstr "Uistite sa, že táto hodnota je menšia alebo rovná %s." -#: newforms/fields.py:139 newforms/fields.py:162 newforms/fields.py:194 +#: newforms/fields.py:145 newforms/fields.py:168 newforms/fields.py:198 #, python-format msgid "Ensure this value is greater than or equal to %s." msgstr "Uistite sa, že hodnota je väčšia alebo rovná %s." -#: newforms/fields.py:158 newforms/fields.py:186 +#: newforms/fields.py:164 newforms/fields.py:191 msgid "Enter a number." msgstr "Zadajte číslo." -#: newforms/fields.py:196 +#: newforms/fields.py:200 #, python-format msgid "Ensure that there are no more than %s digits in total." -msgstr "" +msgstr "Zabezpečte aby výraz nemal celkom viac ako %s číslic ." -#: newforms/fields.py:198 +#: newforms/fields.py:202 #, python-format msgid "Ensure that there are no more than %s decimal places." msgstr "Zabezpečte aby nebolo viac ako %s desatinných miest." -#: newforms/fields.py:200 +#: newforms/fields.py:204 #, python-format msgid "Ensure that there are no more than %s digits before the decimal point." msgstr "Zabezpečte aby nebolo viac ako %s číslic pred desatinnou bodkou." -#: newforms/fields.py:233 +#: newforms/fields.py:237 newforms/fields.py:560 msgid "Enter a valid date." msgstr "Zadajte platný dátum." -#: newforms/fields.py:260 +#: newforms/fields.py:264 newforms/fields.py:562 msgid "Enter a valid time." msgstr "Zadajte platný čas." -#: newforms/fields.py:296 +#: newforms/fields.py:300 msgid "Enter a valid date/time." msgstr "Zadajte platný dátum a čas." -#: newforms/fields.py:310 +#: newforms/fields.py:313 msgid "Enter a valid value." msgstr "Zadajte platnú hodnotu." -#: newforms/fields.py:357 newforms/fields.py:379 +#: newforms/fields.py:353 newforms/fields.py:375 msgid "Enter a valid URL." msgstr "Zadajte platnú adresu URL." -#: newforms/fields.py:381 +#: newforms/fields.py:377 msgid "This URL appears to be a broken link." msgstr "Odkaz na URL neexistuje." @@ -868,7 +870,7 @@ msgstr "dátum a čas odoslania" msgid "is public" msgstr "je verejný" -#: contrib/comments/models.py:85 contrib/admin/views/doc.py:305 +#: contrib/comments/models.py:85 contrib/admin/views/doc.py:306 msgid "IP address" msgstr "IP adresa" @@ -993,24 +995,24 @@ msgstr "Zmazané moderátorom" msgid "Moderator deletion by %r" msgstr "Zmazanané moderátorom %r" -#: contrib/comments/views/karma.py:19 +#: contrib/comments/views/karma.py:20 msgid "Anonymous users cannot vote" msgstr "Hlasovať môžu len prihlásení užívatelia" -#: contrib/comments/views/karma.py:23 +#: contrib/comments/views/karma.py:24 msgid "Invalid comment ID" msgstr "Chybné ID komentára" -#: contrib/comments/views/karma.py:25 +#: contrib/comments/views/karma.py:26 msgid "No voting for yourself" msgstr "Nemôžete hlasovať za samého seba" -#: contrib/comments/views/comments.py:27 +#: contrib/comments/views/comments.py:28 msgid "" "This rating is required because you've entered at least one other rating." msgstr "Toto hlasovanie je nevyhnutné, lebo súvisí s predchádzjúcou voľbou." -#: contrib/comments/views/comments.py:111 +#: contrib/comments/views/comments.py:112 #, python-format msgid "" "This comment was posted by a user who has posted fewer than %(count)s " @@ -1031,7 +1033,7 @@ msgstr[1] "" "príspevkov .\n" "%(text)s" -#: contrib/comments/views/comments.py:116 +#: contrib/comments/views/comments.py:117 #, python-format msgid "" "This comment was posted by a sketchy user:\n" @@ -1042,32 +1044,32 @@ msgstr "" "\n" "%(text)s" -#: contrib/comments/views/comments.py:188 -#: contrib/comments/views/comments.py:280 +#: contrib/comments/views/comments.py:189 +#: contrib/comments/views/comments.py:281 msgid "Only POSTs are allowed" msgstr "Dovolené sú len POST" -#: contrib/comments/views/comments.py:192 -#: contrib/comments/views/comments.py:284 +#: contrib/comments/views/comments.py:193 +#: contrib/comments/views/comments.py:285 msgid "One or more of the required fields wasn't submitted" msgstr "Jedno alebo viac povinných polí nebolo vložených" -#: contrib/comments/views/comments.py:196 -#: contrib/comments/views/comments.py:286 +#: contrib/comments/views/comments.py:197 +#: contrib/comments/views/comments.py:287 msgid "Somebody tampered with the comment form (security violation)" msgstr "" "Niekto sa pokúšal manipulovať s formulárom komentára (porušenie bezpečnosti)" -#: contrib/comments/views/comments.py:206 -#: contrib/comments/views/comments.py:292 +#: contrib/comments/views/comments.py:207 +#: contrib/comments/views/comments.py:293 msgid "" "The comment form had an invalid 'target' parameter -- the object ID was " "invalid" msgstr "" "Formulár komentára ma chybný 'target' parameter -- ID objektu je neplatné" -#: contrib/comments/views/comments.py:257 -#: contrib/comments/views/comments.py:321 +#: contrib/comments/views/comments.py:258 +#: contrib/comments/views/comments.py:322 msgid "The comment form didn't provide either 'preview' or 'post'" msgstr "" "Formulár komentára neobsahuje ani jednu z možností 'náhľad' alebo 'odoslať'." @@ -1141,23 +1143,23 @@ msgstr "Nepovinné" msgid "Post a photo" msgstr "Pošli foto" -#: contrib/sites/models.py:10 +#: contrib/sites/models.py:15 msgid "domain name" msgstr "názov domény" -#: contrib/sites/models.py:11 +#: contrib/sites/models.py:16 msgid "display name" msgstr "zobrazené meno" -#: contrib/sites/models.py:15 +#: contrib/sites/models.py:20 msgid "site" msgstr "web" -#: contrib/sites/models.py:16 +#: contrib/sites/models.py:21 msgid "sites" msgstr "weby" -#: contrib/admin/filterspecs.py:40 +#: contrib/admin/filterspecs.py:42 #, python-format msgid "" "<h3>By %s:</h3>\n" @@ -1166,60 +1168,60 @@ msgstr "" "<h3>Od %s:</h3>\n" "<ul>\n" -#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88 -#: contrib/admin/filterspecs.py:143 contrib/admin/filterspecs.py:169 +#: contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90 +#: contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171 msgid "All" msgstr "Všetko" -#: contrib/admin/filterspecs.py:109 +#: contrib/admin/filterspecs.py:111 msgid "Any date" msgstr "Lubovoľný dátum" -#: contrib/admin/filterspecs.py:110 +#: contrib/admin/filterspecs.py:112 msgid "Today" msgstr "Dnes" -#: contrib/admin/filterspecs.py:113 +#: contrib/admin/filterspecs.py:115 msgid "Past 7 days" msgstr "Posledných 7 dní" -#: contrib/admin/filterspecs.py:115 +#: contrib/admin/filterspecs.py:117 msgid "This month" msgstr "Tento mesiac" -#: contrib/admin/filterspecs.py:117 +#: contrib/admin/filterspecs.py:119 msgid "This year" msgstr "Tento rok" -#: contrib/admin/models.py:16 +#: contrib/admin/models.py:17 msgid "action time" msgstr "čas udalosti" -#: contrib/admin/models.py:19 +#: contrib/admin/models.py:20 msgid "object id" msgstr "id objektu" -#: contrib/admin/models.py:20 +#: contrib/admin/models.py:21 msgid "object repr" msgstr "objekt repr" -#: contrib/admin/models.py:21 +#: contrib/admin/models.py:22 msgid "action flag" msgstr "príznak udalosti" -#: contrib/admin/models.py:22 +#: contrib/admin/models.py:23 msgid "change message" msgstr "zmeniť zprávu" -#: contrib/admin/models.py:25 +#: contrib/admin/models.py:26 msgid "log entry" msgstr "záznam priebehu" -#: contrib/admin/models.py:26 +#: contrib/admin/models.py:27 msgid "log entries" msgstr "záznamy priebehu" -#: contrib/admin/templatetags/admin_list.py:249 +#: contrib/admin/templatetags/admin_list.py:254 msgid "All dates" msgstr "Všetky dátumy" @@ -1261,68 +1263,68 @@ msgid "Your e-mail address is not your username. Try '%s' instead." msgstr "" "Vaša e-mailová adresa nie je užívateľským menom. Skúste použiť meno '%s'." -#: contrib/admin/views/auth.py:19 contrib/admin/views/main.py:257 +#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:264 #, python-format msgid "The %(name)s \"%(obj)s\" was added successfully." msgstr "Objekt %(name)s \"%(obj)s\" bol úspešne pridaný." -#: contrib/admin/views/auth.py:24 contrib/admin/views/main.py:261 -#: contrib/admin/views/main.py:347 +#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:268 +#: contrib/admin/views/main.py:354 msgid "You may edit it again below." msgstr "Môžete pokračovať v zmenách." -#: contrib/admin/views/auth.py:30 +#: contrib/admin/views/auth.py:31 msgid "Add user" msgstr "Pridať užívateľa" -#: contrib/admin/views/auth.py:57 +#: contrib/admin/views/auth.py:58 msgid "Password changed successfully." msgstr "Heslo bolo úspešne zmenené." -#: contrib/admin/views/auth.py:64 +#: contrib/admin/views/auth.py:65 #, python-format msgid "Change password: %s" msgstr "Zmeniť heslo: %s" -#: contrib/admin/views/main.py:223 +#: contrib/admin/views/main.py:230 msgid "Site administration" msgstr "Administrácia" -#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356 +#: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363 #, python-format msgid "You may add another %s below." msgstr "Môžete pokračovať v pridávaní ďaľších %s." -#: contrib/admin/views/main.py:289 +#: contrib/admin/views/main.py:296 #, python-format msgid "Add %s" msgstr "Pridaj %s" -#: contrib/admin/views/main.py:335 +#: contrib/admin/views/main.py:342 #, python-format msgid "Added %s." msgstr "Bol pridaný %s." -#: contrib/admin/views/main.py:337 +#: contrib/admin/views/main.py:344 #, python-format msgid "Changed %s." msgstr "Bol zmenený %s" -#: contrib/admin/views/main.py:339 +#: contrib/admin/views/main.py:346 #, python-format msgid "Deleted %s." msgstr "Bol vymazaný %s." -#: contrib/admin/views/main.py:342 +#: contrib/admin/views/main.py:349 msgid "No fields changed." msgstr "Polia neboli zmenené." -#: contrib/admin/views/main.py:345 +#: contrib/admin/views/main.py:352 #, python-format msgid "The %(name)s \"%(obj)s\" was changed successfully." msgstr "Objekt %(name)s \"%(obj)s\" boli úspešne zmenený." -#: contrib/admin/views/main.py:353 +#: contrib/admin/views/main.py:360 #, python-format msgid "" "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below." @@ -1330,181 +1332,181 @@ msgstr "" "Objekt %(name)s \"%(obj)s\" bol úspešne zmenený. Ďalšie zmeny môžeš urobiť " "zase nižšie." -#: contrib/admin/views/main.py:391 +#: contrib/admin/views/main.py:398 #, python-format msgid "Change %s" msgstr "Zmeniť %s" -#: contrib/admin/views/main.py:476 +#: contrib/admin/views/main.py:483 #, python-format msgid "One or more %(fieldname)s in %(name)s: %(obj)s" msgstr "Jeden alebo viac %(fieldname)s v %(name)s: %(obj)s" -#: contrib/admin/views/main.py:481 +#: contrib/admin/views/main.py:488 #, python-format msgid "One or more %(fieldname)s in %(name)s:" msgstr "Jeden alebo viac %(fieldname)s v %(name)s:" -#: contrib/admin/views/main.py:514 +#: contrib/admin/views/main.py:520 #, python-format msgid "The %(name)s \"%(obj)s\" was deleted successfully." msgstr "Objekt %(name)s \"%(obj)s\" bol úspešne vymazaný." -#: contrib/admin/views/main.py:517 +#: contrib/admin/views/main.py:523 msgid "Are you sure?" msgstr "Ste si istý?" -#: contrib/admin/views/main.py:539 +#: contrib/admin/views/main.py:545 #, python-format msgid "Change history: %s" msgstr "Zmeniť históriu: %s" -#: contrib/admin/views/main.py:573 +#: contrib/admin/views/main.py:579 #, python-format msgid "Select %s" msgstr "Výber %s" -#: contrib/admin/views/main.py:573 +#: contrib/admin/views/main.py:579 #, python-format msgid "Select %s to change" msgstr "Ktorý %s sa má zmeniť?" -#: contrib/admin/views/main.py:768 +#: contrib/admin/views/main.py:780 msgid "Database error" msgstr "Chyba databázy" -#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48 -#: contrib/admin/views/doc.py:50 +#: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49 +#: contrib/admin/views/doc.py:51 msgid "tag:" msgstr "označovač:" -#: contrib/admin/views/doc.py:77 contrib/admin/views/doc.py:79 -#: contrib/admin/views/doc.py:81 +#: contrib/admin/views/doc.py:78 contrib/admin/views/doc.py:80 +#: contrib/admin/views/doc.py:82 msgid "filter:" msgstr "" -#: contrib/admin/views/doc.py:135 contrib/admin/views/doc.py:137 -#: contrib/admin/views/doc.py:139 +#: contrib/admin/views/doc.py:136 contrib/admin/views/doc.py:138 +#: contrib/admin/views/doc.py:140 msgid "view:" msgstr "prehľad:" -#: contrib/admin/views/doc.py:164 +#: contrib/admin/views/doc.py:165 #, python-format msgid "App %r not found" msgstr "Aplikáciu %r sa nepodarilo nájsť." -#: contrib/admin/views/doc.py:171 +#: contrib/admin/views/doc.py:172 #, python-format msgid "Model %(name)r not found in app %(label)r" msgstr "Model %(name)r sa nenachádza v aplikácii %(label)r" -#: contrib/admin/views/doc.py:183 +#: contrib/admin/views/doc.py:184 #, python-format msgid "the related `%(label)s.%(type)s` object" msgstr "Prepojenie na objekt `%(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 +#: contrib/admin/views/doc.py:184 contrib/admin/views/doc.py:206 +#: contrib/admin/views/doc.py:220 contrib/admin/views/doc.py:225 msgid "model:" msgstr "" -#: contrib/admin/views/doc.py:214 +#: contrib/admin/views/doc.py:215 #, python-format msgid "related `%(label)s.%(name)s` objects" msgstr "súvisiace objekty `%(label)s.%(name)s`" -#: contrib/admin/views/doc.py:219 +#: contrib/admin/views/doc.py:220 #, python-format msgid "all %s" msgstr "všetky %s" -#: contrib/admin/views/doc.py:224 +#: contrib/admin/views/doc.py:225 #, python-format msgid "number of %s" msgstr "počet %s" -#: contrib/admin/views/doc.py:229 +#: contrib/admin/views/doc.py:230 #, python-format msgid "Fields on %s objects" msgstr "Polia objektu %s" -#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:302 -#: contrib/admin/views/doc.py:304 contrib/admin/views/doc.py:310 -#: contrib/admin/views/doc.py:311 contrib/admin/views/doc.py:313 +#: contrib/admin/views/doc.py:292 contrib/admin/views/doc.py:303 +#: contrib/admin/views/doc.py:305 contrib/admin/views/doc.py:311 +#: contrib/admin/views/doc.py:312 contrib/admin/views/doc.py:314 msgid "Integer" msgstr "Celé číslo" -#: contrib/admin/views/doc.py:292 +#: contrib/admin/views/doc.py:293 msgid "Boolean (Either True or False)" msgstr "Logická hodnota (True alebo False)" -#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:312 +#: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313 #, python-format msgid "String (up to %(maxlength)s)" msgstr "Dĺžka reťazca (maximálne do %(maxlength)s znakov)" -#: contrib/admin/views/doc.py:294 +#: contrib/admin/views/doc.py:295 msgid "Comma-separated integers" msgstr "Celé čísla oddelené čiarkou" -#: contrib/admin/views/doc.py:295 +#: contrib/admin/views/doc.py:296 msgid "Date (without time)" msgstr "Dátum (bez času)" -#: contrib/admin/views/doc.py:296 +#: contrib/admin/views/doc.py:297 msgid "Date (with time)" msgstr "Dátum (a čas)" -#: contrib/admin/views/doc.py:297 +#: contrib/admin/views/doc.py:298 msgid "Decimal number" msgstr "Desatinné číslo" -#: contrib/admin/views/doc.py:298 +#: contrib/admin/views/doc.py:299 msgid "E-mail address" msgstr "E-mailová adresa" -#: contrib/admin/views/doc.py:299 contrib/admin/views/doc.py:300 -#: contrib/admin/views/doc.py:303 +#: contrib/admin/views/doc.py:300 contrib/admin/views/doc.py:301 +#: contrib/admin/views/doc.py:304 msgid "File path" msgstr "Cesta k súboru" -#: contrib/admin/views/doc.py:301 +#: contrib/admin/views/doc.py:302 msgid "Floating point number" msgstr "Císlo s pohyblivou čiarkou" -#: contrib/admin/views/doc.py:307 +#: contrib/admin/views/doc.py:308 msgid "Boolean (Either True, False or None)" msgstr "Logická hodnota (True, False alebo None)" -#: contrib/admin/views/doc.py:308 +#: contrib/admin/views/doc.py:309 msgid "Relation to parent model" msgstr "Má vzťah k nadradenému modelu" -#: contrib/admin/views/doc.py:309 +#: contrib/admin/views/doc.py:310 msgid "Phone number" msgstr "Číslo telefónu" -#: contrib/admin/views/doc.py:314 +#: contrib/admin/views/doc.py:315 msgid "Text" msgstr "Text" -#: contrib/admin/views/doc.py:315 +#: contrib/admin/views/doc.py:316 msgid "Time" msgstr "Čas" -#: contrib/admin/views/doc.py:316 contrib/flatpages/models.py:7 +#: contrib/admin/views/doc.py:317 contrib/flatpages/models.py:7 msgid "URL" msgstr "URL" -#: contrib/admin/views/doc.py:317 +#: contrib/admin/views/doc.py:318 msgid "U.S. state (two uppercase letters)" msgstr "Štát USA (dve veľké písmena)" -#: contrib/admin/views/doc.py:318 +#: contrib/admin/views/doc.py:319 msgid "XML text" msgstr "XML text" -#: contrib/admin/views/doc.py:344 +#: contrib/admin/views/doc.py:345 #, python-format msgid "%s does not appear to be a urlpattern object" msgstr "%s nie je urlpattern objekt" @@ -2005,51 +2007,51 @@ msgstr "Editácia tohoto objektu (v novom okne)" msgid "As above, but opens the admin page in a new window." msgstr "To isté ako predtým, akurát otvorí administračnú stránku v novom okne." -#: contrib/contenttypes/models.py:36 +#: contrib/contenttypes/models.py:37 msgid "python model class name" msgstr "pythonové meno triedy modelu" -#: contrib/contenttypes/models.py:39 +#: contrib/contenttypes/models.py:40 msgid "content type" msgstr "typ obsahu" -#: contrib/contenttypes/models.py:40 +#: contrib/contenttypes/models.py:41 msgid "content types" msgstr "typy obsahu" -#: contrib/auth/views.py:40 +#: contrib/auth/views.py:41 msgid "Logged out" msgstr "Odhlásený" -#: contrib/auth/models.py:44 contrib/auth/models.py:64 +#: contrib/auth/models.py:51 contrib/auth/models.py:71 msgid "name" msgstr "meno" -#: contrib/auth/models.py:46 +#: contrib/auth/models.py:53 msgid "codename" msgstr "codename" -#: contrib/auth/models.py:49 +#: contrib/auth/models.py:56 msgid "permission" msgstr "povolenie" -#: contrib/auth/models.py:50 contrib/auth/models.py:65 +#: contrib/auth/models.py:57 contrib/auth/models.py:72 msgid "permissions" msgstr "práva" -#: contrib/auth/models.py:68 +#: contrib/auth/models.py:75 msgid "group" msgstr "skupina" -#: contrib/auth/models.py:69 contrib/auth/models.py:109 +#: contrib/auth/models.py:76 contrib/auth/models.py:116 msgid "groups" msgstr "skupiny" -#: contrib/auth/models.py:99 +#: contrib/auth/models.py:106 msgid "username" msgstr "užívateľské meno" -#: contrib/auth/models.py:99 +#: contrib/auth/models.py:106 msgid "" "Required. 30 characters or fewer. Alphanumeric characters only (letters, " "digits and underscores)." @@ -2057,23 +2059,23 @@ msgstr "" "Povinná položka s dĺžkou 30 znakov alebo menej. Povolené sú len " "alfanumerické znaky (písmená, čísla a podtržník)." -#: contrib/auth/models.py:100 +#: contrib/auth/models.py:107 msgid "first name" msgstr "krstné meno" -#: contrib/auth/models.py:101 +#: contrib/auth/models.py:108 msgid "last name" msgstr "priezvisko" -#: contrib/auth/models.py:102 +#: contrib/auth/models.py:109 msgid "e-mail address" msgstr "e-mailová adresa" -#: contrib/auth/models.py:103 +#: contrib/auth/models.py:110 msgid "password" msgstr "heslo" -#: contrib/auth/models.py:103 +#: contrib/auth/models.py:110 msgid "" "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " "password form</a>." @@ -2081,20 +2083,20 @@ msgstr "" "Použite '[algo]$[salt]$[hexdigest]' alebo <a href=\"password/\">formulár na " "zmenu hesla</a>." -#: contrib/auth/models.py:104 +#: contrib/auth/models.py:111 msgid "staff status" msgstr "zamestnanec" -#: contrib/auth/models.py:104 +#: contrib/auth/models.py:111 msgid "Designates whether the user can log into this admin site." msgstr "" "Určuje, či má užívateľ oprávnenie prihlásiť sa do administračnej časti." -#: contrib/auth/models.py:105 +#: contrib/auth/models.py:112 msgid "active" msgstr "aktívny" -#: contrib/auth/models.py:105 +#: contrib/auth/models.py:112 msgid "" "Designates whether this user can log into the Django admin. Unselect this " "instead of deleting accounts." @@ -2102,11 +2104,11 @@ msgstr "" "Určuje, či je účet aktívny. Odškrtnite, ak chcete deaktivovať užívateľský " "účet." -#: contrib/auth/models.py:106 +#: contrib/auth/models.py:113 msgid "superuser status" msgstr "superužívateľ" -#: contrib/auth/models.py:106 +#: contrib/auth/models.py:113 msgid "" "Designates that this user has all permissions without explicitly assigning " "them." @@ -2114,15 +2116,15 @@ msgstr "" "Určuje, či užívateľ získava automaticky všetky práva aj bez priameho " "priradenia." -#: contrib/auth/models.py:107 +#: contrib/auth/models.py:114 msgid "last login" msgstr "naposledy prihlásený" -#: contrib/auth/models.py:108 +#: contrib/auth/models.py:115 msgid "date joined" msgstr "dátum registrácie" -#: contrib/auth/models.py:110 +#: contrib/auth/models.py:117 msgid "" "In addition to the permissions manually assigned, this user will also get " "all permissions granted to each group he/she is in." @@ -2130,42 +2132,38 @@ msgstr "" "Okrem ručne zadaných práv bude mať užívateľ aj všetky práva prislúchajúce " "skupinám, v ktorých sa nachádza." -#: contrib/auth/models.py:111 +#: contrib/auth/models.py:118 msgid "user permissions" msgstr "užívateľské práva" -#: contrib/auth/models.py:115 +#: contrib/auth/models.py:122 msgid "user" msgstr "uživateľ" -#: contrib/auth/models.py:116 +#: contrib/auth/models.py:123 msgid "users" msgstr "užívatelia" -#: contrib/auth/models.py:122 +#: contrib/auth/models.py:129 msgid "Personal info" msgstr "Osobné údaje" -#: contrib/auth/models.py:123 +#: contrib/auth/models.py:130 msgid "Permissions" msgstr "Práva" -#: contrib/auth/models.py:124 +#: contrib/auth/models.py:131 msgid "Important dates" msgstr "Dôležité dátumy" -#: contrib/auth/models.py:125 +#: contrib/auth/models.py:132 msgid "Groups" msgstr "Skupiny" -#: contrib/auth/models.py:269 +#: contrib/auth/models.py:274 msgid "message" msgstr "správa" -#: contrib/auth/models.py:282 -msgid "AnonymousUser" -msgstr "Neregistrovaný užívateľ" - #: contrib/auth/forms.py:17 contrib/auth/forms.py:138 msgid "The two password fields didn't match." msgstr "Pole hesla a jeho potvrdenie sa nezhodujú." @@ -2619,7 +2617,7 @@ msgstr "" msgid "Zurich" msgstr "" -#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:15 +#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:14 msgid "Enter a zip code in the format XXXX." msgstr "Vložte poštové smerovacie číslo v tvare XXXX." @@ -2629,12 +2627,12 @@ msgid "" "1234567890 format." msgstr "" -#: contrib/localflavor/is_/forms.py:16 +#: contrib/localflavor/is_/forms.py:17 msgid "" "Enter a valid Icelandic identification number. The format is XXXXXX-XXXX." msgstr "Zadajte platné Islanské číslo v tvare XXXXXX-XXXX." -#: contrib/localflavor/is_/forms.py:30 +#: contrib/localflavor/is_/forms.py:31 msgid "The Icelandic identification number is not valid." msgstr "" @@ -2650,16 +2648,368 @@ msgstr "Vložte platné číslo sociálneho poistenia ." msgid "Enter a valid VAT number." msgstr "Zadajte platné VAT číslo." -#: contrib/localflavor/no/forms.py:36 +#: contrib/localflavor/no/forms.py:35 msgid "Enter a valid Norwegian social security number." msgstr "" "Vložte platné nórske číslo sociálneho poistenia (social security number)." -#: contrib/localflavor/cl/forms.py:21 +#: contrib/localflavor/sk/sk_regions.py:8 +msgid "Banska Bystrica region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:9 +msgid "Bratislava region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:10 +msgid "Kosice region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:11 +msgid "Nitra region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:12 +msgid "Presov region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:13 +msgid "Trencin region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:14 +msgid "Trnava region" +msgstr "" + +#: contrib/localflavor/sk/sk_regions.py:15 +msgid "Zilina region" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:8 +msgid "Banska Bystrica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:9 +msgid "Banska Stiavnica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:10 +msgid "Bardejov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:11 +msgid "Banovce nad Bebravou" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:12 +msgid "Brezno" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:13 +msgid "Bratislava I" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:14 +msgid "Bratislava II" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:15 +msgid "Bratislava III" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:16 +msgid "Bratislava IV" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:17 +msgid "Bratislava V" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:18 +msgid "Bytca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:19 +msgid "Cadca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:20 +msgid "Detva" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:21 +msgid "Dolny Kubin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:22 +msgid "Dunajska Streda" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:23 +msgid "Galanta" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:24 +msgid "Gelnica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:25 +msgid "Hlohovec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:26 +msgid "Humenne" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:27 +msgid "Ilava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:28 +msgid "Kezmarok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:29 +msgid "Komarno" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:30 +msgid "Kosice I" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:31 +msgid "Kosice II" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:32 +msgid "Kosice III" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:33 +msgid "Kosice IV" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:34 +msgid "Kosice - okolie" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:35 +msgid "Krupina" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:36 +msgid "Kysucke Nove Mesto" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:37 +msgid "Levice" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:38 +msgid "Levoca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:39 +msgid "Liptovsky Mikulas" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:40 +msgid "Lucenec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:41 +msgid "Malacky" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:42 +msgid "Martin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:43 +msgid "Medzilaborce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:44 +msgid "Michalovce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:45 +msgid "Myjava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:46 +msgid "Namestovo" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:47 +msgid "Nitra" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:48 +msgid "Nove Mesto nad Vahom" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:49 +msgid "Nove Zamky" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:50 +msgid "Partizanske" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:51 +msgid "Pezinok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:52 +msgid "Piestany" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:53 +msgid "Poltar" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:54 +msgid "Poprad" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:55 +msgid "Povazska Bystrica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:56 +msgid "Presov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:57 +msgid "Prievidza" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:58 +msgid "Puchov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:59 +msgid "Revuca" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:60 +msgid "Rimavska Sobota" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:61 +msgid "Roznava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:62 +msgid "Ruzomberok" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:63 +msgid "Sabinov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:64 +msgid "Senec" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:65 +msgid "Senica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:66 +msgid "Skalica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:67 +msgid "Snina" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:68 +msgid "Sobrance" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:69 +msgid "Spisska Nova Ves" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:70 +msgid "Stara Lubovna" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:71 +msgid "Stropkov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:72 +msgid "Svidnik" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:73 +msgid "Sala" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:74 +msgid "Topolcany" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:75 +msgid "Trebisov" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:76 +msgid "Trencin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:77 +msgid "Trnava" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:78 +msgid "Turcianske Teplice" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:79 +msgid "Tvrdosin" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:80 +msgid "Velky Krtis" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:81 +msgid "Vranov nad Toplou" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:82 +msgid "Zlate Moravce" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:83 +msgid "Zvolen" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:84 +msgid "Zarnovica" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:85 +msgid "Ziar nad Hronom" +msgstr "" + +#: contrib/localflavor/sk/sk_districts.py:86 +msgid "Zilina" +msgstr "" + +#: contrib/localflavor/sk/forms.py:32 +msgid "Enter a postal code in the format XXXXX or XXX XX." +msgstr "Zadajte poštové smerovacie číslo v tvare XXXXX alebo XXX-XX." + +#: contrib/localflavor/cl/forms.py:32 msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X." msgstr "" -#: contrib/localflavor/cl/forms.py:26 +#: contrib/localflavor/cl/forms.py:37 msgid "Enter valid a Chilean RUT" msgstr "" @@ -2763,127 +3113,155 @@ msgstr "Sobota" msgid "Sunday" msgstr "Nedeľa" -#: utils/dates.py:14 +#: utils/dates.py:10 +msgid "Mon" +msgstr "" + +#: utils/dates.py:10 +msgid "Tue" +msgstr "" + +#: utils/dates.py:10 +msgid "Wed" +msgstr "" + +#: utils/dates.py:10 +msgid "Thu" +msgstr "" + +#: utils/dates.py:10 +msgid "Fri" +msgstr "" + +#: utils/dates.py:11 +msgid "Sat" +msgstr "" + +#: utils/dates.py:11 +msgid "Sun" +msgstr "" + +#: utils/dates.py:18 msgid "January" msgstr "Január" -#: utils/dates.py:14 +#: utils/dates.py:18 msgid "February" msgstr "Február" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "March" msgstr "Marec" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "April" msgstr "Apríl" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "May" msgstr "Máj" -#: utils/dates.py:14 utils/dates.py:27 +#: utils/dates.py:18 utils/dates.py:31 msgid "June" msgstr "Jún" -#: utils/dates.py:15 utils/dates.py:27 +#: utils/dates.py:19 utils/dates.py:31 msgid "July" msgstr "Júl" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "August" msgstr "August" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "September" msgstr "September" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "October" msgstr "Október" -#: utils/dates.py:15 +#: utils/dates.py:19 msgid "November" msgstr "November" -#: utils/dates.py:16 +#: utils/dates.py:20 msgid "December" msgstr "December" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "jan" msgstr "jan" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "feb" msgstr "feb" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "mar" msgstr "mar" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "apr" msgstr "apr" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "may" msgstr "máj" -#: utils/dates.py:19 +#: utils/dates.py:23 msgid "jun" msgstr "jún" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "jul" msgstr "júl" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "aug" msgstr "aug" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "sep" msgstr "sep" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "oct" msgstr "okt" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "nov" msgstr "nov" -#: utils/dates.py:20 +#: utils/dates.py:24 msgid "dec" msgstr "dec" -#: utils/dates.py:27 +#: utils/dates.py:31 msgid "Jan." msgstr "Jan." -#: utils/dates.py:27 +#: utils/dates.py:31 msgid "Feb." msgstr "Feb." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Aug." msgstr "Aug." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Sept." msgstr "Sept." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Oct." msgstr "Okt." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Nov." msgstr "Nov." -#: utils/dates.py:28 +#: utils/dates.py:32 msgid "Dec." msgstr "Dec." @@ -2923,87 +3301,85 @@ msgid_plural "minutes" msgstr[0] "minúta" msgstr[1] "minúty" -#: utils/timesince.py:40 -#, python-format -msgid "%d milliseconds" -msgstr "" - -#: utils/timesince.py:41 +#: utils/timesince.py:39 #, python-format msgid "%(number)d %(type)s" msgstr "" -#: utils/timesince.py:47 +#: utils/timesince.py:45 #, python-format msgid ", %(number)d %(type)s" msgstr "" -#: utils/dateformat.py:40 +#: utils/dateformat.py:41 msgid "p.m." msgstr "p.m." -#: utils/dateformat.py:41 +#: utils/dateformat.py:42 msgid "a.m." msgstr "a.m." -#: utils/dateformat.py:46 +#: utils/dateformat.py:47 msgid "PM" msgstr "" -#: utils/dateformat.py:47 +#: utils/dateformat.py:48 msgid "AM" msgstr "" -#: utils/dateformat.py:95 +#: utils/dateformat.py:97 msgid "midnight" msgstr "polnoc" -#: utils/dateformat.py:97 +#: utils/dateformat.py:99 msgid "noon" msgstr "poludnie" -#: utils/translation/trans_real.py:358 +#: utils/translation/trans_real.py:391 msgid "DATE_FORMAT" msgstr "" -#: utils/translation/trans_real.py:359 +#: utils/translation/trans_real.py:392 msgid "DATETIME_FORMAT" msgstr "" -#: utils/translation/trans_real.py:360 +#: utils/translation/trans_real.py:393 msgid "TIME_FORMAT" msgstr "" -#: utils/translation/trans_real.py:376 +#: utils/translation/trans_real.py:409 msgid "YEAR_MONTH_FORMAT" msgstr "" -#: utils/translation/trans_real.py:377 +#: utils/translation/trans_real.py:410 msgid "MONTH_DAY_FORMAT" msgstr "" -#: template/defaultfilters.py:491 +#: template/defaultfilters.py:485 msgid "yes,no,maybe" msgstr "áno,nie,možno" -#: template/defaultfilters.py:520 +#: template/defaultfilters.py:514 #, python-format msgid "%(size)d byte" msgid_plural "%(size)d bytes" msgstr[0] "" msgstr[1] "" -#: template/defaultfilters.py:522 +#: template/defaultfilters.py:516 #, python-format msgid "%.1f KB" msgstr "" -#: template/defaultfilters.py:524 +#: template/defaultfilters.py:518 #, python-format msgid "%.1f MB" msgstr "" -#: template/defaultfilters.py:525 +#: template/defaultfilters.py:519 #, python-format msgid "%.1f GB" msgstr "" + +#~ msgid "AnonymousUser" +#~ msgstr "Neregistrovaný užívateľ" diff --git a/django/contrib/admin/media/js/urlify.js b/django/contrib/admin/media/js/urlify.js index 9ae036a64d..1545d80ec9 100644 --- a/django/contrib/admin/media/js/urlify.js +++ b/django/contrib/admin/media/js/urlify.js @@ -40,6 +40,10 @@ var RUSSIAN_MAP = { 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', 'Я':'Ya' } +var CZECH_MAP = { + 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', + 'ž':'z' +} var ALL_DOWNCODE_MAPS=new Array() ALL_DOWNCODE_MAPS[0]=LATIN_MAP @@ -47,6 +51,7 @@ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP ALL_DOWNCODE_MAPS[2]=GREEK_MAP ALL_DOWNCODE_MAPS[3]=TURKISH_MAP ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP +ALL_DOWNCODE_MAPS[5]=CZECH_MAP var Downcoder = new Object(); Downcoder.Initialize = function() diff --git a/django/contrib/admin/templates/admin/auth/user/change_password.html b/django/contrib/admin/templates/admin/auth/user/change_password.html index acefebcf4b..8220c31cc5 100644 --- a/django/contrib/admin/templates/admin/auth/user/change_password.html +++ b/django/contrib/admin/templates/admin/auth/user/change_password.html @@ -6,7 +6,7 @@ {% endblock %} {% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %} {% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %} -{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %} +{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %} {% block breadcrumbs %}{% if not is_popup %} <div class="breadcrumbs"> <a href="../../../../">{% trans "Home" %}</a> › diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 141f710bfd..6c40228fab 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -3,7 +3,7 @@ from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm from django import oldforms from django.shortcuts import render_to_response from django.template import RequestContext -from django.contrib.sites.models import Site +from django.contrib.sites.models import Site, RequestSite from django.http import HttpResponseRedirect from django.contrib.auth.decorators import login_required from django.contrib.auth import REDIRECT_FIELD_NAME @@ -27,10 +27,16 @@ def login(request, template_name='registration/login.html'): else: errors = {} request.session.set_test_cookie() + + if Site._meta.installed: + current_site = Site.objects.get_current() + else: + current_site = RequestSite(request) + return render_to_response(template_name, { 'form': oldforms.FormWrapper(manipulator, request.POST, errors), REDIRECT_FIELD_NAME: redirect_to, - 'site_name': Site.objects.get_current().name, + 'site_name': current_site.name, }, context_instance=RequestContext(request)) def logout(request, next_page=None, template_name='registration/logged_out.html'): diff --git a/django/contrib/comments/models.py b/django/contrib/comments/models.py index 76a2457fd1..dea40cb602 100644 --- a/django/contrib/comments/models.py +++ b/django/contrib/comments/models.py @@ -96,7 +96,10 @@ class Comment(models.Model): return "%s: %s..." % (self.user.username, self.comment[:100]) def get_absolute_url(self): - return self.get_content_object().get_absolute_url() + "#c" + str(self.id) + try: + return self.get_content_object().get_absolute_url() + "#c" + str(self.id) + except AttributeError: + return "" def get_crossdomain_url(self): return "/r/%d/%d/" % (self.content_type_id, self.object_id) @@ -172,7 +175,10 @@ class FreeComment(models.Model): return "%s: %s..." % (self.person_name, self.comment[:100]) def get_absolute_url(self): - return self.get_content_object().get_absolute_url() + "#c" + str(self.id) + try: + return self.get_content_object().get_absolute_url() + "#c" + str(self.id) + except AttributeError: + return "" def get_content_object(self): """ diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py index 756ab9c93b..1d4628978d 100644 --- a/django/contrib/comments/templatetags/comments.py +++ b/django/contrib/comments/templatetags/comments.py @@ -112,9 +112,9 @@ class CommentListNode(template.Node): 'site__id__exact': settings.SITE_ID, } kwargs.update(self.extra_kwargs) - if not self.free and settings.COMMENTS_BANNED_USERS_GROUP: - kwargs['select'] = {'is_hidden': 'user_id IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)' % settings.COMMENTS_BANNED_USERS_GROUP} comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related() + if not self.free and settings.COMMENTS_BANNED_USERS_GROUP: + comment_list = comment_list.extra(select={'is_hidden': 'user_id IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)' % settings.COMMENTS_BANNED_USERS_GROUP}) if not self.free: if 'user' in context and context['user'].is_authenticated(): diff --git a/django/contrib/comments/views/comments.py b/django/contrib/comments/views/comments.py index f166fa118f..fbec04c8eb 100644 --- a/django/contrib/comments/views/comments.py +++ b/django/contrib/comments/views/comments.py @@ -113,7 +113,7 @@ class PublicCommentManipulator(AuthenticationForm): 'This comment was posted by a user who has posted fewer than %(count)s comments:\n\n%(text)s', settings.COMMENTS_FIRST_FEW) % \ {'count': settings.COMMENTS_FIRST_FEW, 'text': c.get_as_text()} mail_managers("Comment posted by rookie user", message) - if settings.COMMENTS_SKETCHY_USERS_GROUP and settings.COMMENTS_SKETCHY_USERS_GROUP in [g.id for g in self.user_cache.get_group_list()]: + if settings.COMMENTS_SKETCHY_USERS_GROUP and settings.COMMENTS_SKETCHY_USERS_GROUP in [g.id for g in self.user_cache.groups.all()]: message = _('This comment was posted by a sketchy user:\n\n%(text)s') % {'text': c.get_as_text()} mail_managers("Comment posted by sketchy user (%s)" % self.user_cache.username, c.get_as_text()) return c diff --git a/django/contrib/localflavor/in_/__init__.py b/django/contrib/localflavor/in_/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/django/contrib/localflavor/in_/__init__.py diff --git a/django/contrib/localflavor/in_/forms.py b/django/contrib/localflavor/in_/forms.py new file mode 100644 index 0000000000..5febc40e67 --- /dev/null +++ b/django/contrib/localflavor/in_/forms.py @@ -0,0 +1,49 @@ +""" +India-specific Form helpers. +""" + +from django.newforms import ValidationError +from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES +from django.utils.encoding import smart_unicode +from django.utils.translation import gettext +import re + + +class INZipCodeField(RegexField): + def __init__(self, *args, **kwargs): + super(INZipCodeField, self).__init__(r'^\d{6}$', + max_length=None, min_length=None, + error_message=gettext(u'Enter a zip code in the format XXXXXXX.'), + *args, **kwargs) + +class INStateField(Field): + """ + A form field that validates its input is a Indian state name or + abbreviation. It normalizes the input to the standard two-letter vehicle + registration abbreviation for the given state or union territory + """ + def clean(self, value): + from in_states import STATES_NORMALIZED + super(INStateField, self).clean(value) + if value in EMPTY_VALUES: + return u'' + try: + value = value.strip().lower() + except AttributeError: + pass + else: + try: + return smart_unicode(STATES_NORMALIZED[value.strip().lower()]) + except KeyError: + pass + raise ValidationError(u'Enter a Indian state or territory.') + +class INStateSelect(Select): + """ + A Select widget that uses a list of Indian states/territories as its + choices. + """ + def __init__(self, attrs=None): + from in_states import STATE_CHOICES + super(INStateSelect, self).__init__(attrs, choices=STATE_CHOICES) + diff --git a/django/contrib/localflavor/in_/in_states.py b/django/contrib/localflavor/in_/in_states.py new file mode 100644 index 0000000000..498efe7069 --- /dev/null +++ b/django/contrib/localflavor/in_/in_states.py @@ -0,0 +1,84 @@ +""" +A mapping of state misspellings/abbreviations to normalized abbreviations, and +an alphabetical list of states for use as `choices` in a formfield. + +This exists in this standalone file so that it's only imported into memory +when explicitly needed. +""" + +STATE_CHOICES = ( + 'KA', 'Karnataka', + 'AP', 'Andhra Pradesh', + 'KL', 'Kerala', + 'TN', 'Tamil Nadu', + 'MH', 'Maharashtra', + 'UP', 'Uttar Pradesh', + 'GA', 'Goa', + 'GJ', 'Gujarat', + 'RJ', 'Rajasthan', + 'HP', 'Himachal Pradesh', + 'JK', 'Jammu and Kashmir', + 'AR', 'Arunachal Pradesh', + 'AS', 'Assam', + 'BR', 'Bihar', + 'CG', 'Chattisgarh', + 'HR', 'Haryana', + 'JH', 'Jharkhand', + 'MP', 'Madhya Pradesh', + 'MN', 'Manipur', + 'ML', 'Meghalaya', + 'MZ', 'Mizoram', + 'NL', 'Nagaland', + 'OR', 'Orissa', + 'PB', 'Punjab', + 'SK', 'Sikkim', + 'TR', 'Tripura', + 'UA', 'Uttarakhand', + 'WB', 'West Bengal', + + # Union Territories + 'AN', 'Andaman and Nicobar', + 'CH', 'Chandigarh', + 'DN', 'Dadra and Nagar Haveli', + 'DD', 'Daman and Diu', + 'DL', 'Delhi', + 'LD', 'Lakshadweep', + 'PY', 'Pondicherry', +) + +STATES_NORMALIZED = { + 'ka': 'KA', + 'karnatka': 'KA', + 'tn': 'TN', + 'tamilnad': 'TN', + 'tamilnadu': 'TN', + 'andra pradesh': 'AP', + 'andrapradesh': 'AP', + 'andhrapradesh': 'AP', + 'maharastra': 'MH', + 'mh': 'MH', + 'ap': 'AP', + 'dl': 'DL', + 'dd': 'DD', + 'br': 'BR', + 'ar': 'AR', + 'sk': 'SK', + 'kl': 'KL', + 'ga': 'GA', + 'rj': 'RJ', + 'rajastan': 'RJ', + 'rajasthan': 'RJ', + 'hp': 'HP', + 'ua': 'UA', + 'up': 'UP', + 'mp': 'MP', + 'mz': 'MZ', + 'bengal': 'WB', + 'westbengal': 'WB', + 'mizo': 'MZ', + 'orisa': 'OR', + 'odisa': 'OR', + 'or': 'OR', + 'ar': 'AR', +} + diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 2db83fccfc..99d400d1bb 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -6,6 +6,7 @@ from django.utils.encoding import force_unicode from django import http from pprint import pformat from shutil import copyfileobj +from threading import Lock try: from cStringIO import StringIO except ImportError: @@ -176,13 +177,19 @@ class WSGIRequest(http.HttpRequest): raw_post_data = property(_get_raw_post_data) class WSGIHandler(BaseHandler): + initLock = Lock() + def __call__(self, environ, start_response): from django.conf import settings # Set up middleware if needed. We couldn't do this earlier, because # settings weren't available. if self._request_middleware is None: - self.load_middleware() + self.initLock.acquire() + # Check that middleware is still uninitialised. + if self._request_middleware is None: + self.load_middleware() + self.initLock.release() dispatcher.send(signal=signals.request_started) try: diff --git a/django/core/mail.py b/django/core/mail.py index 325812a5d2..ff653400f9 100644 --- a/django/core/mail.py +++ b/django/core/mail.py @@ -287,7 +287,8 @@ class EmailMessage(object): mimetype = DEFAULT_ATTACHMENT_MIME_TYPE basetype, subtype = mimetype.split('/', 1) if basetype == 'text': - attachment = SafeMIMEText(content, subtype, settings.DEFAULT_CHARSET) + attachment = SafeMIMEText(smart_str(content, + settings.DEFAULT_CHARSET), subtype, settings.DEFAULT_CHARSET) else: # Encode non-text attachments with base64. attachment = MIMEBase(basetype, subtype) diff --git a/django/core/management.py b/django/core/management.py deleted file mode 100644 index be1134506c..0000000000 --- a/django/core/management.py +++ /dev/null @@ -1,1733 +0,0 @@ -# Django management-related functions, including "CREATE TABLE" generation and -# development-server initialization. - -import django -from django.core.exceptions import ImproperlyConfigured -from optparse import OptionParser -from django.utils import termcolors -import os, re, shutil, sys, textwrap - -try: - set -except NameError: - from sets import Set as set # Python 2.3 fallback - -# For backwards compatibility: get_version() used to be in this module. -get_version = django.get_version - -MODULE_TEMPLATE = ''' {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%} - <tr> - <th>{%% if perms.%(app)s.%(changeperm)s %%}<a href="%(app)s/%(mod)s/">{%% endif %%}%(name)s{%% if perms.%(app)s.%(changeperm)s %%}</a>{%% endif %%}</th> - <td class="x50">{%% if perms.%(app)s.%(addperm)s %%}<a href="%(app)s/%(mod)s/add/" class="addlink">{%% endif %%}Add{%% if perms.%(app)s.%(addperm)s %%}</a>{%% endif %%}</td> - <td class="x75">{%% if perms.%(app)s.%(changeperm)s %%}<a href="%(app)s/%(mod)s/" class="changelink">{%% endif %%}Change{%% if perms.%(app)s.%(changeperm)s %%}</a>{%% endif %%}</td> - </tr> - {%% endif %%}''' - -APP_ARGS = '[appname ...]' - -# Use django.__path__[0] because we don't know which directory django into -# which has been installed. -PROJECT_TEMPLATE_DIR = os.path.join(django.__path__[0], 'conf', '%s_template') - -INVALID_PROJECT_NAMES = ('django', 'site', 'test') - -# Set up the terminal color scheme. -class dummy: pass -style = dummy() -style.ERROR = termcolors.make_style(fg='red', opts=('bold',)) -style.ERROR_OUTPUT = termcolors.make_style(fg='red', opts=('bold',)) -style.NOTICE = termcolors.make_style(fg='red') -style.SQL_FIELD = termcolors.make_style(fg='green', opts=('bold',)) -style.SQL_COLTYPE = termcolors.make_style(fg='green') -style.SQL_KEYWORD = termcolors.make_style(fg='yellow') -style.SQL_TABLE = termcolors.make_style(opts=('bold',)) -del dummy - -def disable_termcolors(): - class dummy: - def __getattr__(self, attr): - return lambda x: x - global style - style = dummy() - -# Disable terminal coloring on Windows, Pocket PC, or if somebody's piping the output. -if sys.platform == 'win32' or sys.platform == 'Pocket PC' or not sys.stdout.isatty(): - disable_termcolors() - -def _is_valid_dir_name(s): - return bool(re.search(r'^\w+$', s)) - -def _get_installed_models(table_list): - "Gets a set of all models that are installed, given a list of existing tables" - from django.db import backend, models - all_models = [] - for app in models.get_apps(): - for model in models.get_models(app): - all_models.append(model) - if backend.uses_case_insensitive_names: - converter = str.upper - else: - converter = lambda x: x - return set([m for m in all_models if converter(m._meta.db_table) in map(converter, table_list)]) - -def _get_table_list(): - "Gets a list of all db tables that are physically installed." - from django.db import connection, get_introspection_module - cursor = connection.cursor() - return get_introspection_module().get_table_list(cursor) - -def _get_sequence_list(): - "Returns a list of information about all DB sequences for all models in all apps" - from django.db import models - - apps = models.get_apps() - sequence_list = [] - - for app in apps: - for model in models.get_models(app): - for f in model._meta.fields: - if isinstance(f, models.AutoField): - sequence_list.append({'table':model._meta.db_table,'column':f.column,}) - break # Only one AutoField is allowed per model, so don't bother continuing. - - for f in model._meta.many_to_many: - sequence_list.append({'table':f.m2m_db_table(),'column':None,}) - - return sequence_list - -def get_sql_create(app): - "Returns a list of the CREATE TABLE SQL statements for the given app." - from django.db import models - from django.conf import settings - - if settings.DATABASE_ENGINE == 'dummy': - # This must be the "dummy" database backend, which means the user - # hasn't set DATABASE_ENGINE. - sys.stderr.write(style.ERROR("Error: Django doesn't know which syntax to use for your SQL statements,\n" + - "because you haven't specified the DATABASE_ENGINE setting.\n" + - "Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.\n")) - sys.exit(1) - - # Get installed models, so we generate REFERENCES right. - # We trim models from the current app so that the sqlreset command does not - # generate invalid SQL (leaving models out of known_models is harmless, so - # we can be conservative). - app_models = models.get_models(app) - final_output = [] - known_models = set([model for model in _get_installed_models(_get_table_list()) if model not in app_models]) - pending_references = {} - - for model in app_models: - output, references = _get_sql_model_create(model, known_models) - final_output.extend(output) - for refto, refs in references.items(): - pending_references.setdefault(refto,[]).extend(refs) - final_output.extend(_get_sql_for_pending_references(model, pending_references)) - # Keep track of the fact that we've created the table for this model. - known_models.add(model) - - # Create the many-to-many join tables. - for model in app_models: - final_output.extend(_get_many_to_many_sql_for_model(model)) - - # Handle references to tables that are from other apps - # but don't exist physically - not_installed_models = set(pending_references.keys()) - if not_installed_models: - alter_sql = [] - for model in not_installed_models: - alter_sql.extend(['-- ' + sql for sql in - _get_sql_for_pending_references(model, pending_references)]) - if alter_sql: - final_output.append('-- The following references should be added but depend on non-existent tables:') - final_output.extend(alter_sql) - - return final_output -get_sql_create.help_doc = "Prints the CREATE TABLE SQL statements for the given app name(s)." -get_sql_create.args = APP_ARGS - -def _get_sql_model_create(model, known_models=set()): - """ - Get the SQL required to create a single model. - - Returns list_of_sql, pending_references_dict - """ - from django.db import backend, models - - opts = model._meta - final_output = [] - table_output = [] - pending_references = {} - for f in opts.fields: - col_type = f.db_type() - tablespace = f.db_tablespace or opts.db_tablespace - if col_type is None: - # Skip ManyToManyFields, because they're not represented as - # database columns in this table. - continue - # Make the definition (e.g. 'foo VARCHAR(30)') for this field. - field_output = [style.SQL_FIELD(backend.quote_name(f.column)), - style.SQL_COLTYPE(col_type)] - field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) - if f.unique and (not f.primary_key or backend.allows_unique_and_pk): - field_output.append(style.SQL_KEYWORD('UNIQUE')) - if f.primary_key: - field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) - if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys: - # We must specify the index tablespace inline, because we - # won't be generating a CREATE INDEX statement for this field. - field_output.append(backend.get_tablespace_sql(tablespace, inline=True)) - if f.rel: - if f.rel.to in known_models: - field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ - style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \ - style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + - backend.get_deferrable_sql() - ) - else: - # We haven't yet created the table to which this field - # is related, so save it for later. - pr = pending_references.setdefault(f.rel.to, []).append((model, f)) - table_output.append(' '.join(field_output)) - if opts.order_with_respect_to: - table_output.append(style.SQL_FIELD(backend.quote_name('_order')) + ' ' + \ - style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ - style.SQL_KEYWORD('NULL')) - for field_constraints in opts.unique_together: - table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ - ", ".join([backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) - - full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(backend.quote_name(opts.db_table)) + ' ('] - for i, line in enumerate(table_output): # Combine and add commas. - full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) - full_statement.append(')') - if opts.db_tablespace and backend.supports_tablespaces: - full_statement.append(backend.get_tablespace_sql(opts.db_tablespace)) - full_statement.append(';') - final_output.append('\n'.join(full_statement)) - - if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'): - # Add any extra SQL needed to support auto-incrementing primary keys - autoinc_sql = backend.get_autoinc_sql(opts.db_table) - if autoinc_sql: - for stmt in autoinc_sql: - final_output.append(stmt) - - return final_output, pending_references - -def _get_sql_for_pending_references(model, pending_references): - """ - Get any ALTER TABLE statements to add constraints after the fact. - """ - from django.db import backend - from django.db.backends.util import truncate_name - - final_output = [] - if backend.supports_constraints: - opts = model._meta - if model in pending_references: - for rel_class, f in pending_references[model]: - rel_opts = rel_class._meta - r_table = rel_opts.db_table - r_col = f.column - table = opts.db_table - col = opts.get_field(f.rel.field_name).column - # For MySQL, r_name must be unique in the first 64 characters. - # So we are careful with character usage here. - r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) - final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ - (backend.quote_name(r_table), truncate_name(r_name, backend.get_max_name_length()), - backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col), - backend.get_deferrable_sql())) - del pending_references[model] - return final_output - -def _get_many_to_many_sql_for_model(model): - from django.db import backend, models - from django.contrib.contenttypes import generic - - opts = model._meta - final_output = [] - for f in opts.many_to_many: - if not isinstance(f.rel, generic.GenericRel): - tablespace = f.db_tablespace or opts.db_tablespace - if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys: - tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True) - else: - tablespace_sql = '' - table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ - style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] - table_output.append(' %s %s %s%s,' % \ - (style.SQL_FIELD(backend.quote_name('id')), - style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), - style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), - tablespace_sql)) - table_output.append(' %s %s %s %s (%s)%s,' % \ - (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), - style.SQL_COLTYPE(models.ForeignKey(model).db_type()), - style.SQL_KEYWORD('NOT NULL REFERENCES'), - style.SQL_TABLE(backend.quote_name(opts.db_table)), - style.SQL_FIELD(backend.quote_name(opts.pk.column)), - backend.get_deferrable_sql())) - table_output.append(' %s %s %s %s (%s)%s,' % \ - (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), - style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), - style.SQL_KEYWORD('NOT NULL REFERENCES'), - style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), - style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), - backend.get_deferrable_sql())) - table_output.append(' %s (%s, %s)%s' % \ - (style.SQL_KEYWORD('UNIQUE'), - style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), - style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), - tablespace_sql)) - table_output.append(')') - if opts.db_tablespace and backend.supports_tablespaces: - # f.db_tablespace is only for indices, so ignore its value here. - table_output.append(backend.get_tablespace_sql(opts.db_tablespace)) - table_output.append(';') - final_output.append('\n'.join(table_output)) - - # Add any extra SQL needed to support auto-incrementing PKs - autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table()) - if autoinc_sql: - for stmt in autoinc_sql: - final_output.append(stmt) - - return final_output - -def get_sql_delete(app): - "Returns a list of the DROP TABLE SQL statements for the given app." - from django.db import backend, connection, models, get_introspection_module - from django.db.backends.util import truncate_name - introspection = get_introspection_module() - - # This should work even if a connection isn't available - try: - cursor = connection.cursor() - except: - cursor = None - - # Figure out which tables already exist - if cursor: - table_names = introspection.get_table_list(cursor) - else: - table_names = [] - if backend.uses_case_insensitive_names: - table_name_converter = str.upper - else: - table_name_converter = lambda x: x - - output = [] - - # Output DROP TABLE statements for standard application tables. - to_delete = set() - - references_to_delete = {} - app_models = models.get_models(app) - for model in app_models: - if cursor and table_name_converter(model._meta.db_table) in table_names: - # The table exists, so it needs to be dropped - opts = model._meta - for f in opts.fields: - if f.rel and f.rel.to not in to_delete: - references_to_delete.setdefault(f.rel.to, []).append( (model, f) ) - - to_delete.add(model) - - for model in app_models: - if cursor and table_name_converter(model._meta.db_table) in table_names: - # Drop the table now - output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), - style.SQL_TABLE(backend.quote_name(model._meta.db_table)))) - if backend.supports_constraints and model in references_to_delete: - for rel_class, f in references_to_delete[model]: - table = rel_class._meta.db_table - col = f.column - r_table = model._meta.db_table - r_col = model._meta.get_field(f.rel.field_name).column - r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) - output.append('%s %s %s %s;' % \ - (style.SQL_KEYWORD('ALTER TABLE'), - style.SQL_TABLE(backend.quote_name(table)), - style.SQL_KEYWORD(backend.get_drop_foreignkey_sql()), - style.SQL_FIELD(truncate_name(r_name, backend.get_max_name_length())))) - del references_to_delete[model] - if model._meta.has_auto_field and hasattr(backend, 'get_drop_sequence'): - output.append(backend.get_drop_sequence(model._meta.db_table)) - - # Output DROP TABLE statements for many-to-many tables. - for model in app_models: - opts = model._meta - for f in opts.many_to_many: - if cursor and table_name_converter(f.m2m_db_table()) in table_names: - output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), - style.SQL_TABLE(backend.quote_name(f.m2m_db_table())))) - if hasattr(backend, 'get_drop_sequence'): - output.append(backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) - - - app_label = app_models[0]._meta.app_label - - # Close database connection explicitly, in case this output is being piped - # directly into a database client, to avoid locking issues. - if cursor: - cursor.close() - connection.close() - - return output[::-1] # Reverse it, to deal with table dependencies. -get_sql_delete.help_doc = "Prints the DROP TABLE SQL statements for the given app name(s)." -get_sql_delete.args = APP_ARGS - -def get_sql_reset(app): - "Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module." - return get_sql_delete(app) + get_sql_all(app) -get_sql_reset.help_doc = "Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s)." -get_sql_reset.args = APP_ARGS - -def get_sql_flush(): - "Returns a list of the SQL statements used to flush the database" - from django.db import backend - statements = backend.get_sql_flush(style, _get_table_list(), _get_sequence_list()) - return statements -get_sql_flush.help_doc = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed." -get_sql_flush.args = '' - -def get_custom_sql_for_model(model): - from django.db import models - from django.conf import settings - - opts = model._meta - app_dir = os.path.normpath(os.path.join(os.path.dirname(models.get_app(model._meta.app_label).__file__), 'sql')) - output = [] - - # Some backends can't execute more than one SQL statement at a time, - # so split into separate statements. - statements = re.compile(r";[ \t]*$", re.M) - - # Find custom SQL, if it's available. - sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), settings.DATABASE_ENGINE)), - os.path.join(app_dir, "%s.sql" % opts.object_name.lower())] - for sql_file in sql_files: - if os.path.exists(sql_file): - fp = open(sql_file, 'U') - for statement in statements.split(fp.read().decode(settings.FILE_CHARSET)): - # Remove any comments from the file - statement = re.sub(ur"--.*[\n\Z]", "", statement) - if statement.strip(): - output.append(statement + u";") - fp.close() - - return output - -def get_custom_sql(app): - "Returns a list of the custom table modifying SQL statements for the given app." - from django.db.models import get_models - output = [] - - app_models = get_models(app) - app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql')) - - for model in app_models: - output.extend(get_custom_sql_for_model(model)) - - return output -get_custom_sql.help_doc = "Prints the custom table modifying SQL statements for the given app name(s)." -get_custom_sql.args = APP_ARGS - -def get_sql_initial_data(apps): - "Returns a list of the initial INSERT SQL statements for the given app." - return style.ERROR("This action has been renamed. Try './manage.py sqlcustom %s'." % ' '.join(apps and apps or ['app1', 'app2'])) -get_sql_initial_data.help_doc = "RENAMED: see 'sqlcustom'" -get_sql_initial_data.args = '' - -def get_sql_sequence_reset(app): - "Returns a list of the SQL statements to reset sequences for the given app." - from django.db import backend, models - return backend.get_sql_sequence_reset(style, models.get_models(app)) -get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting sequences for the given app name(s)." -get_sql_sequence_reset.args = APP_ARGS - -def get_sql_indexes(app): - "Returns a list of the CREATE INDEX SQL statements for all models in the given app." - from django.db import models - output = [] - for model in models.get_models(app): - output.extend(get_sql_indexes_for_model(model)) - return output -get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)." -get_sql_indexes.args = APP_ARGS - -def get_sql_indexes_for_model(model): - "Returns the CREATE INDEX SQL statements for a single model" - from django.db import backend - output = [] - - for f in model._meta.fields: - if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys): - unique = f.unique and 'UNIQUE ' or '' - tablespace = f.db_tablespace or model._meta.db_tablespace - if tablespace and backend.supports_tablespaces: - tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace) - else: - tablespace_sql = '' - output.append( - style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ - style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ - style.SQL_KEYWORD('ON') + ' ' + \ - style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \ - "(%s)" % style.SQL_FIELD(backend.quote_name(f.column)) + \ - "%s;" % tablespace_sql - ) - return output - -def get_sql_all(app): - "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module." - return get_sql_create(app) + get_custom_sql(app) + get_sql_indexes(app) -get_sql_all.help_doc = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)." -get_sql_all.args = APP_ARGS - -def _emit_post_sync_signal(created_models, verbosity, interactive): - from django.db import models - from django.dispatch import dispatcher - # Emit the post_sync signal for every application. - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - if verbosity >= 2: - print "Running post-sync handlers for application", app_name - dispatcher.send(signal=models.signals.post_syncdb, sender=app, - app=app, created_models=created_models, - verbosity=verbosity, interactive=interactive) - -def syncdb(verbosity=1, interactive=True): - "Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." - from django.db import backend, connection, transaction, models - from django.conf import settings - - disable_termcolors() - - # First, try validating the models. - _check_for_validation_errors() - - # Import the 'management' module within each installed app, to register - # dispatcher events. - for app_name in settings.INSTALLED_APPS: - try: - __import__(app_name + '.management', {}, {}, ['']) - except ImportError: - pass - - cursor = connection.cursor() - - # Get a list of all existing database tables, - # so we know what needs to be added. - table_list = _get_table_list() - if backend.uses_case_insensitive_names: - table_name_converter = str.upper - else: - table_name_converter = lambda x: x - - # Get a list of already installed *models* so that references work right. - seen_models = _get_installed_models(table_list) - created_models = set() - pending_references = {} - - # Create the tables for each model - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - model_list = models.get_models(app) - for model in model_list: - # Create the model's database table, if it doesn't already exist. - if verbosity >= 2: - print "Processing %s.%s model" % (app_name, model._meta.object_name) - if table_name_converter(model._meta.db_table) in table_list: - continue - sql, references = _get_sql_model_create(model, seen_models) - seen_models.add(model) - created_models.add(model) - for refto, refs in references.items(): - pending_references.setdefault(refto, []).extend(refs) - sql.extend(_get_sql_for_pending_references(model, pending_references)) - if verbosity >= 1: - print "Creating table %s" % model._meta.db_table - for statement in sql: - cursor.execute(statement) - table_list.append(table_name_converter(model._meta.db_table)) - - # Create the m2m tables. This must be done after all tables have been created - # to ensure that all referred tables will exist. - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - model_list = models.get_models(app) - for model in model_list: - if model in created_models: - sql = _get_many_to_many_sql_for_model(model) - if sql: - if verbosity >= 2: - print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name) - for statement in sql: - cursor.execute(statement) - - transaction.commit_unless_managed() - - # Send the post_syncdb signal, so individual apps can do whatever they need - # to do at this point. - _emit_post_sync_signal(created_models, verbosity, interactive) - - # Install custom SQL for the app (but only if this - # is a model we've just created) - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - for model in models.get_models(app): - if model in created_models: - custom_sql = get_custom_sql_for_model(model) - if custom_sql: - if verbosity >= 1: - print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name) - try: - for sql in custom_sql: - cursor.execute(sql) - except Exception, e: - sys.stderr.write("Failed to install custom SQL for %s.%s model: %s" % \ - (app_name, model._meta.object_name, e)) - transaction.rollback_unless_managed() - else: - transaction.commit_unless_managed() - - # Install SQL indicies for all newly created models - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - for model in models.get_models(app): - if model in created_models: - index_sql = get_sql_indexes_for_model(model) - if index_sql: - if verbosity >= 1: - print "Installing index for %s.%s model" % (app_name, model._meta.object_name) - try: - for sql in index_sql: - cursor.execute(sql) - except Exception, e: - sys.stderr.write("Failed to install index for %s.%s model: %s" % \ - (app_name, model._meta.object_name, e)) - transaction.rollback_unless_managed() - else: - transaction.commit_unless_managed() - - # Install the 'initialdata' fixture, using format discovery - load_data(['initial_data'], verbosity=verbosity) -syncdb.help_doc = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." -syncdb.args = '[--verbosity] [--noinput]' - -def get_admin_index(app): - "Returns admin-index template snippet (in list form) for the given app." - from django.utils.text import capfirst - from django.db.models import get_models - output = [] - app_models = get_models(app) - app_label = app_models[0]._meta.app_label - output.append('{%% if perms.%s %%}' % app_label) - output.append('<div class="module"><h2>%s</h2><table>' % app_label.title()) - for model in app_models: - if model._meta.admin: - output.append(MODULE_TEMPLATE % { - 'app': app_label, - 'mod': model._meta.module_name, - 'name': capfirst(model._meta.verbose_name_plural), - 'addperm': model._meta.get_add_permission(), - 'changeperm': model._meta.get_change_permission(), - }) - output.append('</table></div>') - output.append('{% endif %}') - return output -get_admin_index.help_doc = "Prints the admin-index template snippet for the given app name(s)." -get_admin_index.args = APP_ARGS - -def _module_to_dict(module, omittable=lambda k: k.startswith('_')): - "Converts a module namespace to a Python dictionary. Used by get_settings_diff." - return dict([(k, repr(v)) for k, v in module.__dict__.items() if not omittable(k)]) - -def diffsettings(): - """ - Displays differences between the current settings.py and Django's - default settings. Settings that don't appear in the defaults are - followed by "###". - """ - # Inspired by Postfix's "postconf -n". - from django.conf import settings, global_settings - - user_settings = _module_to_dict(settings._target) - default_settings = _module_to_dict(global_settings) - - output = [] - keys = user_settings.keys() - keys.sort() - for key in keys: - if key not in default_settings: - output.append("%s = %s ###" % (key, user_settings[key])) - elif user_settings[key] != default_settings[key]: - output.append("%s = %s" % (key, user_settings[key])) - print '\n'.join(output) -diffsettings.args = "" - -def reset(app, interactive=True): - "Executes the equivalent of 'get_sql_reset' in the current database." - from django.db import connection, transaction - from django.conf import settings - app_name = app.__name__.split('.')[-2] - - disable_termcolors() - - # First, try validating the models. - _check_for_validation_errors(app) - sql_list = get_sql_reset(app) - - if interactive: - confirm = raw_input(""" -You have requested a database reset. -This will IRREVERSIBLY DESTROY any data for -the "%s" application in the database "%s". -Are you sure you want to do this? - -Type 'yes' to continue, or 'no' to cancel: """ % (app_name, settings.DATABASE_NAME)) - else: - confirm = 'yes' - - if confirm == 'yes': - try: - cursor = connection.cursor() - for sql in sql_list: - cursor.execute(sql) - except Exception, e: - sys.stderr.write(style.ERROR("""Error: %s couldn't be reset. Possible reasons: - * The database isn't running or isn't configured correctly. - * At least one of the database tables doesn't exist. - * The SQL was invalid. -Hint: Look at the output of 'django-admin.py sqlreset %s'. That's the SQL this command wasn't able to run. -The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n') - transaction.rollback_unless_managed() - sys.exit(1) - transaction.commit_unless_managed() - else: - print "Reset cancelled." -reset.help_doc = "Executes ``sqlreset`` for the given app(s) in the current database." -reset.args = '[--noinput]' + APP_ARGS - -def flush(verbosity=1, interactive=True): - "Returns all tables in the database to the same state they were in immediately after syncdb." - from django.conf import settings - from django.db import connection, transaction, models - from django.dispatch import dispatcher - - disable_termcolors() - - # First, try validating the models. - _check_for_validation_errors() - - # Import the 'management' module within each installed app, to register - # dispatcher events. - for app_name in settings.INSTALLED_APPS: - try: - __import__(app_name + '.management', {}, {}, ['']) - except ImportError: - pass - - sql_list = get_sql_flush() - - if interactive: - confirm = raw_input(""" -You have requested a flush of the database. -This will IRREVERSIBLY DESTROY all data currently in the database, -and return each table to the state it was in after syncdb. -Are you sure you want to do this? - -Type 'yes' to continue, or 'no' to cancel: """) - else: - confirm = 'yes' - - if confirm == 'yes': - try: - cursor = connection.cursor() - for sql in sql_list: - cursor.execute(sql) - except Exception, e: - sys.stderr.write(style.ERROR("""Error: Database %s couldn't be flushed. Possible reasons: - * The database isn't running or isn't configured correctly. - * At least one of the expected database tables doesn't exist. - * The SQL was invalid. -Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. -The full error: """ % settings.DATABASE_NAME + style.ERROR_OUTPUT(str(e)) + '\n')) - transaction.rollback_unless_managed() - sys.exit(1) - transaction.commit_unless_managed() - - # Emit the post sync signal. This allows individual - # applications to respond as if the database had been - # sync'd from scratch. - _emit_post_sync_signal(models.get_models(), verbosity, interactive) - - # Reinstall the initial_data fixture - load_data(['initial_data'], verbosity=verbosity) - - else: - print "Flush cancelled." -flush.help_doc = "Executes ``sqlflush`` on the current database." -flush.args = '[--verbosity] [--noinput]' - -def _start_helper(app_or_project, name, directory, other_name=''): - other = {'project': 'app', 'app': 'project'}[app_or_project] - if not _is_valid_dir_name(name): - sys.stderr.write(style.ERROR("Error: %r is not a valid %s name. Please use only numbers, letters and underscores.\n" % (name, app_or_project))) - sys.exit(1) - top_dir = os.path.join(directory, name) - try: - os.mkdir(top_dir) - except OSError, e: - sys.stderr.write(style.ERROR("Error: %s\n" % e)) - sys.exit(1) - template_dir = PROJECT_TEMPLATE_DIR % app_or_project - for d, subdirs, files in os.walk(template_dir): - relative_dir = d[len(template_dir)+1:].replace('%s_name' % app_or_project, name) - if relative_dir: - os.mkdir(os.path.join(top_dir, relative_dir)) - for i, subdir in enumerate(subdirs): - if subdir.startswith('.'): - del subdirs[i] - for f in files: - if f.endswith('.pyc'): - continue - path_old = os.path.join(d, f) - path_new = os.path.join(top_dir, relative_dir, f.replace('%s_name' % app_or_project, name)) - fp_old = open(path_old, 'r') - fp_new = open(path_new, 'w') - fp_new.write(fp_old.read().replace('{{ %s_name }}' % app_or_project, name).replace('{{ %s_name }}' % other, other_name)) - fp_old.close() - fp_new.close() - try: - shutil.copymode(path_old, path_new) - except OSError: - sys.stderr.write(style.NOTICE("Notice: Couldn't set permission bits on %s. You're probably using an uncommon filesystem setup. No problem.\n" % path_new)) - -def startproject(project_name, directory): - "Creates a Django project for the given project_name in the given directory." - from random import choice - if project_name in INVALID_PROJECT_NAMES: - sys.stderr.write(style.ERROR("Error: '%r' conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name.\n" % project_name)) - sys.exit(1) - _start_helper('project', project_name, directory) - - # Create a random SECRET_KEY hash, and put it in the main settings. - main_settings_file = os.path.join(directory, project_name, 'settings.py') - settings_contents = open(main_settings_file, 'r').read() - - # If settings.py was copied from a read-only source, make it writeable. - if not os.access(main_settings_file, os.W_OK): - os.chmod(main_settings_file, 0600) - - fp = open(main_settings_file, 'w') - secret_key = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)]) - settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents) - fp.write(settings_contents) - fp.close() -startproject.help_doc = "Creates a Django project directory structure for the given project name in the current directory." -startproject.args = "[projectname]" - -def startapp(app_name, directory): - "Creates a Django app for the given app_name in the given directory." - # Determine the project_name a bit naively -- by looking at the name of - # the parent directory. - project_dir = os.path.normpath(os.path.join(directory, '..')) - parent_dir = os.path.basename(project_dir) - project_name = os.path.basename(directory) - if app_name == project_name: - sys.stderr.write(style.ERROR("Error: You cannot create an app with the same name (%r) as your project.\n" % app_name)) - sys.exit(1) - _start_helper('app', app_name, directory, parent_dir) -startapp.help_doc = "Creates a Django app directory structure for the given app name in the current directory." -startapp.args = "[appname]" - -def inspectdb(): - "Generator that introspects the tables in the given database name and returns a Django model, one line at a time." - from django.db import connection, get_introspection_module - import keyword - - introspection_module = get_introspection_module() - - table2model = lambda table_name: table_name.title().replace('_', '') - - cursor = connection.cursor() - yield "# This is an auto-generated Django model module." - yield "# You'll have to do the following manually to clean this up:" - yield "# * Rearrange models' order" - yield "# * Make sure each model has one field with primary_key=True" - yield "# Feel free to rename the models, but don't rename db_table values or field names." - yield "#" - yield "# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'" - yield "# into your database." - yield '' - yield 'from django.db import models' - yield '' - for table_name in introspection_module.get_table_list(cursor): - yield 'class %s(models.Model):' % table2model(table_name) - try: - relations = introspection_module.get_relations(cursor, table_name) - except NotImplementedError: - relations = {} - try: - indexes = introspection_module.get_indexes(cursor, table_name) - except NotImplementedError: - indexes = {} - for i, row in enumerate(introspection_module.get_table_description(cursor, table_name)): - att_name = row[0].lower() - comment_notes = [] # Holds Field notes, to be displayed in a Python comment. - extra_params = {} # Holds Field parameters such as 'db_column'. - - if ' ' in att_name: - extra_params['db_column'] = att_name - att_name = att_name.replace(' ', '') - comment_notes.append('Field renamed to remove spaces.') - if keyword.iskeyword(att_name): - extra_params['db_column'] = att_name - att_name += '_field' - comment_notes.append('Field renamed because it was a Python reserved word.') - - if i in relations: - rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1]) - field_type = 'ForeignKey(%s' % rel_to - if att_name.endswith('_id'): - att_name = att_name[:-3] - else: - extra_params['db_column'] = att_name - else: - try: - field_type = introspection_module.DATA_TYPES_REVERSE[row[1]] - except KeyError: - field_type = 'TextField' - comment_notes.append('This field type is a guess.') - - # This is a hook for DATA_TYPES_REVERSE to return a tuple of - # (field_type, extra_params_dict). - if type(field_type) is tuple: - field_type, new_params = field_type - extra_params.update(new_params) - - # Add max_length for all CharFields. - if field_type == 'CharField' and row[3]: - extra_params['max_length'] = row[3] - - if field_type == 'DecimalField': - extra_params['max_digits'] = row[4] - extra_params['decimal_places'] = row[5] - - # Add primary_key and unique, if necessary. - column_name = extra_params.get('db_column', att_name) - if column_name in indexes: - if indexes[column_name]['primary_key']: - extra_params['primary_key'] = True - elif indexes[column_name]['unique']: - extra_params['unique'] = True - - field_type += '(' - - # Don't output 'id = meta.AutoField(primary_key=True)', because - # that's assumed if it doesn't exist. - if att_name == 'id' and field_type == 'AutoField(' and extra_params == {'primary_key': True}: - continue - - # Add 'null' and 'blank', if the 'null_ok' flag was present in the - # table description. - if row[6]: # If it's NULL... - extra_params['blank'] = True - if not field_type in ('TextField(', 'CharField('): - extra_params['null'] = True - - field_desc = '%s = models.%s' % (att_name, field_type) - if extra_params: - if not field_desc.endswith('('): - field_desc += ', ' - field_desc += ', '.join(['%s=%r' % (k, v) for k, v in extra_params.items()]) - field_desc += ')' - if comment_notes: - field_desc += ' # ' + ' '.join(comment_notes) - yield ' %s' % field_desc - yield ' class Meta:' - yield ' db_table = %r' % table_name - yield '' -inspectdb.help_doc = "Introspects the database tables in the given database and outputs a Django model module." -inspectdb.args = "" - -class ModelErrorCollection: - def __init__(self, outfile=sys.stdout): - self.errors = [] - self.outfile = outfile - - def add(self, context, error): - self.errors.append((context, error)) - self.outfile.write(style.ERROR("%s: %s\n" % (context, error))) - -def get_validation_errors(outfile, app=None): - """ - Validates all models that are part of the specified app. If no app name is provided, - validates all models of all installed apps. Writes errors, if any, to outfile. - Returns number of errors. - """ - from django.conf import settings - from django.db import models, connection - from django.db.models.loading import get_app_errors - from django.db.models.fields.related import RelatedObject - - e = ModelErrorCollection(outfile) - - for (app_name, error) in get_app_errors().items(): - e.add(app_name, error) - - for cls in models.get_models(app): - opts = cls._meta - - # Do field-specific validation. - for f in opts.fields: - if f.name == 'id' and not f.primary_key and opts.pk.name == 'id': - 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.max_length in (None, 0): - e.add(opts, '"%s": CharFields require a "max_length" attribute.' % f.name) - if isinstance(f, models.DecimalField): - if f.decimal_places is None: - e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name) - if f.max_digits is None: - 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): - try: - from PIL import Image - except ImportError: - e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) - if f.choices: - if not hasattr(f.choices, '__iter__'): - e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name) - else: - for c in f.choices: - if not type(c) in (tuple, list) or len(c) != 2: - e.add(opts, '"%s": "choices" should be a sequence of two-tuples.' % f.name) - if f.db_index not in (None, True, False): - e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name) - - # Check that max_length <= 255 if using older MySQL versions. - if settings.DATABASE_ENGINE == 'mysql': - db_version = connection.get_server_version() - if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.max_length > 255: - e.add(opts, '"%s": %s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]]))) - - # Check to see if the related field will clash with any - # existing fields, m2m fields, m2m related objects or related objects - if f.rel: - rel_opts = f.rel.to._meta - if f.rel.to not in models.get_models(): - e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) - - rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() - rel_query_name = f.related_query_name() - for r in rel_opts.fields: - if r.name == rel_name: - e.add(opts, "Accessor for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - if r.name == rel_query_name: - e.add(opts, "Reverse query name for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - for r in rel_opts.many_to_many: - if r.name == rel_name: - e.add(opts, "Accessor for field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - if r.name == rel_query_name: - e.add(opts, "Reverse query name for field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - for r in rel_opts.get_all_related_many_to_many_objects(): - if r.get_accessor_name() == rel_name: - e.add(opts, "Accessor for field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - if r.get_accessor_name() == rel_query_name: - e.add(opts, "Reverse query name for field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - for r in rel_opts.get_all_related_objects(): - if r.field is not f: - if r.get_accessor_name() == rel_name: - e.add(opts, "Accessor for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - if r.get_accessor_name() == rel_query_name: - e.add(opts, "Reverse query name for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - - - for i, f in enumerate(opts.many_to_many): - # Check to see if the related m2m field will clash with any - # existing fields, m2m fields, m2m related objects or related objects - rel_opts = f.rel.to._meta - if f.rel.to not in models.get_models(): - e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) - - rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() - rel_query_name = f.related_query_name() - # If rel_name is none, there is no reverse accessor. - # (This only occurs for symmetrical m2m relations to self). - # If this is the case, there are no clashes to check for this field, as - # there are no reverse descriptors for this field. - if rel_name is not None: - for r in rel_opts.fields: - if r.name == rel_name: - e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - if r.name == rel_query_name: - e.add(opts, "Reverse query name for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - for r in rel_opts.many_to_many: - if r.name == rel_name: - e.add(opts, "Accessor for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - if r.name == rel_query_name: - e.add(opts, "Reverse query name for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) - for r in rel_opts.get_all_related_many_to_many_objects(): - if r.field is not f: - if r.get_accessor_name() == rel_name: - e.add(opts, "Accessor for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - if r.get_accessor_name() == rel_query_name: - e.add(opts, "Reverse query name for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - for r in rel_opts.get_all_related_objects(): - if r.get_accessor_name() == rel_name: - e.add(opts, "Accessor for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - if r.get_accessor_name() == rel_query_name: - e.add(opts, "Reverse query name for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) - - # Check admin attribute. - if opts.admin is not None: - # prepopulated_fields - if not isinstance(opts.admin.prepopulated_fields, dict): - e.add(opts, '"%s": prepopulated_fields should be a dictionary.' % f.name) - else: - for field_name, field_list in opts.admin.prepopulated_fields.items(): - if not isinstance(field_list, (list, tuple)): - e.add(opts, '"%s": prepopulated_fields "%s" value should be a list or tuple.' % (f.name, field_name)) - - # list_display - if not isinstance(opts.admin.list_display, (list, tuple)): - e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.') - else: - for fn in opts.admin.list_display: - try: - f = opts.get_field(fn) - except models.FieldDoesNotExist: - if not hasattr(cls, fn): - e.add(opts, '"admin.list_display" refers to %r, which isn\'t an attribute, method or property.' % fn) - else: - if isinstance(f, models.ManyToManyField): - e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn) - # list_display_links - if opts.admin.list_display_links and not opts.admin.list_display: - e.add(opts, '"admin.list_display" must be defined for "admin.list_display_links" to be used.') - if not isinstance(opts.admin.list_display_links, (list, tuple)): - e.add(opts, '"admin.list_display_links", if given, must be set to a list or tuple.') - else: - for fn in opts.admin.list_display_links: - try: - f = opts.get_field(fn) - except models.FieldDoesNotExist: - if not hasattr(cls, fn): - e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % fn) - if fn not in opts.admin.list_display: - e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn) - # list_filter - if not isinstance(opts.admin.list_filter, (list, tuple)): - e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.') - else: - for fn in opts.admin.list_filter: - try: - f = opts.get_field(fn) - except models.FieldDoesNotExist: - e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn) - # date_hierarchy - if opts.admin.date_hierarchy: - try: - f = opts.get_field(opts.admin.date_hierarchy) - except models.FieldDoesNotExist: - e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.admin.date_hierarchy) - - # Check ordering attribute. - if opts.ordering: - for field_name in opts.ordering: - if field_name == '?': continue - if field_name.startswith('-'): - field_name = field_name[1:] - if opts.order_with_respect_to and field_name == '_order': - continue - if '.' in field_name: continue # Skip ordering in the format 'table.field'. - try: - opts.get_field(field_name, many_to_many=False) - except models.FieldDoesNotExist: - e.add(opts, '"ordering" refers to "%s", a field that doesn\'t exist.' % field_name) - - # Check core=True, if needed. - for related in opts.get_followed_related_objects(): - if not related.edit_inline: - continue - try: - for f in related.opts.fields: - if f.core: - raise StopIteration - e.add(related.opts, "At least one field in %s should have core=True, because it's being edited inline by %s.%s." % (related.opts.object_name, opts.module_name, opts.object_name)) - except StopIteration: - pass - - # Check unique_together. - for ut in opts.unique_together: - for field_name in ut: - try: - f = opts.get_field(field_name, many_to_many=True) - except models.FieldDoesNotExist: - e.add(opts, '"unique_together" refers to %s, a field that doesn\'t exist. Check your syntax.' % field_name) - else: - if isinstance(f.rel, models.ManyToManyRel): - e.add(opts, '"unique_together" refers to %s. ManyToManyFields are not supported in unique_together.' % f.name) - - return len(e.errors) - -def validate(outfile=sys.stdout, silent_success=False): - "Validates all installed models." - try: - num_errors = get_validation_errors(outfile) - if silent_success and num_errors == 0: - return - outfile.write('%s error%s found.\n' % (num_errors, num_errors != 1 and 's' or '')) - except ImproperlyConfigured: - outfile.write("Skipping validation because things aren't configured properly.\n") -validate.args = '' - -def _check_for_validation_errors(app=None): - """Check that an app has no validation errors, and exit with errors if it does.""" - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - s = StringIO() - num_errors = get_validation_errors(s, app) - if num_errors: - if app: - sys.stderr.write(style.ERROR("Error: %s couldn't be installed, because there were errors in your model:\n" % app)) - else: - sys.stderr.write(style.ERROR("Error: Couldn't install apps, because there were errors in one or more models:\n")) - s.seek(0) - sys.stderr.write(s.read()) - sys.exit(1) - -def runserver(addr, port, use_reloader=True, admin_media_dir=''): - "Starts a lightweight Web server for development." - from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException - from django.core.handlers.wsgi import WSGIHandler - if not addr: - addr = '127.0.0.1' - if not port.isdigit(): - sys.stderr.write(style.ERROR("Error: %r is not a valid port number.\n" % port)) - sys.exit(1) - quit_command = sys.platform == 'win32' and 'CTRL-BREAK' or 'CONTROL-C' - def inner_run(): - from django.conf import settings - print "Validating models..." - validate() - print "\nDjango version %s, using settings %r" % (get_version(), settings.SETTINGS_MODULE) - print "Development server is running at http://%s:%s/" % (addr, port) - print "Quit the server with %s." % quit_command - try: - import django - path = admin_media_dir or django.__path__[0] + '/contrib/admin/media' - handler = AdminMediaHandler(WSGIHandler(), path) - run(addr, int(port), handler) - except WSGIServerException, e: - # Use helpful error messages instead of ugly tracebacks. - ERRORS = { - 13: "You don't have permission to access that port.", - 98: "That port is already in use.", - 99: "That IP address can't be assigned-to.", - } - try: - error_text = ERRORS[e.args[0].args[0]] - except (AttributeError, KeyError): - error_text = str(e) - sys.stderr.write(style.ERROR("Error: %s" % error_text) + '\n') - # Need to use an OS exit because sys.exit doesn't work in a thread - os._exit(1) - except KeyboardInterrupt: - sys.exit(0) - if use_reloader: - from django.utils import autoreload - autoreload.main(inner_run) - else: - inner_run() -runserver.args = '[--noreload] [--adminmedia=ADMIN_MEDIA_PATH] [optional port number, or ipaddr:port]' - -def createcachetable(tablename): - "Creates the table needed to use the SQL cache backend" - from django.db import backend, connection, transaction, models - fields = ( - # "key" is a reserved word in MySQL, so use "cache_key" instead. - models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), - models.TextField(name='value'), - models.DateTimeField(name='expires', db_index=True), - ) - table_output = [] - index_output = [] - for f in fields: - field_output = [backend.quote_name(f.name), f.db_type()] - field_output.append("%sNULL" % (not f.null and "NOT " or "")) - if f.unique: - field_output.append("UNIQUE") - if f.primary_key: - field_output.append("PRIMARY KEY") - if f.db_index: - unique = f.unique and "UNIQUE " or "" - index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ - (unique, tablename, f.name, backend.quote_name(tablename), - backend.quote_name(f.name))) - table_output.append(" ".join(field_output)) - full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)] - for i, line in enumerate(table_output): - full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) - full_statement.append(');') - curs = connection.cursor() - curs.execute("\n".join(full_statement)) - for statement in index_output: - curs.execute(statement) - transaction.commit_unless_managed() -createcachetable.args = "[tablename]" - -def run_shell(use_plain=False): - "Runs a Python interactive interpreter. Tries to use IPython, if it's available." - # XXX: (Temporary) workaround for ticket #1796: force early loading of all - # models from installed apps. - from django.db.models.loading import get_models - loaded_models = get_models() - - try: - if use_plain: - # Don't bother loading IPython, because the user wants plain Python. - raise ImportError - import IPython - # Explicitly pass an empty list as arguments, because otherwise IPython - # would use sys.argv from this script. - shell = IPython.Shell.IPShell(argv=[]) - shell.mainloop() - except ImportError: - import code - # Set up a dictionary to serve as the environment for the shell, so - # that tab completion works on objects that are imported at runtime. - # See ticket 5082. - imported_objects = {} - try: # Try activating rlcompleter, because it's handy. - import readline - except ImportError: - pass - else: - # We don't have to wrap the following import in a 'try', because - # we already know 'readline' was imported successfully. - import rlcompleter - readline.set_completer(rlcompleter.Completer(imported_objects).complete) - readline.parse_and_bind("tab:complete") - code.interact(local=imported_objects) -run_shell.args = '[--plain]' - -def dbshell(): - "Runs the command-line client for the current DATABASE_ENGINE." - from django.db import runshell - runshell() -dbshell.args = "" - -def runfcgi(args): - "Runs this project as a FastCGI application. Requires flup." - from django.conf import settings - from django.utils import translation - # Activate the current language, because it won't get activated later. - try: - translation.activate(settings.LANGUAGE_CODE) - except AttributeError: - pass - from django.core.servers.fastcgi import runfastcgi - runfastcgi(args) -runfcgi.args = '[various KEY=val options, use `runfcgi help` for help]' - -def test(test_labels, verbosity=1, interactive=True): - "Runs the test suite for the specified applications" - from django.conf import settings - from django.db.models import get_app, get_apps - - test_path = settings.TEST_RUNNER.split('.') - # Allow for Python 2.5 relative paths - if len(test_path) > 1: - test_module_name = '.'.join(test_path[:-1]) - else: - test_module_name = '.' - test_module = __import__(test_module_name, {}, {}, test_path[-1]) - test_runner = getattr(test_module, test_path[-1]) - - failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive) - if failures: - sys.exit(failures) - -test.help_doc = 'Runs the test suite for the specified applications, or the entire site if no apps are specified' -test.args = '[--verbosity] [--noinput]' + APP_ARGS - -def load_data(fixture_labels, verbosity=1): - "Installs the provided fixture file(s) as data in the database." - from django.db.models import get_apps - from django.core import serializers - from django.db import connection, transaction, backend - from django.conf import settings - import sys - - disable_termcolors() - - # Keep a count of the installed objects and fixtures - count = [0,0] - models = set() - - humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' - - # Get a cursor (even though we don't need one yet). This has - # the side effect of initializing the test database (if - # it isn't already initialized). - cursor = connection.cursor() - - # Start transaction management. All fixtures are installed in a - # single transaction to ensure that all references are resolved. - transaction.commit_unless_managed() - transaction.enter_transaction_management() - transaction.managed(True) - - app_fixtures = [os.path.join(os.path.dirname(app.__file__),'fixtures') for app in get_apps()] - for fixture_label in fixture_labels: - parts = fixture_label.split('.') - if len(parts) == 1: - fixture_name = fixture_label - formats = serializers.get_serializer_formats() - else: - fixture_name, format = '.'.join(parts[:-1]), parts[-1] - if format in serializers.get_serializer_formats(): - formats = [format] - else: - formats = [] - - if verbosity > 0: - if formats: - print "Loading '%s' fixtures..." % fixture_name - else: - print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format) - - for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']: - if verbosity > 1: - print "Checking %s for fixtures..." % humanize(fixture_dir) - - label_found = False - for format in formats: - serializer = serializers.get_serializer(format) - if verbosity > 1: - print "Trying %s for %s fixture '%s'..." % \ - (humanize(fixture_dir), format, fixture_name) - try: - full_path = os.path.join(fixture_dir, '.'.join([fixture_name, format])) - fixture = open(full_path, 'r') - if label_found: - fixture.close() - print style.ERROR("Multiple fixtures named '%s' in %s. Aborting." % - (fixture_name, humanize(fixture_dir))) - transaction.rollback() - transaction.leave_transaction_management() - return - else: - count[1] += 1 - if verbosity > 0: - print "Installing %s fixture '%s' from %s." % \ - (format, fixture_name, humanize(fixture_dir)) - try: - objects = serializers.deserialize(format, fixture) - for obj in objects: - count[0] += 1 - models.add(obj.object.__class__) - obj.save() - label_found = True - except Exception, e: - fixture.close() - sys.stderr.write( - style.ERROR("Problem installing fixture '%s': %s\n" % - (full_path, str(e)))) - transaction.rollback() - transaction.leave_transaction_management() - return - fixture.close() - except: - if verbosity > 1: - print "No %s fixture '%s' in %s." % \ - (format, fixture_name, humanize(fixture_dir)) - - if count[0] > 0: - sequence_sql = backend.get_sql_sequence_reset(style, models) - if sequence_sql: - if verbosity > 1: - print "Resetting sequences" - for line in sequence_sql: - cursor.execute(line) - - transaction.commit() - transaction.leave_transaction_management() - - if count[0] == 0: - if verbosity > 0: - print "No fixtures found." - else: - if verbosity > 0: - print "Installed %d object(s) from %d fixture(s)" % tuple(count) - -load_data.help_doc = 'Installs the named fixture(s) in the database' -load_data.args = "[--verbosity] fixture, fixture, ..." - -def dump_data(app_labels, format='json', indent=None): - "Output the current contents of the database as a fixture of the given format" - from django.db.models import get_app, get_apps, get_models - from django.core import serializers - - if len(app_labels) == 0: - app_list = get_apps() - else: - app_list = [get_app(app_label) for app_label in app_labels] - - # Check that the serialization format exists; this is a shortcut to - # avoid collating all the objects and _then_ failing. - try: - serializers.get_serializer(format) - except KeyError: - sys.stderr.write(style.ERROR("Unknown serialization format: %s\n" % format)) - - objects = [] - for app in app_list: - for model in get_models(app): - objects.extend(model.objects.all()) - try: - return serializers.serialize(format, objects, indent=indent) - except Exception, e: - sys.stderr.write(style.ERROR("Unable to serialize database: %s\n" % e)) -dump_data.help_doc = 'Output the contents of the database as a fixture of the given format' -dump_data.args = '[--format] [--indent]' + APP_ARGS - -# Utilities for command-line script - -DEFAULT_ACTION_MAPPING = { - 'adminindex': get_admin_index, - 'createcachetable' : createcachetable, - 'dbshell': dbshell, - 'diffsettings': diffsettings, - 'dumpdata': dump_data, - 'flush': flush, - 'inspectdb': inspectdb, - 'loaddata': load_data, - 'reset': reset, - 'runfcgi': runfcgi, - 'runserver': runserver, - 'shell': run_shell, - 'sql': get_sql_create, - 'sqlall': get_sql_all, - 'sqlclear': get_sql_delete, - 'sqlcustom': get_custom_sql, - 'sqlflush': get_sql_flush, - 'sqlindexes': get_sql_indexes, - 'sqlinitialdata': get_sql_initial_data, - 'sqlreset': get_sql_reset, - 'sqlsequencereset': get_sql_sequence_reset, - 'startapp': startapp, - 'startproject': startproject, - 'syncdb': syncdb, - 'validate': validate, - 'test':test, -} - -NO_SQL_TRANSACTION = ( - 'adminindex', - 'createcachetable', - 'dbshell', - 'diffsettings', - 'reset', - 'sqlindexes', - 'syncdb', -) - -class DjangoOptionParser(OptionParser): - def print_usage_and_exit(self): - self.print_help(sys.stderr) - sys.exit(1) - -def get_usage(action_mapping): - """ - Returns a usage string. Doesn't do the options stuff, because optparse - takes care of that. - """ - usage = ["%prog action [options]\nactions:"] - available_actions = action_mapping.keys() - available_actions.sort() - for a in available_actions: - func = action_mapping[a] - usage.append(" %s %s" % (a, func.args)) - usage.extend(textwrap.wrap(getattr(func, 'help_doc', textwrap.dedent(func.__doc__.strip())), initial_indent=' ', subsequent_indent=' ')) - usage.append("") - return '\n'.join(usage[:-1]) # Cut off last list element, an empty space. - -def print_error(msg, cmd): - sys.stderr.write(style.ERROR('Error: %s' % msg) + '\nRun "%s --help" for help.\n' % cmd) - sys.exit(1) - -def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None): - # Use sys.argv if we've not passed in a custom argv - if argv is None: - argv = sys.argv - - # Parse the command-line arguments. optparse handles the dirty work. - parser = DjangoOptionParser(usage=get_usage(action_mapping), version=get_version()) - parser.add_option('--settings', - help='Python path to settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') - parser.add_option('--pythonpath', - help='Lets you manually add a directory the Python path, e.g. "/home/djangoprojects/myproject".') - parser.add_option('--plain', action='store_true', dest='plain', - help='Tells Django to use plain Python, not IPython, for "shell" command.') - parser.add_option('--noinput', action='store_false', dest='interactive', default=True, - help='Tells Django to NOT prompt the user for input of any kind.') - parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True, - help='Tells Django to NOT use the auto-reloader when running the development server.') - parser.add_option('--format', default='json', dest='format', - help='Specifies the output serialization format for fixtures') - parser.add_option('--indent', default=None, dest='indent', - type='int', help='Specifies the indent level to use when pretty-printing output') - parser.add_option('--verbosity', action='store', dest='verbosity', default='1', - type='choice', choices=['0', '1', '2'], - help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), - parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Specifies the directory from which to serve admin media for runserver.'), - - options, args = parser.parse_args(argv[1:]) - - # Take care of options. - if options.settings: - os.environ['DJANGO_SETTINGS_MODULE'] = options.settings - if options.pythonpath: - sys.path.insert(0, options.pythonpath) - - # Run the appropriate action. Unfortunately, optparse can't handle - # positional arguments, so this has to parse/validate them. - try: - action = args[0] - except IndexError: - parser.print_usage_and_exit() - if action not in action_mapping: - print_error("Your action, %r, was invalid." % action, argv[0]) - - # Switch to English, because django-admin.py creates database content - # like permissions, and those shouldn't contain any translations. - # But only do this if we should have a working settings file. - if action not in ('startproject', 'startapp'): - from django.utils import translation - translation.activate('en-us') - - if action == 'shell': - action_mapping[action](options.plain is True) - elif action in ('validate', 'diffsettings', 'dbshell'): - action_mapping[action]() - elif action in ('flush', 'syncdb'): - action_mapping[action](int(options.verbosity), options.interactive) - elif action == 'inspectdb': - try: - for line in action_mapping[action](): - print line - except NotImplementedError: - sys.stderr.write(style.ERROR("Error: %r isn't supported for the currently selected database backend.\n" % action)) - sys.exit(1) - elif action == 'createcachetable': - try: - action_mapping[action](args[1]) - except IndexError: - parser.print_usage_and_exit() - elif action == 'test': - try: - action_mapping[action](args[1:], int(options.verbosity), options.interactive) - except IndexError: - parser.print_usage_and_exit() - elif action == 'loaddata': - try: - action_mapping[action](args[1:], int(options.verbosity)) - except IndexError: - parser.print_usage_and_exit() - elif action == 'dumpdata': - try: - print action_mapping[action](args[1:], options.format, options.indent) - except IndexError: - parser.print_usage_and_exit() - elif action in ('startapp', 'startproject'): - try: - name = args[1] - except IndexError: - parser.print_usage_and_exit() - action_mapping[action](name, os.getcwd()) - elif action == 'runserver': - if len(args) < 2: - addr = '' - port = '8000' - else: - try: - addr, port = args[1].split(':') - except ValueError: - addr, port = '', args[1] - action_mapping[action](addr, port, options.use_reloader, options.admin_media_path) - elif action == 'runfcgi': - action_mapping[action](args[1:]) - elif action == 'sqlinitialdata': - print action_mapping[action](args[1:]) - elif action == 'sqlflush': - print '\n'.join(action_mapping[action]()) - else: - from django.db import models - validate(silent_success=True) - try: - mod_list = [models.get_app(app_label) for app_label in args[1:]] - except ImportError, e: - sys.stderr.write(style.ERROR("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e)) - sys.exit(1) - if not mod_list: - parser.print_usage_and_exit() - if action not in NO_SQL_TRANSACTION: - from django.db import backend - if backend.get_start_transaction_sql(): - print style.SQL_KEYWORD(backend.get_start_transaction_sql()) - for mod in mod_list: - if action == 'reset': - output = action_mapping[action](mod, options.interactive) - else: - output = action_mapping[action](mod) - if output: - print '\n'.join(output) - if action not in NO_SQL_TRANSACTION: - print style.SQL_KEYWORD("COMMIT;") - -def setup_environ(settings_mod): - """ - Configure 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 - # way. For example, if this file (manage.py) lives in a directory - # "myproject", this code would add "/path/to/myproject" to sys.path. - project_directory, settings_filename = os.path.split(settings_mod.__file__) - project_name = os.path.basename(project_directory) - settings_name = os.path.splitext(settings_filename)[0] - sys.path.append(os.path.join(project_directory, '..')) - project_module = __import__(project_name, {}, {}, ['']) - sys.path.pop() - - # Set DJANGO_SETTINGS_MODULE appropriately. - os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name) - return project_directory - -def execute_manager(settings_mod, argv=None): - project_directory = setup_environ(settings_mod) - action_mapping = DEFAULT_ACTION_MAPPING.copy() - - # Remove the "startproject" command from the action_mapping, because that's - # a django-admin.py command, not a manage.py command. - del action_mapping['startproject'] - - # Override the startapp handler so that it always uses the - # project_directory, not the current working directory (which is default). - action_mapping['startapp'] = lambda app_name, directory: startapp(app_name, project_directory) - action_mapping['startapp'].__doc__ = startapp.__doc__ - action_mapping['startapp'].help_doc = startapp.help_doc - action_mapping['startapp'].args = startapp.args - - # Run the django-admin.py command. - execute_from_command_line(action_mapping, argv) diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py new file mode 100644 index 0000000000..7a3f9ca7a5 --- /dev/null +++ b/django/core/management/__init__.py @@ -0,0 +1,180 @@ +import django +from optparse import OptionParser +import os +import sys +import textwrap + +# For backwards compatibility: get_version() used to be in this module. +get_version = django.get_version + +def load_command_class(name): + """ + Given a command name, returns the Command class instance. Raises + ImportError if it doesn't exist. + """ + # Let the ImportError propogate. + return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')() + +def call_command(name, *args, **options): + """ + Calls the given command, with the given options and args/kwargs. + + This is the primary API you should use for calling specific commands. + + Some examples: + call_command('syncdb') + call_command('shell', plain=True) + call_command('sqlall', 'myapp') + """ + klass = load_command_class(name) + return klass.execute(*args, **options) + +class ManagementUtility(object): + """ + Encapsulates the logic of the django-admin.py and manage.py utilities. + + A ManagementUtility has a number of commands, which can be manipulated + by editing the self.commands dictionary. + """ + def __init__(self): + self.commands = self.default_commands() + + def default_commands(self): + """ + Returns a dictionary of instances of all available Command classes. + + This works by looking for and loading all Python modules in the + django.core.management.commands package. + + The dictionary is in the format {name: command_instance}. + """ + command_dir = os.path.join(__path__[0], 'commands') + names = [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')] + return dict([(name, load_command_class(name)) for name in names]) + + def usage(self): + """ + Returns a usage string, for use with optparse. + + The string doesn't include the options (e.g., "--verbose"), because + optparse puts those in automatically. + """ + usage = ["%prog command [options]\nactions:"] + commands = self.commands.items() + commands.sort() + for name, cmd in commands: + usage.append(' %s %s' % (name, cmd.args)) + usage.extend(textwrap.wrap(cmd.help, initial_indent=' ', subsequent_indent=' ')) + usage.append('') + return '\n'.join(usage[:-1]) # Cut off the last list element, an empty space. + + def execute(self, argv=None): + """ + Parses the given argv from the command line, determines which command + to run and runs the command. + """ + if argv is None: + argv = sys.argv + + # Create the parser object and parse the command-line args. + # TODO: Ideally each Command class would register its own options for + # add_option(), but we'd need to figure out how to allow for multiple + # Commands using the same options. The optparse library gets in the way + # by checking for conflicts: + # http://docs.python.org/lib/optparse-conflicts-between-options.html + parser = OptionParser(usage=self.usage(), version=get_version()) + parser.add_option('--settings', + help='The Python path to a settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') + parser.add_option('--pythonpath', + help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".') + parser.add_option('--plain', action='store_true', dest='plain', + help='When using "shell": Tells Django to use plain Python, not IPython.') + parser.add_option('--noinput', action='store_false', dest='interactive', default=True, + help='Tells Django to NOT prompt the user for input of any kind.') + parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True, + help='When using "runserver": Tells Django to NOT use the auto-reloader.') + parser.add_option('--format', default='json', dest='format', + help='Specifies the output serialization format for fixtures') + parser.add_option('--indent', default=None, dest='indent', + type='int', help='Specifies the indent level to use when pretty-printing output') + parser.add_option('--verbosity', action='store', dest='verbosity', default='1', + type='choice', choices=['0', '1', '2'], + help='Verbosity level; 0=minimal output, 1=normal output, 2=all output') + parser.add_option('--adminmedia', dest='admin_media_path', default='', + help='When using "runserver": Specifies the directory from which to serve admin media.') + options, args = parser.parse_args(argv[1:]) + + # If the 'settings' or 'pythonpath' options were submitted, activate those. + if options.settings: + os.environ['DJANGO_SETTINGS_MODULE'] = options.settings + if options.pythonpath: + sys.path.insert(0, options.pythonpath) + + # Run the appropriate command. + try: + command_name = args[0] + except IndexError: + sys.stderr.write("Type '%s --help' for usage.\n" % os.path.basename(argv[0])) + sys.exit(1) + try: + command = self.commands[command_name] + except KeyError: + sys.stderr.write("Unknown command: %r\nType '%s --help' for usage.\n" % (command_name, os.path.basename(argv[0]))) + sys.exit(1) + command.execute(*args[1:], **options.__dict__) + +class ProjectManagementUtility(ManagementUtility): + """ + A ManagementUtility that is specific to a particular Django project. + As such, its commands are slightly different than those of its parent + class. + + In practice, this class represents manage.py, whereas ManagementUtility + represents django-admin.py. + """ + def __init__(self, project_directory): + super(ProjectManagementUtility, self).__init__() + + # Remove the "startproject" command from self.commands, because + # that's a django-admin.py command, not a manage.py command. + del self.commands['startproject'] + + # Override the startapp command so that it always uses the + # project_directory, not the current working directory (which is default). + from django.core.management.commands.startapp import ProjectCommand + self.commands['startapp'] = ProjectCommand(project_directory) + +def setup_environ(settings_mod): + """ + Configure 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 + # way. For example, if this file (manage.py) lives in a directory + # "myproject", this code would add "/path/to/myproject" to sys.path. + project_directory, settings_filename = os.path.split(settings_mod.__file__) + project_name = os.path.basename(project_directory) + settings_name = os.path.splitext(settings_filename)[0] + sys.path.append(os.path.join(project_directory, '..')) + project_module = __import__(project_name, {}, {}, ['']) + sys.path.pop() + + # Set DJANGO_SETTINGS_MODULE appropriately. + os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name) + return project_directory + +def execute_from_command_line(argv=None): + """ + A simple method that runs a ManagementUtility. + """ + utility = ManagementUtility() + utility.execute(argv) + +def execute_manager(settings_mod, argv=None): + """ + Like execute_from_command_line(), but for use by manage.py, a + project-specific django-admin.py utility. + """ + project_directory = setup_environ(settings_mod) + utility = ProjectManagementUtility(project_directory) + utility.execute(argv) diff --git a/django/core/management/base.py b/django/core/management/base.py new file mode 100644 index 0000000000..3b88234a94 --- /dev/null +++ b/django/core/management/base.py @@ -0,0 +1,159 @@ +from django.core.exceptions import ImproperlyConfigured +from django.core.management.color import color_style +import sys + +class CommandError(Exception): + pass + +class BaseCommand(object): + # Metadata about this command. + help = '' + args = '' + + # Configuration shortcuts that alter various logic. + can_import_settings = True + requires_model_validation = True + output_transaction = False # Whether to wrap the output in a "BEGIN; COMMIT;" + + def __init__(self): + self.style = color_style() + + def execute(self, *args, **options): + # Switch to English, because django-admin.py creates database content + # like permissions, and those shouldn't contain any translations. + # But only do this if we can assume we have a working settings file, + # because django.utils.translation requires settings. + if self.can_import_settings: + from django.utils import translation + translation.activate('en-us') + + try: + if self.requires_model_validation: + self.validate() + output = self.handle(*args, **options) + if output: + if self.output_transaction: + # This needs to be imported here, because it relies on settings. + from django.db import backend + if backend.get_start_transaction_sql(): + print self.style.SQL_KEYWORD(backend.get_start_transaction_sql()) + print output + if self.output_transaction: + print self.style.SQL_KEYWORD("COMMIT;") + except CommandError, e: + sys.stderr.write(self.style.ERROR(str('Error: %s\n' % e))) + sys.exit(1) + + def validate(self, app=None): + """ + Validates the given app, raising CommandError for any errors. + + If app is None, then this will validate all installed apps. + """ + from django.core.management.validation import get_validation_errors + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + s = StringIO() + num_errors = get_validation_errors(s, app) + if num_errors: + s.seek(0) + error_text = s.read() + raise CommandError("One or more models did not validate:\n%s" % error_text) + + def handle(self, *args, **options): + raise NotImplementedError() + +class AppCommand(BaseCommand): + args = '[appname ...]' + + def handle(self, *app_labels, **options): + from django.db import models + if not app_labels: + raise CommandError('Enter at least one appname.') + try: + app_list = [models.get_app(app_label) for app_label in app_labels] + except (ImproperlyConfigured, ImportError), e: + raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e) + output = [] + for app in app_list: + app_output = self.handle_app(app, **options) + if app_output: + output.append(app_output) + return '\n'.join(output) + + def handle_app(self, app, **options): + raise NotImplementedError() + +class LabelCommand(BaseCommand): + args = '[label ...]' + label = 'label' + + def handle(self, *labels, **options): + if not labels: + raise CommandError('Enter at least one %s.' % self.label) + + output = [] + for label in labels: + label_output = self.handle_label(label, **options) + if label_output: + output.append(label_output) + return '\n'.join(output) + + def handle_label(self, label, **options): + raise NotImplementedError() + +class NoArgsCommand(BaseCommand): + args = '' + + def handle(self, *args, **options): + from django.db import models + if len(args) != 0: + raise CommandError("Command doesn't accept any arguments") + + return self.handle_noargs(**options) + + def handle_noargs(self, **options): + raise NotImplementedError() + +def copy_helper(style, app_or_project, name, directory, other_name=''): + import django + import os + import re + import shutil + other = {'project': 'app', 'app': 'project'}[app_or_project] + if not re.search(r'^\w+$', name): # If it's not a valid directory name. + raise CommandError("%r is not a valid %s name. Please use only numbers, letters and underscores." % (name, app_or_project)) + top_dir = os.path.join(directory, name) + try: + os.mkdir(top_dir) + except OSError, e: + raise CommandError(e) + + # Determine where the app or project templates are. Use + # django.__path__[0] because we don't know into which directory + # django has been installed. + template_dir = os.path.join(django.__path__[0], 'conf', '%s_template' % app_or_project) + + for d, subdirs, files in os.walk(template_dir): + relative_dir = d[len(template_dir)+1:].replace('%s_name' % app_or_project, name) + if relative_dir: + os.mkdir(os.path.join(top_dir, relative_dir)) + for i, subdir in enumerate(subdirs): + if subdir.startswith('.'): + del subdirs[i] + for f in files: + if f.endswith('.pyc'): + continue + path_old = os.path.join(d, f) + path_new = os.path.join(top_dir, relative_dir, f.replace('%s_name' % app_or_project, name)) + fp_old = open(path_old, 'r') + fp_new = open(path_new, 'w') + fp_new.write(fp_old.read().replace('{{ %s_name }}' % app_or_project, name).replace('{{ %s_name }}' % other, other_name)) + fp_old.close() + fp_new.close() + try: + shutil.copymode(path_old, path_new) + except OSError: + sys.stderr.write(style.NOTICE("Notice: Couldn't set permission bits on %s. You're probably using an uncommon filesystem setup. No problem.\n" % path_new)) diff --git a/django/core/management/color.py b/django/core/management/color.py new file mode 100644 index 0000000000..06edb6066b --- /dev/null +++ b/django/core/management/color.py @@ -0,0 +1,28 @@ +""" +Sets up the terminal color scheme. +""" + +from django.utils import termcolors +import sys + +def color_style(): + "Returns a Style object with the Django color scheme." + if sys.platform == 'win32' or sys.platform == 'Pocket PC' or not sys.stdout.isatty(): + return no_style() + class dummy: pass + style = dummy() + style.ERROR = termcolors.make_style(fg='red', opts=('bold',)) + style.ERROR_OUTPUT = termcolors.make_style(fg='red', opts=('bold',)) + style.NOTICE = termcolors.make_style(fg='red') + style.SQL_FIELD = termcolors.make_style(fg='green', opts=('bold',)) + style.SQL_COLTYPE = termcolors.make_style(fg='green') + style.SQL_KEYWORD = termcolors.make_style(fg='yellow') + style.SQL_TABLE = termcolors.make_style(opts=('bold',)) + return style + +def no_style(): + "Returns a Style object that has no colors." + class dummy: + def __getattr__(self, attr): + return lambda x: x + return dummy() diff --git a/django/core/management/commands/__init__.py b/django/core/management/commands/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/django/core/management/commands/__init__.py diff --git a/django/core/management/commands/adminindex.py b/django/core/management/commands/adminindex.py new file mode 100644 index 0000000000..e3dd493fd3 --- /dev/null +++ b/django/core/management/commands/adminindex.py @@ -0,0 +1,33 @@ +from django.core.management.base import AppCommand +from django.utils.text import capfirst + +MODULE_TEMPLATE = ''' {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%} + <tr> + <th>{%% if perms.%(app)s.%(changeperm)s %%}<a href="%(app)s/%(mod)s/">{%% endif %%}%(name)s{%% if perms.%(app)s.%(changeperm)s %%}</a>{%% endif %%}</th> + <td class="x50">{%% if perms.%(app)s.%(addperm)s %%}<a href="%(app)s/%(mod)s/add/" class="addlink">{%% endif %%}Add{%% if perms.%(app)s.%(addperm)s %%}</a>{%% endif %%}</td> + <td class="x75">{%% if perms.%(app)s.%(changeperm)s %%}<a href="%(app)s/%(mod)s/" class="changelink">{%% endif %%}Change{%% if perms.%(app)s.%(changeperm)s %%}</a>{%% endif %%}</td> + </tr> + {%% endif %%}''' + +class Command(AppCommand): + help = 'Prints the admin-index template snippet for the given app name(s).' + + def handle_app(self, app, **options): + from django.db.models import get_models + output = [] + app_models = get_models(app) + app_label = app_models[0]._meta.app_label + output.append('{%% if perms.%s %%}' % app_label) + output.append('<div class="module"><h2>%s</h2><table>' % app_label.title()) + for model in app_models: + if model._meta.admin: + output.append(MODULE_TEMPLATE % { + 'app': app_label, + 'mod': model._meta.module_name, + 'name': capfirst(model._meta.verbose_name_plural), + 'addperm': model._meta.get_add_permission(), + 'changeperm': model._meta.get_change_permission(), + }) + output.append('</table></div>') + output.append('{% endif %}') + return '\n'.join(output) diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py new file mode 100644 index 0000000000..dc8b1b7854 --- /dev/null +++ b/django/core/management/commands/createcachetable.py @@ -0,0 +1,41 @@ +from django.core.management.base import LabelCommand + +class Command(LabelCommand): + help = "Creates the table needed to use the SQL cache backend." + args = "[tablename]" + label = 'tablename' + + requires_model_validation = False + + def handle_label(self, tablename, **options): + from django.db import backend, connection, transaction, models + fields = ( + # "key" is a reserved word in MySQL, so use "cache_key" instead. + models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), + models.TextField(name='value'), + models.DateTimeField(name='expires', db_index=True), + ) + table_output = [] + index_output = [] + for f in fields: + field_output = [backend.quote_name(f.name), f.db_type()] + field_output.append("%sNULL" % (not f.null and "NOT " or "")) + if f.unique: + field_output.append("UNIQUE") + if f.primary_key: + field_output.append("PRIMARY KEY") + if f.db_index: + unique = f.unique and "UNIQUE " or "" + index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ + (unique, tablename, f.name, backend.quote_name(tablename), + backend.quote_name(f.name))) + table_output.append(" ".join(field_output)) + full_statement = ["CREATE TABLE %s (" % backend.quote_name(tablename)] + for i, line in enumerate(table_output): + full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) + full_statement.append(');') + curs = connection.cursor() + curs.execute("\n".join(full_statement)) + for statement in index_output: + curs.execute(statement) + transaction.commit_unless_managed() diff --git a/django/core/management/commands/dbshell.py b/django/core/management/commands/dbshell.py new file mode 100644 index 0000000000..ec2a961530 --- /dev/null +++ b/django/core/management/commands/dbshell.py @@ -0,0 +1,10 @@ +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + help = "Runs the command-line client for the current DATABASE_ENGINE." + + requires_model_validation = False + + def handle_noargs(self, **options): + from django.db import runshell + runshell() diff --git a/django/core/management/commands/diffsettings.py b/django/core/management/commands/diffsettings.py new file mode 100644 index 0000000000..2459f11700 --- /dev/null +++ b/django/core/management/commands/diffsettings.py @@ -0,0 +1,32 @@ +from django.core.management.base import NoArgsCommand + +def module_to_dict(module, omittable=lambda k: k.startswith('_')): + "Converts a module namespace to a Python dictionary. Used by get_settings_diff." + return dict([(k, repr(v)) for k, v in module.__dict__.items() if not omittable(k)]) + +class Command(NoArgsCommand): + help = """Displays differences between the current settings.py and Django's + default settings. Settings that don't appear in the defaults are + followed by "###".""" + + requires_model_validation = False + + def handle_noargs(self, **options): + # Inspired by Postfix's "postconf -n". + from django.conf import settings, global_settings + + # Because settings are imported lazily, we need to explicitly load them. + settings._import_settings() + + user_settings = module_to_dict(settings._target) + default_settings = module_to_dict(global_settings) + + output = [] + keys = user_settings.keys() + keys.sort() + for key in keys: + if key not in default_settings: + output.append("%s = %s ###" % (key, user_settings[key])) + elif user_settings[key] != default_settings[key]: + output.append("%s = %s" % (key, user_settings[key])) + print '\n'.join(output) diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py new file mode 100644 index 0000000000..48677ca5fa --- /dev/null +++ b/django/core/management/commands/dumpdata.py @@ -0,0 +1,33 @@ +from django.core.management.base import BaseCommand, CommandError + +class Command(BaseCommand): + help = 'Output the contents of the database as a fixture of the given format.' + args = '[--format] [--indent] [appname ...]' + + def handle(self, *app_labels, **options): + from django.db.models import get_app, get_apps, get_models + from django.core import serializers + + format = options.get('format', 'json') + indent = options.get('indent', None) + + if len(app_labels) == 0: + app_list = get_apps() + else: + app_list = [get_app(app_label) for app_label in app_labels] + + # Check that the serialization format exists; this is a shortcut to + # avoid collating all the objects and _then_ failing. + try: + serializers.get_serializer(format) + except KeyError: + raise CommandError("Unknown serialization format: %s" % format) + + objects = [] + for app in app_list: + for model in get_models(app): + objects.extend(model.objects.all()) + try: + return serializers.serialize(format, objects, indent=indent) + except Exception, e: + raise CommandError("Unable to serialize database: %s" % e) diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py new file mode 100644 index 0000000000..bd1dc204d2 --- /dev/null +++ b/django/core/management/commands/flush.py @@ -0,0 +1,64 @@ +from django.core.management.base import NoArgsCommand, CommandError +from django.core.management.color import no_style + +class Command(NoArgsCommand): + help = "Executes ``sqlflush`` on the current database." + args = '[--verbosity] [--noinput]' + + def handle_noargs(self, **options): + from django.conf import settings + from django.db import connection, transaction, models + from django.dispatch import dispatcher + from django.core.management.sql import sql_flush, emit_post_sync_signal + + verbosity = int(options.get('verbosity', 1)) + interactive = options.get('interactive') + + self.style = no_style() + + # Import the 'management' module within each installed app, to register + # dispatcher events. + for app_name in settings.INSTALLED_APPS: + try: + __import__(app_name + '.management', {}, {}, ['']) + except ImportError: + pass + + sql_list = sql_flush(self.style) + + if interactive: + confirm = raw_input("""You have requested a flush of the database. +This will IRREVERSIBLY DESTROY all data currently in the %r database, +and return each table to the state it was in after syncdb. +Are you sure you want to do this? + + Type 'yes' to continue, or 'no' to cancel: """ % settings.DATABASE_NAME) + else: + confirm = 'yes' + + if confirm == 'yes': + try: + cursor = connection.cursor() + for sql in sql_list: + cursor.execute(sql) + except Exception, e: + transaction.rollback_unless_managed() + raise CommandError("""Database %s couldn't be flushed. Possible reasons: + * The database isn't running or isn't configured correctly. + * At least one of the expected database tables doesn't exist. + * The SQL was invalid. + Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. + The full error: %s""" % (settings.DATABASE_NAME, e)) + transaction.commit_unless_managed() + + # Emit the post sync signal. This allows individual + # applications to respond as if the database had been + # sync'd from scratch. + emit_post_sync_signal(models.get_models(), verbosity, interactive) + + # Reinstall the initial_data fixture. + from django.core.management import call_command + call_command('loaddata', 'initial_data', **options) + + else: + print "Flush cancelled." diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py new file mode 100644 index 0000000000..11bc390289 --- /dev/null +++ b/django/core/management/commands/inspectdb.py @@ -0,0 +1,120 @@ +from django.core.management.base import NoArgsCommand, CommandError + +class Command(NoArgsCommand): + help = "Introspects the database tables in the given database and outputs a Django model module." + + requires_model_validation = False + + def handle_noargs(self, **options): + try: + for line in self.handle_inspection(): + print line + except NotImplementedError: + raise CommandError("Database inspection isn't supported for the currently selected database backend.") + + def handle_inspection(self): + from django.db import connection, get_introspection_module + import keyword + + introspection_module = get_introspection_module() + + table2model = lambda table_name: table_name.title().replace('_', '') + + cursor = connection.cursor() + yield "# This is an auto-generated Django model module." + yield "# You'll have to do the following manually to clean this up:" + yield "# * Rearrange models' order" + yield "# * Make sure each model has one field with primary_key=True" + yield "# Feel free to rename the models, but don't rename db_table values or field names." + yield "#" + yield "# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'" + yield "# into your database." + yield '' + yield 'from django.db import models' + yield '' + for table_name in introspection_module.get_table_list(cursor): + yield 'class %s(models.Model):' % table2model(table_name) + try: + relations = introspection_module.get_relations(cursor, table_name) + except NotImplementedError: + relations = {} + try: + indexes = introspection_module.get_indexes(cursor, table_name) + except NotImplementedError: + indexes = {} + for i, row in enumerate(introspection_module.get_table_description(cursor, table_name)): + att_name = row[0].lower() + comment_notes = [] # Holds Field notes, to be displayed in a Python comment. + extra_params = {} # Holds Field parameters such as 'db_column'. + + if ' ' in att_name: + extra_params['db_column'] = att_name + att_name = att_name.replace(' ', '') + comment_notes.append('Field renamed to remove spaces.') + if keyword.iskeyword(att_name): + extra_params['db_column'] = att_name + att_name += '_field' + comment_notes.append('Field renamed because it was a Python reserved word.') + + if i in relations: + rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1]) + field_type = 'ForeignKey(%s' % rel_to + if att_name.endswith('_id'): + att_name = att_name[:-3] + else: + extra_params['db_column'] = att_name + else: + try: + field_type = introspection_module.DATA_TYPES_REVERSE[row[1]] + except KeyError: + field_type = 'TextField' + comment_notes.append('This field type is a guess.') + + # This is a hook for DATA_TYPES_REVERSE to return a tuple of + # (field_type, extra_params_dict). + if type(field_type) is tuple: + field_type, new_params = field_type + extra_params.update(new_params) + + # Add max_length for all CharFields. + if field_type == 'CharField' and row[3]: + extra_params['max_length'] = row[3] + + if field_type == 'DecimalField': + extra_params['max_digits'] = row[4] + extra_params['decimal_places'] = row[5] + + # Add primary_key and unique, if necessary. + column_name = extra_params.get('db_column', att_name) + if column_name in indexes: + if indexes[column_name]['primary_key']: + extra_params['primary_key'] = True + elif indexes[column_name]['unique']: + extra_params['unique'] = True + + field_type += '(' + + # Don't output 'id = meta.AutoField(primary_key=True)', because + # that's assumed if it doesn't exist. + if att_name == 'id' and field_type == 'AutoField(' and extra_params == {'primary_key': True}: + continue + + # Add 'null' and 'blank', if the 'null_ok' flag was present in the + # table description. + if row[6]: # If it's NULL... + extra_params['blank'] = True + if not field_type in ('TextField(', 'CharField('): + extra_params['null'] = True + + field_desc = '%s = models.%s' % (att_name, field_type) + if extra_params: + if not field_desc.endswith('('): + field_desc += ', ' + field_desc += ', '.join(['%s=%r' % (k, v) for k, v in extra_params.items()]) + field_desc += ')' + if comment_notes: + field_desc += ' # ' + ' '.join(comment_notes) + yield ' %s' % field_desc + yield ' class Meta:' + yield ' db_table = %r' % table_name + yield '' diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py new file mode 100644 index 0000000000..82b8968c61 --- /dev/null +++ b/django/core/management/commands/loaddata.py @@ -0,0 +1,123 @@ +from django.core.management.base import BaseCommand +from django.core.management.color import no_style +import sys +import os + +try: + set +except NameError: + from sets import Set as set # Python 2.3 fallback + +class Command(BaseCommand): + help = 'Installs the named fixture(s) in the database.' + args = "[--verbosity] fixture, fixture, ..." + + def handle(self, *fixture_labels, **options): + from django.db.models import get_apps + from django.core import serializers + from django.db import connection, transaction, backend + from django.conf import settings + + self.style = no_style() + + verbosity = int(options.get('verbosity', 1)) + + # Keep a count of the installed objects and fixtures + count = [0, 0] + models = set() + + humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' + + # Get a cursor (even though we don't need one yet). This has + # the side effect of initializing the test database (if + # it isn't already initialized). + cursor = connection.cursor() + + # Start transaction management. All fixtures are installed in a + # single transaction to ensure that all references are resolved. + transaction.commit_unless_managed() + transaction.enter_transaction_management() + transaction.managed(True) + + app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()] + for fixture_label in fixture_labels: + parts = fixture_label.split('.') + if len(parts) == 1: + fixture_name = fixture_label + formats = serializers.get_serializer_formats() + else: + fixture_name, format = '.'.join(parts[:-1]), parts[-1] + if format in serializers.get_serializer_formats(): + formats = [format] + else: + formats = [] + + if verbosity > 0: + if formats: + print "Loading '%s' fixtures..." % fixture_name + else: + print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format) + + for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']: + if verbosity > 1: + print "Checking %s for fixtures..." % humanize(fixture_dir) + + label_found = False + for format in formats: + serializer = serializers.get_serializer(format) + if verbosity > 1: + print "Trying %s for %s fixture '%s'..." % \ + (humanize(fixture_dir), format, fixture_name) + try: + full_path = os.path.join(fixture_dir, '.'.join([fixture_name, format])) + fixture = open(full_path, 'r') + if label_found: + fixture.close() + print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." % + (fixture_name, humanize(fixture_dir))) + transaction.rollback() + transaction.leave_transaction_management() + return + else: + count[1] += 1 + if verbosity > 0: + print "Installing %s fixture '%s' from %s." % \ + (format, fixture_name, humanize(fixture_dir)) + try: + objects = serializers.deserialize(format, fixture) + for obj in objects: + count[0] += 1 + models.add(obj.object.__class__) + obj.save() + label_found = True + except Exception, e: + fixture.close() + sys.stderr.write( + self.style.ERROR("Problem installing fixture '%s': %s\n" % + (full_path, str(e)))) + transaction.rollback() + transaction.leave_transaction_management() + return + fixture.close() + except: + if verbosity > 1: + print "No %s fixture '%s' in %s." % \ + (format, fixture_name, humanize(fixture_dir)) + + if count[0] > 0: + sequence_sql = backend.get_sql_sequence_reset(self.style, models) + if sequence_sql: + if verbosity > 1: + print "Resetting sequences" + for line in sequence_sql: + cursor.execute(line) + + transaction.commit() + transaction.leave_transaction_management() + + if count[0] == 0: + if verbosity > 0: + print "No fixtures found." + else: + if verbosity > 0: + print "Installed %d object(s) from %d fixture(s)" % tuple(count) diff --git a/django/core/management/commands/reset.py b/django/core/management/commands/reset.py new file mode 100644 index 0000000000..5c89d94678 --- /dev/null +++ b/django/core/management/commands/reset.py @@ -0,0 +1,47 @@ +from django.core.management.base import AppCommand, CommandError +from django.core.management.color import no_style + +class Command(AppCommand): + help = "Executes ``sqlreset`` for the given app(s) in the current database." + args = '[--noinput] [appname ...]' + + output_transaction = True + + def handle_app(self, app, **options): + from django.db import connection, transaction + from django.conf import settings + from django.core.management.sql import sql_reset + + app_name = app.__name__.split('.')[-2] + + self.style = no_style() + + sql_list = sql_reset(app, self.style) + + if options.get('interactive'): + confirm = raw_input(""" +You have requested a database reset. +This will IRREVERSIBLY DESTROY any data for +the "%s" application in the database "%s". +Are you sure you want to do this? + +Type 'yes' to continue, or 'no' to cancel: """ % (app_name, settings.DATABASE_NAME)) + else: + confirm = 'yes' + + if confirm == 'yes': + try: + cursor = connection.cursor() + for sql in sql_list: + cursor.execute(sql) + except Exception, e: + transaction.rollback_unless_managed() + raise CommandError("""Error: %s couldn't be reset. Possible reasons: + * The database isn't running or isn't configured correctly. + * At least one of the database tables doesn't exist. + * The SQL was invalid. +Hint: Look at the output of 'django-admin.py sqlreset %s'. That's the SQL this command wasn't able to run. +The full error: %s""" % (app_name, app_name, e)) + transaction.commit_unless_managed() + else: + print "Reset cancelled." diff --git a/django/core/management/commands/runfcgi.py b/django/core/management/commands/runfcgi.py new file mode 100644 index 0000000000..406a27b8c3 --- /dev/null +++ b/django/core/management/commands/runfcgi.py @@ -0,0 +1,16 @@ +from django.core.management.base import BaseCommand + +class Command(BaseCommand): + help = "Runs this project as a FastCGI application. Requires flup." + args = '[various KEY=val options, use `runfcgi help` for help]' + + def handle(self, *args, **options): + from django.conf import settings + from django.utils import translation + # Activate the current language, because it won't get activated later. + try: + translation.activate(settings.LANGUAGE_CODE) + except AttributeError: + pass + from django.core.servers.fastcgi import runfastcgi + runfastcgi(args) diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py new file mode 100644 index 0000000000..f089e80b16 --- /dev/null +++ b/django/core/management/commands/runserver.py @@ -0,0 +1,70 @@ +from django.core.management.base import BaseCommand, CommandError +import os +import sys + +class Command(BaseCommand): + help = "Starts a lightweight Web server for development." + args = '[--noreload] [--adminmedia=ADMIN_MEDIA_PATH] [optional port number, or ipaddr:port]' + + # Validation is called explicitly each time the server is reloaded. + requires_model_validation = False + + def handle(self, addrport='', *args, **options): + import django + from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException + from django.core.handlers.wsgi import WSGIHandler + if len(args) != 0: + raise CommandError('Usage is runserver %s' % self.args) + if not addrport: + addr = '' + port = '8000' + else: + try: + addr, port = addrport.split(':') + except ValueError: + addr, port = '', addrport + if not addr: + addr = '127.0.0.1' + + if not port.isdigit(): + raise CommandError("%r is not a valid port number." % port) + + use_reloader = options.get('use_reloader', True) + admin_media_dir = options.get('admin_media_dir', '') + shutdown_message = options.get('shutdown_message', '') + quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C' + + def inner_run(): + from django.conf import settings + print "Validating models..." + self.validate() + print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE) + print "Development server is running at http://%s:%s/" % (addr, port) + print "Quit the server with %s." % quit_command + try: + path = admin_media_dir or django.__path__[0] + '/contrib/admin/media' + handler = AdminMediaHandler(WSGIHandler(), path) + run(addr, int(port), handler) + except WSGIServerException, e: + # Use helpful error messages instead of ugly tracebacks. + ERRORS = { + 13: "You don't have permission to access that port.", + 98: "That port is already in use.", + 99: "That IP address can't be assigned-to.", + } + try: + error_text = ERRORS[e.args[0].args[0]] + except (AttributeError, KeyError): + error_text = str(e) + sys.stderr.write(self.style.ERROR("Error: %s" % error_text) + '\n') + # Need to use an OS exit because sys.exit doesn't work in a thread + os._exit(1) + except KeyboardInterrupt: + if shutdown_message: + print shutdown_message + sys.exit(0) + if use_reloader: + from django.utils import autoreload + autoreload.main(inner_run) + else: + inner_run() diff --git a/django/core/management/commands/shell.py b/django/core/management/commands/shell.py new file mode 100644 index 0000000000..bc76c44b97 --- /dev/null +++ b/django/core/management/commands/shell.py @@ -0,0 +1,42 @@ +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + help = "Runs a Python interactive interpreter. Tries to use IPython, if it's available." + args = '[--plain]' + + requires_model_validation = False + + def handle_noargs(self, **options): + # XXX: (Temporary) workaround for ticket #1796: force early loading of all + # models from installed apps. + from django.db.models.loading import get_models + loaded_models = get_models() + + use_plain = options.get('plain', False) + + try: + if use_plain: + # Don't bother loading IPython, because the user wants plain Python. + raise ImportError + import IPython + # Explicitly pass an empty list as arguments, because otherwise IPython + # would use sys.argv from this script. + shell = IPython.Shell.IPShell(argv=[]) + shell.mainloop() + except ImportError: + import code + # Set up a dictionary to serve as the environment for the shell, so + # that tab completion works on objects that are imported at runtime. + # See ticket 5082. + imported_objects = {} + try: # Try activating rlcompleter, because it's handy. + import readline + except ImportError: + pass + else: + # We don't have to wrap the following import in a 'try', because + # we already know 'readline' was imported successfully. + import rlcompleter + readline.set_completer(rlcompleter.Completer(imported_objects).complete) + readline.parse_and_bind("tab:complete") + code.interact(local=imported_objects) diff --git a/django/core/management/commands/sql.py b/django/core/management/commands/sql.py new file mode 100644 index 0000000000..4a0107ac02 --- /dev/null +++ b/django/core/management/commands/sql.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the CREATE TABLE SQL statements for the given app name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_create + return '\n'.join(sql_create(app, self.style)) diff --git a/django/core/management/commands/sqlall.py b/django/core/management/commands/sqlall.py new file mode 100644 index 0000000000..d63dfb4b10 --- /dev/null +++ b/django/core/management/commands/sqlall.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_all + return '\n'.join(sql_all(app, self.style)) diff --git a/django/core/management/commands/sqlclear.py b/django/core/management/commands/sqlclear.py new file mode 100644 index 0000000000..d76d6f4de2 --- /dev/null +++ b/django/core/management/commands/sqlclear.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the DROP TABLE SQL statements for the given app name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_delete + return '\n'.join(sql_delete(app, self.style)) diff --git a/django/core/management/commands/sqlcustom.py b/django/core/management/commands/sqlcustom.py new file mode 100644 index 0000000000..2148a9f307 --- /dev/null +++ b/django/core/management/commands/sqlcustom.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the custom table modifying SQL statements for the given app name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_custom + return '\n'.join(sql_custom(app)) diff --git a/django/core/management/commands/sqlflush.py b/django/core/management/commands/sqlflush.py new file mode 100644 index 0000000000..7d14fe61e1 --- /dev/null +++ b/django/core/management/commands/sqlflush.py @@ -0,0 +1,10 @@ +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + help = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed." + + output_transaction = True + + def handle_noargs(self, **options): + from django.core.management.sql import sql_flush + return '\n'.join(sql_flush(self.style)) diff --git a/django/core/management/commands/sqlindexes.py b/django/core/management/commands/sqlindexes.py new file mode 100644 index 0000000000..b5e86f26d6 --- /dev/null +++ b/django/core/management/commands/sqlindexes.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the CREATE INDEX SQL statements for the given model module name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_indexes + return '\n'.join(sql_indexes(app, self.style)) diff --git a/django/core/management/commands/sqlinitialdata.py b/django/core/management/commands/sqlinitialdata.py new file mode 100644 index 0000000000..b9e2249c29 --- /dev/null +++ b/django/core/management/commands/sqlinitialdata.py @@ -0,0 +1,7 @@ +from django.core.management.base import AppCommand, CommandError + +class Command(AppCommand): + help = "RENAMED: see 'sqlcustom'" + + def handle(self, *apps, **options): + raise CommandError("This command has been renamed. Use the 'sqlcustom' command instead.") diff --git a/django/core/management/commands/sqlreset.py b/django/core/management/commands/sqlreset.py new file mode 100644 index 0000000000..a2abb855cf --- /dev/null +++ b/django/core/management/commands/sqlreset.py @@ -0,0 +1,10 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = "Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s)." + + output_transaction = True + + def handle_app(self, app, **options): + from django.core.management.sql import sql_reset + return '\n'.join(sql_reset(app, self.style)) diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py new file mode 100644 index 0000000000..8ed2fbaf97 --- /dev/null +++ b/django/core/management/commands/sqlsequencereset.py @@ -0,0 +1,9 @@ +from django.core.management.base import AppCommand + +class Command(AppCommand): + help = 'Prints the SQL statements for resetting sequences for the given app name(s).' + output_transaction = True + + def handle_app(self, app, **options): + from django.db import backend, models + return '\n'.join(backend.get_sql_sequence_reset(self.style, models.get_models(app))) diff --git a/django/core/management/commands/startapp.py b/django/core/management/commands/startapp.py new file mode 100644 index 0000000000..1da2776cf5 --- /dev/null +++ b/django/core/management/commands/startapp.py @@ -0,0 +1,34 @@ +from django.core.management.base import copy_helper, CommandError, LabelCommand +import os + +class Command(LabelCommand): + help = "Creates a Django app directory structure for the given app name in the current directory." + args = "[appname]" + label = 'application name' + + requires_model_validation = False + # Can't import settings during this command, because they haven't + # necessarily been created. + can_import_settings = False + + def handle_label(self, app_name, directory=None, **options): + if directory is None: + directory = os.getcwd() + # Determine the project_name a bit naively -- by looking at the name of + # the parent directory. + project_dir = os.path.normpath(os.path.join(directory, '..')) + parent_dir = os.path.basename(project_dir) + project_name = os.path.basename(directory) + if app_name == project_name: + raise CommandError("You cannot create an app with the same name (%r) as your project." % app_name) + copy_helper(self.style, 'app', app_name, directory, parent_dir) + +class ProjectCommand(Command): + help = "Creates a Django app directory structure for the given app name in this project's directory." + + def __init__(self, project_directory): + super(ProjectCommand, self).__init__() + self.project_directory = project_directory + + def handle_label(self, app_name, **options): + super(ProjectCommand, self).handle_label(app_name, self.project_directory, **options) diff --git a/django/core/management/commands/startproject.py b/django/core/management/commands/startproject.py new file mode 100644 index 0000000000..0d9e4bd381 --- /dev/null +++ b/django/core/management/commands/startproject.py @@ -0,0 +1,40 @@ +from django.core.management.base import copy_helper, CommandError, LabelCommand +import os +import re +from random import choice + +INVALID_PROJECT_NAMES = ('django', 'site', 'test') + +class Command(LabelCommand): + help = "Creates a Django project directory structure for the given project name in the current directory." + args = "[projectname]" + label = 'project name' + + requires_model_validation = False + # Can't import settings during this command, because they haven't + # necessarily been created. + can_import_settings = False + + def handle_label(self, project_name, **options): + # Determine the project_name a bit naively -- by looking at the name of + # the parent directory. + directory = os.getcwd() + + if project_name in INVALID_PROJECT_NAMES: + raise CommandError("%r conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name." % project_name) + + copy_helper(self.style, 'project', project_name, directory) + + # Create a random SECRET_KEY hash, and put it in the main settings. + main_settings_file = os.path.join(directory, project_name, 'settings.py') + settings_contents = open(main_settings_file, 'r').read() + + # If settings.py was copied from a read-only source, make it writeable. + if not os.access(main_settings_file, os.W_OK): + os.chmod(main_settings_file, 0600) + + fp = open(main_settings_file, 'w') + secret_key = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)]) + settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents) + fp.write(settings_contents) + fp.close() diff --git a/django/core/management/commands/syncdb.py b/django/core/management/commands/syncdb.py new file mode 100644 index 0000000000..d4f430c069 --- /dev/null +++ b/django/core/management/commands/syncdb.py @@ -0,0 +1,130 @@ +from django.core.management.base import NoArgsCommand +from django.core.management.color import no_style +import sys + +try: + set +except NameError: + from sets import Set as set # Python 2.3 fallback + +class Command(NoArgsCommand): + help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." + args = '[--verbosity] [--noinput]' + + def handle_noargs(self, **options): + from django.db import backend, connection, transaction, models + from django.conf import settings + from django.core.management.sql import table_list, installed_models, sql_model_create, sql_for_pending_references, many_to_many_sql_for_model, custom_sql_for_model, sql_indexes_for_model, emit_post_sync_signal + + verbosity = int(options.get('verbosity', 1)) + interactive = options.get('interactive') + + self.style = no_style() + + # Import the 'management' module within each installed app, to register + # dispatcher events. + for app_name in settings.INSTALLED_APPS: + try: + __import__(app_name + '.management', {}, {}, ['']) + except ImportError: + pass + + cursor = connection.cursor() + + # Get a list of all existing database tables, + # so we know what needs to be added. + table_list = table_list() + if backend.uses_case_insensitive_names: + table_name_converter = str.upper + else: + table_name_converter = lambda x: x + + # Get a list of already installed *models* so that references work right. + seen_models = installed_models(table_list) + created_models = set() + pending_references = {} + + # Create the tables for each model + for app in models.get_apps(): + app_name = app.__name__.split('.')[-2] + model_list = models.get_models(app) + for model in model_list: + # Create the model's database table, if it doesn't already exist. + if verbosity >= 2: + print "Processing %s.%s model" % (app_name, model._meta.object_name) + if table_name_converter(model._meta.db_table) in table_list: + continue + sql, references = sql_model_create(model, self.style, seen_models) + seen_models.add(model) + created_models.add(model) + for refto, refs in references.items(): + pending_references.setdefault(refto, []).extend(refs) + sql.extend(sql_for_pending_references(model, self.style, pending_references)) + if verbosity >= 1: + print "Creating table %s" % model._meta.db_table + for statement in sql: + cursor.execute(statement) + table_list.append(table_name_converter(model._meta.db_table)) + + # Create the m2m tables. This must be done after all tables have been created + # to ensure that all referred tables will exist. + for app in models.get_apps(): + app_name = app.__name__.split('.')[-2] + model_list = models.get_models(app) + for model in model_list: + if model in created_models: + sql = many_to_many_sql_for_model(model, self.style) + if sql: + if verbosity >= 2: + print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name) + for statement in sql: + cursor.execute(statement) + + transaction.commit_unless_managed() + + # Send the post_syncdb signal, so individual apps can do whatever they need + # to do at this point. + emit_post_sync_signal(created_models, verbosity, interactive) + + # Install custom SQL for the app (but only if this + # is a model we've just created) + for app in models.get_apps(): + app_name = app.__name__.split('.')[-2] + for model in models.get_models(app): + if model in created_models: + custom_sql = custom_sql_for_model(model) + if custom_sql: + if verbosity >= 1: + print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name) + try: + for sql in custom_sql: + cursor.execute(sql) + except Exception, e: + sys.stderr.write("Failed to install custom SQL for %s.%s model: %s" % \ + (app_name, model._meta.object_name, e)) + transaction.rollback_unless_managed() + else: + transaction.commit_unless_managed() + + # Install SQL indicies for all newly created models + for app in models.get_apps(): + app_name = app.__name__.split('.')[-2] + for model in models.get_models(app): + if model in created_models: + index_sql = sql_indexes_for_model(model, self.style) + if index_sql: + if verbosity >= 1: + print "Installing index for %s.%s model" % (app_name, model._meta.object_name) + try: + for sql in index_sql: + cursor.execute(sql) + except Exception, e: + sys.stderr.write("Failed to install index for %s.%s model: %s" % \ + (app_name, model._meta.object_name, e)) + transaction.rollback_unless_managed() + else: + transaction.commit_unless_managed() + + # Install the 'initialdata' fixture, using format discovery + from django.core.management import call_command + call_command('loaddata', 'initial_data', **options) diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py new file mode 100644 index 0000000000..8e27fd5606 --- /dev/null +++ b/django/core/management/commands/test.py @@ -0,0 +1,28 @@ +from django.core.management.base import BaseCommand +import sys + +class Command(BaseCommand): + help = 'Runs the test suite for the specified applications, or the entire site if no apps are specified.' + args = '[--verbosity] [--noinput] [appname ...]' + + requires_model_validation = False + + def handle(self, *test_labels, **options): + from django.conf import settings + from django.db.models import get_app, get_apps + + verbosity = int(options.get('verbosity', 1)) + interactive = options.get('interactive', True) + + test_path = settings.TEST_RUNNER.split('.') + # Allow for Python 2.5 relative paths + if len(test_path) > 1: + test_module_name = '.'.join(test_path[:-1]) + else: + test_module_name = '.' + test_module = __import__(test_module_name, {}, {}, test_path[-1]) + test_runner = getattr(test_module, test_path[-1]) + + failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive) + if failures: + sys.exit(failures) diff --git a/django/core/management/commands/testserver.py b/django/core/management/commands/testserver.py new file mode 100644 index 0000000000..907960894c --- /dev/null +++ b/django/core/management/commands/testserver.py @@ -0,0 +1,26 @@ +from django.core.management.base import BaseCommand + +class Command(BaseCommand): + help = 'Runs a development server with data from the given fixture(s).' + args = '[fixture ...]' + + requires_model_validation = False + + def handle(self, *fixture_labels, **options): + from django.conf import settings + from django.core.management import call_command + from django.test.utils import create_test_db + + verbosity = int(options.get('verbosity', 1)) + + # Create a test database. + db_name = create_test_db(verbosity=verbosity) + + # Import the fixture data into the test database. + call_command('loaddata', *fixture_labels, **{'verbosity': verbosity}) + + # Run the development server. Turn off auto-reloading because it causes + # a strange error -- it causes this handle() method to be called + # multiple times. + shutdown_message = '\nServer stopped.\nNote that the test database, %r, has not been deleted. You can explore it on your own.' % db_name + call_command('runserver', shutdown_message=shutdown_message, use_reloader=False) diff --git a/django/core/management/commands/validate.py b/django/core/management/commands/validate.py new file mode 100644 index 0000000000..2751f41abd --- /dev/null +++ b/django/core/management/commands/validate.py @@ -0,0 +1,9 @@ +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + help = "Validates all installed models." + + requires_model_validation = False + + def handle_noargs(self, **options): + self.validate() diff --git a/django/core/management/sql.py b/django/core/management/sql.py new file mode 100644 index 0000000000..d9736262a1 --- /dev/null +++ b/django/core/management/sql.py @@ -0,0 +1,420 @@ +from django.core.management.base import CommandError +import os +import re + +try: + set +except NameError: + from sets import Set as set # Python 2.3 fallback + +def table_list(): + "Returns a list of all table names that exist in the database." + from django.db import connection, get_introspection_module + cursor = connection.cursor() + return get_introspection_module().get_table_list(cursor) + +def installed_models(table_list): + "Returns a set of all models that are installed, given a list of existing table names." + from django.db import backend, models + all_models = [] + for app in models.get_apps(): + for model in models.get_models(app): + all_models.append(model) + if backend.uses_case_insensitive_names: + converter = lambda x: x.upper() + else: + converter = lambda x: x + return set([m for m in all_models if converter(m._meta.db_table) in map(converter, table_list)]) + +def sequence_list(): + "Returns a list of information about all DB sequences for all models in all apps." + from django.db import models + + apps = models.get_apps() + sequence_list = [] + + for app in apps: + for model in models.get_models(app): + for f in model._meta.fields: + if isinstance(f, models.AutoField): + sequence_list.append({'table': model._meta.db_table, 'column': f.column}) + break # Only one AutoField is allowed per model, so don't bother continuing. + + for f in model._meta.many_to_many: + sequence_list.append({'table': f.m2m_db_table(), 'column': None}) + + return sequence_list + +def sql_create(app, style): + "Returns a list of the CREATE TABLE SQL statements for the given app." + from django.db import models + from django.conf import settings + + if settings.DATABASE_ENGINE == 'dummy': + # This must be the "dummy" database backend, which means the user + # hasn't set DATABASE_ENGINE. + raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" + + "because you haven't specified the DATABASE_ENGINE setting.\n" + + "Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.") + + # Get installed models, so we generate REFERENCES right. + # We trim models from the current app so that the sqlreset command does not + # generate invalid SQL (leaving models out of known_models is harmless, so + # we can be conservative). + app_models = models.get_models(app) + final_output = [] + known_models = set([model for model in installed_models(table_list()) if model not in app_models]) + pending_references = {} + + for model in app_models: + output, references = sql_model_create(model, style, known_models) + final_output.extend(output) + for refto, refs in references.items(): + pending_references.setdefault(refto, []).extend(refs) + final_output.extend(sql_for_pending_references(model, style, pending_references)) + # Keep track of the fact that we've created the table for this model. + known_models.add(model) + + # Create the many-to-many join tables. + for model in app_models: + final_output.extend(many_to_many_sql_for_model(model, style)) + + # Handle references to tables that are from other apps + # but don't exist physically. + not_installed_models = set(pending_references.keys()) + if not_installed_models: + alter_sql = [] + for model in not_installed_models: + alter_sql.extend(['-- ' + sql for sql in + sql_for_pending_references(model, style, pending_references)]) + if alter_sql: + final_output.append('-- The following references should be added but depend on non-existent tables:') + final_output.extend(alter_sql) + + return final_output + +def sql_delete(app, style): + "Returns a list of the DROP TABLE SQL statements for the given app." + from django.db import backend, connection, models, get_introspection_module + from django.db.backends.util import truncate_name + introspection = get_introspection_module() + + # This should work even if a connection isn't available + try: + cursor = connection.cursor() + except: + cursor = None + + # Figure out which tables already exist + if cursor: + table_names = introspection.get_table_list(cursor) + else: + table_names = [] + if backend.uses_case_insensitive_names: + table_name_converter = str.upper + else: + table_name_converter = lambda x: x + + output = [] + + # Output DROP TABLE statements for standard application tables. + to_delete = set() + + references_to_delete = {} + app_models = models.get_models(app) + for model in app_models: + if cursor and table_name_converter(model._meta.db_table) in table_names: + # The table exists, so it needs to be dropped + opts = model._meta + for f in opts.fields: + if f.rel and f.rel.to not in to_delete: + references_to_delete.setdefault(f.rel.to, []).append( (model, f) ) + + to_delete.add(model) + + for model in app_models: + if cursor and table_name_converter(model._meta.db_table) in table_names: + # Drop the table now + output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), + style.SQL_TABLE(backend.quote_name(model._meta.db_table)))) + if backend.supports_constraints and model in references_to_delete: + for rel_class, f in references_to_delete[model]: + table = rel_class._meta.db_table + col = f.column + r_table = model._meta.db_table + r_col = model._meta.get_field(f.rel.field_name).column + r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((table, r_table)))) + output.append('%s %s %s %s;' % \ + (style.SQL_KEYWORD('ALTER TABLE'), + style.SQL_TABLE(backend.quote_name(table)), + style.SQL_KEYWORD(backend.get_drop_foreignkey_sql()), + style.SQL_FIELD(truncate_name(r_name, backend.get_max_name_length())))) + del references_to_delete[model] + if model._meta.has_auto_field and hasattr(backend, 'get_drop_sequence'): + output.append(backend.get_drop_sequence(model._meta.db_table)) + + # Output DROP TABLE statements for many-to-many tables. + for model in app_models: + opts = model._meta + for f in opts.many_to_many: + if cursor and table_name_converter(f.m2m_db_table()) in table_names: + output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'), + style.SQL_TABLE(backend.quote_name(f.m2m_db_table())))) + if hasattr(backend, 'get_drop_sequence'): + output.append(backend.get_drop_sequence("%s_%s" % (model._meta.db_table, f.column))) + + app_label = app_models[0]._meta.app_label + + # Close database connection explicitly, in case this output is being piped + # directly into a database client, to avoid locking issues. + if cursor: + cursor.close() + connection.close() + + return output[::-1] # Reverse it, to deal with table dependencies. + +def sql_reset(app, style): + "Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module." + return sql_delete(app, style) + sql_all(app, style) + +def sql_flush(style): + "Returns a list of the SQL statements used to flush the database" + from django.db import backend + statements = backend.get_sql_flush(style, table_list(), sequence_list()) + return statements + +def sql_custom(app): + "Returns a list of the custom table modifying SQL statements for the given app." + from django.db.models import get_models + output = [] + + app_models = get_models(app) + app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql')) + + for model in app_models: + output.extend(custom_sql_for_model(model)) + + return output + +def sql_indexes(app, style): + "Returns a list of the CREATE INDEX SQL statements for all models in the given app." + from django.db import models + output = [] + for model in models.get_models(app): + output.extend(sql_indexes_for_model(model, style)) + return output + +def sql_all(app, style): + "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module." + return sql_create(app, style) + sql_custom(app) + sql_indexes(app, style) + +def sql_model_create(model, style, known_models=set()): + """ + Returns the SQL required to create a single model, as a tuple of: + (list_of_sql, pending_references_dict) + """ + from django.db import backend, models + + opts = model._meta + final_output = [] + table_output = [] + pending_references = {} + for f in opts.fields: + col_type = f.db_type() + tablespace = f.db_tablespace or opts.db_tablespace + if col_type is None: + # Skip ManyToManyFields, because they're not represented as + # database columns in this table. + continue + # Make the definition (e.g. 'foo VARCHAR(30)') for this field. + field_output = [style.SQL_FIELD(backend.quote_name(f.column)), + style.SQL_COLTYPE(col_type)] + field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) + if f.unique and (not f.primary_key or backend.allows_unique_and_pk): + field_output.append(style.SQL_KEYWORD('UNIQUE')) + if f.primary_key: + field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) + if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys: + # We must specify the index tablespace inline, because we + # won't be generating a CREATE INDEX statement for this field. + field_output.append(backend.get_tablespace_sql(tablespace, inline=True)) + if f.rel: + if f.rel.to in known_models: + field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ + style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \ + style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' + + backend.get_deferrable_sql() + ) + else: + # We haven't yet created the table to which this field + # is related, so save it for later. + pr = pending_references.setdefault(f.rel.to, []).append((model, f)) + table_output.append(' '.join(field_output)) + if opts.order_with_respect_to: + table_output.append(style.SQL_FIELD(backend.quote_name('_order')) + ' ' + \ + style.SQL_COLTYPE(models.IntegerField().db_type()) + ' ' + \ + style.SQL_KEYWORD('NULL')) + for field_constraints in opts.unique_together: + table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ + ", ".join([backend.quote_name(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints])) + + full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(backend.quote_name(opts.db_table)) + ' ('] + for i, line in enumerate(table_output): # Combine and add commas. + full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) + full_statement.append(')') + if opts.db_tablespace and backend.supports_tablespaces: + full_statement.append(backend.get_tablespace_sql(opts.db_tablespace)) + full_statement.append(';') + final_output.append('\n'.join(full_statement)) + + if opts.has_auto_field and hasattr(backend, 'get_autoinc_sql'): + # Add any extra SQL needed to support auto-incrementing primary keys + autoinc_sql = backend.get_autoinc_sql(opts.db_table) + if autoinc_sql: + for stmt in autoinc_sql: + final_output.append(stmt) + + return final_output, pending_references + +def sql_for_pending_references(model, style, pending_references): + """ + Returns any ALTER TABLE statements to add constraints after the fact. + """ + from django.db import backend + from django.db.backends.util import truncate_name + + final_output = [] + if backend.supports_constraints: + opts = model._meta + if model in pending_references: + for rel_class, f in pending_references[model]: + rel_opts = rel_class._meta + r_table = rel_opts.db_table + r_col = f.column + table = opts.db_table + col = opts.get_field(f.rel.field_name).column + # For MySQL, r_name must be unique in the first 64 characters. + # So we are careful with character usage here. + r_name = '%s_refs_%s_%x' % (r_col, col, abs(hash((r_table, table)))) + final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % \ + (backend.quote_name(r_table), truncate_name(r_name, backend.get_max_name_length()), + backend.quote_name(r_col), backend.quote_name(table), backend.quote_name(col), + backend.get_deferrable_sql())) + del pending_references[model] + return final_output + +def many_to_many_sql_for_model(model, style): + from django.db import backend, models + from django.contrib.contenttypes import generic + + opts = model._meta + final_output = [] + for f in opts.many_to_many: + if not isinstance(f.rel, generic.GenericRel): + tablespace = f.db_tablespace or opts.db_tablespace + if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys: + tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True) + else: + tablespace_sql = '' + table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ + style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] + table_output.append(' %s %s %s%s,' % \ + (style.SQL_FIELD(backend.quote_name('id')), + style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), + style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), + tablespace_sql)) + table_output.append(' %s %s %s %s (%s)%s,' % \ + (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), + style.SQL_COLTYPE(models.ForeignKey(model).db_type()), + style.SQL_KEYWORD('NOT NULL REFERENCES'), + style.SQL_TABLE(backend.quote_name(opts.db_table)), + style.SQL_FIELD(backend.quote_name(opts.pk.column)), + backend.get_deferrable_sql())) + table_output.append(' %s %s %s %s (%s)%s,' % \ + (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), + style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), + style.SQL_KEYWORD('NOT NULL REFERENCES'), + style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), + style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), + backend.get_deferrable_sql())) + table_output.append(' %s (%s, %s)%s' % \ + (style.SQL_KEYWORD('UNIQUE'), + style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), + style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), + tablespace_sql)) + table_output.append(')') + if opts.db_tablespace and backend.supports_tablespaces: + # f.db_tablespace is only for indices, so ignore its value here. + table_output.append(backend.get_tablespace_sql(opts.db_tablespace)) + table_output.append(';') + final_output.append('\n'.join(table_output)) + + # Add any extra SQL needed to support auto-incrementing PKs + autoinc_sql = backend.get_autoinc_sql(f.m2m_db_table()) + if autoinc_sql: + for stmt in autoinc_sql: + final_output.append(stmt) + + return final_output + +def custom_sql_for_model(model): + from django.db import models + from django.conf import settings + + opts = model._meta + app_dir = os.path.normpath(os.path.join(os.path.dirname(models.get_app(model._meta.app_label).__file__), 'sql')) + output = [] + + # Some backends can't execute more than one SQL statement at a time, + # so split into separate statements. + statements = re.compile(r";[ \t]*$", re.M) + + # Find custom SQL, if it's available. + sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), settings.DATABASE_ENGINE)), + os.path.join(app_dir, "%s.sql" % opts.object_name.lower())] + for sql_file in sql_files: + if os.path.exists(sql_file): + fp = open(sql_file, 'U') + for statement in statements.split(fp.read().decode(settings.FILE_CHARSET)): + # Remove any comments from the file + statement = re.sub(ur"--.*[\n\Z]", "", statement) + if statement.strip(): + output.append(statement + u";") + fp.close() + + return output + +def sql_indexes_for_model(model, style): + "Returns the CREATE INDEX SQL statements for a single model" + from django.db import backend + output = [] + + for f in model._meta.fields: + if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys): + unique = f.unique and 'UNIQUE ' or '' + tablespace = f.db_tablespace or model._meta.db_tablespace + if tablespace and backend.supports_tablespaces: + tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace) + else: + tablespace_sql = '' + output.append( + style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ + style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ + style.SQL_KEYWORD('ON') + ' ' + \ + style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \ + "(%s)" % style.SQL_FIELD(backend.quote_name(f.column)) + \ + "%s;" % tablespace_sql + ) + return output + +def emit_post_sync_signal(created_models, verbosity, interactive): + from django.db import models + from django.dispatch import dispatcher + # Emit the post_sync signal for every application. + for app in models.get_apps(): + app_name = app.__name__.split('.')[-2] + if verbosity >= 2: + print "Running post-sync handlers for application", app_name + dispatcher.send(signal=models.signals.post_syncdb, sender=app, + app=app, created_models=created_models, + verbosity=verbosity, interactive=interactive) diff --git a/django/core/management/validation.py b/django/core/management/validation.py new file mode 100644 index 0000000000..aa4ef47c2f --- /dev/null +++ b/django/core/management/validation.py @@ -0,0 +1,221 @@ +import sys +from django.core.management.color import color_style + +class ModelErrorCollection: + def __init__(self, outfile=sys.stdout): + self.errors = [] + self.outfile = outfile + self.style = color_style() + + def add(self, context, error): + self.errors.append((context, error)) + self.outfile.write(self.style.ERROR("%s: %s\n" % (context, error))) + +def get_validation_errors(outfile, app=None): + """ + Validates all models that are part of the specified app. If no app name is provided, + validates all models of all installed apps. Writes errors, if any, to outfile. + Returns number of errors. + """ + from django.conf import settings + from django.db import models, connection + from django.db.models.loading import get_app_errors + from django.db.models.fields.related import RelatedObject + + e = ModelErrorCollection(outfile) + + for (app_name, error) in get_app_errors().items(): + e.add(app_name, error) + + for cls in models.get_models(app): + opts = cls._meta + + # Do field-specific validation. + for f in opts.fields: + if f.name == 'id' and not f.primary_key and opts.pk.name == 'id': + 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.max_length in (None, 0): + e.add(opts, '"%s": CharFields require a "max_length" attribute.' % f.name) + if isinstance(f, models.DecimalField): + if f.decimal_places is None: + e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name) + if f.max_digits is None: + 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): + try: + from PIL import Image + except ImportError: + e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) + if f.prepopulate_from is not None and type(f.prepopulate_from) not in (list, tuple): + e.add(opts, '"%s": prepopulate_from should be a list or tuple.' % f.name) + if f.choices: + if not hasattr(f.choices, '__iter__'): + e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name) + else: + for c in f.choices: + if not type(c) in (tuple, list) or len(c) != 2: + e.add(opts, '"%s": "choices" should be a sequence of two-tuples.' % f.name) + if f.db_index not in (None, True, False): + e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name) + + # Check that max_length <= 255 if using older MySQL versions. + if settings.DATABASE_ENGINE == 'mysql': + db_version = connection.get_server_version() + if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.max_length > 255: + e.add(opts, '"%s": %s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]]))) + + # Check to see if the related field will clash with any + # existing fields, m2m fields, m2m related objects or related objects + if f.rel: + rel_opts = f.rel.to._meta + if f.rel.to not in models.get_models(): + e.add(opts, "'%s' has relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) + + rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() + rel_query_name = f.related_query_name() + for r in rel_opts.fields: + if r.name == rel_name: + e.add(opts, "Accessor for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + if r.name == rel_query_name: + e.add(opts, "Reverse query name for field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + for r in rel_opts.many_to_many: + if r.name == rel_name: + e.add(opts, "Accessor for field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + if r.name == rel_query_name: + e.add(opts, "Reverse query name for field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + for r in rel_opts.get_all_related_many_to_many_objects(): + if r.get_accessor_name() == rel_name: + e.add(opts, "Accessor for field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + if r.get_accessor_name() == rel_query_name: + e.add(opts, "Reverse query name for field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + for r in rel_opts.get_all_related_objects(): + if r.field is not f: + if r.get_accessor_name() == rel_name: + e.add(opts, "Accessor for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + if r.get_accessor_name() == rel_query_name: + e.add(opts, "Reverse query name for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + + for i, f in enumerate(opts.many_to_many): + # Check to see if the related m2m field will clash with any + # existing fields, m2m fields, m2m related objects or related objects + rel_opts = f.rel.to._meta + if f.rel.to not in models.get_models(): + e.add(opts, "'%s' has m2m relation with model %s, which has not been installed" % (f.name, rel_opts.object_name)) + + rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() + rel_query_name = f.related_query_name() + # If rel_name is none, there is no reverse accessor. + # (This only occurs for symmetrical m2m relations to self). + # If this is the case, there are no clashes to check for this field, as + # there are no reverse descriptors for this field. + if rel_name is not None: + for r in rel_opts.fields: + if r.name == rel_name: + e.add(opts, "Accessor for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + if r.name == rel_query_name: + e.add(opts, "Reverse query name for m2m field '%s' clashes with field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + for r in rel_opts.many_to_many: + if r.name == rel_name: + e.add(opts, "Accessor for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + if r.name == rel_query_name: + e.add(opts, "Reverse query name for m2m field '%s' clashes with m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.name, f.name)) + for r in rel_opts.get_all_related_many_to_many_objects(): + if r.field is not f: + if r.get_accessor_name() == rel_name: + e.add(opts, "Accessor for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + if r.get_accessor_name() == rel_query_name: + e.add(opts, "Reverse query name for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + for r in rel_opts.get_all_related_objects(): + if r.get_accessor_name() == rel_name: + e.add(opts, "Accessor for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + if r.get_accessor_name() == rel_query_name: + e.add(opts, "Reverse query name for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) + + # Check admin attribute. + if opts.admin is not None: + if not isinstance(opts.admin, models.AdminOptions): + e.add(opts, '"admin" attribute, if given, must be set to a models.AdminOptions() instance.') + else: + # list_display + if not isinstance(opts.admin.list_display, (list, tuple)): + e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.') + else: + for fn in opts.admin.list_display: + try: + f = opts.get_field(fn) + except models.FieldDoesNotExist: + if not hasattr(cls, fn): + e.add(opts, '"admin.list_display" refers to %r, which isn\'t an attribute, method or property.' % fn) + else: + if isinstance(f, models.ManyToManyField): + e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn) + # list_display_links + if opts.admin.list_display_links and not opts.admin.list_display: + e.add(opts, '"admin.list_display" must be defined for "admin.list_display_links" to be used.') + if not isinstance(opts.admin.list_display_links, (list, tuple)): + e.add(opts, '"admin.list_display_links", if given, must be set to a list or tuple.') + else: + for fn in opts.admin.list_display_links: + try: + f = opts.get_field(fn) + except models.FieldDoesNotExist: + if not hasattr(cls, fn): + e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % fn) + if fn not in opts.admin.list_display: + e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn) + # list_filter + if not isinstance(opts.admin.list_filter, (list, tuple)): + e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.') + else: + for fn in opts.admin.list_filter: + try: + f = opts.get_field(fn) + except models.FieldDoesNotExist: + e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn) + # date_hierarchy + if opts.admin.date_hierarchy: + try: + f = opts.get_field(opts.admin.date_hierarchy) + except models.FieldDoesNotExist: + e.add(opts, '"admin.date_hierarchy" refers to %r, which isn\'t a field.' % opts.admin.date_hierarchy) + + # Check ordering attribute. + if opts.ordering: + for field_name in opts.ordering: + if field_name == '?': continue + if field_name.startswith('-'): + field_name = field_name[1:] + if opts.order_with_respect_to and field_name == '_order': + continue + if '.' in field_name: continue # Skip ordering in the format 'table.field'. + try: + opts.get_field(field_name, many_to_many=False) + except models.FieldDoesNotExist: + e.add(opts, '"ordering" refers to "%s", a field that doesn\'t exist.' % field_name) + + # Check core=True, if needed. + for related in opts.get_followed_related_objects(): + if not related.edit_inline: + continue + try: + for f in related.opts.fields: + if f.core: + raise StopIteration + e.add(related.opts, "At least one field in %s should have core=True, because it's being edited inline by %s.%s." % (related.opts.object_name, opts.module_name, opts.object_name)) + except StopIteration: + pass + + # Check unique_together. + for ut in opts.unique_together: + for field_name in ut: + try: + f = opts.get_field(field_name, many_to_many=True) + except models.FieldDoesNotExist: + e.add(opts, '"unique_together" refers to %s, a field that doesn\'t exist. Check your syntax.' % field_name) + else: + if isinstance(f.rel, models.ManyToManyRel): + e.add(opts, '"unique_together" refers to %s. ManyToManyFields are not supported in unique_together.' % f.name) + + return len(e.errors) diff --git a/django/core/validators.py b/django/core/validators.py index fde4f052cb..8a93462b21 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -269,10 +269,10 @@ def hasNoProfanities(field_data, all_data): words_seen = [w for w in settings.PROFANITIES_LIST if w in field_data] if words_seen: from django.utils.text import get_text_list - plural = len(words_seen) > 1 + plural = len(words_seen) raise ValidationError, ungettext("Watch your mouth! The word %s is not allowed here.", "Watch your mouth! The words %s are not allowed here.", plural) % \ - get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], 'and') + get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], _('and')) class AlwaysMatchesOtherField(object): def __init__(self, other_field_name, error_message=None): diff --git a/django/core/xheaders.py b/django/core/xheaders.py index 3beb930158..34335f12c5 100644 --- a/django/core/xheaders.py +++ b/django/core/xheaders.py @@ -4,7 +4,7 @@ information about those pages -- namely, the content type and object ID. This module contains utility functions for retrieving and doing interesting things with these special "X-Headers" (so called because the HTTP spec demands -that custom headers are prefxed with "X-"). +that custom headers are prefixed with "X-"). Next time you're at slashdot.org, watch out for X-Fry and X-Bender. :) """ @@ -17,6 +17,8 @@ def populate_xheaders(request, response, model, object_id): or if the request is from a logged in staff member. """ from django.conf import settings - if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or (hasattr(request, 'user') and request.user.is_authenticated() and request.user.is_staff): + if (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS + or (hasattr(request, 'user') and request.user.is_authenticated() + and request.user.is_staff)): response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.object_name.lower()) response['X-Object-Id'] = str(object_id) diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index af498fa9ff..b1b32dd23e 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -109,7 +109,7 @@ def create_test_db(settings, connection, backend, verbosity=1, autoclobber=False settings.DATABASE_USER = TEST_DATABASE_USER settings.DATABASE_PASSWORD = TEST_DATABASE_PASSWD - management.syncdb(verbosity, interactive=False) + management.call_command('syncdb', verbosity=verbosity, interactive=False) # Get a cursor (even though we don't need one yet). This has # the side effect of initializing the test database. diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index d90f0cc225..9d0967fa2b 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -278,7 +278,7 @@ def typecast_string(s): """ Cast all returned strings to unicode strings. """ - if not s: + if not s and not isinstance(s, str): return s return smart_unicode(s) diff --git a/django/db/models/base.py b/django/db/models/base.py index 528bf7fb06..85ddb79fff 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -218,11 +218,11 @@ class Model(object): record_exists = True if pk_set: # Determine whether a record with the primary key already exists. - cursor.execute("SELECT COUNT(*) FROM %s WHERE %s=%%s" % \ + cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % \ (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), self._meta.pk.get_db_prep_lookup('exact', pk_val)) # If it does already exist, do an UPDATE. - if cursor.fetchone()[0] > 0: + if cursor.fetchone(): db_values = [f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False)) for f in non_pks] if db_values: cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ diff --git a/django/db/models/query.py b/django/db/models/query.py index f5213ba903..7620c366ce 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -114,7 +114,7 @@ class _QuerySet(object): def __getitem__(self, k): "Retrieve an item or slice from the set of results." - if not isinstance(k, (slice, int)): + if not isinstance(k, (slice, int, long)): raise TypeError assert (not isinstance(k, slice) and (k >= 0)) \ or (isinstance(k, slice) and (k.start is None or k.start >= 0) and (k.stop is None or k.stop >= 0)), \ diff --git a/django/http/__init__.py b/django/http/__init__.py index bcb06cbb87..7cd47481dc 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -2,7 +2,7 @@ import os from Cookie import SimpleCookie from pprint import pformat from urllib import urlencode -from django.utils.datastructures import MultiValueDict +from django.utils.datastructures import MultiValueDict, FileDict from django.utils.encoding import smart_str, iri_to_uri, force_unicode RESERVED_CHARS="!*'();:@&=+$,/?%#[]" @@ -84,13 +84,15 @@ def parse_file_upload(header_dict, post_data): if not name_dict['filename'].strip(): continue # IE submits the full path, so trim everything but the basename. - # (We can't use os.path.basename because it expects Linux paths.) + # (We can't use os.path.basename because that uses the server's + # directory separator, which may not be the same as the + # client's one.) filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:] - FILES.appendlist(name_dict['name'], { + FILES.appendlist(name_dict['name'], FileDict({ 'filename': filename, 'content-type': 'Content-Type' in submessage and submessage['Content-Type'] or None, 'content': submessage.get_payload(), - }) + })) else: POST.appendlist(name_dict['name'], submessage.get_payload()) return POST, FILES @@ -212,18 +214,22 @@ class HttpResponse(object): status_code = 200 - def __init__(self, content='', mimetype=None, status=None): + def __init__(self, content='', mimetype=None, status=None, + content_type=None): from django.conf import settings self._charset = settings.DEFAULT_CHARSET - if not mimetype: - mimetype = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, settings.DEFAULT_CHARSET) + if mimetype: + content_type = mimetype # For backwards compatibility + if not content_type: + content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, + settings.DEFAULT_CHARSET) if not isinstance(content, basestring) and hasattr(content, '__iter__'): self._container = content self._is_string = False else: self._container = [content] self._is_string = True - self.headers = {'Content-Type': mimetype} + self.headers = {'Content-Type': content_type} self.cookies = SimpleCookie() if status: self.status_code = status diff --git a/django/middleware/common.py b/django/middleware/common.py index d238bb182d..e18ec079af 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -80,7 +80,9 @@ class CommonMiddleware(object): else: etag = md5.new(response.content).hexdigest() if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag: + cookies = response.cookies response = http.HttpResponseNotModified() + response.cookies = cookies else: response['ETag'] = etag diff --git a/django/middleware/gzip.py b/django/middleware/gzip.py index a7c74481d0..9b2a5f3d22 100644 --- a/django/middleware/gzip.py +++ b/django/middleware/gzip.py @@ -11,6 +11,11 @@ class GZipMiddleware(object): on the Accept-Encoding header. """ def process_response(self, request, response): + if response.status_code != 200 or len(response.content) < 200: + # Not worth compressing really short responses or 304 status + # responses, etc. + return response + patch_vary_headers(response, ('Accept-Encoding',)) # Avoid gzipping if we've already got a content-encoding or if the diff --git a/django/newforms/extras/widgets.py b/django/newforms/extras/widgets.py index 96b1c7244d..60936a6bd6 100644 --- a/django/newforms/extras/widgets.py +++ b/django/newforms/extras/widgets.py @@ -57,4 +57,4 @@ class SelectDateWidget(Widget): y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name) if y and m and d: return '%s-%s-%s' % (y, m, d) - return None + return data.get(name, None) diff --git a/django/newforms/fields.py b/django/newforms/fields.py index e9f50ad4ec..bb8a3dc582 100644 --- a/django/newforms/fields.py +++ b/django/newforms/fields.py @@ -344,7 +344,7 @@ url_re = re.compile( try: from django.conf import settings URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT -except ImportError: +except (ImportError, EnvironmentError): # It's OK if Django settings aren't configured. URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)' diff --git a/django/oldforms/__init__.py b/django/oldforms/__init__.py index b3d78f8919..93cfa1d8fa 100644 --- a/django/oldforms/__init__.py +++ b/django/oldforms/__init__.py @@ -204,7 +204,7 @@ class FormFieldCollection(FormFieldWrapper): def __str__(self): return unicode(self).encode('utf-8') - def __str__(self): + def __unicode__(self): return unicode(self.formfield_dict) def __getitem__(self, template_key): diff --git a/django/test/client.py b/django/test/client.py index 7e62715205..9ec3615973 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -253,3 +253,14 @@ class Client: else: return False + def logout(self): + """Removes the authenticated user's cookies. + + Causes the authenticated user to be logged out. + """ + try: + Session.objects.get(session_key=self.cookies['sessionid'].value).delete() + except KeyError: + pass + + self.cookies = SimpleCookie() diff --git a/django/test/testcases.py b/django/test/testcases.py index 5373d822df..21c429271c 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1,7 +1,8 @@ import re, unittest from urlparse import urlparse from django.db import transaction -from django.core import management, mail +from django.core import mail +from django.core.management import call_command from django.db.models import get_apps from django.test import _doctest as doctest from django.test.client import Client @@ -42,9 +43,11 @@ class TestCase(unittest.TestCase): * Clearing the mail test outbox. """ - management.flush(verbosity=0, interactive=False) + call_command('flush', verbosity=0, interactive=False) if hasattr(self, 'fixtures'): - management.load_data(self.fixtures, verbosity=0) + # We have to use this slightly awkward syntax due to the fact + # that we're using *args and **kwargs together. + call_command('loaddata', *self.fixtures, **{'verbosity': 0}) mail.outbox = [] def __call__(self, result=None): @@ -88,7 +91,7 @@ class TestCase(unittest.TestCase): self.assertEqual(real_count, count, "Found %d instances of '%s' in response (expected %d)" % (real_count, text, count)) else: - self.assertTrue(real_count != 0, "Couldn't find '%s' in response" % text) + self.failUnless(real_count != 0, "Couldn't find '%s' in response" % text) def assertFormError(self, response, form, field, errors): "Assert that a form used to render the response has a specific field error" diff --git a/django/test/utils.py b/django/test/utils.py index e9525b4dd4..bc53ef4bfb 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -1,8 +1,8 @@ import sys, time from django.conf import settings from django.db import connection, backend, get_creation_module -from django.core import management, mail -from django.core import management, mail +from django.core import mail +from django.core.management import call_command from django.dispatch import dispatcher from django.test import signals from django.template import Template @@ -18,12 +18,12 @@ def instrumented_test_render(self, context): """ dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context) return self.nodelist.render(context) - + class TestSMTPConnection(object): """A substitute SMTP connection for use during test sessions. The test connection stores email messages in a dummy outbox, rather than sending them out on the wire. - + """ def __init__(*args, **kwargs): pass @@ -36,37 +36,38 @@ class TestSMTPConnection(object): def send_messages(self, messages): "Redirect messages to the dummy outbox" mail.outbox.extend(messages) + return len(messages) def setup_test_environment(): """Perform any global pre-test setup. This involves: - + - Installing the instrumented test renderer - Diverting the email sending functions to a test buffer - + """ Template.original_render = Template.render Template.render = instrumented_test_render - + mail.original_SMTPConnection = mail.SMTPConnection mail.SMTPConnection = TestSMTPConnection mail.outbox = [] - + def teardown_test_environment(): """Perform any global post-test teardown. This involves: - Restoring the original test renderer - Restoring the email sending functions - + """ Template.render = Template.original_render del Template.original_render - + mail.SMTPConnection = mail.original_SMTPConnection del mail.original_SMTPConnection - + del mail.outbox - + def _set_autocommit(connection): "Make sure a connection is in autocommit mode." if hasattr(connection.connection, "autocommit"): @@ -89,12 +90,16 @@ def get_postgresql_create_suffix(): return '' def create_test_db(verbosity=1, autoclobber=False): + """ + Creates a test database, prompting the user for confirmation if the + database already exists. Returns the name of the test database created. + """ # If the database backend wants to create the test DB itself, let it creation_module = get_creation_module() if hasattr(creation_module, "create_test_db"): creation_module.create_test_db(settings, connection, backend, verbosity, autoclobber) return - + if verbosity >= 1: print "Creating test database..." # If we're using SQLite, it's more convenient to test against an @@ -112,22 +117,22 @@ def create_test_db(verbosity=1, autoclobber=False): TEST_DATABASE_NAME = settings.TEST_DATABASE_NAME else: TEST_DATABASE_NAME = TEST_DATABASE_PREFIX + settings.DATABASE_NAME - + # Create the test database and connect to it. We need to autocommit - # if the database supports it because PostgreSQL doesn't allow + # if the database supports it because PostgreSQL doesn't allow # CREATE/DROP DATABASE statements within transactions. cursor = connection.cursor() _set_autocommit(connection) try: cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix)) - except Exception, e: + except Exception, e: sys.stderr.write("Got an error creating the test database: %s\n" % e) if not autoclobber: confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % TEST_DATABASE_NAME) if autoclobber or confirm == 'yes': try: if verbosity >= 1: - print "Destroying old test database..." + print "Destroying old test database..." cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) if verbosity >= 1: print "Creating test database..." @@ -138,27 +143,29 @@ def create_test_db(verbosity=1, autoclobber=False): else: print "Tests cancelled." sys.exit(1) - + connection.close() settings.DATABASE_NAME = TEST_DATABASE_NAME - management.syncdb(verbosity, interactive=False) + call_command('syncdb', verbosity=verbosity, interactive=False) if settings.CACHE_BACKEND.startswith('db://'): cache_name = settings.CACHE_BACKEND[len('db://'):] - management.createcachetable(cache_name) + call_command('createcachetable', cache_name) # Get a cursor (even though we don't need one yet). This has # the side effect of initializing the test database. cursor = connection.cursor() + return TEST_DATABASE_NAME + def destroy_test_db(old_database_name, verbosity=1): # If the database wants to drop the test DB itself, let it creation_module = get_creation_module() if hasattr(creation_module, "destroy_test_db"): creation_module.destroy_test_db(settings, connection, backend, old_database_name, verbosity) return - + # Unless we're using SQLite, remove the test database to clean up after # ourselves. Connect to the previous database (not the test database) # to do so, because it's not allowed to delete a database while being diff --git a/django/utils/_os.py b/django/utils/_os.py index 56ef0f2014..30d7cbd444 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -1,23 +1,23 @@ -from os.path import join, normcase, abspath, sep
-
-def safe_join(base, *paths):
- """
- Joins one or more path components to the base path component intelligently.
- Returns a normalized, absolute version of the final path.
-
- The final path must be located inside of the base path component (otherwise
- a ValueError is raised).
- """
- # We need to use normcase to ensure we don't false-negative on case
- # insensitive operating systems (like Windows).
- final_path = normcase(abspath(join(base, *paths)))
- base_path = normcase(abspath(base))
- base_path_len = len(base_path)
- # Ensure final_path starts with base_path and that the next character after
- # the final path is os.sep (or nothing, in which case final_path must be
- # equal to base_path).
- if not final_path.startswith(base_path) \
- or final_path[base_path_len:base_path_len+1] not in ('', sep):
- raise ValueError('the joined path is located outside of the base path'
- ' component')
- return final_path
+from os.path import join, normcase, abspath, sep + +def safe_join(base, *paths): + """ + Joins one or more path components to the base path component intelligently. + Returns a normalized, absolute version of the final path. + + The final path must be located inside of the base path component (otherwise + a ValueError is raised). + """ + # We need to use normcase to ensure we don't false-negative on case + # insensitive operating systems (like Windows). + final_path = normcase(abspath(join(base, *paths))) + base_path = normcase(abspath(base)) + base_path_len = len(base_path) + # Ensure final_path starts with base_path and that the next character after + # the final path is os.sep (or nothing, in which case final_path must be + # equal to base_path). + if not final_path.startswith(base_path) \ + or final_path[base_path_len:base_path_len+1] not in ('', sep): + raise ValueError('the joined path is located outside of the base path' + ' component') + return final_path diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 60bc0051a2..4b60d1d194 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -267,3 +267,16 @@ class DotExpandedDict(dict): current[bits[-1]] = v except TypeError: # Special-case if current isn't a dict. current = {bits[-1] : v} + +class FileDict(dict): + """ + A dictionary used to hold uploaded file contents. The only special feature + here is that repr() of this object won't dump the entire contents of the + file to the output. A handy safeguard for a large file upload. + """ + def __repr__(self): + if 'content' in self: + d = dict(self, content='<omitted>') + return dict.__repr__(d) + return dict.__repr__(self) + diff --git a/django/utils/text.py b/django/utils/text.py index c41c35151b..4670ab47fa 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -2,6 +2,7 @@ import re from django.conf import settings from django.utils.encoding import force_unicode from django.utils.functional import allow_lazy +from django.utils.translation import ugettext_lazy # Capitalizes the first letter of a string. capfirst = lambda x: x and force_unicode(x)[0].upper() + force_unicode(x)[1:] @@ -123,7 +124,7 @@ def get_valid_filename(s): return re.sub(r'[^-A-Za-z0-9_.]', '', s) get_valid_filename = allow_lazy(get_valid_filename, unicode) -def get_text_list(list_, last_word=u'or'): +def get_text_list(list_, last_word=ugettext_lazy(u'or')): """ >>> get_text_list(['a', 'b', 'c', 'd']) 'a, b, c or d' diff --git a/django/views/debug.py b/django/views/debug.py index d2efe76072..cf0b6b5a0b 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -123,10 +123,20 @@ def technical_500_response(request, exc_type, exc_value, tb): 'function': '?', 'lineno': '?', }] + + unicode_hint = '' + if issubclass(exc_type, UnicodeError): + start = getattr(exc_value, 'start', None) + end = getattr(exc_value, 'end', None) + if start is not None and end is not None: + unicode_str = exc_value.args[1] + unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace') + t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') c = Context({ 'exception_type': exc_type.__name__, 'exception_value': smart_unicode(exc_value, errors='replace'), + 'unicode_hint': unicode_hint, 'frames': frames, 'lastframe': frames[-1], 'request': request, @@ -258,6 +268,7 @@ TECHNICAL_500_TEMPLATE = """ #explanation { background:#eee; } #template, #template-not-exist { background:#f6f6f6; } #template-not-exist ul { margin: 0 0 0 20px; } + #unicode-hint { background:#eee; } #traceback { background:#eee; } #requestinfo { background:#f6f6f6; padding-left:120px; } #summary table { border:none; background:transparent; } @@ -358,6 +369,12 @@ TECHNICAL_500_TEMPLATE = """ </tr> </table> </div> +{% if unicode_hint %} +<div id="unicode-hint"> + <h2>Unicode error hint</h2> + <p>The string that could not be encoded/decoded was: <strong>{{ unicode_hint|escape }}</strong></p> +</div> +{% endif %} {% if template_does_not_exist %} <div id="template-not-exist"> <h2>Template-loader postmortem</h2> diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py index a4559ad495..46e92fe26e 100644 --- a/django/views/generic/create_update.py +++ b/django/views/generic/create_update.py @@ -71,7 +71,7 @@ def create_object(request, model, template_name=None, return HttpResponse(t.render(c)) def update_object(request, model, object_id=None, slug=None, - slug_field=None, template_name=None, template_loader=loader, + slug_field='slug', template_name=None, template_loader=loader, extra_context=None, post_save_redirect=None, login_required=False, follow=None, context_processors=None, template_object_name='object'): @@ -146,7 +146,7 @@ def update_object(request, model, object_id=None, slug=None, return response def delete_object(request, model, post_delete_redirect, - object_id=None, slug=None, slug_field=None, template_name=None, + object_id=None, slug=None, slug_field='slug', template_name=None, template_loader=loader, extra_context=None, login_required=False, context_processors=None, template_object_name='object'): """ diff --git a/django/views/generic/date_based.py b/django/views/generic/date_based.py index d13c0293be..c0f219f280 100644 --- a/django/views/generic/date_based.py +++ b/django/views/generic/date_based.py @@ -286,7 +286,7 @@ def archive_today(request, **kwargs): def object_detail(request, year, month, day, queryset, date_field, month_format='%b', day_format='%d', object_id=None, slug=None, - slug_field=None, template_name=None, template_name_field=None, + slug_field='slug', template_name=None, template_name_field=None, template_loader=loader, extra_context=None, context_processors=None, template_object_name='object', mimetype=None, allow_future=False): """ diff --git a/django/views/generic/list_detail.py b/django/views/generic/list_detail.py index 16d55202da..f5616b9745 100644 --- a/django/views/generic/list_detail.py +++ b/django/views/generic/list_detail.py @@ -87,7 +87,7 @@ def object_list(request, queryset, paginate_by=None, page=None, return HttpResponse(t.render(c), mimetype=mimetype) def object_detail(request, queryset, object_id=None, slug=None, - slug_field=None, template_name=None, template_name_field=None, + slug_field='slug', template_name=None, template_name_field=None, template_loader=loader, extra_context=None, context_processors=None, template_object_name='object', mimetype=None): diff --git a/django/views/i18n.py b/django/views/i18n.py index 0fec6b6c6f..320caf37d7 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -69,9 +69,9 @@ function pluralidx(count) { return (count == 1) ? 0 : 1; } InterPolate = r""" function interpolate(fmt, obj, named) { if (named) { - return fmt.replace(/%\(\w+\)s/, function(match){return String(obj[match.slice(2,-2)])}); + return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])}); } else { - return fmt.replace(/%s/, function(match){return String(obj.shift())}); + return fmt.replace(/%s/g, function(match){return String(obj.shift())}); } } """ diff --git a/docs/authentication.txt b/docs/authentication.txt index 589e8c9f1b..7860b59d7d 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -436,7 +436,10 @@ template context variables: * ``next``: The URL to redirect to after successful login. This may contain a query string, too. * ``site_name``: The name of the current ``Site``, according to the - ``SITE_ID`` setting. See the `site framework docs`_. + ``SITE_ID`` setting. If you're using the Django development version and + you don't have the site framework installed, this will be set to the + value of ``request.META['SERVER_NAME']``. For more on sites, see the + `site framework docs`_. If you'd prefer not to call the template ``registration/login.html``, you can pass the ``template_name`` parameter via the extra arguments to the view in @@ -675,8 +678,6 @@ Example in Python 2.4 syntax:: The permission_required decorator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**New in Django development version** - It's a relatively common task to check whether a user has a particular permission. For that reason, Django provides a shortcut for that case: the ``permission_required()`` decorator. Using this decorator, the earlier example diff --git a/docs/contributing.txt b/docs/contributing.txt index 61c368d32a..cce54fa485 100644 --- a/docs/contributing.txt +++ b/docs/contributing.txt @@ -67,6 +67,13 @@ particular: likely to get lost. If a particular ticket is controversial, please move discussion to `django-developers`_. + * **Don't** post to django-developers just to announce that you have filed + a bug report. All the tickets are mailed to another list + (`django-updates`_), which is tracked by developers and triagers, so we + see them as they are filed. + +.. _django-updates: http://groups.google.com/group/django-updates + Reporting security issues ========================= diff --git a/docs/csrf.txt b/docs/csrf.txt index c12dd1d116..7d79e39502 100644 --- a/docs/csrf.txt +++ b/docs/csrf.txt @@ -41,10 +41,10 @@ CsrfMiddleware does two things: This ensures that only forms that have originated from your web site can be used to POST data back. -It deliberately only targets HTTP POST requests (and the corresponding -POST forms). GET requests ought never to have side effects (if you are -using HTTP GET and POST correctly), and so a CSRF attack with a GET -request will always be harmless. +It deliberately only targets HTTP POST requests (and the corresponding POST +forms). GET requests ought never to have any potentially dangerous side +effects (see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a +CSRF attack with a GET request ought to be harmless. POST requests that are not accompanied by a session cookie are not protected, but they do not need to be protected, since the 'attacking' web site @@ -54,6 +54,8 @@ The Content-Type is checked before modifying the response, and only pages that are served as 'text/html' or 'application/xml+xhtml' are modified. +.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html + Limitations =========== diff --git a/docs/databrowse.txt b/docs/databrowse.txt index 9c03e7e4ea..81e9e8e83b 100644 --- a/docs/databrowse.txt +++ b/docs/databrowse.txt @@ -35,6 +35,7 @@ How to use Databrowse 2. Register a number of models with the Databrowse site:: from django.contrib import databrowse + from myapp.models import SomeModel, SomeOtherModel databrowse.site.register(SomeModel) databrowse.site.register(SomeOtherModel) diff --git a/docs/django-admin.txt b/docs/django-admin.txt index ad17907b5e..aea990c5dc 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -235,6 +235,7 @@ The ``dumpdata`` command can be used to generate input for ``loaddata``. reset [appname appname ...] --------------------------- + Executes the equivalent of ``sqlreset`` for the given appnames. runfcgi [options] @@ -426,7 +427,46 @@ test Discover and run tests for all installed models. See `Testing Django applications`_ for more information. -.. _testing django applications: ../testing/ +.. _testing Django applications: ../testing/ + +testserver [fixture fixture ...] +-------------------------------- + +**New in Django development version** + +Runs a Django development server (as in ``runserver``) using data from the +given fixture(s). + +For example, this command:: + + django-admin.py testserver mydata.json + +...would perform the following steps: + + 1. Create a test database, as described in `testing Django applications`_. + 2. Populate the test database with fixture data from the given fixtures. + (For more on fixtures, see the documentation for ``loaddata`` above.) + 3. Runs the Django development server (as in ``runserver``), pointed at + this newly created test database instead of your production database. + +This is useful in a number of ways: + + * When you're writing `unit tests`_ of how your views act with certain + fixture data, you can use ``testserver`` to interact with the views in + a Web browser, manually. + + * Let's say you're developing your Django application and have a "pristine" + copy of a database that you'd like to interact with. You can dump your + database to a fixture (using the ``dumpdata`` command, explained above), + then use ``testserver`` to run your Web application with that data. With + this arrangement, you have the flexibility of messing up your data + in any way, knowing that whatever data changes you're making are only + being made to a test database. + +Note that this server can only run on the default port on localhost; it does +not yet accept a ``host`` or ``port`` parameter. + +.. _unit tests: ../testing/ validate -------- diff --git a/docs/generic_views.txt b/docs/generic_views.txt index 2b80348903..0601aead11 100644 --- a/docs/generic_views.txt +++ b/docs/generic_views.txt @@ -40,7 +40,7 @@ simple weblog app that drives the blog on djangoproject.com:: } urlpatterns = patterns('django.views.generic.date_based', - (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')), + (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', info_dict), (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict), (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict), (r'^(?P<year>\d{4})/$', 'archive_year', info_dict), @@ -603,7 +603,7 @@ future, the view will throw a 404 error by default, unless you set Otherwise, ``slug`` should be the slug of the given object, and ``slug_field`` should be the name of the slug field in the ``QuerySet``'s - model. + model. By default, ``slug_field`` is ``'slug'``. **Optional arguments:** @@ -804,7 +804,7 @@ A page representing an individual object. Otherwise, ``slug`` should be the slug of the given object, and ``slug_field`` should be the name of the slug field in the ``QuerySet``'s - model. + model. By default, ``slug_field`` is ``'slug'``. **Optional arguments:** @@ -948,7 +948,7 @@ object. This uses the automatic manipulators that come with Django models. Otherwise, ``slug`` should be the slug of the given object, and ``slug_field`` should be the name of the slug field in the ``QuerySet``'s - model. + model. By default, ``slug_field`` is ``'slug'``. **Optional arguments:** @@ -1033,7 +1033,7 @@ contain a form that POSTs to the same URL. Otherwise, ``slug`` should be the slug of the given object, and ``slug_field`` should be the name of the slug field in the ``QuerySet``'s - model. + model. By default, ``slug_field`` is ``'slug'``. * ``post_delete_redirect``: A URL to which the view will redirect after deleting the object. diff --git a/docs/middleware.txt b/docs/middleware.txt index 533f1ccede..63ba8c6999 100644 --- a/docs/middleware.txt +++ b/docs/middleware.txt @@ -91,6 +91,12 @@ django.middleware.gzip.GZipMiddleware Compresses content for browsers that understand gzip compression (all modern browsers). +It is suggested to place this first in the middleware list, so that the +compression of the response content is the last thing that happens. Will not +compress content bodies less than 200 bytes long, when the response code is +something other than 200, Javascript files (for IE compatibitility), or +responses that have the ``Content-Encoding`` header already specified. + django.middleware.http.ConditionalGetMiddleware ----------------------------------------------- diff --git a/docs/model-api.txt b/docs/model-api.txt index ddeb481206..0f872c3097 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -415,7 +415,8 @@ form:: models.SlugField(prepopulate_from=("pre_name", "name")) -``prepopulate_from`` doesn't accept DateTimeFields. +``prepopulate_from`` doesn't accept DateTimeFields, ForeignKeys nor +ManyToManyFields. The admin represents ``SlugField`` as an ``<input type="text">`` (a single-line input). diff --git a/docs/modpython.txt b/docs/modpython.txt index 676aab19ac..c90296bd9a 100644 --- a/docs/modpython.txt +++ b/docs/modpython.txt @@ -63,6 +63,30 @@ computer, you'll have to tell mod_python where your project can be found: **PythonPath "['/path/to/project'] + sys.path"** </Location> +The value you use for ``PythonPath`` should include the parent directories of +all the modules you are going to import in your application. It should also +include the parent directory of the ``DJANGO_SETTINGS_MODULE`` location. This +is exactly the same situation as setting the Python path for interactive +usage. Whenever you try to import something, Python will run through all the +directories in ``sys.path`` in turn, from first to last, and try to import +from each directory until one succeeds. + +An example might make this clearer. Suppose +you have some applications under ``/usr/local/django-apps/`` (for example, +``/usr/local/django-apps/weblog/`` and so forth), your settings file is at +``/var/www/mysite/settings.py`` and you have specified +``DJANGO_SETTINGS_MODULE`` as in the above example. In this case, you would +need to write your ``PythonPath`` directive as:: + + PythonPath "['/var/production/django-apps/', '/var/www'] + sys.path" + +With this path, ``import weblog`` and ``import mysite.settings`` will both +work. If you had ``import blogroll`` in your code somewhere and ``blogroll`` +lived under the ``weblog/`` directory, you would *also* need to add +``/var/production/django-apps/weblog/`` to your ``PythonPath``. Remember: the +**parent directories** of anything you import directly must be on the Python +path. + .. caution:: If you're using Windows, remember that the path will contain backslashes. diff --git a/docs/newforms.txt b/docs/newforms.txt index acc28604df..803dc6458a 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -678,7 +678,7 @@ The easiest way is to iterate over the form's fields, with <form method="post" action=""> <dl> {% for field in form %} - <dt>{{ field.label }}</dt> + <dt>{{ field.label_tag }}</dt> <dd>{{ field }}</dd> {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %} {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %} @@ -698,11 +698,11 @@ For example:: <form method="post" action=""> <ul class="myformclass"> - <li>{{ form.sender.label }} {{ form.sender }}</li> + <li>{{ form.sender.label_tag }} {{ form.sender }}</li> <li class="helptext">{{ form.sender.help_text }}</li> {% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</ul>{% endif %} - <li>{{ form.subject.label }} {{ form.subject }}</li> + <li>{{ form.subject.label_tag }} {{ form.subject }}</li> <li class="helptext">{{ form.subject.help_text }}</li> {% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</ul>{% endif %} @@ -962,7 +962,7 @@ validation if a particular field's value is not given. ``initial`` values are ~~~~~~~~~~ The ``widget`` argument lets you specify a ``Widget`` class to use when -rendering this ``Field``. See "Widgets" below for more information. +rendering this ``Field``. See "Widgets"_ below for more information. ``help_text`` ~~~~~~~~~~~~~ @@ -1129,6 +1129,24 @@ If no ``input_formats`` argument is provided, the default input formats are:: '%m/%d/%y %H:%M', # '10/25/06 14:30' '%m/%d/%y', # '10/25/06' +``DecimalField`` +~~~~~~~~~~~~~~~~ + +**New in Django development version** + + * Default widget: ``TextInput`` + * Empty value: ``None`` + * Normalizes to: A Python ``decimal``. + * Validates that the given value is a decimal. Leading and trailing + whitespace is ignored. + +Takes four optional arguments: ``max_value``, ``min_value``, ``max_digits``, +and ``decimal_places``. The first two define the limits for the fields value. +``max_digits`` is the maximum number of digits (those before the decimal +point plus those after the decimal point, with leading zeros stripped) +permitted in the value, whilst ``decimal_places`` is the maximum number of +decimal places permitted. + ``EmailField`` ~~~~~~~~~~~~~~ @@ -1199,6 +1217,9 @@ When you use a ``FileField`` on a form, you must also remember to * Validates that the given value is an integer. Leading and trailing whitespace is allowed, as in Python's ``int()`` function. +Takes two optional arguments for validation, ``max_value`` and ``min_value``. +These control the range of values permitted in the field. + ``MultipleChoiceField`` ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1416,6 +1437,156 @@ like so:: senders = MultiEmailField() cc_myself = forms.BooleanField() +Widgets +======= + +A widget is Django's representation of a HTML input element. The widget +handles the rendering of the HTML, and the extraction of data from a GET/POST +dictionary that corresponds to the widget. + +Django provides a representation of all the basic HTML widgets, plus some +commonly used groups of widgets: + + ============================ =========================================== + Widget HTML Equivalent + ============================ =========================================== + ``TextInput`` ``<input type='text' ...`` + ``PasswordInput`` ``<input type='password' ...`` + ``HiddenInput`` ``<input type='hidden' ...`` + ``MultipleHiddenInput`` Multiple ``<input type='hidden' ...`` + instances. + ``FileInput`` ``<input type='file' ...`` + ``Textarea`` ``<textarea>...</textarea>`` + ``CheckboxInput`` ``<input type='checkbox' ...`` + ``Select`` ``<select><option ...`` + ``NullBooleanSelect`` Select widget with options 'Unknown', + 'Yes' and 'No' + ``SelectMultiple`` ``<select multiple='multiple'><option ...`` + ``RadioSelect`` ``<ul><li><input type='radio' ...`` + ``CheckboxSelectMultiple`` ``<ul><li><input type='checkbox' ...`` + ``MultiWidget`` Wrapper around multiple other widgets + ``SplitDateTimeWidget`` Wrapper around two ``TextInput`` widgets: + one for the Date, and one for the Time. + ============================ =========================================== + +Specifying widgets +------------------ + +Whenever you specify a field on a form, Django will use a default widget +that is appropriate to the type of data that is to be displayed. To find +which widget is used on which field, see the documentation for the +built-in Field classes. + +However, if you want to use a different widget for a field, you can - +just use the 'widget' argument on the field definition. For example:: + + class CommentForm(forms.Form): + name = forms.CharField() + url = forms.URLField() + comment = forms.CharField(widget=forms.Textarea) + +This would specify a form with a comment that uses a larger Textarea widget, +rather than the default TextInput widget. + +Customizing widget instances +---------------------------- + +When Django renders a widget as HTML, it only renders the bare minimum +HTML - Django doesn't add a class definition, or any other widget-specific +attributes. This means that all 'TextInput' widgets will appear the same +on your web page. + +If you want to make one widget look different to another, you need to +specify additional attributes for each widget. When you specify a +widget, you can provide a list of attributes that will be added to the +rendered HTML for the widget. + +For example, take the following simple form:: + + class CommentForm(forms.Form): + name = forms.CharField() + url = forms.URLField() + comment = forms.CharField() + +This form will include three default TextInput widgets, with default rendering - +no CSS class, no extra attributes. This means that the inputs boxes provided for +each widget will be rendered exactly the same:: + + >>> f = CommentForm(auto_id=False) + >>> f.as_table() + <tr><th>Name:</th><td><input type="text" name="name" /></td></tr> + <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> + <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr> + +On a real web page, you probably don't want every widget to look the same. You +might want a larger input element for the comment, and you might want the +'name' widget to have some special CSS class. To do this, you specify a +custom widget for your fields, and specify some attributes to use +when rendering those widgets:: + + class CommentForm(forms.Form): + name = forms.CharField( + widget=forms.TextInput(attrs={'class':'special'})) + url = forms.URLField() + comment = forms.CharField( + widget=forms.TextInput(attrs={'size':'40'})) + +Django will then include the extra attributes in the rendered output:: + + >>> f = CommentForm(auto_id=False) + >>> f.as_table() + <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr> + <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> + <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr> + +Custom Widgets +-------------- + +When you start to write a lot of forms, you will probably find that you will +reuse certain sets of widget attributes over and over again. Rather than +repeat these attribute definitions every time you need them, Django allows +you to capture those definitions as a custom widget. + +For example, if you find that you are including a lot of comment fields on forms, +you could capture the idea of a ``TextInput`` with a specific ``size`` attribute +as a custom extension to the ``TextInput`` widget:: + + class CommentWidget(forms.TextInput): + def __init__(self, *args, **kwargs): + kwargs.setdefault('attrs',{}).update({'size': '40'}) + super(forms.TextInput, self).__init__(*args, **kwargs) + +Then you can use this widget in your forms:: + + class CommentForm(forms.Form): + name = forms.CharField() + url = forms.URLField() + comment = forms.CharField(widget=CommentWidget) + +You can even customize your custom widget, in the same way as you would +any other widget. Adding a once-off class to your ``CommentWidget`` is as +simple as adding an attribute definition:: + + class CommentForm(forms.Form): + name = forms.CharField(max_length=20) + url = forms.URLField() + comment = forms.CharField( + widget=CommentWidget(attrs={'class': 'special'})) + +Django also makes it easy to specify a custom field type that uses your custom +widget. For example, you could define a customized field type for comments +by defining:: + + class CommentInput(forms.CharField): + widget = CommentWidget + +You can then use this field whenever you have a form that requires a comment:: + + class CommentForm(forms.Form): + name = forms.CharField() + url = forms.URLField() + comment = CommentInput() + Generating forms for models =========================== diff --git a/docs/request_response.txt b/docs/request_response.txt index a17a60ff17..867464226a 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -38,6 +38,16 @@ All attributes except ``session`` should be considered read-only. elif request.method == 'POST': do_something_else() +``encoding`` + **New in Django development version** + + A string representing the current encoding used to decode form submission + data (or ``None``, which means the ``DEFAULT_CHARSET`` setting is used). + You can write to this attribute to change the encoding used when accessing + the form data. Any subsequent attribute accesses (such as reading from + ``GET`` or ``POST``) will use the new ``encoding`` value. Useful if you + know the form data is not in the ``DEFAULT_CHARSET`` encoding. + ``GET`` A dictionary-like object containing all given HTTP GET parameters. See the ``QueryDict`` documentation below. @@ -342,7 +352,7 @@ hard-coded strings. If you use this technique, follow these guidelines: Methods ------- -``__init__(content='', mimetype=DEFAULT_CONTENT_TYPE)`` +``__init__(content='', mimetype=None, status=200, content_type=DEFAULT_CONTENT_TYPE)`` Instantiates an ``HttpResponse`` object with the given page content (a string) and MIME type. The ``DEFAULT_CONTENT_TYPE`` is ``'text/html'``. @@ -350,6 +360,16 @@ Methods return strings, and those strings will be joined together to form the content of the response. + ``status`` is the `HTTP Status code`_ for the response. + + **(New in Django development version)** ``content_type`` is an alias for + ``mimetype``. Historically, the parameter was only called ``mimetype``, + but since this is actually the value included in the HTTP ``Content-Type`` + header, it can also include the character set encoding, which makes it + more than just a MIME type specification. If ``mimetype`` is specifiedi + (not None), that value is used. Otherwise, ``content_type`` is used. If + neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used. + ``__setitem__(header, value)`` Sets the given header name to the given value. Both ``header`` and ``value`` should be strings. @@ -396,6 +416,8 @@ Methods ``write(content)``, ``flush()`` and ``tell()`` These methods make an ``HttpResponse`` instance a file-like object. +.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 + HttpResponse subclasses ----------------------- diff --git a/docs/sessions.txt b/docs/sessions.txt index c7124ba703..96a88c617a 100644 --- a/docs/sessions.txt +++ b/docs/sessions.txt @@ -190,6 +190,12 @@ deleted:: # request.session['foo'] instead of request.session. request.session['foo']['bar'] = 'baz' +In the last case of the above example, we can tell the session object +explicitly that it has been modified by setting the ``modified`` attribute on +the session object:: + + request.session.modified = True + To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save the session to the database on every single request. diff --git a/docs/testing.txt b/docs/testing.txt index 52285f5e8e..f189aa4578 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -22,6 +22,9 @@ it should be doing. The best part is, it's really easy. +This document is split into two primary sections. First, we explain how to +write tests with Django. Then, we explain how to run them. + .. admonition:: Note This testing framework is currently under development. It may change @@ -32,35 +35,81 @@ The best part is, it's really easy. Writing tests ============= -Tests in Django come in two forms: doctests and unit tests. +There are two primary ways to write tests with Django, corresponding to the +two test frameworks that ship in the Python standard library. The two +frameworks are: + + * **Doctests** -- tests that are embedded in your functions' docstrings and + are written in a way that emulates a session of the Python interactive + interpreter. For example:: + + def my_func(a_list, idx): + """ + >>> a = ['larry', 'curly', 'moe'] + >>> my_func(a, 0) + 'larry' + >>> my_func(a, 1) + 'curly' + """ + return a_list[idx] + + * **Unit tests** -- tests that are expressed as methods on a Python class + that subclasses ``unittest.TestCase``. For example:: + + import unittest + + class MyFuncTestCase(unittest.TestCase) + def testBasic(self): + a = ['larry', 'curly', 'moe'] + self.assertEquals(my_func(a, 0), 'larry') + self.assertEquals(my_func(a, 1), 'curly') + +You can choose the test framework you like, depending on which syntax you +prefer, or you can mix and match, using one framework for some of your code and +the other framework for other code. You can also use any *other* Python test +frameworks, as we'll explain in a bit. Writing doctests ---------------- -Doctests use Python's standard doctest_ module, which searches for tests in -your docstrings. Django's test runner looks for doctests in your ``models.py`` -file, and executes any that it finds. Django will also search for a file -called ``tests.py`` in the application directory (i.e., the directory that -holds ``models.py``). If a ``tests.py`` is found, it will also be searched -for doctests. +Doctests use Python's standard doctest_ module, which searches your docstrings +for statements that resemble a session of the Python interactive interpreter. +A full explanation of how doctest works is out of the scope of this document; +read Python's official documentation for the details. .. admonition:: What's a **docstring**? - A good explanation of docstrings (and some guidlines for using them + A good explanation of docstrings (and some guidelines for using them effectively) can be found in :PEP:`257`: A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the ``__doc__`` special attribute of that object. - Since tests often make great documentation, doctest lets you put your - tests directly in your docstrings. + For example, this function has a docstring that describes what it does:: -You can put doctest strings on any object in your ``models.py``, but it's -common practice to put application-level doctests in the module docstring, and -model-level doctests in the docstring for each model. + def add_two(num): + "Adds 2 to the given number and returns the result." + return num + 2 -For example:: + Because tests often make great documentation, putting tests directly in + your docstrings is an effective way to document *and* test your code. + +For a given Django application, the test runner looks for doctests in two +places: + + * The ``models.py`` file. You can define module-level doctests and/or a + doctest for individual models. It's common practice to put + application-level doctests in the module docstring and model-level + doctests in the model docstrings. + + * A file called ``tests.py`` in the application directory -- i.e., the + directory that holds ``models.py``. This file is a hook for any and all + doctests you want to write that aren't necessarily related to models. + +Here is an example model doctest:: + + # models.py from django.db import models @@ -78,38 +127,53 @@ For example:: >>> cat.speak() 'The cat says "meow"' """ - name = models.CharField(max_length=20) sound = models.CharField(max_length=20) def speak(self): return 'The %s says "%s"' % (self.name, self.sound) -When you `run your tests`_, the test utility will find this docstring, notice +When you `run your tests`_, the test runner will find this docstring, notice that portions of it look like an interactive Python session, and execute those lines while checking that the results match. +In the case of model tests, note that the test runner takes care of creating +its own test database. That is, any test that accesses a database -- by +creating and saving model instances, for example -- will not affect your +production database. Each doctest begins with a "blank slate" -- a fresh +database containing an empty table for each model. (See the section on +fixtures, below, for more on this.) + For more details about how doctest works, see the `standard library documentation for doctest`_ .. _doctest: http://docs.python.org/lib/module-doctest.html .. _standard library documentation for doctest: doctest_ -Writing unittests ------------------ +Writing unit tests +------------------ Like doctests, Django's unit tests use a standard library module: unittest_. -As with doctests, Django's test runner looks for any unit test cases defined -in ``models.py``, or in a ``tests.py`` file stored in the application -directory. +This module uses a different way of defining tests, taking a class-based +approach. + +As with doctests, for a given Django application, the test runner looks for +unit tests in two places: + + * The ``models.py`` file. The test runner looks for any subclass of + ``unittest.TestCase`` in this module. + + * A file called ``tests.py`` in the application directory -- i.e., the + directory that holds ``models.py``. Again, the test runner looks for any + subclass of ``unittest.TestCase`` in this module. -An equivalent unittest test case for the above example would look like:: +This example ``unittest.TestCase`` subclass is equivalent to the example given +in the doctest section above:: import unittest from myapp.models import Animal class AnimalTestCase(unittest.TestCase): - def setUp(self): self.lion = Animal.objects.create(name="lion", sound="roar") self.cat = Animal.objects.create(name="cat", sound="meow") @@ -123,13 +187,12 @@ to find all the test cases (that is, subclasses of ``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a test suite out of those test cases, and run that suite. -**New in Django development version** - -However, if you define a method called ``suite()`` in either ``models.py`` or -``tests.py``, that method will be used to construct the test suite for that -module. This follows the `suggested organization`_ for unit tests. See the -Python documentation for more details on how to construct a complex test -suite. +In the Django development version, there is a second way to define the test +suite for a module: if you define a function called ``suite()`` in either +``models.py`` or ``tests.py``, the Django test runner will use that function +to construct the test suite for that module. This follows the +`suggested organization`_ for unit tests. See the Python documentation for +more details on how to construct a complex test suite. For more details about ``unittest``, see the `standard library unittest documentation`_. @@ -142,304 +205,552 @@ documentation`_. Which should I use? ------------------- -Choosing a test framework is often contentious, so Django simply supports -both of the standard Python test frameworks. Choosing one is up to each -developer's personal tastes; each is supported equally. Since each test -system has different benefits, the best approach is probably to use both -together, picking the test system to match the type of tests you need to -write. +Because Django supports both of the standard Python test frameworks, it's up to +you and your tastes to decide which one to use. You can even decide to use +*both*. -For developers new to testing, however, this choice can seem -confusing, so here are a few key differences to help you decide whether -doctests or unit tests are right for you. +For developers new to testing, however, this choice can seem confusing. Here, +then, are a few key differences to help you decide which approach is right for +you: -If you've been using Python for a while, ``doctest`` will probably feel more -"pythonic". It's designed to make writing tests as easy as possible, so -there's no overhead of writing classes or methods; you simply put tests in -docstrings. This gives the added advantage of giving your modules automatic -documentation -- well-written doctests can kill both the documentation and the -testing bird with a single stone. + * If you've been using Python for a while, ``doctest`` will probably feel + more "pythonic". It's designed to make writing tests as easy as possible, + so it requires no overhead of writing classes or methods. You simply put + tests in docstrings. This has the added advantage of serving as + documentation (and correct documentation, at that!). -For developers just getting started with testing, using doctests will probably -get you started faster. + If you're just getting started with testing, using doctests will probably + get you started faster. -The ``unittest`` framework will probably feel very familiar to developers -coming from Java. Since ``unittest`` is inspired by Java's JUnit, if -you've used testing frameworks in other languages that similarly were -inspired by JUnit, ``unittest`` should also feel pretty familiar. + * The ``unittest`` framework will probably feel very familiar to developers + coming from Java. ``unittest`` is inspired by Java's JUnit, so you'll + feel at home with this method if you've used JUnit or any test framework + inspired by JUnit. -Since ``unittest`` is organized around classes and methods, if you need -to write a bunch of tests that all share similar code, you can easily use -subclass to abstract common tasks; this makes test code shorter and cleaner. -There's also support for explicit setup and/or cleanup routines, which give -you a high level of control over the environment your test cases run in. + * If you need to write a bunch of tests that share similar code, then + you'll appreciate the ``unittest`` framework's organization around + classes and methods. This makes it easy to abstract common tasks into + common methods. The framework also supports explicit setup and/or cleanup + routines, which give you a high level of control over the environment + in which your test cases are run. Again, remember that you can use both systems side-by-side (even in the same -app). In the end, most projects will eventually end up using both; each shines +app). In the end, most projects will eventually end up using both. Each shines in different circumstances. -Testing Tools +Running tests ============= -To assist in testing various features of your application, Django provides -tools that can be used to establish tests and test conditions. +Once you've written tests, run them using your project's ``manage.py`` utility:: + + $ ./manage.py test + +By default, this will run every test in every application in ``INSTALLED_APPS``. +If you only want to run tests for a particular application, add the +application name to the command line. For example, if your ``INSTALLED_APPS`` +contains ``'myproject.polls'`` and ``'myproject.animals'``, you can run the +``myproject.animals`` unit tests alone with this command:: + + # ./manage.py test animals + +Note that we used ``animals``, not ``myproject.animals``. -* `Test Client`_ -* `TestCase`_ -* `E-mail services`_ +**New in Django development version:** If you use unit tests, as opposed to +doctests, you can be even *more* specific in choosing which tests to execute. +To run a single test case in an application (for example, the +``AnimalTestCase`` described in the "Writing unit tests" section), add the +name of the test case to the label on the command line:: + + $ ./manage.py test animals.AnimalTestCase + +And it gets even more granular than that! To run a *single* test method inside +a test case, add the name of the test method to the label:: + + $ ./manage.py test animals.AnimalTestCase.testFluffyAnimals + +Understanding the test output +----------------------------- + +When you run your tests, you'll see a number of messages as the test runner +prepares itself:: + + Creating test database... + Creating table myapp_animal + Creating table myapp_mineral + Loading 'initial_data' fixtures... + No fixtures found. + +This tells you that the test runner is creating a test database -- a blank, +from-scratch database that it will use for any tests that happen to require a +database (namely, model tests). + +Don't worry -- the test runner will not touch your "real" (production) +database. It creates a separate database purely for the tests. This test +database gets its name by prepending ``test_`` to the value of the +``DATABASE_NAME`` setting. If you want to use a different name, specify the +``TEST_DATABASE_NAME`` setting. + +Aside from using a separate database, the test runner will otherwise use all of +the same database settings you have in your settings file: ``DATABASE_ENGINE``, +``DATABASE_USER``, ``DATABASE_HOST``, etc. The test database is created by the +user specified by ``DATABASE_USER``, so you'll need to make sure that the given +user account has sufficient privileges to create a new database on the system. + +**New in Django development version:** For fine-grained control over the +character encoding of your test database, use the ``TEST_DATABASE_CHARSET`` +setting. If you're using MySQL, you can also use the ``TEST_DATABASE_COLLATION`` +setting to control the particular collation used by the test database. See the +settings_ documentation for details of these advanced settings. -Test Client ------------ +.. _settings: ../settings/ -The Test Client is a simple dummy browser. It allows you to simulate -GET and POST requests on a URL, and observe the response that is received. -This allows you to test that the correct view is executed for a given URL, -and that the view constructs the correct response. +Once the test database has been created, Django will run your tests. +If everything goes well, you'll see something like this:: -As the response is generated, the Test Client gathers details on the -Template and Context objects that were used to generate the response. These -Templates and Contexts are then provided as part of the response, and can be -used as test conditions. + ---------------------------------------------------------------------- + Ran 22 tests in 0.221s -.. admonition:: Test Client vs Browser Automation? + OK - The Test Client is not intended as a replacement for Twill_, Selenium_, - or other browser automation frameworks - it is intended to allow - testing of the contexts and templates produced by a view, - rather than the HTML rendered to the end-user. +If there are test failures, however, you'll see full details about which tests +failed:: - A comprehensive test suite should use a combination of both: Test Client - tests to establish that the correct view is being called and that - the view is collecting the correct context data, and Browser Automation - tests to check that user interface behaves as expected. + ====================================================================== + FAIL: Doctest: ellington.core.throttle.models + ---------------------------------------------------------------------- + Traceback (most recent call last): + File "/dev/django/test/doctest.py", line 2153, in runTest + raise self.failureException(self.format_failure(new.getvalue())) + AssertionError: Failed doctest test for myapp.models + File "/dev/myapp/models.py", line 0, in models + + ---------------------------------------------------------------------- + File "/dev/myapp/models.py", line 14, in myapp.models + Failed example: + throttle.check("actor A", "action one", limit=2, hours=1) + Expected: + True + Got: + False + + ---------------------------------------------------------------------- + Ran 2 tests in 0.048s + + FAILED (failures=1) + +A full explanation of this error output is beyond the scope of this document, +but it's pretty intuitive. You can consult the documentation of Python's +``unittest`` library for details. + +Note that the return code for the test-runner script is the total number of +failed and erroneous tests. If all the tests pass, the return code is 0. This +feature is useful if you're using the test-runner script in a shell script and +need to test for success or failure at that level. + +Regardless of whether the tests pass or fail, the test database is destroyed when +all the tests have been executed. + +Testing tools +============= + +Django provides a small set of tools that come in handy when writing tests. + +The test client +--------------- + +The test client is a Python class that acts as a dummy Web browser, allowing +you to test your views and interact with your Django-powered application +programatically. + +Some of the things you can do with the test client are: + + * Simulate GET and POST requests on a URL and observe the response -- + everything from low-level HTTP (result headers and status codes) to + page content. + + * Test that the correct view is executed for a given URL. + + * Test that a given request is rendered by a given Django template, with + a template context that contains certain values. + +Note that the test client is not intended to be a replacement for Twill_, +Selenium_, or other "in-browser" frameworks. Django's test client has +a different focus. In short: + + * Use Django's test client to establish that the correct view is being + called and that the view is collecting the correct context data. + + * Use in-browser frameworks such as Twill and Selenium to test *rendered* + HTML and the *behavior* of Web pages, namely JavaScript functionality. + +A comprehensive test suite should use a combination of both test types. .. _Twill: http://twill.idyll.org/ .. _Selenium: http://www.openqa.org/selenium/ +Overview and a quick example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the test client, instantiate ``django.test.client.Client`` and retrieve +Web pages:: + + >>> from django.test.client import Client + >>> c = Client() + >>> response = c.post('/login/', {'username': 'john', 'password': 'smith'}) + >>> response.status_code + 200 + >>> response = c.get('/customer/details/') + >>> response.content + '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...' + +As this example suggests, you can instantiate ``Client`` from within a session +of the Python interactive interpreter. + +Note a few important things about how the test client works: + + * The test client does *not* require the Web server to be running. In fact, + it will run just fine with no Web server running at all! That's because + it avoids the overhead of HTTP and deals directly with the Django + framework. This helps make the unit tests run quickly. + + * When retrieving pages, remember to specify the *path* of the URL, not the + whole domain. For example, this is correct:: + + >>> c.get('/login/') + + This is incorrect:: + + >>> c.get('http://www.example.com/login/') + + The test client is not capable of retrieving Web pages that are not + powered by your Django project. If you need to retrieve other Web pages, + use a Python standard library module such as urllib_ or urllib2_. + + * To resolve URLs, the test client uses whatever URLconf is pointed-to by + your ``ROOT_URLCONF`` setting. + + * Although the above example would work in the Python interactive + interpreter, some of the test client's functionality, notably the + template-related functionality, is only available *while tests are running*. + + The reason for this is that Django's test runner performs a bit of black + magic in order to determine which template was loaded by a given view. + This black magic (essentially a patching of Django's template system in + memory) only happens during test running. + +.. _urllib: http://docs.python.org/lib/module-urllib.html +.. _urllib2: http://docs.python.org/lib/module-urllib2.html + Making requests ~~~~~~~~~~~~~~~ -Creating an instance of ``Client`` (``django.test.client.Client``) requires -no arguments at time of construction. Once constructed, the following methods -can be invoked on the ``Client`` instance. +Use the ``django.test.client.Client`` class to make requests. It requires no +arguments at time of construction:: + + >>> c = Client() + +Once you have a ``Client`` instance, you can call any of the following methods: ``get(path, data={})`` - Make a GET request on the provided ``path``. The key-value pairs in the - data dictionary will be used to create a GET data payload. For example:: + Makes a GET request on the provided ``path`` and returns a ``Response`` + object, which is documented below. + + The key-value pairs in the ``data`` dictionary are used to create a GET + data payload. For example:: - c = Client() - c.get('/customers/details/', {'name':'fred', 'age':7}) + >>> c = Client() + >>> c.get('/customers/details/', {'name': 'fred', 'age': 7}) - will result in the evaluation of a GET request equivalent to:: + ...will result in the evaluation of a GET request equivalent to:: - http://yoursite.com/customers/details/?name=fred&age=7 + /customers/details/?name=fred&age=7 ``post(path, data={}, content_type=MULTIPART_CONTENT)`` - Make a POST request on the provided ``path``. If you provide a content type - (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be - sent as-is in the POST request, using the content type in the HTTP - ``Content-Type`` header. + Makes a POST request on the provided ``path`` and returns a ``Response`` + object, which is documented below. + + The key-value pairs in the ``data`` dictionary are used to submit POST + data. For example:: + + >>> c = Client() + >>> c.get('/login/', {'name': 'fred', 'passwd': 'secret'}) + + ...will result in the evaluation of a POST request to this URL:: + + /login/ - If you do not provide a value for ``content_type``, the values in + ...with this POST data:: + + name=fred&passwd=secret + + If you provide ``content_type`` (e.g., ``text/xml`` for an XML payload), + the contents of ``data`` will be sent as-is in the POST request, using + ``content_type`` in the HTTP ``Content-Type`` header. + + If you don't provide a value for ``content_type``, the values in ``data`` will be transmitted with a content type of ``multipart/form-data``. - The key-value pairs in the data dictionary will be encoded as a multipart - message and used to create the POST data payload. + In this case, the key-value pairs in ``data`` will be encoded as a + multipart message and used to create the POST data payload. + + To submit multiple values for a given key -- for example, to specify + the selections for a ``<select multiple>`` -- provide the values as a + list or tuple for the required key. For example, this value of ``data`` + would submit three selected values for the field named ``choices``:: - To submit multiple values for a given key (for example, to specify - the selections for a multiple selection list), provide the values as a - list or tuple for the required key. For example, a data dictionary of - ``{'choices': ('a','b','d')}`` would submit three selected rows for the - field named ``choices``. + {'choices': ('a', 'b', 'd')} - Submitting files is a special case. To POST a file, you need only - provide the file field name as a key, and a file handle to the file you wish to - upload as a value. The Test Client will populate the two POST fields (i.e., - ``field`` and ``field_file``) required by Django's FileField. For example:: + Submitting files is a special case. To POST a file, you need only provide + the file field name as a key, and a file handle to the file you wish to + upload as a value. For example:: - c = Client() - f = open('wishlist.doc') - c.post('/customers/wishes/', {'name':'fred', 'attachment':f}) - f.close() + >>> c = Client() + >>> f = open('wishlist.doc') + >>> c.post('/customers/wishes/', {'name': 'fred', 'attachment': f}) + >>> f.close() - will result in the evaluation of a POST request on ``/customers/wishes/``, - with a POST dictionary that contains ``name``, ``attachment`` (containing the - file name), and ``attachment_file`` (containing the file data). Note that you - need to manually close the file after it has been provided to the POST. + (The name ``attachment`` here is not relevant; use whatever name your + file-processing code expects.) + + Note that you should manually close the file after it has been provided to + ``post()``. ``login(**credentials)`` **New in Django development version** - On a production site, it is likely that some views will be protected from - anonymous access through the use of the @login_required decorator, or some - other login checking mechanism. The ``login()`` method can be used to - simulate the effect of a user logging into the site. As a result of calling - this method, the Client will have all the cookies and session data required - to pass any login-based tests that may form part of a view. + If your site uses Django's `authentication system`_ and you deal with + logging in users, you can use the test client's ``login()`` method to + simulate the effect of a user logging into the site. + + After you call this method, the test client will have all the cookies and + session data required to pass any login-based tests that may form part of + a view. - In most cases, the ``credentials`` required by this method are the username - and password of the user that wants to log in, provided as keyword - arguments:: + The format of the ``credentials`` argument depends on which + `authentication backend`_ you're using (which is configured by your + ``AUTHENTICATION_BACKENDS`` setting). If you're using the standard + authentication backend provided by Django (``ModelBackend``), + ``credentials`` should be the user's username and password, provided as + keyword arguments:: - c = Client() - c.login(username='fred', password='secret') - # Now you can access a login protected view + >>> c = Client() + >>> c.login(username='fred', password='secret') + >>> # Now you can access a view that's only available to logged-in users. - If you are using a different authentication backend, this method may - require different credentials. + If you're using a different authentication backend, this method may require + different credentials. It requires whichever credentials are required by + your backend's ``authenticate()`` method. ``login()`` returns ``True`` if it the credentials were accepted and login was successful. - Note that since the test suite will be executed using the test database, - which contains no users by default. As a result, logins that are valid - on your production site will not work under test conditions. You will - need to create users as part of the test suite (either manually, or - using a test fixture). + Finally, you'll need to remember to create user accounts before you can use + this method. As we explained above, the test runner is executed using a + test database, which contains no users by default. As a result, user + accounts that are valid on your production site will not work under test + conditions. You'll need to create users as part of the test suite -- either + manually (using the Django model API) or with a test fixture. + +``logout()`` + **New in Django development version** + + If your site uses Django's `authentication system`_, the ``logout()`` + method can be used to simulate the effect of a user logging out of + your site. + + After you call this method, the test client will have all the cookies and + session data cleared to defaults. Subsequent requests will appear to + come from an AnonymousUser. + +.. _authentication system: ../authentication/ +.. _authentication backend: ../authentication/#other-authentication-sources -Testing Responses +Testing responses ~~~~~~~~~~~~~~~~~ -The ``get()`` and ``post()`` methods both return a Response object. This -Response object has the following properties that can be used for testing -purposes: +The ``get()`` and ``post()`` methods both return a ``Response`` object. This +``Response`` object is *not* the same as the ``HttpResponse`` object returned +Django views; this object is simpler and has some additional data useful for +tests. + +Specifically, a ``Response`` object has the following attributes: =============== ========================================================== - Property Description + Attribute Description =============== ========================================================== - ``status_code`` The HTTP status of the response. See RFC2616_ for a - full list of HTTP status codes. + ``status_code`` The HTTP status of the response, as an integer. See + RFC2616_ for a full list of HTTP status codes. - ``content`` The body of the response. This is the final page - content as rendered by the view, or any error message - (such as the URL for a 302 redirect). + ``content`` The body of the response, as a string. This is the final + page content as rendered by the view, or any error + message (such as the URL for a 302 redirect). - ``template`` The Template instance that was used to render the final - content. Testing ``template.name`` can be particularly - useful; if the template was loaded from a file, - ``template.name`` will be the file name that was loaded. + ``template`` The ``Template`` instance that was used to render the + final content. Use ``template.name`` to get the + template's file name, if the template was loaded from a + file. (The name is a string such as + ``'admin/index.html'``.) - If multiple templates were rendered, (e.g., if one - template includes another template),``template`` will - be a list of Template objects, in the order in which - they were rendered. + If the rendered page used multiple templates -- e.g., + using `template inheritance`_ -- then ``template`` will + be a list of ``Template`` instances, in the order in + which they were rendered. - ``context`` The Context that was used to render the template that - produced the response content. + ``context`` The template ``Context`` instance that was used to render + the template that produced the response content. - As with ``template``, if multiple templates were rendered - ``context`` will be a list of Context objects, stored in - the order in which they were rendered. + As with ``template``, if the rendered page used multiple + templates, then ``context`` will be a list of ``Context`` + objects, in the order in which they were rendered. =============== ========================================================== .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html +.. _template inheritance: ../templates/#template-inheritance Exceptions ~~~~~~~~~~ -If you point the Test Client at a view that raises an exception, that exception +If you point the test client at a view that raises an exception, that exception will be visible in the test case. You can then use a standard ``try...catch`` -block, or ``unittest.TestCase.assertRaises()`` to test for exceptions. +block or ``unittest.TestCase.assertRaises()`` to test for exceptions. -The only exceptions that are not visible in a Test Case are ``Http404``, +The only exceptions that are not visible to the test client are ``Http404``, ``PermissionDenied`` and ``SystemExit``. Django catches these exceptions -internally and converts them into the appropriate HTTP responses codes. +internally and converts them into the appropriate HTTP response codes. In these +cases, you can check ``response.status_code`` in your test. Persistent state ~~~~~~~~~~~~~~~~ -The Test Client is stateful; if a cookie is returned as part of a response, -that cookie is provided as part of the next request issued by that Client -instance. Expiry policies for these cookies are not followed; if you want -a cookie to expire, either delete it manually or create a new Client -instance (which will effectively delete all cookies). +The test client is stateful. If a response returns a cookie, then that cookie +will be stored in the test client and sent with all subsequent ``get()`` and +``post()`` requests. + +Expiration policies for these cookies are not followed. If you want a cookie +to expire, either delete it manually or create a new ``Client`` instance (which +will effectively delete all cookies). -There are two properties of the Test Client which are used to store persistent -state information. If necessary, these properties can be interrogated as -part of a test condition. +A test client has two attributes that store persistent state information. You +can access these properties as part of a test condition. =============== ========================================================== - Property Description + Attribute Description =============== ========================================================== ``cookies`` A Python ``SimpleCookie`` object, containing the current - values of all the client cookies. + values of all the client cookies. See the + `Cookie module documentation`_ for more. ``session`` A dictionary-like object containing session information. See the `session documentation`_ for full details. =============== ========================================================== -.. _`session documentation`: ../sessions/ +.. _Cookie module documentation: http://docs.python.org/lib/module-Cookie.html +.. _session documentation: ../sessions/ Example ~~~~~~~ -The following is a simple unit test using the Test Client:: +The following is a simple unit test using the test client:: import unittest from django.test.client import Client class SimpleTest(unittest.TestCase): def setUp(self): - # Every test needs a client + # Every test needs a client. self.client = Client() + def test_details(self): - # Issue a GET request + # Issue a GET request. response = self.client.get('/customer/details/') - # Check that the respose is 200 OK + # Check that the respose is 200 OK. self.failUnlessEqual(response.status_code, 200) - # Check that the rendered context contains 5 customers + + # Check that the rendered context contains 5 customers. self.failUnlessEqual(len(response.context['customers']), 5) TestCase -------- -Normal python unit tests extend a base class of ``unittest.testCase``. -Django provides an extension of this base class - ``django.test.TestCase`` -- that provides some additional capabilities that can be useful for -testing web sites. +Normal Python unit test classes extend a base class of ``unittest.TestCase``. +Django provides an extension of this base class -- ``django.test.TestCase`` +-- that provides some additional capabilities that can be useful for +testing Web sites. -Moving from a normal unittest TestCase to a Django TestCase is easy - just -change the base class of your test from ``unittest.TestCase`` to -``django.test.TestCase``. All of the standard Python unit test facilities -will continue to be available, but they will be augmented with some useful -extra facilities. +Converting a normal ``unittest.TestCase`` to a Django ``TestCase`` is easy: +just change the base class of your test from ``unittest.TestCase`` to +``django.test.TestCase``. All of the standard Python unit test functionality +will continue to be available, but it will be augmented with some useful +additions. -Default Test Client +Default test client ~~~~~~~~~~~~~~~~~~~ + **New in Django development version** Every test case in a ``django.test.TestCase`` instance has access to an -instance of a Django `Test Client`_. This Client can be accessed as -``self.client``. This client is recreated for each test. +instance of a Django test client. This client can be accessed as +``self.client``. This client is recreated for each test, so you don't have to +worry about state (such as cookies) carrying over from one test to another. + +This means, instead of instantiating a ``Client`` in each test:: + + import unittest + from django.test.client import Client + + class SimpleTest(unittest.TestCase): + def test_details(self): + client = Client() + response = client.get('/customer/details/') + self.failUnlessEqual(response.status_code, 200) + + def test_index(self): + client = Client() + response = client.get('/customer/index/') + self.failUnlessEqual(response.status_code, 200) + +...you can just refer to ``self.client``, like so:: + + from django.test import TestCase + from django.test.client import Client + + class SimpleTest(TestCase): + def test_details(self): + response = self.client.get('/customer/details/') + self.failUnlessEqual(response.status_code, 200) + + def test_index(self): + response = self.client.get('/customer/index/') + self.failUnlessEqual(response.status_code, 200) Fixture loading ~~~~~~~~~~~~~~~ -A test case for a database-backed website isn't much use if there isn't any +A test case for a database-backed Web site isn't much use if there isn't any data in the database. To make it easy to put test data into the database, -Django provides a fixtures framework. +Django's custom ``TestCase`` class provides a way of loading **fixtures**. + +A fixture is a collection of data that Django knows how to import into a +database. For example, if your site has user accounts, you might set up a +fixture of fake user accounts in order to populate your database during tests. -A *Fixture* is a collection of files that contain the serialized contents of -the database. Each fixture has a unique name; however, the files that -comprise the fixture can be distributed over multiple directories, in -multiple applications. +The most straightforward way of creating a fixture is to use the +``manage.py dumpdata`` command. This assumes you already have some data in +your database. See the `dumpdata documentation`_ for more details. .. note:: - If you have synchronized a Django project, you have already experienced - the use of one fixture -- the ``initial_data`` fixture. Every time you - synchronize the database, Django installs the ``initial_data`` fixture. - This provides a mechanism to populate a new database with any initial - data (such as a default set of categories). Fixtures with other names - can be installed manually using ``django-admin.py loaddata``. + If you've ever run ``manage.py syncdb``, you've already used a fixture + without even knowing it! When you call ``syncdb`` in the database for + the first time, Django installs a fixture called ``initial_data``. + This gives you a way of populating a new database with any initial data, + such as a default set of categories. -However, for the purposes of unit testing, each test must be able to -guarantee the contents of the database at the start of each and every -test. + Fixtures with other names can always be installed manually using the + ``manage.py loaddata`` command. -To define a fixture for a test, all you need to do is add a class -attribute to your test describing the fixtures you want the test to use. -For example, the test case from `Writing unittests`_ would -look like:: +Once you've created a fixture and placed it somewhere in your Django project, +you can use it in your unit tests by specifying a ``fixtures`` class attribute +on your ``django.test.TestCase`` subclass:: from django.test import TestCase from myapp.models import Animal @@ -448,260 +759,205 @@ look like:: fixtures = ['mammals.json', 'birds'] def setUp(self): - # test definitions as before + # Test definitions as before. def testFluffyAnimals(self): - # A test that uses the fixtures + # A test that uses the fixtures. -At the start of each test case, before ``setUp()`` is run, Django will -flush the database, returning the database the state it was in directly -after ``syncdb`` was called. Then, all the named fixtures are installed. -In this example, any JSON fixture called ``mammals``, and any fixture -named ``birds`` will be installed. See the documentation on -`loading fixtures`_ for more details on defining and installing fixtures. +Here's specifically what will happen: -.. _`loading fixtures`: ../django-admin/#loaddata-fixture-fixture + * At the start of each test case, before ``setUp()`` is run, Django will + flush the database, returning the database to the state it was in + directly after ``syncdb`` was called. + + * Then, all the named fixtures are installed. In this example, Django will + install any JSON fixture named ``mammals``, followed by any fixture named + ``birds``. See the `loaddata documentation`_ for more details on defining + and installing fixtures. This flush/load procedure is repeated for each test in the test case, so you can be certain that the outcome of a test will not be affected by -another test, or the order of test execution. +another test, or by the order of test execution. + +.. _dumpdata documentation: ../django-admin/#dumpdata-appname-appname +.. _loaddata documentation: ../django-admin/#loaddata-fixture-fixture Emptying the test outbox ~~~~~~~~~~~~~~~~~~~~~~~~ + **New in Django development version** -At the start of each test case, in addition to installing fixtures, -Django clears the contents of the test e-mail outbox. +If you use Django's custom ``TestCase`` class, the test runner will clear the +contents of the test e-mail outbox at the start of each test case. For more detail on e-mail services during tests, see `E-mail services`_. Assertions ~~~~~~~~~~ + **New in Django development version** -Normal Python unit tests have a wide range of assertions, such as -``assertTrue`` and ``assertEquals`` that can be used to validate behavior. -``django.TestCase`` adds to these, providing some assertions -that can be useful in testing the behavior of web sites. +As Python's normal ``unittest.TestCase`` class implements assertion +methods such as ``assertTrue`` and ``assertEquals``, Django's custom +``TestCase`` class provides a number of custom assertion methods that are +useful for testing Web applications: ``assertContains(response, text, count=None, status_code=200)`` - Assert that a response indicates that a page could be retrieved and - produced the nominated status code, and that ``text`` in the content - of the response. If ``count`` is provided, ``text`` must occur exactly - ``count`` times in the response. + Asserts that a ``Response`` instance produced the given ``status_code`` and + that ``text`` appears in the content of the response. If ``count`` is + provided, ``text`` must occur exactly ``count`` times in the response. ``assertFormError(response, form, field, errors)`` - Assert that a field on a form raised the provided list of errors when + Asserts that a field on a form raises the provided list of errors when rendered on the form. - ``form`` is the name the form object was given in the template context. + ``form`` is the name the ``Form`` instance was given in the template + context. Note that this works only for ``newforms.Form`` instances, not + ``oldforms.Form`` instances. ``field`` is the name of the field on the form to check. If ``field`` - has a value of ``None``, non-field errors will be checked. + has a value of ``None``, non-field errors (errors you can access via + ``form.non_field_errors()``) will be checked. ``errors`` is an error string, or a list of error strings, that are expected as a result of form validation. ``assertTemplateNotUsed(response, template_name)`` - Assert that the template with the given name was *not* used in rendering + Asserts that the template with the given name was *not* used in rendering the response. ``assertRedirects(response, expected_path, status_code=302, target_status_code=200)`` - Assert that the response received produced the nominated status code, - redirects the browser to the provided path, and that retrieving the provided - path yields a response with the target status code. + Asserts that the response return a ``status_code`` redirect status, + it redirected to ``expected_path`` and the subsequent page was received with + ``target_status_code``. ``assertTemplateUsed(response, template_name)`` - Assert that the template with the given name was used in rendering the + Asserts that the template with the given name was used in rendering the response. + The name is a string such as ``'admin/index.html'``. + E-mail services --------------- **New in Django development version** -If your view makes use of the `Django e-mail services`_, you don't really -want e-mail to be sent every time you run a test using that view. +If any of your Django views send e-mail using `Django's e-mail functionality`_, +you probably don't want to send e-mail each time you run a test using that +view. For this reason, Django's test runner automatically redirects all +Django-sent e-mail to a dummy outbox. This lets you test every aspect of +sending e-mail -- from the number of messages sent to the contents of each +message -- without actually sending the messages. -When the Django test framework is initialized, it transparently replaces the -normal `SMTPConnection`_ class with a dummy implementation that redirects all -e-mail to a dummy outbox. This outbox, stored as ``django.core.mail.outbox``, -is a simple list of all `EmailMessage`_ instances that have been sent. -For example, during test conditions, it would be possible to run the following -code:: +The test runner accomplishes this by transparently replacing the normal +`SMTPConnection`_ class with a different version. (Don't worry -- this has no +effect on any other e-mail senders outside of Django, such as your machine's +mail server, if you're running one.) + +During test running, each outgoing e-mail is saved in +``django.core.mail.outbox``. This is a simple list of all `EmailMessage`_ +instances that have been sent. It does not exist under normal execution +conditions, i.e., when you're not running unit tests. The outbox is created +during test setup, along with the dummy `SMTPConnection`_. When the test +framework is torn down, the standard `SMTPConnection`_ class is restored, and +the test outbox is destroyed. + +Here's an example test that examines ``django.core.mail.outbox`` for length +and contents:: from django.core import mail + from django.test import TestCase - # Send message - mail.send_mail('Subject here', 'Here is the message.', 'from@example.com', - ['to@example.com'], fail_silently=False) + class EmailTest(TestCase): + def test_send_email(self): + # Send message. + mail.send_mail('Subject here', 'Here is the message.', + 'from@example.com', ['to@example.com'], + fail_silently=False) - # One message has been sent - self.assertEqual(len(mail.outbox), 1) - # Subject of first message is correct - self.assertEqual(mail.outbox[0].subject, 'Subject here') + # Test that one message has been sent. + self.assertEqual(len(mail.outbox), 1) -The ``mail.outbox`` object does not exist under normal execution conditions. -The outbox is created during test setup, along with the dummy `SMTPConnection`_. -When the test framework is torn down, the standard `SMTPConnection`_ class -is restored, and the test outbox is destroyed. + # Verify that the subject of the first message is correct. + self.assertEqual(mail.outbox[0].subject, 'Subject here') As noted `previously`_, the test outbox is emptied at the start of every -test in a Django TestCase. To empty the outbox manually, assign the empty list -to mail.outbox:: +test in a Django ``TestCase``. To empty the outbox manually, assign the +empty list to ``mail.outbox``:: from django.core import mail # Empty the test outbox mail.outbox = [] -.. _`Django e-mail services`: ../email/ +.. _`Django's e-mail functionality`: ../email/ .. _`SMTPConnection`: ../email/#the-emailmessage-and-smtpconnection-classes .. _`EmailMessage`: ../email/#the-emailmessage-and-smtpconnection-classes .. _`previously`: #emptying-the-test-outbox -Running tests -============= - -Run your tests using your project's ``manage.py`` utility:: - - $ ./manage.py test - -If you only want to run tests for a particular application, add the -application name to the command line. For example, if your -``INSTALLED_APPS`` contains ``myproject.polls`` and ``myproject.animals``, -but you only want to run the animals unit tests, run:: - - $ ./manage.py test animals +Using different testing frameworks +================================== -**New in Django development version:** If you use unit tests, you can be more -specific in the tests that are executed. To run a single test case in an -application (for example, the AnimalTestCase described previously), add the -name of the test case to the label on the command line:: - - $ ./manage.py test animals.AnimalTestCase +Clearly, ``doctest`` and ``unittest`` are not the only Python testing +frameworks. While Django doesn't provide explicit support for alternative +frameworks, it does provide a way to invoke tests constructed for an +alternative framework as if they were normal Django tests. -**New in Django development version:** To run a single test method inside a -test case, add the name of the test method to the label:: - - $ ./manage.py test animals.AnimalTestCase.testFluffyAnimals - -When you run your tests, you'll see a bunch of text flow by as the test -database is created and models are initialized. This test database is -created from scratch every time you run your tests. - -By default, the test database gets its name by prepending ``test_`` to -the database name specified by the ``DATABASE_NAME`` setting; all other -database settings will the same as they would be for the project normally. -If you wish to use a name other than the default for the test database, -you can use the ``TEST_DATABASE_NAME`` setting to provide a name. - -**New in Django development version:** For fine-grained control over the -character encoding of your database, use the ``TEST_DATABASE_CHARSET`` setting. -If you're using MySQL, you can also use the ``TEST_DATABASE_COLLATION`` setting -to control the particular collation used by the test database. See the -settings_ documentation for details of these advanced settings. - -.. _settings: ../settings/ - -The test database is created by the user in the ``DATABASE_USER`` setting. -This user needs to have sufficient privileges to create a new database on the -system. - -Once the test database has been established, Django will run your tests. -If everything goes well, at the end you'll see:: - - ---------------------------------------------------------------------- - Ran 22 tests in 0.221s - - OK - -If there are test failures, however, you'll see full details about what tests -failed:: - - ====================================================================== - FAIL: Doctest: ellington.core.throttle.models - ---------------------------------------------------------------------- - Traceback (most recent call last): - File "/dev/django/test/doctest.py", line 2153, in runTest - raise self.failureException(self.format_failure(new.getvalue())) - AssertionError: Failed doctest test for myapp.models - File "/dev/myapp/models.py", line 0, in models - - ---------------------------------------------------------------------- - File "/dev/myapp/models.py", line 14, in myapp.models - Failed example: - throttle.check("actor A", "action one", limit=2, hours=1) - Expected: - True - Got: - False +When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER`` +setting to determine what to do. By default, ``TEST_RUNNER`` points to +``'django.test.simple.run_tests'``. This method defines the default Django +testing behavior. This behavior involves: - ---------------------------------------------------------------------- - Ran 2 tests in 0.048s + #. Performing global pre-test setup. - FAILED (failures=1) + #. Creating the test database. -The return code for the script is the total number of failed and erroneous -tests. If all the tests pass, the return code is 0. + #. Running ``syncdb`` to install models and initial data into the test + database. -Regardless of whether the tests pass or fail, the test database is destroyed when -all the tests have been executed. + #. Looking for unit tests and doctests in the ``models.py`` and + ``tests.py`` files in each installed application. -Using a different testing framework -=================================== + #. Running the unit tests and doctests that are found. -Doctest and Unittest are not the only Python testing frameworks. While -Django doesn't provide explicit support these alternative frameworks, -it does provide a mechanism to allow you to invoke tests constructed for -an alternative framework as if they were normal Django tests. + #. Destroying the test database. -When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER`` -setting to determine what to do. By default, ``TEST_RUNNER`` points to -``django.test.simple.run_tests``. This method defines the default Django -testing behavior. This behavior involves: - -#. Performing global pre-test setup -#. Creating the test database -#. Running ``syncdb`` to install models and initial data into the test database -#. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application -#. Running the Unit Tests and Doctests that are found -#. Destroying the test database -#. Performing global post-test teardown + #. Performing global post-test teardown. -If you define your own test runner method and point ``TEST_RUNNER`` -at that method, Django will execute your test runner whenever you run -``./manage.py test``. In this way, it is possible to use any test -framework that can be executed from Python code. +If you define your own test runner method and point ``TEST_RUNNER`` at that +method, Django will execute your test runner whenever you run +``./manage.py test``. In this way, it is possible to use any test framework +that can be executed from Python code. Defining a test runner ---------------------- -By convention, a test runner should be called ``run_tests``; however, you -can call it anything you want. The only requirement is that it has the -same arguments as the Django test runner: + +**New in Django development version** + +By convention, a test runner should be called ``run_tests``. The only strict +requirement is that it has the same arguments as the Django test runner: ``run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[])`` - - **New in Django development version:** ``test_labels`` is a list of - strings describing the tests to be run. A test label can take one of - three forms: - * ``app.TestCase.test_method`` - Run a single test method in a test case - * ``app.TestCase`` - Run all the test methods in a test case - * ``app`` - Search for and run all tests in the named application. + ``test_labels`` is a list of strings describing the tests to be run. A test + label can take one of three forms: + + * ``app.TestCase.test_method`` -- Run a single test method in a test case. + * ``app.TestCase`` -- Run all the test methods in a test case. + * ``app`` -- Search for and run all tests in the named application. If ``test_labels`` has a value of ``None``, the test runner should run search for tests in all the applications in ``INSTALLED_APPS``. - Verbosity determines the amount of notification and debug information that - will be printed to the console; ``0`` is no output, ``1`` is normal output, - and ``2`` is verbose output. + ``verbosity`` determines the amount of notification and debug information + that will be printed to the console; ``0`` is no output, ``1`` is normal + output, and ``2`` is verbose output. - **New in Django development version:** If ``interactive`` is ``True``, the - test suite may ask the user for instructions when the test suite is - executed. An example of this behavior would be asking for permission to - delete an existing test database. If ``interactive`` is ``False``, the - test suite must be able to run without any manual intervention. + If ``interactive`` is ``True``, the test suite has permission to ask the + user for instructions when the test suite is executed. An example of this + behavior would be asking for permission to delete an existing test + database. If ``interactive`` is ``False``, the test suite must be able to + run without any manual intervention. ``extra_tests`` is a list of extra ``TestCase`` instances to add to the suite that is executed by the test runner. These extra tests are run @@ -718,28 +974,36 @@ a number of utility methods in the ``django.test.utils`` module. ``setup_test_environment()`` Performs any global pre-test setup, such as the installing the instrumentation of the template rendering system and setting up - the dummy SMTPConnection. + the dummy ``SMTPConnection``. ``teardown_test_environment()`` - Performs any global post-test teardown, such as removing the instrumentation - of the template rendering system and restoring normal e-mail services. + Performs any global post-test teardown, such as removing the + black magic hooks into the template system and restoring normal e-mail + services. ``create_test_db(verbosity=1, autoclobber=False)`` - Creates a new test database, and run ``syncdb`` against it. + Creates a new test database and runs ``syncdb`` against it. - ``verbosity`` has the same behavior as in the test runner. + ``verbosity`` has the same behavior as in ``run_tests()``. - ``Autoclobber`` describes the behavior that will occur if a database with - the same name as the test database is discovered. If ``autoclobber`` is False, - the user will be asked to approve destroying the existing database. ``sys.exit`` - is called if the user does not approve. If autoclobber is ``True``, the database - will be destroyed without consulting the user. + ``autoclobber`` describes the behavior that will occur if a database with + the same name as the test database is discovered: + + * If ``autoclobber`` is ``False``, the user will be asked to approve + destroying the existing database. ``sys.exit`` is called if the user + does not approve. + + * If autoclobber is ``True``, the database will be destroyed without + consulting the user. ``create_test_db()`` has the side effect of modifying ``settings.DATABASE_NAME`` to match the name of the test database. + New in the Django development version, this function returns the name of + the test database that it created. + ``destroy_test_db(old_database_name, verbosity=1)`` - Destroys the database with the name ``settings.DATABASE_NAME`` matching, - and restores the value of ``settings.DATABASE_NAME`` to the provided name. + Destroys the database whose name is in the ``DATABASE_NAME`` setting + and restores the value of ``DATABASE_NAME`` to the provided name. - ``verbosity`` has the same behavior as in the test runner. + ``verbosity`` has the same behavior as in ``run_tests()``. diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index 4f39fb4141..cf2b76e9be 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -444,8 +444,8 @@ Once you're in the shell, explore the database API:: [] # Create a new Poll. - >>> from datetime import datetime - >>> p = Poll(question="What's up?", pub_date=datetime.now()) + >>> import datetime + >>> p = Poll(question="What's up?", pub_date=datetime.datetime.now()) # Save the object into the database. You have to call save() explicitly. >>> p.save() @@ -464,7 +464,7 @@ Once you're in the shell, explore the database API:: datetime.datetime(2007, 7, 15, 12, 00, 53) # Change values by changing the attributes, then calling save(). - >>> p.pub_date = datetime(2007, 4, 1, 0, 0) + >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0) >>> p.save() # objects.all() displays all the polls in the database. diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py index d2220320a0..0a09579761 100644 --- a/tests/modeltests/basic/models.py +++ b/tests/modeltests/basic/models.py @@ -247,6 +247,19 @@ datetime.datetime(2005, 7, 28, 0, 0) >>> (s1 | s2 | s3)[::2] [<Article: Area woman programs in Python>, <Article: Third article>] +# Slicing works with longs. +>>> Article.objects.all()[0L] +<Article: Area woman programs in Python> +>>> Article.objects.all()[1L:3L] +[<Article: Second article>, <Article: Third article>] +>>> s3 = Article.objects.filter(id__exact=3) +>>> (s1 | s2 | s3)[::2L] +[<Article: Area woman programs in Python>, <Article: Third article>] + +# And can be mixed with ints. +>>> Article.objects.all()[1:3L] +[<Article: Second article>, <Article: Third article>] + # Slices (without step) are lazy: >>> Article.objects.all()[0:5].filter() [<Article: Area woman programs in Python>, <Article: Second article>, <Article: Third article>, <Article: Article 6>, <Article: Default headline>] diff --git a/tests/modeltests/fixtures/models.py b/tests/modeltests/fixtures/models.py index b59dc82884..b59c388bbd 100644 --- a/tests/modeltests/fixtures/models.py +++ b/tests/modeltests/fixtures/models.py @@ -26,54 +26,54 @@ __test__ = {'API_TESTS': """ # Reset the database representation of this app. # This will return the database to a clean initial state. ->>> management.flush(verbosity=0, interactive=False) +>>> management.call_command('flush', verbosity=0, interactive=False) # Syncdb introduces 1 initial data object from initial_data.json. >>> Article.objects.all() [<Article: Python program becomes self aware>] # Load fixture 1. Single JSON file, with two objects. ->>> management.load_data(['fixture1.json'], verbosity=0) +>>> management.call_command('loaddata', 'fixture1.json', verbosity=0) >>> Article.objects.all() [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] # Load fixture 2. JSON file imported by default. Overwrites some existing objects ->>> management.load_data(['fixture2.json'], verbosity=0) +>>> management.call_command('loaddata', 'fixture2.json', verbosity=0) >>> Article.objects.all() [<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] # Load fixture 3, XML format. ->>> management.load_data(['fixture3.xml'], verbosity=0) +>>> management.call_command('loaddata', 'fixture3.xml', verbosity=0) >>> Article.objects.all() [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>] # Load a fixture that doesn't exist ->>> management.load_data(['unknown.json'], verbosity=0) +>>> management.call_command('loaddata', 'unknown.json', verbosity=0) # object list is unaffected >>> Article.objects.all() [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>] # Reset the database representation of this app. This will delete all data. ->>> management.flush(verbosity=0, interactive=False) +>>> management.call_command('flush', verbosity=0, interactive=False) >>> Article.objects.all() [<Article: Python program becomes self aware>] # Load fixture 1 again, using format discovery ->>> management.load_data(['fixture1'], verbosity=0) +>>> management.call_command('loaddata', 'fixture1', verbosity=0) >>> Article.objects.all() [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] # Try to load fixture 2 using format discovery; this will fail # because there are two fixture2's in the fixtures directory ->>> management.load_data(['fixture2'], verbosity=0) # doctest: +ELLIPSIS +>>> management.call_command('loaddata', 'fixture2', verbosity=0) # doctest: +ELLIPSIS Multiple fixtures named 'fixture2' in '...fixtures'. Aborting. >>> Article.objects.all() [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>] # Dump the current contents of the database as a JSON fixture ->>> print management.dump_data(['fixtures'], format='json') +>>> management.call_command('dumpdata', 'fixtures', format='json') [{"pk": "3", "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "2", "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": "1", "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}] """} diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index 951a41d61c..98b6a808a1 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -246,6 +246,22 @@ class ClientTest(TestCase): login = self.client.login(username='inactive', password='password') self.failIf(login) + def test_logout(self): + # Log in + self.client.login(username='testclient', password='password') + + # Request a page that requires a login + response = self.client.get('/test_client/login_protected_view/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['user'].username, 'testclient') + + # Log out + self.client.logout() + + # Request a page that requires a login + response = self.client.get('/test_client/login_protected_view/') + self.assertRedirects(response, '/accounts/login/') + def test_session_modifying_view(self): "Request a page that modifies the session" # Session value isn't set initially diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py index 18eb4fcccd..3920e1ca40 100644 --- a/tests/regressiontests/datastructures/tests.py +++ b/tests/regressiontests/datastructures/tests.py @@ -64,4 +64,13 @@ True ['Holovaty'] >>> d['person']['2']['firstname'] ['Adrian'] + +### FileDict ################################################################ + +>>> d = FileDict({'content': 'once upon a time...'}) +>>> repr(d) +"{'content': '<omitted>'}" +>>> d = FileDict({'other-key': 'once upon a time...'}) +>>> repr(d) +"{'other-key': 'once upon a time...'}" """ diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index 2c92839f0f..c6a50f73ce 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -26,7 +26,7 @@ __test__ = {'API_TESTS':""" >>> from django.core import management # Load a fixture that uses PK=1 ->>> management.load_data(['sequence'], verbosity=0) +>>> management.call_command('loaddata', 'sequence', verbosity=0) # Create a new animal. Without a sequence reset, this new object # will take a PK of 1 (on Postgres), and the save will fail. @@ -39,7 +39,7 @@ __test__ = {'API_TESTS':""" # doesn't affect parsing of None values. # Load a pretty-printed XML fixture with Nulls. ->>> management.load_data(['pretty.xml'], verbosity=0) +>>> management.call_command('loaddata', 'pretty.xml', verbosity=0) >>> Stuff.objects.all() [<Stuff: None is owned by None>] diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index d14ffc514e..6eea519cd2 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3636,6 +3636,29 @@ True <option value="2016">2016</option> </select> +Using a SelectDateWidget in a form: + +>>> class GetDate(Form): +... mydate = DateField(widget=SelectDateWidget) +>>> a = GetDate({'mydate_month':'4', 'mydate_day':'1', 'mydate_year':'2008'}) +>>> print a.is_valid() +True +>>> print a.cleaned_data['mydate'] +2008-04-01 + +As with any widget that implements get_value_from_datadict, +we must be prepared to accept the input from the "as_hidden" +rendering as well. + +>>> print a['mydate'].as_hidden() +<input type="hidden" name="mydate" value="2008-4-1" id="id_mydate" /> +>>> b=GetDate({'mydate':'2008-4-1'}) +>>> print b.is_valid() +True +>>> print b.cleaned_data['mydate'] +2008-04-01 + + # MultiWidget and MultiValueField ############################################# # MultiWidgets are widgets composed of other widgets. They are usually # combined with MultiValueFields - a field that is composed of other fields. diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py index 0fee831212..7aa9e2a7c4 100644 --- a/tests/regressiontests/model_regress/models.py +++ b/tests/regressiontests/model_regress/models.py @@ -10,6 +10,7 @@ class Article(models.Model): headline = models.CharField(max_length=100, default='Default headline') pub_date = models.DateTimeField() status = models.IntegerField(blank=True, null=True, choices=CHOICES) + misc_data = models.CharField(max_length=100, blank=True) class Meta: ordering = ('pub_date','headline') @@ -30,5 +31,10 @@ An empty choice field should return None for the display name. >>> a.save() >>> a.get_status_display() is None True + +Empty strings should be returned as Unicode +>>> a2 = Article.objects.get(pk=a.id) +>>> a2.misc_data +u'' """ } diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index 86dc311269..24111308d7 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -273,7 +273,7 @@ class SerializerTests(unittest.TestCase): def serializerTest(format, self): # Clear the database first - management.flush(verbosity=0, interactive=False) + management.call_command('flush', verbosity=0, interactive=False) # Create all the objects defined in the test data objects = [] @@ -291,7 +291,7 @@ def serializerTest(format, self): serialized_data = serializers.serialize(format, objects, indent=2) # Flush the database and recreate from the serialized data - management.flush(verbosity=0, interactive=False) + management.call_command('flush', verbosity=0, interactive=False) transaction.enter_transaction_management() transaction.managed(True) for obj in serializers.deserialize(format, serialized_data): @@ -306,7 +306,7 @@ def serializerTest(format, self): def fieldsTest(format, self): # Clear the database first - management.flush(verbosity=0, interactive=False) + management.call_command('flush', verbosity=0, interactive=False) obj = ComplexModel(field1='first',field2='second',field3='third') obj.save(raw=True) @@ -322,7 +322,7 @@ def fieldsTest(format, self): def streamTest(format, self): # Clear the database first - management.flush(verbosity=0, interactive=False) + management.call_command('flush', verbosity=0, interactive=False) obj = ComplexModel(field1='first',field2='second',field3='third') obj.save(raw=True) diff --git a/tests/runtests.py b/tests/runtests.py index 4cda2ac65d..8c3abe908e 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -51,7 +51,7 @@ class InvalidModelTestCase(unittest.TestCase): self.model_label = model_label def runTest(self): - from django.core import management + from django.core.management.validation import get_validation_errors from django.db.models.loading import load_app from cStringIO import StringIO @@ -60,8 +60,14 @@ class InvalidModelTestCase(unittest.TestCase): except Exception, e: self.fail('Unable to load invalid model module') + # Make sure sys.stdout is not a tty so that we get errors without + # coloring attached (makes matching the results easier). We restore + # sys.stderr afterwards. + orig_stdout = sys.stdout s = StringIO() - count = management.get_validation_errors(s, module) + sys.stdout = s + count = get_validation_errors(s, module) + sys.stdout = orig_stdout s.seek(0) error_log = s.read() actual = error_log.split('\n') @@ -94,6 +100,8 @@ def django_tests(verbosity, interactive, test_labels): 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.common.CommonMiddleware', ) + if not hasattr(settings, 'SITE_ID'): + settings.SITE_ID = 1 # Load all the ALWAYS_INSTALLED_APPS. # (This import statement is intentionally delayed until after we |
