summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Bronn <jbronn@gmail.com>2008-08-05 17:15:33 +0000
committerJustin Bronn <jbronn@gmail.com>2008-08-05 17:15:33 +0000
commitaa239e3e5405933af6a29dac3cf587b59a099927 (patch)
treeea2cbd139c9a8cf84c09e0b2008bff70e05927ef
parent45b73c9a4685809236f84046cc7ffd32a50db958 (diff)
downloaddjango-attic/gis.tar.gz
gis: Merged revisions 7981-8001,8003-8011,8013-8033,8035-8036,8038-8039,8041-8063,8065-8076,8078-8139,8141-8154,8156-8214 via svnmerge from trunk.archive/attic/gisattic/gis
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@8215 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS13
-rw-r--r--django/__init__.py2
-rw-r--r--django/conf/global_settings.py6
-rw-r--r--django/conf/locale/de/LC_MESSAGES/django.mobin52607 -> 55380 bytes
-rw-r--r--django/conf/locale/de/LC_MESSAGES/django.po1243
-rw-r--r--django/conf/locale/es/LC_MESSAGES/django.mobin63019 -> 68193 bytes
-rw-r--r--django/conf/locale/es/LC_MESSAGES/django.po1850
-rw-r--r--django/conf/locale/es_AR/LC_MESSAGES/django.mobin67118 -> 67678 bytes
-rw-r--r--django/conf/locale/es_AR/LC_MESSAGES/django.po1372
-rw-r--r--django/conf/locale/fr/LC_MESSAGES/django.mobin67158 -> 67164 bytes
-rw-r--r--django/conf/locale/fr/LC_MESSAGES/django.po70
-rw-r--r--django/conf/locale/it/LC_MESSAGES/django.mobin66524 -> 69007 bytes
-rw-r--r--django/conf/locale/it/LC_MESSAGES/django.po1179
-rw-r--r--django/conf/locale/ka/LC_MESSAGES/django.mobin67194 -> 67386 bytes
-rw-r--r--django/conf/locale/ka/LC_MESSAGES/django.po346
-rw-r--r--django/conf/locale/nl/LC_MESSAGES/django.mobin42340 -> 66957 bytes
-rw-r--r--django/conf/locale/nl/LC_MESSAGES/django.po2702
-rw-r--r--django/conf/locale/no/LC_MESSAGES/django.mobin40780 -> 41683 bytes
-rw-r--r--django/conf/locale/no/LC_MESSAGES/django.po3422
-rw-r--r--django/conf/locale/pl/LC_MESSAGES/django.mobin66481 -> 67643 bytes
-rw-r--r--django/conf/locale/pl/LC_MESSAGES/django.po1098
-rw-r--r--django/conf/locale/pt_BR/LC_MESSAGES/django.mobin52903 -> 52903 bytes
-rw-r--r--django/conf/locale/pt_BR/LC_MESSAGES/django.po2
-rw-r--r--django/conf/locale/sr/LC_MESSAGES/django.mobin32213 -> 42073 bytes
-rw-r--r--django/conf/locale/sr/LC_MESSAGES/django.po4814
-rw-r--r--django/conf/locale/sr/LC_MESSAGES/djangojs.mobin1669 -> 1810 bytes
-rw-r--r--django/conf/locale/sr/LC_MESSAGES/djangojs.po59
-rw-r--r--django/conf/locale/sv/LC_MESSAGES/django.mobin57325 -> 57615 bytes
-rw-r--r--django/conf/locale/sv/LC_MESSAGES/django.po1238
-rw-r--r--django/conf/project_template/urls.py13
-rw-r--r--django/contrib/admin/__init__.py7
-rw-r--r--django/contrib/admin/media/css/rtl.css3
-rw-r--r--django/contrib/admin/options.py99
-rw-r--r--django/contrib/admin/sites.py68
-rw-r--r--django/contrib/admin/templates/admin/includes/fieldset.html4
-rw-r--r--django/contrib/admin/templates/admin_doc/model_detail.html2
-rw-r--r--django/contrib/admin/templates/registration/password_reset_complete.html16
-rw-r--r--django/contrib/admin/templates/registration/password_reset_confirm.html32
-rw-r--r--django/contrib/admin/templates/registration/password_reset_done.html2
-rw-r--r--django/contrib/admin/templates/registration/password_reset_email.html14
-rw-r--r--django/contrib/admin/templates/registration/password_reset_form.html2
-rw-r--r--django/contrib/admin/validation.py11
-rw-r--r--django/contrib/admin/views/decorators.py8
-rw-r--r--django/contrib/admin/views/main.py1
-rw-r--r--django/contrib/admin/widgets.py3
-rw-r--r--django/contrib/admindocs/views.py2
-rw-r--r--django/contrib/auth/admin.py2
-rw-r--r--django/contrib/auth/decorators.py4
-rw-r--r--django/contrib/auth/forms.py103
-rw-r--r--django/contrib/auth/management/commands/createsuperuser.py2
-rw-r--r--django/contrib/auth/models.py3
-rw-r--r--django/contrib/auth/tests/__init__.py5
-rw-r--r--django/contrib/auth/tests/basic.py21
-rw-r--r--django/contrib/auth/tests/forms.py33
-rw-r--r--django/contrib/auth/tests/tokens.py29
-rw-r--r--django/contrib/auth/tests/views.py88
-rw-r--r--django/contrib/auth/tokens.py66
-rw-r--r--django/contrib/auth/urls.py11
-rw-r--r--django/contrib/auth/views.py64
-rw-r--r--django/contrib/comments/models.py4
-rw-r--r--django/contrib/contenttypes/generic.py5
-rw-r--r--django/contrib/csrf/middleware.py53
-rw-r--r--django/contrib/databrowse/plugins/calendars.py1
-rw-r--r--django/contrib/databrowse/plugins/fieldchoices.py1
-rw-r--r--django/contrib/databrowse/sites.py2
-rw-r--r--django/contrib/databrowse/views.py2
-rw-r--r--django/contrib/formtools/preview.py7
-rw-r--r--django/contrib/formtools/tests.py1
-rw-r--r--django/contrib/formtools/wizard.py7
-rw-r--r--django/contrib/gis/db/backend/oracle/field.py2
-rw-r--r--django/contrib/gis/db/backend/postgis/field.py2
-rw-r--r--django/contrib/gis/db/models/manager.py5
-rw-r--r--django/contrib/localflavor/at/__init__.py (renamed from tests/regressiontests/maxlength/__init__.py)0
-rw-r--r--django/contrib/localflavor/at/at_states.py14
-rw-r--r--django/contrib/localflavor/at/forms.py65
-rw-r--r--django/contrib/localflavor/ro/__init__.py (renamed from tests/regressiontests/maxlength/models.py)0
-rw-r--r--django/contrib/localflavor/ro/forms.py200
-rw-r--r--django/contrib/localflavor/ro/ro_counties.py52
-rw-r--r--django/contrib/redirects/admin.py11
-rw-r--r--django/contrib/redirects/models.py15
-rw-r--r--django/contrib/sessions/backends/base.py10
-rw-r--r--django/contrib/sessions/backends/cache.py2
-rw-r--r--django/contrib/sessions/backends/db.py3
-rw-r--r--django/contrib/sessions/middleware.py5
-rw-r--r--django/contrib/sessions/models.py6
-rw-r--r--django/contrib/sitemaps/__init__.py16
-rw-r--r--django/contrib/sitemaps/management/__init__.py0
-rw-r--r--django/contrib/sitemaps/management/commands/__init__.py0
-rw-r--r--django/contrib/sitemaps/views.py24
-rw-r--r--django/contrib/sites/tests.py5
-rw-r--r--django/contrib/syndication/feeds.py2
-rw-r--r--django/core/cache/__init__.py23
-rw-r--r--django/core/cache/backends/base.py9
-rw-r--r--django/core/cache/backends/filebased.py29
-rw-r--r--django/core/cache/backends/locmem.py2
-rw-r--r--django/core/files/temp.py58
-rw-r--r--django/core/files/uploadedfile.py3
-rw-r--r--django/core/files/uploadhandler.py3
-rw-r--r--django/core/handlers/base.py41
-rw-r--r--django/core/handlers/modpython.py25
-rw-r--r--django/core/handlers/wsgi.py19
-rw-r--r--django/core/mail.py7
-rw-r--r--django/core/management/commands/compilemessages.py3
-rw-r--r--django/core/management/commands/test.py1
-rw-r--r--django/core/management/commands/testserver.py1
-rw-r--r--django/core/management/sql.py12
-rw-r--r--django/core/management/validation.py45
-rw-r--r--django/core/paginator.py98
-rw-r--r--django/core/serializers/base.py6
-rw-r--r--django/core/serializers/json.py9
-rw-r--r--django/core/serializers/pyyaml.py8
-rw-r--r--django/core/urlresolvers.py33
-rw-r--r--django/db/backends/__init__.py70
-rw-r--r--django/db/backends/mysql/base.py19
-rw-r--r--django/db/backends/oracle/base.py30
-rw-r--r--django/db/backends/oracle/query.py9
-rw-r--r--django/db/backends/sqlite3/base.py8
-rw-r--r--django/db/backends/util.py12
-rw-r--r--django/db/models/__init__.py2
-rw-r--r--django/db/models/base.py38
-rw-r--r--django/db/models/fields/__init__.py244
-rw-r--r--django/db/models/fields/related.py173
-rw-r--r--django/db/models/fields/subclassing.py5
-rw-r--r--django/db/models/query.py35
-rw-r--r--django/db/models/sql/query.py34
-rw-r--r--django/db/models/sql/where.py39
-rw-r--r--django/dispatch/dispatcher.py32
-rw-r--r--django/dispatch/saferef.py1
-rw-r--r--django/forms/fields.py16
-rw-r--r--django/forms/formsets.py18
-rw-r--r--django/forms/models.py30
-rw-r--r--django/forms/util.py1
-rw-r--r--django/http/__init__.py13
-rw-r--r--django/http/multipartparser.py15
-rw-r--r--django/middleware/common.py6
-rw-r--r--django/oldforms/__init__.py4
-rw-r--r--django/template/context.py2
-rw-r--r--django/template/defaulttags.py35
-rw-r--r--django/test/client.py2
-rw-r--r--django/test/testcases.py144
-rw-r--r--django/utils/cache.py6
-rw-r--r--django/utils/dateformat.py2
-rw-r--r--django/utils/encoding.py2
-rw-r--r--django/utils/functional.py60
-rw-r--r--django/utils/hashcompat.py16
-rw-r--r--django/utils/html.py6
-rw-r--r--django/utils/http.py29
-rw-r--r--django/utils/maxlength.py65
-rw-r--r--django/utils/simplejson/LICENSE.txt1
-rw-r--r--django/utils/simplejson/__init__.py186
-rw-r--r--django/utils/simplejson/decoder.py104
-rw-r--r--django/utils/simplejson/encoder.py86
-rw-r--r--django/utils/simplejson/jsonfilter.py40
-rw-r--r--django/utils/simplejson/scanner.py18
-rw-r--r--django/utils/simplejson/tool.py44
-rw-r--r--django/utils/thread_support.py12
-rw-r--r--django/utils/translation/trans_real.py13
-rw-r--r--django/views/debug.py2
-rw-r--r--django/views/generic/create_update.py8
-rw-r--r--django/views/generic/simple.py1
-rw-r--r--docs/add_ons.txt5
-rw-r--r--docs/admin.txt221
-rw-r--r--docs/api_stability.txt5
-rw-r--r--docs/authentication.txt10
-rw-r--r--docs/cache.txt38
-rw-r--r--docs/contenttypes.txt8
-rw-r--r--docs/contributing.txt1
-rw-r--r--docs/csrf.txt12
-rw-r--r--docs/custom_model_fields.txt59
-rw-r--r--docs/databases.txt4
-rw-r--r--docs/db-api.txt36
-rw-r--r--docs/django-admin.txt2
-rw-r--r--docs/email.txt2
-rw-r--r--docs/faq.txt17
-rw-r--r--docs/fastcgi.txt36
-rw-r--r--docs/form_for_model.txt14
-rw-r--r--docs/form_preview.txt4
-rw-r--r--docs/form_wizard.txt16
-rw-r--r--docs/forms.txt2976
-rw-r--r--docs/generic_views.txt1275
-rw-r--r--docs/i18n.txt35
-rw-r--r--docs/index.txt2
-rw-r--r--docs/install.txt4
-rw-r--r--docs/localflavor.txt78
-rw-r--r--docs/middleware.txt2
-rw-r--r--docs/model-api.txt166
-rw-r--r--docs/modelforms.txt26
-rw-r--r--docs/modpython.txt20
-rw-r--r--docs/newforms.txt2522
-rw-r--r--docs/oldforms.txt696
-rw-r--r--docs/overview.txt6
-rw-r--r--docs/pagination.txt121
-rw-r--r--docs/release_notes_0.95.txt4
-rw-r--r--docs/release_notes_1.0_alpha.txt163
-rw-r--r--docs/request_response.txt12
-rw-r--r--docs/serialization.txt24
-rw-r--r--docs/sessions.txt8
-rw-r--r--docs/settings.txt16
-rw-r--r--docs/sitemaps.txt4
-rw-r--r--docs/templates.txt29
-rw-r--r--docs/testing.txt15
-rw-r--r--docs/tutorial02.txt30
-rw-r--r--docs/tutorial03.txt4
-rw-r--r--docs/upload_handling.txt12
-rw-r--r--docs/url_dispatch.txt4
-rw-r--r--setup.py20
-rw-r--r--tests/modeltests/choices/models.py11
-rw-r--r--tests/modeltests/custom_methods/models.py3
-rw-r--r--tests/modeltests/delete/models.py31
-rw-r--r--tests/modeltests/generic_relations/models.py55
-rw-r--r--tests/modeltests/invalid_models/models.py65
-rw-r--r--tests/modeltests/m2m_through/__init__.py2
-rw-r--r--tests/modeltests/m2m_through/models.py337
-rw-r--r--tests/modeltests/many_to_one/models.py8
-rw-r--r--tests/modeltests/model_forms/models.py6
-rw-r--r--tests/modeltests/model_formsets/models.py56
-rw-r--r--tests/modeltests/pagination/models.py107
-rw-r--r--tests/modeltests/validation/models.py22
-rw-r--r--tests/regressiontests/admin_registration/__init__.py0
-rw-r--r--tests/regressiontests/admin_registration/models.py64
-rw-r--r--tests/regressiontests/admin_scripts/tests.py181
-rw-r--r--tests/regressiontests/admin_views/tests.py8
-rw-r--r--tests/regressiontests/auth_backends/tests.py8
-rw-r--r--tests/regressiontests/cache/tests.py33
-rw-r--r--tests/regressiontests/context_processors/__init__.py0
-rw-r--r--tests/regressiontests/context_processors/models.py1
-rw-r--r--tests/regressiontests/context_processors/templates/context_processors/request_attrs.html13
-rw-r--r--tests/regressiontests/context_processors/tests.py38
-rw-r--r--tests/regressiontests/context_processors/urls.py8
-rw-r--r--tests/regressiontests/context_processors/views.py8
-rw-r--r--tests/regressiontests/dispatch/tests/test_dispatcher.py18
-rw-r--r--tests/regressiontests/file_uploads/models.py11
-rw-r--r--tests/regressiontests/file_uploads/tests.py76
-rw-r--r--tests/regressiontests/forms/fields.py106
-rw-r--r--tests/regressiontests/forms/forms.py4
-rw-r--r--tests/regressiontests/forms/formsets.py16
-rw-r--r--tests/regressiontests/forms/localflavor/at.py80
-rw-r--r--tests/regressiontests/forms/localflavor/ro.py175
-rw-r--r--tests/regressiontests/forms/models.py19
-rw-r--r--tests/regressiontests/forms/tests.py4
-rw-r--r--tests/regressiontests/m2m_through_regress/__init__.py2
-rw-r--r--tests/regressiontests/m2m_through_regress/models.py204
-rw-r--r--tests/regressiontests/mail/tests.py9
-rw-r--r--tests/regressiontests/many_to_one_regress/models.py52
-rw-r--r--tests/regressiontests/max_lengths/tests.py2
-rw-r--r--tests/regressiontests/maxlength/tests.py160
-rw-r--r--tests/regressiontests/model_fields/models.py60
-rw-r--r--tests/regressiontests/model_fields/tests.py38
-rw-r--r--tests/regressiontests/model_inheritance_regress/models.py35
-rw-r--r--tests/regressiontests/model_regress/models.py19
-rw-r--r--tests/regressiontests/modeladmin/models.py14
-rw-r--r--tests/regressiontests/null_fk/models.py18
-rw-r--r--tests/regressiontests/one_to_one_regress/models.py35
-rw-r--r--tests/regressiontests/pagination_regress/__init__.py0
-rw-r--r--tests/regressiontests/pagination_regress/models.py1
-rw-r--r--tests/regressiontests/pagination_regress/tests.py157
-rw-r--r--tests/regressiontests/queries/models.py69
-rw-r--r--tests/regressiontests/requests/tests.py5
-rw-r--r--tests/regressiontests/reverse_single_related/__init__.py0
-rw-r--r--tests/regressiontests/reverse_single_related/models.py54
-rw-r--r--tests/regressiontests/serializers_regress/tests.py36
-rw-r--r--tests/regressiontests/templates/loaders.py5
-rw-r--r--tests/regressiontests/templates/tests.py25
-rw-r--r--tests/regressiontests/test_client_regress/models.py12
-rw-r--r--tests/regressiontests/test_utils/__init__.py0
-rw-r--r--tests/regressiontests/test_utils/models.py0
-rw-r--r--tests/regressiontests/test_utils/tests.py72
-rw-r--r--tests/regressiontests/utils/datastructures.py6
-rw-r--r--tests/regressiontests/utils/tests.py7
269 files changed, 20710 insertions, 13554 deletions
diff --git a/AUTHORS b/AUTHORS
index 24e3e5bcac..a9f55836e6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,6 +41,7 @@ And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --
people who have submitted patches, reported bugs, added translations, helped
answer newbie questions, and generally made Django that much better:
+ ajs <adi@sieker.info>
alang@bright-green.com
Marty Alchin <gulopine@gamemusic.org>
atlithorn <atlithorn@gmail.com>
@@ -70,7 +71,7 @@ answer newbie questions, and generally made Django that much better:
Esdras Beleza <linux@esdrasbeleza.com>
Chris Bennett <chrisrbennett@yahoo.com>
James Bennett
- Ben Godfrey <http://aftnn.org>
+ Julian Bez
Arvis Bickovskis <viestards.lists@gmail.com>
Paul Bissex <http://e-scribe.com/>
Simon Blanchard
@@ -150,8 +151,10 @@ answer newbie questions, and generally made Django that much better:
Stefane Fermgier <sf@fermigier.com>
Afonso Fernández Nogueira <fonzzo.django@gmail.com>
J. Pablo Fernandez <pupeno@pupeno.com>
+ Maciej Fijalkowski
Matthew Flanagan <http://wadofstuff.blogspot.com>
Eric Floehr <eric@intellovations.com>
+ Eric Florenzano <floguy@gmail.com>
Vincent Foley <vfoleybourgon@yahoo.ca>
Rudolph Froger <rfroger@estrate.nl>
Jorge Gajon <gajon@gajon.org>
@@ -164,6 +167,7 @@ answer newbie questions, and generally made Django that much better:
glin@seznam.cz
martin.glueck@gmail.com
Artyom Gnilov <boobsd@gmail.com>
+ Ben Godfrey <http://aftnn.org>
GomoX <gomo@datafull.com>
Guilherme Mesquita Gondim <semente@taurinus.org>
Mario Gonzalez <gonzalemario@gmail.com>
@@ -172,6 +176,7 @@ answer newbie questions, and generally made Django that much better:
Owen Griffiths
Espen Grindhaug <http://grindhaug.org/>
Thomas Güttler <hv@tbz-pariv.de>
+ Horst Gutmann <zerok@zerokspot.com>
dAniel hAhler
hambaloney
Brian Harring <ferringb@gmail.com>
@@ -234,6 +239,7 @@ answer newbie questions, and generally made Django that much better:
Stuart Langridge <http://www.kryogenix.org/>
Paul Lanier <planier@google.com>
Nicola Larosa <nico@teknico.net>
+ Lau Bech Lauritzen
Rune Rønde Laursen <runerl@skjoldhoej.dk>
Eugene Lazutkin <http://lazutkin.com/blog/>
lcordier@point45.com
@@ -276,6 +282,7 @@ answer newbie questions, and generally made Django that much better:
Eric Moritz <http://eric.themoritzfamily.com/>
mrmachine <real.human@mrmachine.net>
Robin Munn <http://www.geekforgod.com/>
+ James Murty
msundstr
Robert Myers <myer0052@gmail.com>
Nebojša Dorđević
@@ -301,6 +308,7 @@ answer newbie questions, and generally made Django that much better:
phil@produxion.net
phil.h.smith@gmail.com
Gustavo Picon
+ Michael Placentra II <someone@michaelplacentra2.net>
Luke Plant <http://lukeplant.me.uk/>
plisk
Mihai Preda <mihai_preda@yahoo.com>
@@ -338,8 +346,10 @@ answer newbie questions, and generally made Django that much better:
Pete Shinners <pete@shinners.org>
Leo Shklovskii
jason.sidabras@gmail.com
+ Brenton Simpson <http://theillustratedlife.com>
Jozko Skrablin <jozko.skrablin@gmail.com>
Ben Slavin <benjamin.slavin@gmail.com>
+ sloonz <simon.lipp@insa-lyon.fr>
SmileyChris <smileychris@gmail.com>
smurf@smurf.noris.de
Vsevolod Solovyov
@@ -398,6 +408,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 Wilk <ubanus@users.sf.net>
Jakub Wiśniowski <restless.being@gmail.com>
Maciej Wiśniowski <pigletto@gmail.com>
wojtek
diff --git a/django/__init__.py b/django/__init__.py
index de473fa4e9..e5f3d5df9b 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -1,4 +1,4 @@
-VERSION = (0, 97, 'pre')
+VERSION = (1, 0, 'alpha')
def get_version():
"Returns the version as a human-format string."
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 2c9720da10..811feed349 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -188,6 +188,9 @@ APPEND_SLASH = True
# Whether to prepend the "www." subdomain to URLs that don't have it.
PREPEND_WWW = False
+# Override the server-derived value of SCRIPT_NAME
+FORCE_SCRIPT_NAME = None
+
# List of compiled regular expression objects representing User-Agent strings
# that are not allowed to visit any page, systemwide. Use this for bad
# robots/crawlers. Here are a few examples:
@@ -363,6 +366,9 @@ LOGOUT_URL = '/accounts/logout/'
LOGIN_REDIRECT_URL = '/accounts/profile/'
+# The number of days a password reset link is valid for
+PASSWORD_RESET_TIMEOUT_DAYS = 3
+
###########
# TESTING #
###########
diff --git a/django/conf/locale/de/LC_MESSAGES/django.mo b/django/conf/locale/de/LC_MESSAGES/django.mo
index 234819f879..638bf5e76a 100644
--- a/django/conf/locale/de/LC_MESSAGES/django.mo
+++ b/django/conf/locale/de/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/de/LC_MESSAGES/django.po b/django/conf/locale/de/LC_MESSAGES/django.po
index f529167baa..897634f4d2 100644
--- a/django/conf/locale/de/LC_MESSAGES/django.po
+++ b/django/conf/locale/de/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-06-23 20:23+0200\n"
-"PO-Revision-Date: 2008-06-23 20:51+0100\n"
+"POT-Creation-Date: 2008-08-01 11:38+0200\n"
+"PO-Revision-Date: 2008-08-01 12:42+0100\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -252,51 +252,208 @@ msgid "This year"
msgstr "Dieses Jahr"
#: contrib/admin/filterspecs.py:147
-#: newforms/widgets.py:231
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Ja"
#: contrib/admin/filterspecs.py:147
-#: newforms/widgets.py:231
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "Nein"
#: contrib/admin/filterspecs.py:154
-#: newforms/widgets.py:231
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Unbekannt"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "Zeitpunkt der Aktion"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "Objekt-ID"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "Objekt Darst."
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "Aktionskennzeichen"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "Änderungsmeldung"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "Logeintrag"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "Logeinträge"
+#: contrib/admin/options.py:140
+#: contrib/admin/options.py:178
+msgid "None"
+msgstr "-"
+
+#: contrib/admin/options.py:358
+#: contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt."
+
+#: contrib/admin/options.py:362
+#: contrib/admin/options.py:430
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "Das Element kann jetzt weiter bearbeitet werden."
+
+#: contrib/admin/options.py:372
+#: contrib/admin/options.py:439
+#, python-format
+msgid "You may add another %s below."
+msgstr "Jetzt kann ein weiteres Element des Typs %s angelegt werden."
+
+#: contrib/admin/options.py:406
+#, python-format
+msgid "Changed %s."
+msgstr "%s geändert."
+
+#: contrib/admin/options.py:406
+#: contrib/admin/options.py:416
+#: core/validators.py:279
+#: db/models/manipulators.py:305
+msgid "and"
+msgstr "und"
+
+#: contrib/admin/options.py:411
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "%(name)s \"%(object)s\" hinzugefügt."
+
+#: contrib/admin/options.py:415
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "%(list)s von %(name)s \"%(object)s\" geändert."
+
+#: contrib/admin/options.py:420
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "%(name)s \"%(object)s\" gelöscht."
+
+#: contrib/admin/options.py:425
+msgid "No fields changed."
+msgstr "Keine Felder geändert."
+
+#: contrib/admin/options.py:428
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "%(name)s \"%(obj)s\" wurde erfolgreich geändert."
+
+#: contrib/admin/options.py:436
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt. Das Element kann jetzt geändert werden."
+
+#: contrib/admin/options.py:517
+#, python-format
+msgid "Add %s"
+msgstr "%s hinzufügen"
+
+#: contrib/admin/options.py:579
+#, python-format
+msgid "Change %s"
+msgstr "%s ändern"
+
+#: contrib/admin/options.py:609
+msgid "Database error"
+msgstr "Datenbankfehler"
+
+#: contrib/admin/options.py:658
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "%(name)s \"%(obj)s\" wurde erfolgreich gelöscht."
+
+#: contrib/admin/options.py:664
+msgid "Are you sure?"
+msgstr "Sind Sie ganz sicher?"
+
+#: contrib/admin/options.py:691
+#, python-format
+msgid "Change history: %s"
+msgstr "Änderungsgeschichte: %s"
+
+#: contrib/admin/sites.py:18
+#: contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:72
+#: contrib/comments/views/comments.py:56
+msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
+msgstr "Bitte einen gültigen Benutzernamen und ein Passwort eingeben. Beide Felder berücksichtigen die Groß-/Kleinschreibung."
+
+#: contrib/admin/sites.py:233
+#: contrib/admin/views/decorators.py:68
+msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
+msgstr "Bitte neu anmelden, da die Session ausgelaufen ist. Keine Angst, die Beiträge wurden gesichert."
+
+#: contrib/admin/sites.py:240
+#: contrib/admin/views/decorators.py:75
+msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
+msgstr "Es sieht danach aus, dass der Browser keine Cookies akzeptiert. Bitte im Browser Cookies aktivieren und diese Seite neu laden."
+
+#: contrib/admin/sites.py:254
+#: contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Benutzernamen dürfen das Zeichen '@' nicht enthalten."
+
+#: contrib/admin/sites.py:257
+#: contrib/admin/views/decorators.py:88
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "Die E-Mail-Adresse entspricht nicht Ihrem Benutzernamen. Bitte stattdessen '%s' versuchen."
+
+#: contrib/admin/sites.py:325
+msgid "Site administration"
+msgstr "Seitenverwaltung"
+
+#: contrib/admin/sites.py:347
+#: contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Anmelden"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Ein oder mehrere %(fieldname)s in %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Ein oder mehrere %(fieldname)s in %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Datum:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Zeit:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Derzeit:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Ändern:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -307,17 +464,19 @@ 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."
#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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:4
+#: contrib/admin/templates/registration/password_change_form.html:4
+#: contrib/admin/templates/registration/password_reset_complete.html:4
+#: contrib/admin/templates/registration/password_reset_confirm.html:4
#: contrib/admin/templates/registration/password_reset_done.html:4
#: contrib/admin/templates/registration/password_reset_form.html:4
msgid "Home"
@@ -339,22 +498,28 @@ msgstr "Serverfehler <em>(500)</em>"
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-Mail weitergegeben und sollte bald behoben sein. Vielen Dank für Ihr Verständnis."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Willkommen,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Passwort ändern"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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"
@@ -367,56 +532,53 @@ msgstr "Django-Systemverwaltung"
msgid "Django administration"
msgstr "Django-Verwaltung"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Hinzufügen"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Geschichte"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Im Web anzeigen"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
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:49
-msgid "Ordering"
-msgstr "Sortierung"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Reihenfolge:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "%(name)s hinzufügen"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filter"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Löschen"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, 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 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:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, 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 wollen? Es werden zusätzlich die folgenden abhängigen Daten mit gelöscht:"
-#: contrib/admin/templates/admin/delete_confirmation.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Ja, ich bin sicher"
@@ -425,77 +587,68 @@ msgstr "Ja, ich bin sicher"
msgid " By %(filter_title)s "
msgstr " Nach %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filter"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, 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
+#: contrib/admin/templates/admin/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Ändern"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "Sie haben keine Berechtigung, irgendetwas zu ändern."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Kürzliche Aktionen"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Meine Aktionen"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Keine vorhanden"
-#: contrib/admin/templates/admin/invalid_setup.html:8
+#: contrib/admin/templates/admin/invalid_setup.html:7
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."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: 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/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Passwort:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Anmelden"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Datum/Zeit"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Benutzer"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Aktion"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "j. N Y, H:i"
-#: contrib/admin/templates/admin/object_history.html:35
+#: contrib/admin/templates/admin/object_history.html:32
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 über diese Verwaltungsseiten angelegt."
@@ -539,26 +692,32 @@ msgstr "Sichern"
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 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:13
+#: contrib/auth/forms.py:14
+#: contrib/auth/forms.py:51
msgid "Username"
msgstr "Benutzername"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:17
+#: contrib/auth/forms.py:52
+#: contrib/auth/forms.py:176
msgid "Password"
msgstr "Passwort"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:177
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:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: 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:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, 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</strong> ein."
@@ -629,42 +788,47 @@ msgstr "Vielen Dank, dass Sie hier ein paar nette Minuten verbracht haben."
msgid "Log in again"
msgstr "Erneut anmelden"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 "Passwort ändern"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: contrib/admin/templates/registration/password_change_done.html:6
+#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
msgstr "Passwort erfolgreich geändert"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Ihr Passwort wurde geändert."
-#: contrib/admin/templates/registration/password_change_form.html:11
+#: 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 "Bitte geben Sie aus Sicherheitsgründen erst Ihr altes Passwort und darunter dann zweimal (um sicherzustellen, dass Sie es korrekt eingegeben haben) das neue Kennwort ein."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Altes Passwort:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
+#: contrib/admin/templates/registration/password_reset_confirm.html:18
msgid "New password:"
msgstr "Neues Passwort:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
+#: contrib/admin/templates/registration/password_reset_confirm.html:20
msgid "Confirm password:"
msgstr "Passwort wiederholen:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
+#: contrib/admin/templates/registration/password_reset_confirm.html:21
msgid "Change my password"
msgstr "Mein Passwort ändern"
+#: contrib/admin/templates/registration/password_reset_complete.html:4
+#: contrib/admin/templates/registration/password_reset_confirm.html:6
#: 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
@@ -672,14 +836,43 @@ msgstr "Mein Passwort ändern"
msgid "Password reset"
msgstr "Passwort zurücksetzen"
+#: contrib/admin/templates/registration/password_reset_complete.html:6
+#: contrib/admin/templates/registration/password_reset_complete.html:10
+msgid "Password reset complete"
+msgstr "Passwort zurücksetzen beendet"
+
+#: contrib/admin/templates/registration/password_reset_complete.html:12
+msgid "Your password has been set. You may go ahead and log in now."
+msgstr "Ihr Passwort wurde zurückgesetzt. Sie können sich nun anmelden."
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:4
+msgid "Password reset confirmation"
+msgstr "Zurücksetzen des Passworts bestätigen"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:12
+msgid "Enter new password"
+msgstr "Neues Passwort eingeben"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:14
+msgid "Please enter your new password twice so we can verify you typed it in correctly."
+msgstr "Bitte geben Sie Ihr neues Passwort zweimal ein, damit wir überprüfen können, ob es richtig eingetippt wurde."
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:26
+msgid "Password reset unsuccessful"
+msgstr "Passwort wurde nicht erfolgreich zurückgesetzt"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:28
+msgid "The password reset link was invalid, possibly because it has already been used. Please request a new password reset."
+msgstr "Der Link zum Zurücksetzen Ihres Passworts ist ungültig, wahrscheinlich weil er schon einmal benutzt wurde. Bitte setzen Sie Ihr Passwort erneut zurück."
+
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
msgstr "Passwort wurde erfolgreich zurückgesetzt"
#: 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 "Wir haben ein neues Passwort an die von Ihnen angegebene E-Mail-Adresse geschickt. Sie sollten es in Kürze erhalten."
+msgid "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly."
+msgstr "Wir haben Ihnen eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passwort an die von Ihnen angegebene E-Mail-Adresse geschickt. Sie sollten sie in Kürze erhalten."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
@@ -691,30 +884,25 @@ msgid "for your user account at %(site_name)s"
msgstr "für Ihren Benutzer bei %(site_name)s angefordert haben."
#: contrib/admin/templates/registration/password_reset_email.html:5
-#, python-format
-msgid "Your new password is: %(new_password)s"
-msgstr "Ihr neues Passwort lautet: %(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 "Sie können das Passwort auf folgender Seite ändern:"
+msgid "Please go to the following page and choose a new password:"
+msgstr "Bitte öffnen Sie folgende Seite, um Ihr neues Passwort einzugeben:"
-#: contrib/admin/templates/registration/password_reset_email.html:11
+#: contrib/admin/templates/registration/password_reset_email.html:9
msgid "Your username, in case you've forgotten:"
msgstr "Ihr Benutzername, falls Sie ihn vergessen haben:"
-#: contrib/admin/templates/registration/password_reset_email.html:13
+#: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Thanks for using our site!"
msgstr "Vielen Dank, dass Sie unsere Seiten benutzen!"
-#: contrib/admin/templates/registration/password_reset_email.html:15
+#: contrib/admin/templates/registration/password_reset_email.html:13
#, python-format
msgid "The %(site_name)s team"
msgstr "Das Team von %(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 "Passwort vergessen? Einfach die E-Mail-Adresse eingeben und wir setzen das Passwort zurück und lassen es Ihnen per E-Mail zukommen."
+msgid "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one."
+msgstr "Passwort vergessen? Einfach Ihre E-Mail-Adresse eingeben und wir senden Ihnen Anweisungen zum Zurücksetzen Ihres Passworts."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -724,351 +912,252 @@ msgstr "E-Mail-Adresse:"
msgid "Reset my password"
msgstr "Mein Passwort zurücksetzen"
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Datum:"
-
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Zeit:"
-
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Derzeit:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Ändern:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Alle Tage"
-#: contrib/admin/views/auth.py:20
-#: contrib/admin/views/main.py:267
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt."
-
-#: contrib/admin/views/auth.py:25
-#: contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "Das Element kann jetzt weiter bearbeitet werden."
-
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Benutzer hinzufügen"
-
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Passwort erfolgreich geändert."
-
-#: contrib/admin/views/auth.py:65
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Change password: %s"
-msgstr "Passwort ändern: %s"
-
-#: contrib/admin/views/decorators.py:17
-#: contrib/auth/forms.py:60
-msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
-msgstr "Bitte einen gültigen Benutzernamen und ein Passwort eingeben. Beide Felder berücksichtigen die Groß-/Kleinschreibung."
-
-#: contrib/admin/views/decorators.py:69
-msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
-msgstr "Bitte neu anmelden, da die Session ausgelaufen ist. Keine Angst, die Beiträge wurden gesichert."
-
-#: contrib/admin/views/decorators.py:76
-msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
-msgstr "Es sieht danach aus, dass der Browser keine Cookies akzeptiert. Bitte im Browser Cookies aktivieren und diese Seite neu laden."
+msgid "Select %s"
+msgstr "%s auswählen"
-#: contrib/admin/views/decorators.py:89
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Die E-Mail-Adresse entspricht nicht Ihrem Benutzernamen. Bitte stattdessen '%s' versuchen."
-
-#: contrib/admin/views/decorators.py:93
-msgid "Usernames cannot contain the '@' character."
-msgstr "Benutzernamen dürfen das Zeichen '@' nicht enthalten."
+msgid "Select %s to change"
+msgstr "%s zur Änderung auswählen"
-#: contrib/admin/views/doc.py:48
-#: contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53
+#: contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "Schlagwort:"
-#: contrib/admin/views/doc.py:79
-#: contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87
+#: contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "Filter:"
-#: contrib/admin/views/doc.py:137
-#: contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153
+#: contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "Ansicht:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Anwendung %r nicht gefunden"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Modell %(name)r wurde nicht in Anwendung %(label)r gefunden"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Modell %(model_name)r wurde nicht in Anwendung %(app_label)r gefunden"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "Das verknüpfte `%(label)s.%(type)s` Objekt"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "Das verknüpfte `%(app_label)s.%(data_type)s` Objekt"
-#: contrib/admin/views/doc.py:185
-#: contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206
+#: contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242
+#: contrib/admindocs/views.py:247
msgid "model:"
msgstr "Modell:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "verknüpftes `%(label)s.%(name)s` Objekt"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "verknüpftes `%(app_label)s.%(object_name)s` Objekt"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "Alle %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "Anzahl von %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Felder am %s Objekt"
-#: contrib/admin/views/doc.py:293
-#: contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306
-#: contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313
-#: contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317
+#: contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330
+#: contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337
+#: contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Ganzzahl"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Boolscher Wert (True oder False)"
-#: contrib/admin/views/doc.py:295
-#: contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319
+#: contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Zeichenkette (bis zu %(max_length)s Zeichen)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Kommaseparierte Liste von Ganzzahlen"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Datum (ohne Uhrzeit)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Datum (mit Uhrzeit)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Dezimalzahl"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "E-Mail-Adresse"
-#: contrib/admin/views/doc.py:301
-#: contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325
+#: contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Dateipfad"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Fließkommazahl"
-#: contrib/admin/views/doc.py:307
+#: contrib/admindocs/views.py:331
#: contrib/comments/models.py:89
msgid "IP address"
msgstr "IP-Adresse"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Boolscher Wert (True, False oder None)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Beziehung zum Eltern-Modell"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Telefonnummer"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Text"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Zeit"
-#: contrib/admin/views/doc.py:318
+#: contrib/admindocs/views.py:342
#: contrib/flatpages/models.py:8
msgid "URL"
msgstr "Adresse (URL)"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "U.S. Bundesstaat (zwei Großbuchstaben)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "XML-Text"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s ist scheinbar kein urlpattern Objekt"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Website-Verwaltung"
-
-#: contrib/admin/views/main.py:280
-#: contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "Jetzt kann ein weiteres Element vom Typ %s angelegt werden."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "%s hinzufügen"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "%s hinzugefügt."
-
-#: contrib/admin/views/main.py:344
-#: contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348
-#: core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "und"
-
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "%s geändert."
-
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "%s gelöscht."
-
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "Keine Felder geändert."
-
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "%(name)s \"%(obj)s\" wurde erfolgreich geändert."
-
-#: contrib/admin/views/main.py:362
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt. Das Element kann jetzt geändert werden."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "%s ändern"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Persönliche Infos"
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Ein oder mehrere %(fieldname)s in %(name)s: %(obj)s"
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Berechtigungen"
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Ein oder mehrere %(fieldname)s in %(name)s:"
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Wichtige Daten"
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "%(name)s \"%(obj)s\" wurde erfolgreich gelöscht."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Gruppen"
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "Sind Sie ganz sicher?"
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Benutzer hinzufügen"
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Änderungsgeschichte: %s"
+#: contrib/auth/forms.py:15
+#: contrib/auth/models.py:134
+msgid "Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."
+msgstr "Erforderlich. 30 Zeichen oder weniger. Alphanumerische Zeichen (Buchstaben, Ziffern und Unterstriche sind erlaubt)."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "%s auswählen"
+#: contrib/auth/forms.py:16
+#: core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Dieser Wert darf nur Buchstaben, Ziffern und Unterstriche enthalten."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "%s zur Änderung auswählen"
+#: contrib/auth/forms.py:18
+msgid "Password confirmation"
+msgstr "Passwort bestätigen"
-#: contrib/admin/views/main.py:765
-msgid "Database error"
-msgstr "Datenbankfehler"
+#: contrib/auth/forms.py:30
+msgid "A user with that username already exists."
+msgstr "Ein Benutzer mit diesem Namen existiert bereits."
-#: contrib/auth/forms.py:17
-#: contrib/auth/forms.py:138
+#: contrib/auth/forms.py:36
+#: contrib/auth/forms.py:146
+#: contrib/auth/forms.py:188
msgid "The two password fields didn't match."
msgstr "Die beiden Passwörter sind nicht identisch."
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "Ein Benutzer mit diesem Namen existiert bereits."
+#: contrib/auth/forms.py:74
+#: contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "Dieser Benutzer ist inaktiv."
-#: contrib/auth/forms.py:53
+#: contrib/auth/forms.py:79
+#: contrib/comments/views/comments.py:49
msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
msgstr "Der Webbrowser scheint keine Cookies aktiviert zu haben. Cookies sind für die Anmeldung zwingend erforderlich."
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Dieser Benutzer ist inaktiv."
+#: contrib/auth/forms.py:92
+msgid "E-mail"
+msgstr "E-Mail-Adresse"
-#: contrib/auth/forms.py:84
+#: contrib/auth/forms.py:101
msgid "That e-mail address doesn't have an associated user account. Are you sure you've registered?"
msgstr "Zu dieser E-Mail-Adresse existiert kein Benutzer. Sicher, dass Sie sich mit dieser Adresse angemeldet haben?"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:126
#, python-format
msgid "Password reset on %s"
msgstr "Passwort auf %s zurücksetzen"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "Die beiden neuen Passwörter sind nicht identisch."
+#: contrib/auth/forms.py:134
+msgid "New password"
+msgstr "Neues Passwort"
+
+#: contrib/auth/forms.py:135
+msgid "New password confirmation"
+msgstr "Neues Passwort bestätigen"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:160
+msgid "Old password"
+msgstr "Altes Passwort"
+
+#: contrib/auth/forms.py:168
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "Das alte Passwort war falsch. Bitte neu eingeben."
@@ -1095,112 +1184,101 @@ msgid "group"
msgstr "Gruppe"
#: contrib/auth/models.py:98
-#: contrib/auth/models.py:148
+#: contrib/auth/models.py:144
msgid "groups"
msgstr "Gruppen"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:134
msgid "username"
msgstr "Benutzername"
-#: contrib/auth/models.py:138
-msgid "Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."
-msgstr "Erforderlich. 30 Zeichen oder weniger. Alphanumerische Zeichen (Buchstaben, Ziffern und Unterstriche sind erlaubt)."
-
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "Vorname"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "Nachname"
-#: contrib/auth/models.py:141
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "E-Mail-Adresse"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid "password"
msgstr "Passwort"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."
msgstr "Die Form '[algo]$[salt]$[hexdigest]' verwenden, oder das <a href=\"password/\">Passwort ändern Formular</a> benutzen."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "staff status"
-msgstr "Administrator"
+msgstr "Redakteur"
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
msgstr "Legt fest, ob sich der Benutzer an der Administrationsseite anmelden kann."
-#: contrib/auth/models.py:144
+#: contrib/auth/models.py:140
msgid "active"
msgstr "Aktiv"
-#: contrib/auth/models.py:144
+#: contrib/auth/models.py:140
msgid "Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
msgstr "Legt fest, ob dieser Benutzer aktiv ist. Kann deaktiviert werden, anstatt Benutzer zu löschen."
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid "superuser status"
-msgstr "Hauptadmin."
+msgstr "Hauptadmin"
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid "Designates that this user has all permissions without explicitly assigning them."
msgstr "Legt fest, dass der Benutzer alle Berechtigungen hat, ohne diese einzeln zuweisen zu müssen."
-#: contrib/auth/models.py:146
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "Letzte Anmeldung"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "Mitglied seit"
-#: contrib/auth/models.py:149
+#: contrib/auth/models.py:145
msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
msgstr "Zusätzlich zu den manuell angelegten Rechten erhält dieser Benutzer auch alle Rechte, die seine zugewiesenen Gruppen haben."
-#: contrib/auth/models.py:150
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "Berechtigungen"
-#: contrib/auth/models.py:154
+#: contrib/auth/models.py:150
msgid "user"
msgstr "Benutzer"
-#: contrib/auth/models.py:155
+#: contrib/auth/models.py:151
msgid "users"
msgstr "Benutzer"
-#: contrib/auth/models.py:161
-msgid "Personal info"
-msgstr "Persönliche Infos"
-
-#: contrib/auth/models.py:162
-msgid "Permissions"
-msgstr "Berechtigungen"
-
-#: contrib/auth/models.py:163
-msgid "Important dates"
-msgstr "Wichtige Daten"
-
-#: contrib/auth/models.py:164
-msgid "Groups"
-msgstr "Gruppen"
-
-#: contrib/auth/models.py:323
+#: contrib/auth/models.py:306
msgid "message"
msgstr "Mitteilung"
-#: contrib/auth/views.py:48
+#: contrib/auth/views.py:50
msgid "Logged out"
msgstr "Abgemeldet"
+#: contrib/auth/views.py:160
+msgid "Password changed successfully."
+msgstr "Passwort erfolgreich geändert."
+
+#: contrib/auth/views.py:166
+#, python-format
+msgid "Change password: %s"
+msgstr "Passwort ändern: %s"
+
#: contrib/comments/models.py:71
-#: contrib/comments/models.py:176
+#: contrib/comments/models.py:164
msgid "object ID"
msgstr "Objekt-ID"
@@ -1210,7 +1288,7 @@ msgstr "Ãœberschrift"
#: contrib/comments/models.py:73
#: contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "Kommentar"
@@ -1251,12 +1329,12 @@ msgid "is valid rating"
msgstr "ist eine Bewertung"
#: contrib/comments/models.py:87
-#: contrib/comments/models.py:179
+#: contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "Datum/Zeit Erstellung"
#: contrib/comments/models.py:88
-#: contrib/comments/models.py:180
+#: contrib/comments/models.py:168
msgid "is public"
msgstr "ist öffentlich"
@@ -1272,12 +1350,12 @@ msgstr "Hier einen Haken setzen, wenn der Kommentar unpassend ist. Stattdessen w
msgid "comments"
msgstr "Kommentare"
-#: contrib/comments/models.py:140
-#: contrib/comments/models.py:222
+#: contrib/comments/models.py:128
+#: contrib/comments/models.py:199
msgid "Content object"
msgstr "Inhaltsobjekt"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1292,48 +1370,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "Autorname"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "IP-Adresse"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "Bestätigt vom Betreiber"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "Freier Kommentar"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "Freie Kommentare"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "Bewertung"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "Bewertungsdatum"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "Karma Bewertung"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "Karma Bewertungen"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "%(score)d Bewertung von %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1344,36 +1422,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "Kennzeichnungsdatum"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "Benutzerkennzeichnung"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "Benutzerkennzeichnungen"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Gekennzeichnet von %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "Löschdatum"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "Löschung vom Moderator"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "Löschungen vom Moderator"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Vom Moderator %r gelöscht"
@@ -1414,11 +1492,11 @@ msgstr "Kommentarvorschau"
msgid "Your name:"
msgstr "Ihr Name:"
-#: contrib/comments/views/comments.py:28
+#: contrib/comments/views/comments.py:76
msgid "This rating is required because you've entered at least one other rating."
msgstr "Diese Abstimmung ist zwingend erforderlich, da Sie an mindestens einer weiteren Abstimmung teilnehmen."
-#: contrib/comments/views/comments.py:112
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
"This comment was posted by a user who has posted fewer than %(count)s comment:\n"
@@ -1437,7 +1515,7 @@ msgstr[1] ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1448,28 +1526,28 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Nur POST ist erlaubt"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
msgid "One or more of the required fields wasn't submitted"
msgstr "Eines oder mehrere der erforderlichen Felder fehlen"
-#: contrib/comments/views/comments.py:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
msgid "Somebody tampered with the comment form (security violation)"
msgstr "Jemand hat mit dem Kommentarformular herumgespielt (Sicherheitsverletzung)"
-#: contrib/comments/views/comments.py:208
-#: contrib/comments/views/comments.py:295
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
msgid "The comment form had an invalid 'target' parameter -- the object ID was invalid"
msgstr "Das Kommentarformular hatte einen falschen 'target' Parameter -- die Objekt-ID ist ungültig."
-#: contrib/comments/views/comments.py:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Das Kommentarformular wurde nicht mit 'preview' oder 'post' abgeschickt"
@@ -1497,6 +1575,10 @@ msgstr "Inhaltstyp"
msgid "content types"
msgstr "Inhaltstypen"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Erweiterte Optionen"
+
#: contrib/flatpages/models.py:9
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr "Beispiel: '/about/contact/'. Wichtig: Am Anfang und Ende muss ein / stehen."
@@ -1537,10 +1619,6 @@ msgstr "Webseite"
msgid "flat pages"
msgstr "Webseiten"
-#: contrib/flatpages/models.py:27
-msgid "Advanced options"
-msgstr "Erweiterte Optionen"
-
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "."
@@ -1650,6 +1728,52 @@ msgstr "Bitte eine gültige CUIT im Format XX-XXXXXXXX-X oder XXXXXXXXXXXX einge
msgid "Invalid CUIT."
msgstr "Ungültige CUIT."
+#: contrib/localflavor/at/at_states.py:5
+msgid "Burgenland"
+msgstr "Burgenland"
+
+#: contrib/localflavor/at/at_states.py:6
+msgid "Carinthia"
+msgstr "Kärnten"
+
+#: contrib/localflavor/at/at_states.py:7
+msgid "Lower Austria"
+msgstr "Niederösterreich"
+
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr "Oberösterreich"
+
+#: contrib/localflavor/at/at_states.py:9
+msgid "Salzburg"
+msgstr "Salzburg"
+
+#: contrib/localflavor/at/at_states.py:10
+msgid "Styria"
+msgstr "Steiermark"
+
+#: contrib/localflavor/at/at_states.py:11
+msgid "Tyrol"
+msgstr "Tirol"
+
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr "Vorarlberg"
+
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr "Wien"
+
+#: contrib/localflavor/at/forms.py:20
+#: contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Bitte eine gültige Postleitzahl im Format XXXX eingeben."
+
+#: contrib/localflavor/at/forms.py:48
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
+msgstr "Bitte eine gültige österreichische Sozialversicherungsnummer im Format XXXX XXXXXX eingeben."
+
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
msgstr "Bitte eine gültige vierstellige Postleitzahl eingeben."
@@ -1692,15 +1816,15 @@ msgstr "Bitte eine gültige kanadische Sozialversicherungsnummer im Format XXX-X
#: contrib/localflavor/ch/ch_states.py:5
msgid "Aargau"
-msgstr ""
+msgstr "Aargau"
#: contrib/localflavor/ch/ch_states.py:6
msgid "Appenzell Innerrhoden"
-msgstr ""
+msgstr "Appenzell Innerrhoden"
#: contrib/localflavor/ch/ch_states.py:7
msgid "Appenzell Ausserrhoden"
-msgstr ""
+msgstr "Appenzell Ausserrhoden"
#: contrib/localflavor/ch/ch_states.py:8
msgid "Basel-Stadt"
@@ -1794,11 +1918,6 @@ msgstr ""
msgid "Zurich"
msgstr "Zürich"
-#: contrib/localflavor/ch/forms.py:16
-#: contrib/localflavor/no/forms.py:12
-msgid "Enter a zip code in the format XXXX."
-msgstr "Bitte eine gültige Postleitzahl im Format XXXX eingeben."
-
#: contrib/localflavor/ch/forms.py:64
msgid "Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format."
msgstr "Bitte eine gültige Schweizer Identifikations- oder Reisepassnummer im FormatX1234567<0 oder 1234567890 eingeben."
@@ -2149,6 +2268,7 @@ msgid "Region of Murcia"
msgstr ""
#: contrib/localflavor/es/es_regions.py:20
+#, fuzzy
msgid "Foral Community of Navarre"
msgstr ""
@@ -2704,6 +2824,26 @@ msgstr ""
msgid "West Pomerania"
msgstr ""
+#: contrib/localflavor/ro/forms.py:19
+msgid "Enter a valid CIF."
+msgstr "Bitte eine gültige CIF eingeben."
+
+#: contrib/localflavor/ro/forms.py:56
+msgid "Enter a valid CNP."
+msgstr "Bitte eine gültige CNP eingeben."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr "Bitte eine gültige IBAN im Format ROXX-XXXX-XXXX-XXXX-XXXX-XXXX eingeben."
+
+#: contrib/localflavor/ro/forms.py:171
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Telefonnummern müssen das Format XXXX-XXXXXX haben."
+
+#: contrib/localflavor/ro/forms.py:194
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Bitte eine gültige Postleitzahl im Format XXXXXX eingeben"
+
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
msgstr "Bitte eine gültige Postleitzahl im Format XXXXX oder XXX XX eingeben."
@@ -3444,18 +3584,14 @@ msgstr "Domainname"
msgid "display name"
msgstr "Anzeigename"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "Website"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "Websites"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Dieser Wert darf nur Buchstaben, Ziffern und Unterstriche enthalten."
-
#: core/validators.py:76
msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
msgstr "Dieser Wert darf nur Buchstaben, Ziffern, Unterstriche und Schrägstriche enthalten."
@@ -3497,7 +3633,7 @@ msgid "This value can't be comprised solely of digits."
msgstr "Dieser Wert darf nicht nur aus Ziffern bestehen."
#: core/validators.py:128
-#: newforms/fields.py:152
+#: forms/fields.py:161
msgid "Enter a whole number."
msgstr "Bitte eine ganze Zahl eingeben."
@@ -3506,65 +3642,59 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Nur alphabetische Zeichen sind hier erlaubt."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "Das Jahr muss 1900 oder später sein."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Ungültiges Datum: %s"
-#: core/validators.py:156
-#: db/models/fields/__init__.py:548
+#: core/validators.py:152
+#: db/models/fields/__init__.py:574
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Bitte ein gültiges Datum im Format JJJJ-MM-TT eingeben."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Bitte eine gültige Zeit im Format SS:MM eingeben."
-#: core/validators.py:165
-#: db/models/fields/__init__.py:625
+#: core/validators.py:161
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Bitte eine gültige Datums- und Zeitangabe im Format JJJJ-MM-TT SS:MM eingeben."
-#: core/validators.py:170
-#: newforms/fields.py:403
+#: core/validators.py:166
+#: forms/fields.py:412
msgid "Enter a valid e-mail address."
msgstr "Bitte eine gültige E-Mail-Adresse eingeben."
-#: core/validators.py:182
-#: core/validators.py:474
-#: newforms/fields.py:433
-#: oldforms/__init__.py:687
+#: core/validators.py:178
+#: core/validators.py:470
+#: forms/fields.py:430
msgid "No file was submitted. Check the encoding type on the form."
msgstr "Es wurde keine Datei übermittelt. Eventuell ist das Formular-Encoding falsch."
-#: core/validators.py:193
-#: newforms/fields.py:459
+#: core/validators.py:189
+#: forms/fields.py:470
msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
msgstr "Bitte ein Bild hochladen. Die hochgeladene Datei ist kein Bild, oder ist defekt."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "Die URL %s zeigt nicht auf ein gültiges Bild."
-#: core/validators.py:204
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr "Telefonnummern müssen das Format XXX-XXX-XXXX haben. \"%s\" ist ungültig."
-#: core/validators.py:212
+#: core/validators.py:208
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "Die URL %s zeigt nicht auf ein gültiges QuickTime-Video."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Eine gültige URL wird hier verlangt."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3573,331 +3703,337 @@ msgstr ""
"Bitte gültiges HTML eingeben. Fehler sind:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "Ungültiges XML: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "Ungültige URL: %s"
-#: core/validators.py:259
-#: core/validators.py:261
+#: core/validators.py:255
+#: core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "Die URL %s funktioniert nicht."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Bitte eine gültige Abkürzung für einen US-Staat eingeben."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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] "Keine Schimpfworte! Das Wort %s ist hier nicht gern gesehen!"
msgstr[1] "Keine Schimpfworte! Die Wörter %s sind hier nicht gern gesehen!"
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Dieses Feld muss zum Feld '%s' passen."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Bitte mindestens eines der Felder ausfüllen."
-#: core/validators.py:316
-#: core/validators.py:327
+#: core/validators.py:312
+#: core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Bitte entweder beide Felder ausfüllen, oder beide leer lassen."
-#: core/validators.py:335
+#: core/validators.py:331
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "Dieses Feld muss gefüllt sein, wenn Feld %(field)s den Wert %(value)s hat."
-#: core/validators.py:348
+#: core/validators.py:344
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr "Dieses Feld muss gefüllt sein, wenn Feld %(field)s nicht %(value)s ist."
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Doppelte Werte sind hier nicht erlaubt."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Dieser Wert muss zwischen %(lower)s und %(upper)s sein."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Dieser Wert muss mindestens %s sein."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Dieser Wert darf maximal %s sein."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Dieser Wert muss eine Potenz von %s sein."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Bitte eine gültige Dezimalzahl eingeben."
-#: core/validators.py:444
+#: core/validators.py:440
#, 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] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffer eingeben."
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffern eingeben."
-#: core/validators.py:447
+#: core/validators.py:443
#, 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] "Bitte eine gültige Dezimalzahl mit einer Gesamtzahl von maximal %s Ziffer eingeben."
msgstr[1] "Bitte eine gültige Dezimalzahl mit einer Gesamtzahl von maximal %s Ziffern eingeben."
-#: core/validators.py:450
+#: core/validators.py:446
#, 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] "Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstelle eingeben."
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstellen eingeben."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Bitte eine gültige Dezimalzahl eingeben."
-#: core/validators.py:467
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "Bitte sicherstellen, dass die hochgeladene Datei mindestens %s Bytes groß ist."
-#: core/validators.py:468
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "Bitte sicherstellen, dass die hochgeladene Datei maximal %s Bytes groß ist."
-#: core/validators.py:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Das Format für dieses Feld ist falsch."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Dieses Feld ist ungültig."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Konnte nichts von %s empfangen."
-#: core/validators.py:539
+#: core/validators.py:535
#, python-format
msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
msgstr "Die URL %(url)s lieferte den falschen Content-Type '%(contenttype)s'."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
msgid "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with \"%(start)s\".)"
msgstr "Bitte das ungeschlossene %(tag)s Tag in Zeile %(line)s schließen. Die Zeile beginnt mit \"%(start)s\"."
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
msgid "Some text starting on line %(line)s is not allowed in that context. (Line starts with \"%(start)s\".)"
msgstr "In Zeile %(line)s ist Text, der nicht in dem Kontext erlaubt ist. Die Zeile beginnt mit \"%(start)s\"."
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
msgid "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%(start)s\".)"
msgstr "Das Attribute %(attr)s in Zeile %(line)s ist ungültig. Die Zeile beginnt mit \"%(start)s\"."
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
msgid "\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%(start)s\".)"
msgstr "<%(tag)s> in Zeile %(line)s ist ungültig. Die Zeile beginnt mit \"%(start)s\"."
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
msgid "A tag on line %(line)s is missing one or more required attributes. (Line starts with \"%(start)s\".)"
msgstr "Ein Tag in Zeile %(line)s hat eines oder mehrere Pflichtattribute nicht. Die Zeile beginnt mit \"%(start)s\"."
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
msgid "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line starts with \"%(start)s\".)"
msgstr "Das Attribut %(attr)s in Zeile %(line)s hat einen ungültigen Wert. Die Zeile beginnt mit \"%(start)s\"."
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "Ein '%(object)s' in dieser '%(type)s' existiert bereits für dieses '%(field)s'."
-#: db/models/fields/__init__.py:51
+#: db/models/fields/__init__.py:47
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "Ein '%(optname)s' mit diesem '%(fieldname)s' existiert bereits."
-#: db/models/fields/__init__.py:176
+#: db/models/fields/__init__.py:175
#: db/models/fields/__init__.py:348
-#: db/models/fields/__init__.py:780
-#: db/models/fields/__init__.py:791
-#: newforms/fields.py:46
+#: db/models/fields/__init__.py:797
+#: db/models/fields/__init__.py:808
+#: forms/fields.py:52
#: oldforms/__init__.py:374
msgid "This field is required."
msgstr "Dieses Feld ist zwingend erforderlich."
-#: db/models/fields/__init__.py:448
+#: db/models/fields/__init__.py:462
msgid "This value must be an integer."
msgstr "Dieser Wert muss eine Ganzzahl sein."
-#: db/models/fields/__init__.py:487
+#: db/models/fields/__init__.py:508
msgid "This value must be either True or False."
msgstr "Dieser Wert muss wahr oder falsch sein."
-#: db/models/fields/__init__.py:511
+#: db/models/fields/__init__.py:537
msgid "This field cannot be null."
msgstr "Dieses Feld darf nicht leer sein."
-#: db/models/fields/__init__.py:689
+#: db/models/fields/__init__.py:639
+#: db/models/fields/__init__.py:656
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format."
+msgstr "Bitte eine gültige Datums- und Zeitangabe im Format JJJJ-MM-TT SS:MM[ss[.uuuuuu]] eingeben."
+
+#: db/models/fields/__init__.py:712
msgid "This value must be a decimal number."
-msgstr "Dieser Wert muss eine Ganzzahl sein."
+msgstr "Dieser Wert muss eine Dezimalzahl sein."
-#: db/models/fields/__init__.py:800
+#: db/models/fields/__init__.py:817
msgid "Enter a valid filename."
msgstr "Bitte einen gültigen Dateinamen eingeben."
-#: db/models/fields/__init__.py:981
+#: db/models/fields/__init__.py:1018
msgid "This value must be either None, True or False."
msgstr "Dieser Wert muss None, True oder False sein."
-#: db/models/fields/related.py:94
+#: db/models/fields/__init__.py:1133
+#: db/models/fields/__init__.py:1146
+msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
+msgstr "Bitte eine gültige Zeit im Format HH:MM[:ss[.uuuuuu]] eingeben."
+
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Bitte ein gültiges '%s' eingeben."
-#: db/models/fields/related.py:746
-msgid "Separate multiple IDs with commas."
-msgstr "Mehrere IDs können mit Komma getrennt werden."
-
-#: db/models/fields/related.py:748
+#: db/models/fields/related.py:758
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "Um mehr als eine Selektion zu treffen, \"Strg\", oder auf dem Mac \"Command\", beim Klicken gedrückt halten."
-#: db/models/fields/related.py:795
+#: db/models/fields/related.py:838
#, 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] "Bitte gültige IDs für %(self)s eingeben. Der Wert %(value)r ist ungültig."
msgstr[1] "Bitte gültige IDs für %(self)s eingeben. Die Werte %(value)r sind ungültig."
-#: newforms/fields.py:47
+#: forms/fields.py:53
msgid "Enter a valid value."
msgstr "Bitte einen gültigen Wert eingeben."
-#: newforms/fields.py:124
+#: forms/fields.py:133
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr "Bitte sicherstellen, dass der Text maximal %(max)d Zeichen hat. (Er hat %(length)d)."
-#: newforms/fields.py:125
+#: forms/fields.py:134
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr "Bitte sicherstellen, dass der Text wenigstens %(min)d Zeichen hat. (Er hat %(length)d.)"
-#: newforms/fields.py:153
-#: newforms/fields.py:182
-#: newforms/fields.py:211
+#: forms/fields.py:162
+#: forms/fields.py:191
+#: forms/fields.py:220
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Dieser Wert darf maximal %s sein."
-#: newforms/fields.py:154
-#: newforms/fields.py:183
-#: newforms/fields.py:212
+#: forms/fields.py:163
+#: forms/fields.py:192
+#: forms/fields.py:221
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Dieser Wert muss größer oder gleich %s sein."
-#: newforms/fields.py:181
-#: newforms/fields.py:210
+#: forms/fields.py:190
+#: forms/fields.py:219
msgid "Enter a number."
msgstr "Bitte eine Zahl eingeben."
-#: newforms/fields.py:213
+#: forms/fields.py:222
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "Bitte geben Sie nicht mehr als insgesamt %s Ziffern ein."
-#: newforms/fields.py:214
+#: forms/fields.py:223
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "Bitte geben Sie nicht mehr als %s Dezimalstellen ein."
-#: newforms/fields.py:215
+#: forms/fields.py:224
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Bitte geben Sie nicht mehr als %s Ziffern vor dem Komma ein."
-#: newforms/fields.py:263
-#: newforms/fields.py:750
+#: forms/fields.py:272
+#: forms/fields.py:802
msgid "Enter a valid date."
msgstr "Bitte ein gültiges Datum eingeben."
-#: newforms/fields.py:296
-#: newforms/fields.py:751
+#: forms/fields.py:305
+#: forms/fields.py:803
msgid "Enter a valid time."
msgstr "Bitte eine gültige Uhrzeit eingeben."
-#: newforms/fields.py:335
+#: forms/fields.py:344
msgid "Enter a valid date/time."
-msgstr "Bitte gültiges Datum und Uhrzeit eingeben."
+msgstr "Bitte ein gültiges Datum und Uhrzeit eingeben."
-#: newforms/fields.py:434
+#: forms/fields.py:431
msgid "No file was submitted."
msgstr "Es wurde keine Datei übertragen."
-#: newforms/fields.py:435
-#: oldforms/__init__.py:689
+#: forms/fields.py:432
+#: oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "Die ausgewählte Datei ist leer."
-#: newforms/fields.py:497
+#: forms/fields.py:531
msgid "Enter a valid URL."
msgstr "Bitte eine gültige Adresse eingeben."
-#: newforms/fields.py:498
+#: forms/fields.py:532
msgid "This URL appears to be a broken link."
msgstr "Diese Adresse scheint nicht gültig zu sein."
-#: newforms/fields.py:559
-#: newforms/models.py:305
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Bitte eine gültige Auswahl treffen."
-
-#: newforms/fields.py:598
+#: forms/fields.py:600
+#: forms/fields.py:651
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "Bitte eine gültige Auswahl treffen. %(value)s ist keine gültige Auswahl."
-#: newforms/fields.py:599
-#: newforms/fields.py:661
-#: newforms/models.py:372
+#: forms/fields.py:652
+#: forms/fields.py:713
+#: forms/models.py:588
msgid "Enter a list of values."
-msgstr "Eine Liste mit Werten eingeben."
+msgstr "Bitte eine Liste mit Werten eingeben."
-#: newforms/fields.py:779
+#: forms/fields.py:831
msgid "Enter a valid IPv4 address."
msgstr "Bitte eine gültige IPv4-Adresse eingeben."
-#: newforms/models.py:373
+#: forms/models.py:521
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Bitte eine gültige Auswahl treffen."
+
+#: forms/models.py:589
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr "Bitte eine gültige Auswahl treffen. %s ist keine gültige Auswahl."
@@ -3920,15 +4056,15 @@ msgstr "Zeilenumbrüche sind hier nicht erlaubt."
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Bitte eine gültige Auswahl treffen; '%(data)s' ist nicht in %(choices)s."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
-msgstr "Bitte eine Ganzzahl zwischen -32.768 und 32.767 eingeben."
+msgstr "Bitte eine ganze Zahl zwischen -32.768 und 32.767 eingeben."
-#: oldforms/__init__.py:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Bitte eine ganze, positive Zahl eingeben."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Bitte eine ganze Zahl zwischen 0 und 32.767 eingeben."
@@ -4167,7 +4303,7 @@ msgstr "Nov."
msgid "Dec."
msgstr "Dez."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "oder"
@@ -4221,38 +4357,57 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:403
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "j. N Y"
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "j. N Y, H:i"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "H:i"
-#: utils/translation/trans_real.py:421
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "j. F"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "%(verbose_name)s wurde erfolgreich angelegt."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "%(verbose_name)s wurde erfolgreich aktualisiert."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s wurde gelöscht"
+#~ msgid "Ordering"
+#~ msgstr "Sortierung"
+#~ msgid "Order:"
+#~ msgstr "Reihenfolge:"
+#~ msgid "Your new password is: %(new_password)s"
+#~ msgstr "Ihr neues Passwort lautet: %(new_password)s"
+#~ msgid "Feel free to change this password by going to this page:"
+#~ msgstr "Sie können das Passwort auf folgender Seite ändern:"
+#~ msgid "Added %s."
+#~ msgstr "%s hinzugefügt."
+#~ msgid "Deleted %s."
+#~ msgstr "%s gelöscht."
+#~ msgid "The two 'new password' fields didn't match."
+#~ msgstr "Die beiden neuen Passwörter sind nicht identisch."
+#~ msgid "Year must be 1900 or later."
+#~ msgstr "Das Jahr muss 1900 oder später sein."
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Mehrere IDs können mit Komma getrennt werden."
+
diff --git a/django/conf/locale/es/LC_MESSAGES/django.mo b/django/conf/locale/es/LC_MESSAGES/django.mo
index a2fd2f77db..49f4fa3541 100644
--- a/django/conf/locale/es/LC_MESSAGES/django.mo
+++ b/django/conf/locale/es/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/es/LC_MESSAGES/django.po b/django/conf/locale/es/LC_MESSAGES/django.po
index b665fcf9a6..78e6b75b24 100644
--- a/django/conf/locale/es/LC_MESSAGES/django.po
+++ b/django/conf/locale/es/LC_MESSAGES/django.po
@@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-06-13 16:14+0200\n"
-"PO-Revision-Date: 2008-06-18 22:45+0200\n"
+"POT-Creation-Date: 2008-07-24 12:48+0200\n"
+"PO-Revision-Date: 2008-07-24 13:30+0100\n"
"Last-Translator: Django Spanish Translation Team <django-cat@googlegroups.com>\n"
"Language-Team: Django Spanish Translation Team <django-cat@googlegroups.com>\n"
"MIME-Version: 1.0\n"
@@ -59,146 +59,154 @@ msgid "Spanish"
msgstr "español"
#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "estonio"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
msgstr "español de Argentina"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:57
msgid "Basque"
msgstr "vasco"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:58
msgid "Persian"
msgstr "persa"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:59
msgid "Finnish"
msgstr "finés"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:60
msgid "French"
msgstr "francés"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:61
msgid "Irish"
msgstr "irlandés"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:62
msgid "Galician"
msgstr "gallego"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:63
msgid "Hungarian"
msgstr "húngaro"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:64
msgid "Hebrew"
msgstr "hebreo"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:65
msgid "Croatian"
msgstr "croata"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:66
msgid "Icelandic"
msgstr "islandés"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:67
msgid "Italian"
msgstr "italiano"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:68
msgid "Japanese"
msgstr "japonés"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:69
msgid "Georgian"
msgstr "georgiano"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:70
msgid "Korean"
msgstr "koreano"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:71
msgid "Khmer"
msgstr "khmer"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:72
msgid "Kannada"
msgstr "kannada"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:73
msgid "Latvian"
msgstr "letón"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "lituano"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
msgstr "macedonio"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:76
msgid "Dutch"
msgstr "holandés"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:77
msgid "Norwegian"
msgstr "noruego"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:78
msgid "Polish"
msgstr "polaco"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:79
msgid "Portugese"
msgstr "portugués"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:80
msgid "Brazilian Portuguese"
msgstr "portugués de Brasil"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:81
msgid "Romanian"
msgstr "rumano"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:82
msgid "Russian"
msgstr "ruso"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:83
msgid "Slovak"
msgstr "eslovaco"
-#: conf/global_settings.py:82
+#: conf/global_settings.py:84
msgid "Slovenian"
msgstr "esloveno"
-#: conf/global_settings.py:83
+#: conf/global_settings.py:85
msgid "Serbian"
msgstr "serbio"
-#: conf/global_settings.py:84
+#: conf/global_settings.py:86
msgid "Swedish"
msgstr "sueco"
-#: conf/global_settings.py:85
+#: conf/global_settings.py:87
msgid "Tamil"
msgstr "tamil"
-#: conf/global_settings.py:86
+#: conf/global_settings.py:88
msgid "Telugu"
msgstr "telugu"
-#: conf/global_settings.py:87
+#: conf/global_settings.py:89
msgid "Turkish"
msgstr "turco"
-#: conf/global_settings.py:88
+#: conf/global_settings.py:90
msgid "Ukrainian"
msgstr "ucraniano"
-#: conf/global_settings.py:89
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
msgstr "chino simplificado"
-#: conf/global_settings.py:90
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
msgstr "chino tradicional"
@@ -211,8 +219,10 @@ msgstr ""
"<h3>Por %s:</h3>\n"
"<ul>\n"
-#: contrib/admin/filterspecs.py:74 contrib/admin/filterspecs.py:92
-#: contrib/admin/filterspecs.py:147 contrib/admin/filterspecs.py:173
+#: contrib/admin/filterspecs.py:74
+#: contrib/admin/filterspecs.py:92
+#: contrib/admin/filterspecs.py:147
+#: contrib/admin/filterspecs.py:173
msgid "All"
msgstr "Todo"
@@ -236,49 +246,209 @@ msgstr "Este mes"
msgid "This year"
msgstr "Este año"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Sí"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "No"
-#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:154
+#: forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Desconocido"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "hora de acción"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "id de objeto"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "repr de objeto"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "marca de acción"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "mensaje de cambio"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "entrada de registro"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "entradas de registro"
+#: contrib/admin/options.py:161
+#: contrib/admin/options.py:180
+msgid "None"
+msgstr "Ninguno"
+
+#: contrib/admin/options.py:347
+#: contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "Se añadió con éxito el %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:351
+#: contrib/admin/options.py:419
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "Puede editarlo de nuevo abajo."
+
+#: contrib/admin/options.py:361
+#: contrib/admin/options.py:428
+#, python-format
+msgid "You may add another %s below."
+msgstr "Puede añadir otro %s abajo."
+
+#: contrib/admin/options.py:395
+#, python-format
+msgid "Changed %s."
+msgstr "Modificado/a %s."
+
+#: contrib/admin/options.py:395
+#: contrib/admin/options.py:405
+#: core/validators.py:279
+#: db/models/manipulators.py:305
+msgid "and"
+msgstr "y"
+
+#: contrib/admin/options.py:400
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Añadido/a \"%(object)s\" %(name)s."
+
+#: contrib/admin/options.py:404
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Modificados %(list)s para \"%(object)s\" %(name)s."
+
+#: contrib/admin/options.py:409
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Eliminado/a \"%(object)s\" %(name)s."
+
+#: contrib/admin/options.py:414
+msgid "No fields changed."
+msgstr "No ha cambiado ningún campo."
+
+#: contrib/admin/options.py:417
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "Se modificó con éxito el %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:425
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr "Se añadió con éxito el %(name)s \"%(obj)s. Puede editarlo de nuevo abajo."
+
+#: contrib/admin/options.py:506
+#, python-format
+msgid "Add %s"
+msgstr "Añadir %s"
+
+#: contrib/admin/options.py:568
+#, python-format
+msgid "Change %s"
+msgstr "Modificar %s"
+
+#: contrib/admin/options.py:598
+msgid "Database error"
+msgstr "Error en la base de datos"
+
+#: contrib/admin/options.py:647
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "Se eliminó con éxito el %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:653
+msgid "Are you sure?"
+msgstr "¿Está seguro?"
+
+#: contrib/admin/options.py:680
+#, python-format
+msgid "Change history: %s"
+msgstr "Histórico de modificaciones: %s"
+
+#: contrib/admin/sites.py:18
+#: contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:70
+#: contrib/comments/views/comments.py:56
+msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
+msgstr "Por favor, introduzca un nombre de usuario y contraseña correctos. Note que ambos campos son sensibles a mayúsculas/minúsculas."
+
+#: contrib/admin/sites.py:233
+#: contrib/admin/views/decorators.py:68
+msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
+msgstr "Por favor, inicie sesión de nuevo, ya que su sesión ha caducado. No se preocupe: se ha guardado su envío."
+
+#: contrib/admin/sites.py:240
+#: contrib/admin/views/decorators.py:75
+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 , recargue esta página, e inténtelo de nuevo."
+
+#: contrib/admin/sites.py:254
+#: contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Los nombres de usuario no pueden contener el carácter '@'."
+
+#: contrib/admin/sites.py:257
+#: contrib/admin/views/decorators.py:88
+#, 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/sites.py:325
+msgid "Site administration"
+msgstr "Sitio administrativo"
+
+#: contrib/admin/sites.py:347
+#: contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Iniciar sesión"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Uno o más %(fieldname)s en %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Uno o más %(fieldname)s en %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Fecha:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Hora:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Actualmente:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Modificar:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -289,17 +459,17 @@ 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/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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: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"
@@ -318,30 +488,31 @@ msgid "Server Error <em>(500)</em>"
msgstr "Error de servidor <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 ""
-"Ha ocurrido un error. Se ha informado a los administradores del sitio "
-"mediante correo electrónico y debería arreglarse en breve. Gracias por su "
-"paciencia."
+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 "Ha ocurrido un error. Se ha informado a los administradores del sitio mediante correo electrónico y debería arreglarse en breve. Gracias por su paciencia."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Bienvenido/a,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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 "Documentación"
-#: contrib/admin/templates/admin/base.html:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Cambiar contraseña"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Terminar sesión"
@@ -354,66 +525,53 @@ msgstr "Sitio de administración de Django"
msgid "Django administration"
msgstr "Administración de Django"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Añadir"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Histórico"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Ver en el sitio"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
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:49
-msgid "Ordering"
-msgstr "Ordenación"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Orden:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "Añadir %(name)s"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filtro"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Eliminar"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, 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:"
+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:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, 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:"
+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:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Sí, estoy seguro"
@@ -422,89 +580,70 @@ msgstr "Sí, estoy seguro"
msgid " By %(filter_title)s "
msgstr " Por %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filtro"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, 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/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Modificar"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "No tiene permiso para editar nada."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Acciones recientes"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Mis acciones"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Ninguno disponible"
-#: 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 ""
-"Algo va mal con la instalación de la base de datos. Asegúrese que las tablas "
-"necesarias han sido creadas, y que la base de datos puede ser leída por el "
-"usuario apropiado."
+#: contrib/admin/templates/admin/invalid_setup.html:7
+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 "Algo va mal con la instalación de la base de datos. Asegúrese que las tablas necesarias han sido creadas, y que la base de datos puede ser leída por el usuario apropiado."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
msgid "Username:"
msgstr "Usuario:"
-#: contrib/admin/templates/admin/login.html:20
+#: contrib/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Contraseña:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Iniciar sesión"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Fecha/hora"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Usuario"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Acción"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "j M Y P"
-#: contrib/admin/templates/admin/object_history.html:35
-msgid ""
-"This object doesn't have a change history. It probably wasn't added via this "
-"admin site."
-msgstr ""
-"Este objeto no tiene histórico de cambios. Probablemente no fue añadido "
-"usando este sitio de administración."
+#: contrib/admin/templates/admin/object_history.html:32
+msgid "This object doesn't have a change history. It probably wasn't added via this admin site."
+msgstr "Este objeto no tiene histórico de cambios. Probablemente no fue añadido usando este sitio de administración."
#: contrib/admin/templates/admin/pagination.html:10
msgid "Show all"
@@ -543,38 +682,38 @@ 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 "
-"options."
-msgstr ""
-"Primero introduzca un nombre de usuario y una contraseña. Luego podrá editar "
-"el resto de opciones del usuario."
+msgid "First, enter a username and password. Then, you'll be able to edit more user options."
+msgstr "Primero introduzca un nombre de usuario y una contraseña. Luego podrá editar el resto de opciones del usuario."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:12
+#: contrib/auth/forms.py:49
msgid "Username"
msgstr "Nombre de usuario"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:15
+#: contrib/auth/forms.py:50
+#: contrib/auth/forms.py:166
msgid "Password"
msgstr "Contraseña"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:167
msgid "Password (again)"
msgstr "Contraseña (de nuevo)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Introduzca la misma contraseña que arriba, para verificación."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
-msgstr ""
-"Introduzca una nueva contraseña para el usuario <strong>%(username)s</"
-"strong>."
+msgstr "Introduzca una nueva contraseña para el usuario <strong>%(username)s</strong>."
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
msgid "Bookmarklets"
@@ -596,36 +735,27 @@ msgid ""
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"
+"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 del sitio.\n"
"Observe que algunos de estos bookmarklets precisan que esté viendo\n"
"el sitio desde un ordenador señalado como \"interno\" (hable\n"
-"con su administrador de sistemas si no está seguro si el suyo lo es).</"
-"p>\n"
+"con su administrador de sistemas si no está seguro si el suyo lo es).</p>\n"
#: contrib/admin/templates/admin_doc/bookmarklets.html:18
msgid "Documentation for this page"
msgstr "Documentación para esta página"
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
-msgid ""
-"Jumps you from any page to the documentation for the view that generates "
-"that page."
-msgstr ""
-"Lleva desde cualquier página a la documentación de la vista que la genera."
+msgid "Jumps you from any page to the documentation for the view that generates that page."
+msgstr "Lleva desde cualquier página a la documentación de la vista que la genera."
#: contrib/admin/templates/admin_doc/bookmarklets.html:21
msgid "Show object ID"
msgstr "Mostrar ID de objeto"
#: contrib/admin/templates/admin_doc/bookmarklets.html:22
-msgid ""
-"Shows the content-type and unique ID for pages that represent a single "
-"object."
-msgstr ""
-"Muestra el tipo de contenido e ID único de las páginas que representan un "
-"simple objeto."
+msgid "Shows the content-type and unique ID for pages that represent a single object."
+msgstr "Muestra el tipo de contenido e ID único de las páginas que representan un simple objeto."
#: contrib/admin/templates/admin_doc/bookmarklets.html:24
msgid "Edit this object (current window)"
@@ -633,9 +763,7 @@ msgstr "Editar este objeto (ventana actual)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:25
msgid "Jumps to the admin page for pages that represent a single object."
-msgstr ""
-"Lleva a la página de administración de páginas que representan un único "
-"objeto."
+msgstr "Lleva a la página de administración de páginas que representan un único objeto."
#: contrib/admin/templates/admin_doc/bookmarklets.html:27
msgid "Edit this object (new window)"
@@ -643,8 +771,7 @@ msgstr "Editar este objeto (nueva ventana)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
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."
+msgstr "Como antes, pero abre la página de administración en una nueva ventana."
#: contrib/admin/templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today."
@@ -654,43 +781,39 @@ msgstr "Gracias por el tiempo que ha dedicado hoy al sitio web."
msgid "Log in again"
msgstr "Iniciar sesión de nuevo"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 contraseña"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: 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 contraseña exitoso"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Su contraseña ha sido cambiada."
-#: contrib/admin/templates/registration/password_change_form.html:11
-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 ""
-"Por favor, introduzca su contraseña antigua, por seguridad, y después introduzca "
-"la nueva contraseña dos veces para verificar que la ha escrito correctamente."
+#: 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 "Por favor, introduzca su contraseña antigua, por seguridad, y después introduzca la nueva contraseña dos veces para verificar que la ha escrito correctamente."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Contraseña antigua:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Contraseña nueva:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Confirme contraseña:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Cambiar mi contraseña"
@@ -707,12 +830,8 @@ msgid "Password reset successful"
msgstr "Restablecimiento de contraseña exitoso"
#: 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 ""
-"Le hemos enviado una contraseña nueva a la dirección que ha suministrado. Debería "
-"recibirla en breve."
+msgid "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly."
+msgstr "Le hemos enviado una contraseña nueva a la dirección que ha suministrado. Debería recibirla en breve."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
@@ -746,12 +865,8 @@ msgid "The %(site_name)s team"
msgstr "El equipo de %(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 ""
-"¿Ha olvidado su contraseña? Introduzca su dirección de correo electrónico, y "
-"crearemos una nueva que le enviaremos por correo."
+msgid "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you."
+msgstr "¿Ha olvidado su contraseña? Introduzca su dirección de correo electrónico, y crearemos una nueva que le enviaremos por correo."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -761,363 +876,257 @@ msgstr "Dirección de correo electrónico:"
msgid "Reset my password"
msgstr "Restablecer mi contraseña"
-#: 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/widget/file.html:2
-msgid "Currently:"
-msgstr "Actualmente:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Modificar:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Todas las fechas"
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
+#: contrib/admin/views/main.py:65
#, 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/auth.py:25 contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-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 contraseña se ha cambiado con éxito."
-
-#: contrib/admin/views/auth.py:65
-#, python-format
-msgid "Change password: %s"
-msgstr "Cambiar contraseña: %s"
-
-#: contrib/admin/views/decorators.py:17 contrib/auth/forms.py:60
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"Por favor, introduzca un nombre de usuario y contraseña correctos. Note que "
-"ambos campos son sensibles a mayúsculas/minúsculas."
-
-#: contrib/admin/views/decorators.py:69
-msgid ""
-"Please log in again, because your session has expired. Don't worry: Your "
-"submission has been saved."
-msgstr ""
-"Por favor, inicie sesión de nuevo, ya que su sesión ha caducado. No se "
-"preocupe: se ha guardado su envío."
-
-#: contrib/admin/views/decorators.py:76
-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 "
-", recargue esta página, e inténtelo de nuevo."
+msgid "Select %s"
+msgstr "Escoja %s"
-#: contrib/admin/views/decorators.py:89
+#: contrib/admin/views/main.py:65
#, 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/decorators.py:93
-msgid "Usernames cannot contain the '@' character."
-msgstr "Los nombres de usuario no pueden contener el carácter '@'."
+msgid "Select %s to change"
+msgstr "Escoja %s a modificar"
-#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53
+#: contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "etiqueta:"
-#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87
+#: contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filtro:"
-#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153
+#: contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "vista:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Aplicación %r no encontrada"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "El modelo %(name)s no se ha encontrado en la aplicación %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "El modelo %(model_name)r no se ha encontrado en la aplicación %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "el objeto relacionado `%(label)s.%(type)s`"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "el objeto relacionado `%(app_label)s.%(data_type)s`"
-#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206
+#: contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242
+#: contrib/admindocs/views.py:247
msgid "model:"
msgstr "modelo:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "los objetos relacionados `%(label)s.%(name)s`"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "los objetos relacionados `%(app_label)s.%(object_name)s`"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "todo %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "número de %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Campos en %s objetos"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317
+#: contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330
+#: contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337
+#: contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Entero"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Booleano (Verdadero o Falso)"
-#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319
+#: contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Cadena (máximo %(max_length)s)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Enteros separados por comas"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Fecha (sin hora)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Fecha (con hora)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Número decimal"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "Dirección de correo electrónico"
-#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325
+#: contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Ruta de fichero"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Número en coma flotante"
-#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331
+#: contrib/comments/models.py:89
msgid "IP address"
msgstr "Dirección IP"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Booleano (Verdadero, Falso o Nulo)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Relación con el modelo padre"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Número de teléfono"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Texto"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Hora"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
+#: contrib/admindocs/views.py:342
+#: contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Estado de los EEUU (dos letras mayúsculas)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "Texto XML"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s no parece ser un objeto urlpattern"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Sitio administrativo"
-
-#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "Puede añadir otro %s abajo."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Añadir %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "Añadido %s."
-
-#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348 core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "y"
-
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "Modificado %s."
-
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "Borrado %s."
-
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "No ha cambiado ningún campo."
-
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "Se modificó con éxito el %(name)s \"%(obj)s\"."
-
-#: contrib/admin/views/main.py:362
-#, python-format
-msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr ""
-"Se añadió con éxito el %(name)s \"%(obj)s. Puede editarlo de nuevo abajo."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Modificar %s"
-
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Uno o más %(fieldname)s en %(name)s: %(obj)s"
-
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Uno o más %(fieldname)s en %(name)s:"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Información personal"
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "Se eliminó con éxito el %(name)s \"%(obj)s\"."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Permisos"
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "¿Está seguro?"
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Fechas importantes"
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Histórico de modificaciones: %s"
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Grupos"
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Escoja %s"
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Añadir usuario"
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Escoja %s a modificar"
+#: contrib/auth/forms.py:13
+#: contrib/auth/models.py:134
+msgid "Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."
+msgstr "Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, dígitos y guiones bajos)."
-#: contrib/admin/views/main.py:765
-msgid "Database error"
-msgstr "Error en la base de datos"
+#: contrib/auth/forms.py:14
+#: core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Este valor debe contener sólo letras, números y guiones bajos."
-#: 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/auth/forms.py:16
+msgid "Password confirmation"
+msgstr "Contraseña (confirmación)"
-#: contrib/auth/forms.py:25
+#: contrib/auth/forms.py:28
msgid "A user with that username already exists."
msgstr "Ya existe un usuario con este nombre."
-#: contrib/auth/forms.py:53
-msgid ""
-"Your Web browser doesn't appear to have cookies enabled. Cookies are "
-"required for logging in."
-msgstr ""
-"Su navegador no parece tener las cookies habilitadas. Las "
-"cookies se necesitan para poder ingresar."
+#: contrib/auth/forms.py:34
+#: contrib/auth/forms.py:153
+#: contrib/auth/forms.py:178
+msgid "The two password fields didn't match."
+msgstr "Las dos contraseñas no coinciden."
-#: contrib/auth/forms.py:62
+#: contrib/auth/forms.py:72
+#: contrib/comments/views/comments.py:58
msgid "This account is inactive."
msgstr "Esta cuenta está inactiva."
-#: 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/auth/forms.py:77
+#: contrib/comments/views/comments.py:49
+msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
+msgstr "Su navegador no parece tener las cookies habilitadas. Las cookies se necesitan para poder ingresar."
+
+#: contrib/auth/forms.py:90
+msgid "E-mail"
+msgstr "Correo electrónico"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:99
+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/auth/forms.py:124
#, python-format
msgid "Password reset on %s"
msgstr "Contraseña restablecida en %s"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr ""
-"Los dos campos 'nueva contraseña' no coinciden."
+#: contrib/auth/forms.py:131
+msgid "Old password"
+msgstr "Contraseña antigua"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:132
+msgid "New password"
+msgstr "Contraseña nueva"
+
+#: contrib/auth/forms.py:133
+msgid "New password confirmation"
+msgstr "Contraseña nueva (confirmación):"
+
+#: contrib/auth/forms.py:145
msgid "Your old password was entered incorrectly. Please enter it again."
-msgstr ""
-"Su contraseña antigua es incorrecta. Por favor, vuelva a introducirla "
-"correctamente."
+msgstr "Su contraseña antigua es incorrecta. Por favor, vuelva a introducirla correctamente."
-#: contrib/auth/models.py:73 contrib/auth/models.py:93
+#: contrib/auth/models.py:73
+#: contrib/auth/models.py:93
msgid "name"
msgstr "nombre"
@@ -1129,7 +1138,8 @@ msgstr "nombre en código"
msgid "permission"
msgstr "permiso"
-#: contrib/auth/models.py:79 contrib/auth/models.py:94
+#: contrib/auth/models.py:79
+#: contrib/auth/models.py:94
msgid "permissions"
msgstr "permisos"
@@ -1137,131 +1147,102 @@ msgstr "permisos"
msgid "group"
msgstr "grupo"
-#: contrib/auth/models.py:98 contrib/auth/models.py:148
+#: contrib/auth/models.py:98
+#: contrib/auth/models.py:144
msgid "groups"
msgstr "grupos"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:134
msgid "username"
msgstr "nombre de usuario"
-#: contrib/auth/models.py:138
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr ""
-"Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, "
-"dígitos y guiones bajos)."
-
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "nombre propio"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "apellidos"
-#: contrib/auth/models.py:141
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "dirección de correo electrónico"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid "password"
msgstr "contraseña"
-#: contrib/auth/models.py:142
-msgid ""
-"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
-"password form</a>."
-msgstr ""
-"Use'[algo]$[sal]$[hash hexadecimal]' o use <a href=\"password/\">el "
-"formulario para cambiar la contraseña</a>."
+#: contrib/auth/models.py:138
+msgid "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."
+msgstr "Use'[algo]$[sal]$[hash hexadecimal]' o use <a href=\"password/\">el formulario para cambiar la contraseña</a>."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "es staff"
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
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:144
+#: contrib/auth/models.py:140
msgid "active"
msgstr "activo"
-#: contrib/auth/models.py:144
-msgid ""
-"Designates whether this user should be treated as active. Unselect this "
-"instead of deleting accounts."
-msgstr ""
-"Indica si el usuario puede ser tratado como activo. Desmarque "
-"esta opción en lugar de borrar la cuenta."
+#: contrib/auth/models.py:140
+msgid "Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
+msgstr "Indica si el usuario puede ser tratado como activo. Desmarque esta opción en lugar de borrar la cuenta."
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "es superusuario"
-#: contrib/auth/models.py:145
-msgid ""
-"Designates that this user has all permissions without explicitly assigning "
-"them."
-msgstr ""
-"Indica que este usuario tiene todos los permisos sin asignárselos "
-"explícitamente."
+#: contrib/auth/models.py:141
+msgid "Designates that this user has all permissions without explicitly assigning them."
+msgstr "Indica que este usuario tiene todos los permisos sin asignárselos explícitamente."
-#: contrib/auth/models.py:146
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "último inicio de sesión"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "fecha de alta"
-#: contrib/auth/models.py:149
-msgid ""
-"In addition to the permissions manually assigned, this user will also get "
-"all permissions granted to each group he/she is in."
-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:145
+msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
+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:150
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "permisos de usuario"
-#: contrib/auth/models.py:154
+#: contrib/auth/models.py:150
msgid "user"
msgstr "usuario"
-#: contrib/auth/models.py:155
+#: contrib/auth/models.py:151
msgid "users"
msgstr "usuarios"
-#: contrib/auth/models.py:161
-msgid "Personal info"
-msgstr "Información personal"
-
-#: contrib/auth/models.py:162
-msgid "Permissions"
-msgstr "Permisos"
-
-#: contrib/auth/models.py:163
-msgid "Important dates"
-msgstr "Fechas importantes"
-
-#: contrib/auth/models.py:164
-msgid "Groups"
-msgstr "Grupos"
-
-#: contrib/auth/models.py:323
+#: contrib/auth/models.py:306
msgid "message"
msgstr "mensaje"
-#: contrib/auth/views.py:47
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "Sesión terminada"
-#: contrib/comments/models.py:71 contrib/comments/models.py:176
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "La contraseña se ha cambiado con éxito."
+
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Cambiar contraseña: %s"
+
+#: contrib/comments/models.py:71
+#: contrib/comments/models.py:164
msgid "object ID"
msgstr "ID de objeto"
@@ -1269,8 +1250,9 @@ msgstr "ID de objeto"
msgid "headline"
msgstr "encabezado"
-#: contrib/comments/models.py:73 contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:73
+#: contrib/comments/models.py:95
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "comentario"
@@ -1310,11 +1292,13 @@ msgstr "puntuación 8"
msgid "is valid rating"
msgstr "puntuación válida"
-#: contrib/comments/models.py:87 contrib/comments/models.py:179
+#: contrib/comments/models.py:87
+#: contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "fecha/hora de envío"
-#: contrib/comments/models.py:88 contrib/comments/models.py:180
+#: contrib/comments/models.py:88
+#: contrib/comments/models.py:168
msgid "is public"
msgstr "es público"
@@ -1323,22 +1307,19 @@ msgid "is removed"
msgstr "está eliminado"
#: contrib/comments/models.py:90
-msgid ""
-"Check this box if the comment is inappropriate. A \"This comment has been "
-"removed\" message will be displayed instead."
-msgstr ""
-"Marque esta opción si el comentario es inapropiado. En su lugar se mostrará "
-"el mensaje \"Este comentario ha sido eliminado\"."
+msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
+msgstr "Marque esta opción si el comentario es inapropiado. En su lugar se mostrará el mensaje \"Este comentario ha sido eliminado\"."
#: contrib/comments/models.py:96
msgid "comments"
msgstr "comentarios"
-#: contrib/comments/models.py:140 contrib/comments/models.py:222
+#: contrib/comments/models.py:128
+#: contrib/comments/models.py:199
msgid "Content object"
msgstr "Objeto contenido"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1353,48 +1334,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "nombre de la persona"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "dirección ip"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "aprobado por el staff"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "comentario libre"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "comentarios libres"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "puntuación"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "fecha de la puntuación"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "punto karma"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "puntos karma"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "puntuado %(score)d por %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1405,36 +1386,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "fecha de la marca"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "marca de usuario"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "marcas de usuario"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Marca de %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "fecha de eliminación"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "eliminación del moderador"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "eliminaciones del moderador"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Eliminación del moderador %r"
@@ -1475,35 +1456,30 @@ msgstr "Previsualizar comentario"
msgid "Your name:"
msgstr "Su nombre:"
-#: contrib/comments/views/comments.py:28
-msgid ""
-"This rating is required because you've entered at least one other rating."
+#: contrib/comments/views/comments.py:76
+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
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
-"This comment was posted by a user who has posted fewer than %(count)s "
-"comment:\n"
+"This comment was posted by a user who has posted fewer than %(count)s comment:\n"
"\n"
"%(text)s"
msgid_plural ""
-"This comment was posted by a user who has posted fewer than %(count)s "
-"comments:\n"
+"This comment was posted by a user who has posted fewer than %(count)s comments:\n"
"\n"
"%(text)s"
msgstr[0] ""
-"Este comentario lo envió un usuario que ha enviado menos de %(count)s "
-"comentario:\n"
+"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"
+"Este comentario lo envió un usuario que ha enviado menos de %(count)s comentarios:\n"
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1514,33 +1490,28 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Sólo se admiten POSTs"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
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:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
msgid "Somebody tampered with the comment form (security violation)"
-msgstr ""
-"Alguien manipuló el formulario de comentarios (violación de seguridad)"
+msgstr "Alguien manipuló el formulario de comentarios (violación de seguridad)"
-#: contrib/comments/views/comments.py:208
-#: contrib/comments/views/comments.py:295
-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:256
+#: contrib/comments/views/comments.py:343
+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:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "El formulario de comentario no proporcionó 'previsualizar' ni 'enviar'"
@@ -1568,12 +1539,13 @@ msgstr "tipo de contenido"
msgid "content types"
msgstr "tipos de contenido"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Opciones avanzadas"
+
#: contrib/flatpages/models.py:9
-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."
+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:10
msgid "title"
@@ -1592,12 +1564,8 @@ msgid "template name"
msgstr "nombre de plantilla"
#: contrib/flatpages/models.py:14
-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'."
+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:15
msgid "registration required"
@@ -1615,10 +1583,6 @@ msgstr "página estática"
msgid "flat pages"
msgstr "páginas estáticas"
-#: contrib/flatpages/models.py:27
-msgid "Advanced options"
-msgstr "Opciones avanzadas"
-
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "º"
@@ -1708,8 +1672,10 @@ msgstr "ayer"
msgid "Enter a postal code in the format NNNN or ANNNNAAA."
msgstr "Introduzca un código postal en el formato NNNN or ANNNNAAA."
-#: contrib/localflavor/ar/forms.py:49 contrib/localflavor/br/forms.py:96
-#: contrib/localflavor/br/forms.py:135 contrib/localflavor/pe/forms.py:23
+#: contrib/localflavor/ar/forms.py:49
+#: contrib/localflavor/br/forms.py:96
+#: contrib/localflavor/br/forms.py:135
+#: contrib/localflavor/pe/forms.py:23
#: contrib/localflavor/pe/forms.py:51
msgid "This field requires only numbers."
msgstr "Este campo sólo acepta números."
@@ -1739,12 +1705,8 @@ msgid "Phone numbers must be in XX-XXXX-XXXX format."
msgstr "Los números de teléfono deben tener el formato XXX-XXX-XXXX."
#: contrib/localflavor/br/forms.py:58
-msgid ""
-"Select a valid brazilian state. That state is not one of the available "
-"states."
-msgstr ""
-"Seleccione un estado brasileño válido. Este estado no es uno de los estados "
-"disponibles."
+msgid "Select a valid brazilian state. That state is not one of the available states."
+msgstr "Seleccione un estado brasileño válido. Este estado no es uno de los estados disponibles."
#: contrib/localflavor/br/forms.py:94
msgid "Invalid CPF number."
@@ -1768,9 +1730,7 @@ msgstr "Introduzca un código postal en el formato XXX XXX."
#: contrib/localflavor/ca/forms.py:88
msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format."
-msgstr ""
-"Introduzca un Número del Seguro Social de Canadá válido en el formato XXX-"
-"XXX-XXX."
+msgstr "Introduzca un Número del Seguro Social de Canadá válido en el formato XXX-XXX-XXX."
#: contrib/localflavor/ch/ch_states.py:5
msgid "Aargau"
@@ -1876,17 +1836,14 @@ msgstr "Zug"
msgid "Zurich"
msgstr "Zurich"
-#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
+#: contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
msgid "Enter a zip code in the format XXXX."
msgstr "Introduzca un código postal en el formato XXXX."
#: contrib/localflavor/ch/forms.py:64
-msgid ""
-"Enter a valid Swiss identity or passport card number in X1234567<0 or "
-"1234567890 format."
-msgstr ""
-"Introduzca un número de identificación o pasaporte suizos válidos en el "
-"formato X1234567<0 o 1234567890."
+msgid "Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format."
+msgstr "Introduzca un número de identificación o pasaporte suizos válidos en el formato X1234567<0 o 1234567890."
#: contrib/localflavor/cl/forms.py:29
msgid "Enter a valid Chilean RUT."
@@ -1902,80 +1859,77 @@ msgstr "El RUT chileno no es válido."
#: contrib/localflavor/de/de_states.py:5
msgid "Baden-Wuerttemberg"
-msgstr ""
+msgstr "Baden-Wuerttemberg"
#: contrib/localflavor/de/de_states.py:6
msgid "Bavaria"
-msgstr ""
+msgstr "Bavaria"
#: contrib/localflavor/de/de_states.py:7
msgid "Berlin"
-msgstr ""
+msgstr "Berlín"
#: contrib/localflavor/de/de_states.py:8
msgid "Brandenburg"
-msgstr ""
+msgstr "Brandenburg"
#: contrib/localflavor/de/de_states.py:9
msgid "Bremen"
-msgstr ""
+msgstr "Bremen"
#: contrib/localflavor/de/de_states.py:10
msgid "Hamburg"
-msgstr ""
+msgstr "Hamburgo"
#: contrib/localflavor/de/de_states.py:11
msgid "Hessen"
-msgstr ""
+msgstr "Hessen"
#: contrib/localflavor/de/de_states.py:12
msgid "Mecklenburg-Western Pomerania"
-msgstr ""
+msgstr "Mecklenburg-Western Pomerania"
#: contrib/localflavor/de/de_states.py:13
msgid "Lower Saxony"
-msgstr ""
+msgstr "Lower Saxony"
#: contrib/localflavor/de/de_states.py:14
msgid "North Rhine-Westphalia"
-msgstr ""
+msgstr "North Rhine-Westphalia"
#: contrib/localflavor/de/de_states.py:15
msgid "Rhineland-Palatinate"
-msgstr ""
+msgstr "Rhineland-Palatinate"
#: contrib/localflavor/de/de_states.py:16
msgid "Saarland"
-msgstr ""
+msgstr "Saarland"
#: contrib/localflavor/de/de_states.py:17
msgid "Saxony"
-msgstr ""
+msgstr "Saxony"
#: contrib/localflavor/de/de_states.py:18
msgid "Saxony-Anhalt"
-msgstr ""
+msgstr "Saxony-Anhalt"
#: contrib/localflavor/de/de_states.py:19
msgid "Schleswig-Holstein"
-msgstr ""
+msgstr "Schleswig-Holstein"
#: contrib/localflavor/de/de_states.py:20
msgid "Thuringia"
-msgstr ""
+msgstr "Thuringia"
-#: contrib/localflavor/de/forms.py:14 contrib/localflavor/fi/forms.py:12
+#: contrib/localflavor/de/forms.py:14
+#: contrib/localflavor/fi/forms.py:12
#: contrib/localflavor/fr/forms.py:15
msgid "Enter a zip code in the format XXXXX."
msgstr "Introduzca un código postal en el formato XXXXX."
#: contrib/localflavor/de/forms.py:41
-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."
+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/es/es_provinces.py:5
msgid "Arava"
@@ -2249,12 +2203,8 @@ msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
msgstr "Introduzca un código postal en el rango y formato 01XXX - 52XXX."
#: contrib/localflavor/es/forms.py:39
-msgid ""
-"Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or "
-"9XXXXXXXX."
-msgstr ""
-"Introduzca un número de teléfono válido en el formato 6XXXXXXXX, 8XXXXXXXX "
-"o 9XXXXXXXX."
+msgid "Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX."
+msgstr "Introduzca un número de teléfono válido en el formato 6XXXXXXXX, 8XXXXXXXX o 9XXXXXXXX."
#: contrib/localflavor/es/forms.py:66
msgid "Please enter a valid NIF, NIE, or CIF."
@@ -2277,11 +2227,8 @@ msgid "Invalid checksum for CIF."
msgstr "El CIF es incorrecto."
#: contrib/localflavor/es/forms.py:142
-msgid ""
-"Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
-msgstr ""
-"Introduzca un número de cuenta bancaria en el formato XXXX-XXXX-XX-"
-"XXXXXXXXXX."
+msgid "Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
+msgstr "Introduzca un número de cuenta bancaria en el formato XXXX-XXXX-XX-XXXXXXXXXX."
#: contrib/localflavor/es/forms.py:143
msgid "Invalid checksum for bank account number."
@@ -2296,11 +2243,8 @@ msgid "Enter a zip code in the format XXXXXXX."
msgstr "Introduzca un código postal en el formato XXXXXXX."
#: 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."
+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:18
msgid "The Icelandic identification number is not valid."
@@ -2719,11 +2663,8 @@ msgid "Wrong checksum for the National Identification Number."
msgstr "El Número de Identificación Nacional es incorrecto."
#: contrib/localflavor/pl/forms.py:72
-msgid ""
-"Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
-msgstr ""
-"Introduzca un número de impuesto (NIP) en el formato XXX-XXX-XX-XX o XX-XX-"
-"XXX-XXX."
+msgid "Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
+msgstr "Introduzca un número de impuesto (NIP) en el formato XXX-XXX-XX-XX o XX-XX-XXX-XXX."
#: contrib/localflavor/pl/forms.py:73
msgid "Wrong checksum for the Tax Number (NIP)."
@@ -2731,8 +2672,7 @@ msgstr "El Número de Identificación Tributaria (NIP) es incorrecto."
#: contrib/localflavor/pl/forms.py:112
msgid "National Business Register Number (REGON) consists of 7 or 9 digits."
-msgstr ""
-"El Número Nacional de Registro de Negocios (REGON) consiste en 7 o 9 dígitos."
+msgstr "El Número Nacional de Registro de Negocios (REGON) consiste en 7 o 9 dígitos."
#: contrib/localflavor/pl/forms.py:113
msgid "Wrong checksum for the National Business Register Number (REGON)."
@@ -2806,6 +2746,26 @@ msgstr "Greater Poland"
msgid "West Pomerania"
msgstr "West Pomerania"
+#: contrib/localflavor/ro/forms.py:19
+msgid "Enter a valid CIF."
+msgstr "Introduzca un CIF válido."
+
+#: contrib/localflavor/ro/forms.py:56
+msgid "Enter a valid CNP."
+msgstr "Introduzca un CNP válido."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr "Introduzca un IBAN válido en el formato ROXX-XXXX-XXXX-XXXX-XXXX-XXXX."
+
+#: contrib/localflavor/ro/forms.py:171
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Los números de teléfono deben tener el formato XXXX-XXXXXX."
+
+#: contrib/localflavor/ro/forms.py:194
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Introduzca un código postal válido en el formato XXXXXX"
+
#: contrib/localflavor/sk/forms.py:30
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."
@@ -3164,267 +3124,267 @@ msgstr "Introduzca un código postal válido."
#: contrib/localflavor/uk/uk_regions.py:11
msgid "Bedfordshire"
-msgstr ""
+msgstr "Bedfordshire"
#: contrib/localflavor/uk/uk_regions.py:12
msgid "Buckinghamshire"
-msgstr ""
+msgstr "Buckinghamshire"
#: contrib/localflavor/uk/uk_regions.py:14
msgid "Cheshire"
-msgstr ""
+msgstr "Cheshire"
#: contrib/localflavor/uk/uk_regions.py:15
msgid "Cornwall and Isles of Scilly"
-msgstr ""
+msgstr "Cornwall and Isles of Scilly"
#: contrib/localflavor/uk/uk_regions.py:16
msgid "Cumbria"
-msgstr ""
+msgstr "Cumbria"
#: contrib/localflavor/uk/uk_regions.py:17
msgid "Derbyshire"
-msgstr ""
+msgstr "Derbyshire"
#: contrib/localflavor/uk/uk_regions.py:18
msgid "Devon"
-msgstr ""
+msgstr "Devon"
#: contrib/localflavor/uk/uk_regions.py:19
msgid "Dorset"
-msgstr ""
+msgstr "Dorset"
#: contrib/localflavor/uk/uk_regions.py:20
msgid "Durham"
-msgstr ""
+msgstr "Durham"
#: contrib/localflavor/uk/uk_regions.py:21
msgid "East Sussex"
-msgstr ""
+msgstr "East Sussex"
#: contrib/localflavor/uk/uk_regions.py:22
msgid "Essex"
-msgstr ""
+msgstr "Essex"
#: contrib/localflavor/uk/uk_regions.py:23
msgid "Gloucestershire"
-msgstr ""
+msgstr "Gloucestershire"
#: contrib/localflavor/uk/uk_regions.py:24
msgid "Greater London"
-msgstr ""
+msgstr "Londres (área metropolitana)"
#: contrib/localflavor/uk/uk_regions.py:25
msgid "Greater Manchester"
-msgstr ""
+msgstr "Manchester (área metropolitana)"
#: contrib/localflavor/uk/uk_regions.py:26
msgid "Hampshire"
-msgstr ""
+msgstr "Hampshire"
#: contrib/localflavor/uk/uk_regions.py:27
msgid "Hertfordshire"
-msgstr ""
+msgstr "Hertfordshire"
#: contrib/localflavor/uk/uk_regions.py:28
msgid "Kent"
-msgstr ""
+msgstr "Kent"
#: contrib/localflavor/uk/uk_regions.py:29
msgid "Lancashire"
-msgstr ""
+msgstr "Lancashire"
#: contrib/localflavor/uk/uk_regions.py:30
msgid "Leicestershire"
-msgstr ""
+msgstr "Leicestershire"
#: contrib/localflavor/uk/uk_regions.py:31
msgid "Lincolnshire"
-msgstr ""
+msgstr "Lincolnshire"
#: contrib/localflavor/uk/uk_regions.py:32
msgid "Merseyside"
-msgstr ""
+msgstr "Merseyside"
#: contrib/localflavor/uk/uk_regions.py:33
msgid "Norfolk"
-msgstr ""
+msgstr "Norfolk"
#: contrib/localflavor/uk/uk_regions.py:34
msgid "North Yorkshire"
-msgstr ""
+msgstr "North Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:35
msgid "Northamptonshire"
-msgstr ""
+msgstr "Northamptonshire"
#: contrib/localflavor/uk/uk_regions.py:36
msgid "Northumberland"
-msgstr ""
+msgstr "Northumberland"
#: contrib/localflavor/uk/uk_regions.py:37
msgid "Nottinghamshire"
-msgstr ""
+msgstr "Nottinghamshire"
#: contrib/localflavor/uk/uk_regions.py:38
msgid "Oxfordshire"
-msgstr ""
+msgstr "Oxfordshire"
#: contrib/localflavor/uk/uk_regions.py:39
msgid "Shropshire"
-msgstr ""
+msgstr "Shropshire"
#: contrib/localflavor/uk/uk_regions.py:40
msgid "Somerset"
-msgstr ""
+msgstr "Somerset"
#: contrib/localflavor/uk/uk_regions.py:41
msgid "South Yorkshire"
-msgstr ""
+msgstr "South Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:42
msgid "Staffordshire"
-msgstr ""
+msgstr "Staffordshire"
#: contrib/localflavor/uk/uk_regions.py:43
msgid "Suffolk"
-msgstr ""
+msgstr "Suffolk"
#: contrib/localflavor/uk/uk_regions.py:44
msgid "Surrey"
-msgstr ""
+msgstr "Surrey"
#: contrib/localflavor/uk/uk_regions.py:45
msgid "Tyne and Wear"
-msgstr ""
+msgstr "Tyne and Wear"
#: contrib/localflavor/uk/uk_regions.py:46
msgid "Warwickshire"
-msgstr ""
+msgstr "Warwickshire"
#: contrib/localflavor/uk/uk_regions.py:47
msgid "West Midlands"
-msgstr ""
+msgstr "West Midlands"
#: contrib/localflavor/uk/uk_regions.py:48
msgid "West Sussex"
-msgstr ""
+msgstr "West Sussex"
#: contrib/localflavor/uk/uk_regions.py:49
msgid "West Yorkshire"
-msgstr ""
+msgstr "West Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:50
msgid "Wiltshire"
-msgstr ""
+msgstr "Wiltshire"
#: contrib/localflavor/uk/uk_regions.py:51
msgid "Worcestershire"
-msgstr ""
+msgstr "Worcestershire"
#: contrib/localflavor/uk/uk_regions.py:55
msgid "County Antrim"
-msgstr ""
+msgstr "Condado de Antrim"
#: contrib/localflavor/uk/uk_regions.py:56
msgid "County Armagh"
-msgstr ""
+msgstr "Condado de Armagh"
#: contrib/localflavor/uk/uk_regions.py:57
msgid "County Down"
-msgstr ""
+msgstr "Condado de Down"
#: contrib/localflavor/uk/uk_regions.py:58
msgid "County Fermanagh"
-msgstr ""
+msgstr "Condado de Fermanagh"
#: contrib/localflavor/uk/uk_regions.py:59
msgid "County Londonderry"
-msgstr ""
+msgstr "Condado de Londonderry"
#: contrib/localflavor/uk/uk_regions.py:60
msgid "County Tyrone"
-msgstr ""
+msgstr "Condado de Tyrone"
#: contrib/localflavor/uk/uk_regions.py:64
msgid "Clwyd"
-msgstr ""
+msgstr "Clwyd"
#: contrib/localflavor/uk/uk_regions.py:65
msgid "Dyfed"
-msgstr ""
+msgstr "Dyfed"
#: contrib/localflavor/uk/uk_regions.py:66
msgid "Gwent"
-msgstr ""
+msgstr "Gwent"
#: contrib/localflavor/uk/uk_regions.py:67
msgid "Gwynedd"
-msgstr ""
+msgstr "Gwynedd"
#: contrib/localflavor/uk/uk_regions.py:68
msgid "Mid Glamorgan"
-msgstr ""
+msgstr "Mid Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:69
msgid "Powys"
-msgstr ""
+msgstr "Powys"
#: contrib/localflavor/uk/uk_regions.py:70
msgid "South Glamorgan"
-msgstr ""
+msgstr "South Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:71
msgid "West Glamorgan"
-msgstr ""
+msgstr "West Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:75
msgid "Borders"
-msgstr ""
+msgstr "Borders"
#: contrib/localflavor/uk/uk_regions.py:76
msgid "Central Scotland"
-msgstr ""
+msgstr "Central Scotland"
#: contrib/localflavor/uk/uk_regions.py:77
msgid "Dumfries and Galloway"
-msgstr ""
+msgstr "Dumfries and Galloway"
#: contrib/localflavor/uk/uk_regions.py:78
msgid "Fife"
-msgstr ""
+msgstr "Fife"
#: contrib/localflavor/uk/uk_regions.py:79
msgid "Grampian"
-msgstr ""
+msgstr "Grampian"
#: contrib/localflavor/uk/uk_regions.py:80
msgid "Highland"
-msgstr ""
+msgstr "Highland"
#: contrib/localflavor/uk/uk_regions.py:81
msgid "Lothian"
-msgstr ""
+msgstr "Lothian"
#: contrib/localflavor/uk/uk_regions.py:82
msgid "Orkney Islands"
-msgstr ""
+msgstr "Orkney Islands"
#: contrib/localflavor/uk/uk_regions.py:83
msgid "Shetland Islands"
-msgstr ""
+msgstr "Shetland Islands"
#: contrib/localflavor/uk/uk_regions.py:84
msgid "Strathclyde"
-msgstr ""
+msgstr "Strathclyde"
#: contrib/localflavor/uk/uk_regions.py:85
msgid "Tayside"
-msgstr ""
+msgstr "Tayside"
#: contrib/localflavor/uk/uk_regions.py:86
msgid "Western Isles"
-msgstr ""
+msgstr "Western Isles"
#: contrib/localflavor/uk/uk_regions.py:90
msgid "England"
@@ -3432,7 +3392,7 @@ msgstr "Inglaterra"
#: contrib/localflavor/uk/uk_regions.py:91
msgid "Northern Ireland"
-msgstr ""
+msgstr "Irlanda del Norte"
#: contrib/localflavor/uk/uk_regions.py:92
msgid "Scotland"
@@ -3448,8 +3408,7 @@ msgstr "Introduzca un código postal en el formato XXXXX o XXXX-XXXX."
#: contrib/localflavor/us/forms.py:54
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"
+msgstr "Introduzca un Número Seguro Social de EEUU válido en el formato XXX-XX-XXXX"
#: contrib/localflavor/za/forms.py:20
msgid "Enter a valid South African ID number"
@@ -3461,63 +3420,55 @@ msgstr "Introduzca un código postal surafricano válido"
#: contrib/localflavor/za/za_provinces.py:4
msgid "Eastern Cape"
-msgstr ""
+msgstr "Eastern Cape"
#: contrib/localflavor/za/za_provinces.py:5
msgid "Free State"
-msgstr ""
+msgstr "Free State"
#: contrib/localflavor/za/za_provinces.py:6
msgid "Gauteng"
-msgstr ""
+msgstr "Gauteng"
#: contrib/localflavor/za/za_provinces.py:7
msgid "KwaZulu-Natal"
-msgstr ""
+msgstr "KwaZulu-Natal"
#: contrib/localflavor/za/za_provinces.py:8
msgid "Limpopo"
-msgstr ""
+msgstr "Limpopo"
#: contrib/localflavor/za/za_provinces.py:9
msgid "Mpumalanga"
-msgstr ""
+msgstr "Mpumalanga"
#: contrib/localflavor/za/za_provinces.py:10
msgid "Northern Cape"
-msgstr ""
+msgstr "Northern Cape"
#: contrib/localflavor/za/za_provinces.py:11
msgid "North West"
-msgstr ""
+msgstr "North West"
#: contrib/localflavor/za/za_provinces.py:12
msgid "Western Cape"
-msgstr ""
+msgstr "Western Cape"
#: 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. Ejemplo: '/"
-"events/search/'."
+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. Ejemplo: '/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://'."
+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"
@@ -3527,23 +3478,23 @@ msgstr "redirección"
msgid "redirects"
msgstr "redirecciones"
-#: contrib/sessions/models.py:41
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "clave de sesión"
-#: contrib/sessions/models.py:42
+#: contrib/sessions/models.py:47
msgid "session data"
msgstr "datos de sesión"
-#: contrib/sessions/models.py:43
+#: contrib/sessions/models.py:48
msgid "expire date"
msgstr "fecha de caducidad"
-#: contrib/sessions/models.py:48
+#: contrib/sessions/models.py:53
msgid "session"
msgstr "sesión"
-#: contrib/sessions/models.py:49
+#: contrib/sessions/models.py:54
msgid "sessions"
msgstr "sesiones"
@@ -3555,24 +3506,17 @@ msgstr "nombre de dominio"
msgid "display name"
msgstr "nombre para mostrar"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "sitio"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "sitios"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Este valor debe contener sólo letras, números y guiones bajos."
-
#: core/validators.py:76
-msgid ""
-"This value must contain only letters, numbers, underscores, dashes or "
-"slashes."
-msgstr ""
-"Este valor debe contener sólo letras, números, guiones bajos y barras."
+msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
+msgstr "Este valor debe contener sólo letras, números, guiones bajos y barras."
#: core/validators.py:80
msgid "This value must contain only letters, numbers, underscores or hyphens."
@@ -3610,7 +3554,8 @@ msgstr "No se admiten caracteres no numéricos."
msgid "This value can't be comprised solely of digits."
msgstr "Este valor no puede comprender sólo dígitos."
-#: core/validators.py:128 newforms/fields.py:152
+#: core/validators.py:128
+#: forms/fields.py:157
msgid "Enter a whole number."
msgstr "Introduzca un número entero."
@@ -3619,67 +3564,60 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Sólo se admiten caracteres alfabéticos."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "El año debe ser 1900 o posterior."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Fecha no válida: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:548
+#: core/validators.py:152
+#: db/models/fields/__init__.py:552
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Introduzca una fecha válida en formato AAAA-MM-DD."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Introduzca una hora válida en formato HH:MM."
-#: core/validators.py:165 db/models/fields/__init__.py:625
+#: core/validators.py:161
+#: db/models/fields/__init__.py:633
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."
-#: core/validators.py:170 newforms/fields.py:403
+#: core/validators.py:166
+#: forms/fields.py:408
msgid "Enter a valid e-mail address."
msgstr "Introduzca una dirección de correo electrónico válida."
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:433
-#: oldforms/__init__.py:687
+#: core/validators.py:178
+#: core/validators.py:470
+#: forms/fields.py:426
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."
+msgstr "No se ha enviado ningún fichero. Compruebe el tipo de codificación en el formulario."
-#: core/validators.py:193 newforms/fields.py:459
-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."
+#: core/validators.py:189
+#: forms/fields.py:466
+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."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "La URL %s no apunta a una imagen válida."
-#: core/validators.py:204
+#: core/validators.py:200
#, 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."
+msgstr "Los números de teléfono deben guardar el formato XXX-XXX-XXXX. \"%s\" no es válido."
-#: core/validators.py:212
+#: core/validators.py:208
#, 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."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Se precisa una URL válida."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3688,371 +3626,327 @@ msgstr ""
"Se precisa HTML válido. Los errores específicos son:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "XML mal formado: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "URL no válida: %s"
-#: core/validators.py:259 core/validators.py:261
+#: core/validators.py:255
+#: core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "La URL %s es un enlace roto."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Introduzca una abreviatura válida de estado de los EEUU."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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] "¡Cuide su vocabulario! Aquí no admitimos la palabra %s."
msgstr[1] "¡Cuide su vocabulario! Aquí no admitimos las palabras %s."
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Este campo debe concordar con el campo '%s'."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Por favor, introduzca algo en al menos un campo."
-#: core/validators.py:316 core/validators.py:327
+#: core/validators.py:312
+#: core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Por favor, rellene ambos campos o deje ambos vacíos."
-#: core/validators.py:335
+#: core/validators.py:331
#, 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"
-#: core/validators.py:348
+#: core/validators.py:344
#, 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"
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "No se admiten valores duplicados."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Este valor debe estar entre %(lower)s y %(upper)s."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Este valor debe ser como mínimo %s."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Este valor no debe ser mayor que %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Este valor debe ser una potencia de %s."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Por favor, introduzca un número decimal válido."
-#: core/validators.py:444
+#: core/validators.py:440
#, 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."
+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."
-#: core/validators.py:447
+#: core/validators.py:443
#, 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 "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."
-#: core/validators.py:450
+#: core/validators.py:446
#, 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_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."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Por favor, introduzca un número de coma flotante válido."
-#: core/validators.py:467
+#: core/validators.py:463
#, 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."
-#: core/validators.py:468
+#: core/validators.py:464
#, 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:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "El formato de este campo es incorrecto."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Este campo no es válido."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "No se pudo obtener nada de %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, 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 "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."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
-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\".)"
+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\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
-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\".)"
+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\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, 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 "\"%(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\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, 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 "\"<%(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\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, 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 "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\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, 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 "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\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "%(object)s de este %(type)s ya existen en este %(field)s."
-#: db/models/fields/__init__.py:54
+#: db/models/fields/__init__.py:47
#, 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:179 db/models/fields/__init__.py:348
-#: db/models/fields/__init__.py:780 db/models/fields/__init__.py:791
-#: newforms/fields.py:46 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:175
+#: db/models/fields/__init__.py:343
+#: db/models/fields/__init__.py:795
+#: db/models/fields/__init__.py:806
+#: forms/fields.py:51
+#: oldforms/__init__.py:374
msgid "This field is required."
msgstr "Este campo es obligatorio."
-#: db/models/fields/__init__.py:448
+#: db/models/fields/__init__.py:450
msgid "This value must be an integer."
msgstr "Este valor debe ser un entero."
-#: db/models/fields/__init__.py:487
+#: db/models/fields/__init__.py:491
msgid "This value must be either True or False."
msgstr "Este valor debe ser Verdadero o Falso."
-#: db/models/fields/__init__.py:511
+#: db/models/fields/__init__.py:515
msgid "This field cannot be null."
msgstr "Este campo no puede estar vacío."
-#: db/models/fields/__init__.py:689
+#: db/models/fields/__init__.py:702
msgid "This value must be a decimal number."
msgstr "Este valor debe ser un entero."
-#: db/models/fields/__init__.py:800
+#: db/models/fields/__init__.py:815
msgid "Enter a valid filename."
msgstr "Introduzca un nombre de fichero válido"
-#: db/models/fields/__init__.py:981
+#: db/models/fields/__init__.py:1006
msgid "This value must be either None, True or False."
msgstr "Este valor debe ser Verdadero, Falso o Ninguno."
-#: db/models/fields/related.py:94
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Por favor, introduzca un %s válido."
-#: db/models/fields/related.py:746
-msgid "Separate multiple IDs with commas."
-msgstr "Separe múltiples IDs con comas."
-
-#: db/models/fields/related.py:748
-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 una opción."
+#: db/models/fields/related.py:729
+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 una opción."
-#: db/models/fields/related.py:795
+#: db/models/fields/related.py:773
#, 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."
+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."
-#: newforms/fields.py:47
+#: forms/fields.py:52
msgid "Enter a valid value."
msgstr "Introduzca un valor correcto."
-#: newforms/fields.py:124
+#: forms/fields.py:129
#, 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)."
+msgstr "Asegúrese de que su texto tiene a lo más %(max)d caracteres (actualmente tiene %(length)d)."
-#: newforms/fields.py:125
+#: forms/fields.py:130
#, python-format
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)."
+msgstr "Asegúrese de que su texto tiene al menos %(min)d caracteres (actualmente tiene %(length)d)."
-#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
+#: forms/fields.py:158
+#: forms/fields.py:187
+#: forms/fields.py:216
#, 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."
-#: newforms/fields.py:154 newforms/fields.py:183 newforms/fields.py:212
+#: forms/fields.py:159
+#: forms/fields.py:188
+#: forms/fields.py:217
#, 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:181 newforms/fields.py:210
+#: forms/fields.py:186
+#: forms/fields.py:215
msgid "Enter a number."
msgstr "Introduzca un número."
-#: newforms/fields.py:213
+#: forms/fields.py:218
#, 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."
-#: newforms/fields.py:214
+#: forms/fields.py:219
#, 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."
-#: newforms/fields.py:215
+#: forms/fields.py:220
#, 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 de la coma decimal."
-#: newforms/fields.py:263 newforms/fields.py:751
+#: forms/fields.py:268
+#: forms/fields.py:795
msgid "Enter a valid date."
msgstr "Introduzca una fecha válida."
-#: newforms/fields.py:296 newforms/fields.py:752
+#: forms/fields.py:301
+#: forms/fields.py:796
msgid "Enter a valid time."
msgstr "Introduzca una hora válida."
-#: newforms/fields.py:335
+#: forms/fields.py:340
msgid "Enter a valid date/time."
msgstr "Introduzca una fecha/hora válida."
-#: newforms/fields.py:434
+#: forms/fields.py:427
msgid "No file was submitted."
msgstr "No se ha enviado ningún fichero"
-#: newforms/fields.py:435 oldforms/__init__.py:689
+#: forms/fields.py:428
+#: oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "El fichero enviado está vacío."
-#: newforms/fields.py:497
+#: forms/fields.py:527
msgid "Enter a valid URL."
msgstr "Introduzca una URL válida."
-#: newforms/fields.py:498
+#: forms/fields.py:528
msgid "This URL appears to be a broken link."
msgstr "La URL parece ser un enlace roto."
-#: newforms/fields.py:560 newforms/models.py:299
-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 disponibles."
-
-#: newforms/fields.py:599
+#: forms/fields.py:593
+#: forms/fields.py:644
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
-msgstr ""
-"Escoja una opción válida. %(value)s no es una de las opciones disponibles."
+msgstr "Escoja una opción válida. %(value)s no es una de las opciones disponibles."
-#: newforms/fields.py:600 newforms/fields.py:662 newforms/models.py:371
+#: forms/fields.py:645
+#: forms/fields.py:706
+#: forms/models.py:581
msgid "Enter a list of values."
msgstr "Introduzca una lista de valores."
-#: newforms/fields.py:780
+#: forms/fields.py:824
msgid "Enter a valid IPv4 address."
msgstr "Introduzca una dirección IPv4 válida."
-#: newforms/models.py:372
+#: forms/models.py:514
+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 disponibles."
+
+#: forms/models.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."
@@ -4068,20 +3962,22 @@ msgstr[1] "Asegúrese de que su texto tiene menos de %s caracteres."
msgid "Line breaks are not allowed here."
msgstr "No se permiten saltos de línea."
-#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
+#: oldforms/__init__.py:512
+#: oldforms/__init__.py:586
+#: oldforms/__init__.py:625
#, 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:745
+#: oldforms/__init__.py:754
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:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Introduzca un número positivo."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Introduzca un número entero entre 0 y 32.767."
@@ -4199,23 +4095,28 @@ msgstr "enero"
msgid "February"
msgstr "febrero"
-#: utils/dates.py:18 utils/dates.py:31
+#: utils/dates.py:18
+#: utils/dates.py:31
msgid "March"
msgstr "marzo"
-#: utils/dates.py:18 utils/dates.py:31
+#: utils/dates.py:18
+#: utils/dates.py:31
msgid "April"
msgstr "abril"
-#: utils/dates.py:18 utils/dates.py:31
+#: utils/dates.py:18
+#: utils/dates.py:31
msgid "May"
msgstr "mayo"
-#: utils/dates.py:18 utils/dates.py:31
+#: utils/dates.py:18
+#: utils/dates.py:31
msgid "June"
msgstr "junio"
-#: utils/dates.py:19 utils/dates.py:31
+#: utils/dates.py:19
+#: utils/dates.py:31
msgid "July"
msgstr "julio"
@@ -4315,7 +4216,7 @@ msgstr "nov."
msgid "Dec."
msgstr "dic."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "o"
@@ -4369,38 +4270,53 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:403
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "j N Y"
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "j N Y P"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "P"
-#: utils/translation/trans_real.py:421
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "j \\de F"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
-msgstr "El %(verbose_name)s se ha creado exitosamente."
+msgstr "El/La %(verbose_name)s se ha creado exitosamente."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, 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
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
-msgstr "El %(verbose_name)s ha sido borrado."
+msgstr "El/La %(verbose_name)s ha sido borrado."
+
+#~ msgid "Ordering"
+#~ msgstr "Ordenación"
+#~ msgid "Order:"
+#~ msgstr "Orden:"
+#~ msgid "Added %s."
+#~ msgstr "Añadido %s."
+#~ msgid "Deleted %s."
+#~ msgstr "Borrado %s."
+#~ msgid "The two 'new password' fields didn't match."
+#~ msgstr "Los dos campos 'nueva contraseña' no coinciden."
+#~ msgid "Year must be 1900 or later."
+#~ msgstr "El año debe ser 1900 o posterior."
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Separe múltiples IDs con comas."
diff --git a/django/conf/locale/es_AR/LC_MESSAGES/django.mo b/django/conf/locale/es_AR/LC_MESSAGES/django.mo
index e66de9a8e3..ca1ea679ae 100644
--- a/django/conf/locale/es_AR/LC_MESSAGES/django.mo
+++ b/django/conf/locale/es_AR/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/es_AR/LC_MESSAGES/django.po b/django/conf/locale/es_AR/LC_MESSAGES/django.po
index 40f2b5a114..fa26d5f6d7 100644
--- a/django/conf/locale/es_AR/LC_MESSAGES/django.po
+++ b/django/conf/locale/es_AR/LC_MESSAGES/django.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-02-01 13:16-0200\n"
-"PO-Revision-Date: 2008-02-02 14:26-0200\n"
+"POT-Creation-Date: 2008-07-19 13:34-0300\n"
+"PO-Revision-Date: 2008-07-19 19:37-0300\n"
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
"Language-Team: Django-I18N <django-i18n@googlegroups.com>\n"
"MIME-Version: 1.0\n"
@@ -15,185 +15,201 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: conf/global_settings.py:39
+#: conf/global_settings.py:44
msgid "Arabic"
-msgstr "Ãrabe"
+msgstr "árabe"
-#: conf/global_settings.py:40
+#: conf/global_settings.py:45
msgid "Bengali"
-msgstr "Bengalí"
+msgstr "bengalí"
-#: conf/global_settings.py:41
+#: conf/global_settings.py:46
msgid "Bulgarian"
-msgstr "Búlgaro"
+msgstr "búlgaro"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:47
msgid "Catalan"
-msgstr "Catalán"
+msgstr "catalán"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:48
msgid "Czech"
-msgstr "Checo"
+msgstr "checo"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:49
msgid "Welsh"
-msgstr "Galés"
+msgstr "galés"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:50
msgid "Danish"
-msgstr "Danés"
+msgstr "danés"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:51
msgid "German"
-msgstr "Alemán"
+msgstr "alemán"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:52
msgid "Greek"
-msgstr "Griego"
+msgstr "griego"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:53
msgid "English"
-msgstr "Inglés"
+msgstr "inglés"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:54
msgid "Spanish"
-msgstr "Español"
+msgstr "español"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "estonio"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
-msgstr "Español Argentino"
+msgstr "español de Argentina"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:57
+msgid "Basque"
+msgstr "vasco"
+
+#: conf/global_settings.py:58
msgid "Persian"
-msgstr "Persa"
+msgstr "persa"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:59
msgid "Finnish"
-msgstr "Finlandés"
+msgstr "finlandés"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:60
msgid "French"
-msgstr "Francés"
+msgstr "francés"
-#: conf/global_settings.py:54
-msgid "Gaeilge"
-msgstr "Irlandés"
+#: conf/global_settings.py:61
+msgid "Irish"
+msgstr "irlandés"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:62
msgid "Galician"
-msgstr "Gallego"
+msgstr "gallego"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:63
msgid "Hungarian"
-msgstr "Húngaro"
+msgstr "húngaro"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:64
msgid "Hebrew"
-msgstr "Hebreo"
+msgstr "hebreo"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:65
msgid "Croatian"
-msgstr "Croata"
+msgstr "croata"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:66
msgid "Icelandic"
-msgstr "Islandés"
+msgstr "islandés"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:67
msgid "Italian"
-msgstr "Italiano"
+msgstr "italiano"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:68
msgid "Japanese"
-msgstr "Japonés"
+msgstr "japonés"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:69
+msgid "Georgian"
+msgstr "georgiano"
+
+#: conf/global_settings.py:70
msgid "Korean"
-msgstr "Koreano"
+msgstr "koreano"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:71
msgid "Khmer"
-msgstr "Jémer"
+msgstr "jémer"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:72
msgid "Kannada"
-msgstr "Canarés"
+msgstr "canarés"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:73
msgid "Latvian"
-msgstr "Letón"
+msgstr "letón"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "lituano"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
-msgstr "Macedonio"
+msgstr "macedonio"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:76
msgid "Dutch"
-msgstr "Holandés"
+msgstr "holandés"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:77
msgid "Norwegian"
-msgstr "Noruego"
+msgstr "noruego"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:78
msgid "Polish"
-msgstr "Polaco"
+msgstr "polaco"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:79
msgid "Portugese"
-msgstr "Portugués"
+msgstr "portugués"
-#: conf/global_settings.py:71
-msgid "Brazilian"
-msgstr "Brasileño"
+#: conf/global_settings.py:80
+msgid "Brazilian Portuguese"
+msgstr "portugués de Brasil"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:81
msgid "Romanian"
-msgstr "Rumano"
+msgstr "rumano"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:82
msgid "Russian"
-msgstr "Ruso"
+msgstr "ruso"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:83
msgid "Slovak"
-msgstr "Eslovaco"
+msgstr "eslovaco"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:84
msgid "Slovenian"
-msgstr "Esloveno"
+msgstr "esloveno"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:85
msgid "Serbian"
-msgstr "Serbio"
+msgstr "serbio"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:86
msgid "Swedish"
-msgstr "Sueco"
+msgstr "sueco"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:87
msgid "Tamil"
-msgstr "Tamil"
+msgstr "tamil"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:88
msgid "Telugu"
-msgstr "Telugu"
+msgstr "telugu"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:89
msgid "Turkish"
-msgstr "Turco"
+msgstr "turco"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:90
msgid "Ukrainian"
-msgstr "Ucraniano"
+msgstr "ucraniano"
-#: conf/global_settings.py:82
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
-msgstr "Chino simplificado"
+msgstr "chino simplificado"
-#: conf/global_settings.py:83
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
-msgstr "Chino tradicional"
+msgstr "chino tradicional"
#: contrib/admin/filterspecs.py:44
#, python-format
@@ -229,49 +245,209 @@ msgstr "Este mes"
msgid "This year"
msgstr "Este año"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Sí"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "No"
-#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:154 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Desconocido"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "hora de acción"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "id de objeto"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "repr de objeto"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "marca de acción"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "mensaje de cambio"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "entrada de registro"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "entradas de registro"
+#: contrib/admin/options.py:162 contrib/admin/options.py:181
+msgid "None"
+msgstr "Ninguno"
+
+#: contrib/admin/options.py:348 contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "Se agregó con éxito %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:352 contrib/admin/options.py:420
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "Puede modificarlo nuevamente abajo."
+
+#: contrib/admin/options.py:362 contrib/admin/options.py:429
+#, python-format
+msgid "You may add another %s below."
+msgstr "Puede agregar otro %s abajo."
+
+#: contrib/admin/options.py:396
+#, python-format
+msgid "Changed %s."
+msgstr "Modifica %s."
+
+#: contrib/admin/options.py:396 contrib/admin/options.py:406
+#: core/validators.py:279 db/models/manipulators.py:305
+msgid "and"
+msgstr "y"
+
+#: contrib/admin/options.py:401
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Se agregó %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:405
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Se modificaron %(list)s en %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:410
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Se eliminó %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:415
+msgid "No fields changed."
+msgstr "No ha modificado ningún campo."
+
+#: contrib/admin/options.py:418
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "Se modificó con éxito %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:426
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"Se agregó con éxito %(name)s \"%(obj)s\". Puede modificarlo nuevamente abajo."
+
+#: contrib/admin/options.py:507
+#, python-format
+msgid "Add %s"
+msgstr "Agregar %s"
+
+#: contrib/admin/options.py:570
+#, python-format
+msgid "Change %s"
+msgstr "Modificar %s"
+
+#: contrib/admin/options.py:600
+msgid "Database error"
+msgstr "Error de base de datos"
+
+#: contrib/admin/options.py:649
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "Se eliminó con éxito %(name)s \"%(obj)s\"."
+
+#: contrib/admin/options.py:655
+msgid "Are you sure?"
+msgstr "¿Está seguro?"
+
+#: contrib/admin/options.py:682
+#, python-format
+msgid "Change history: %s"
+msgstr "Historia de modificaciones: %s"
+
+#: contrib/admin/sites.py:17 contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:71 contrib/comments/views/comments.py:56
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Por favor introduzca un nombre de usuario y una contraseña correctos. Note "
+"que ambos campos son sensibles a mayúsculas/minúsculas."
+
+#: contrib/admin/sites.py:218 contrib/admin/views/decorators.py:68
+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/sites.py:225 contrib/admin/views/decorators.py:75
+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. Por favor "
+"actívelas, recargue esta página, e inténtelo de nuevo."
+
+#: contrib/admin/sites.py:239 contrib/admin/sites.py:245
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Los nombres de usuario no pueden contener el carácter '@'."
+
+#: contrib/admin/sites.py:242 contrib/admin/views/decorators.py:88
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr ""
+"Su dirección de correo electrónico no es su nombre de usuario. Intente "
+"nuevamente usando '%s'."
+
+#: contrib/admin/sites.py:313
+msgid "Site administration"
+msgstr "Administración de sitio"
+
+#: contrib/admin/sites.py:335 contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Identificarse"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Uno o más %(fieldname)s en %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Uno o más %(fieldname)s en %(name)s:"
+
+#: contrib/admin/widgets.py:66
+msgid "Date:"
+msgstr "Fecha:"
+
+#: contrib/admin/widgets.py:66
+msgid "Time:"
+msgstr "Hora:"
+
+#: contrib/admin/widgets.py:90
+msgid "Currently:"
+msgstr "Actualmente"
+
+#: contrib/admin/widgets.py:90
+msgid "Change:"
+msgstr "Modificar:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -282,17 +458,17 @@ 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/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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: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"
@@ -319,22 +495,28 @@ msgstr ""
"mediante correo electrónico y debería ser solucionado en breve. Gracias por "
"su paciencia."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Bienvenido,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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 "Documentación"
-#: contrib/admin/templates/admin/base.html:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Cambiar contraseña"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Cerrar sesión"
@@ -347,46 +529,43 @@ msgstr "Sitio de administración de Django"
msgid "Django administration"
msgstr "Administración de Django"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Agregar"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Historia"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Ver en el sitio"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
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:49
-msgid "Ordering"
-msgstr "Ordenación"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Orden:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "Agregar %(name)s"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filtrar"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Eliminar"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, python-format
msgid ""
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
@@ -397,7 +576,7 @@ msgstr ""
"de objetos relacionados, pero su cuenta no tiene permiso para eliminar los "
"siguientes tipos de objetos:"
-#: contrib/admin/templates/admin/delete_confirmation.html:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, python-format
msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
@@ -406,7 +585,7 @@ msgstr ""
"¿Está seguro de que quiere eliminar los %(object_name)s \"%(escaped_object)s"
"\"? Se eliminarán los siguientes objetos relacionados:"
-#: contrib/admin/templates/admin/delete_confirmation.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Sí, estoy seguro"
@@ -415,41 +594,37 @@ msgstr "Sí, estoy seguro"
msgid " By %(filter_title)s "
msgstr " Por %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filtrar"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, 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/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Modificar"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "No tiene permiso para editar nada."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Acciones recientes"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Mis acciones"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Ninguna disponible"
-#: contrib/admin/templates/admin/invalid_setup.html:8
+#: contrib/admin/templates/admin/invalid_setup.html:7
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 "
@@ -459,39 +634,34 @@ msgstr ""
"tablas de la misma hayan sido creadas, y asegúrese de que el usuario "
"apropiado tenga permisos de lectura en la base de datos."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
msgid "Username:"
msgstr "Usuario:"
-#: contrib/admin/templates/admin/login.html:20
+#: contrib/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Contraseña:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:25
-msgid "Log in"
-msgstr "Identificarse"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Fecha/hora"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Usuario"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Acción"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "j M Y P"
-#: contrib/admin/templates/admin/object_history.html:35
+#: contrib/admin/templates/admin/object_history.html:32
msgid ""
"This object doesn't have a change history. It probably wasn't added via this "
"admin site."
@@ -543,27 +713,30 @@ msgstr ""
"Primero, introduzca un nombre de usuario y una contraseña. Luego podrá "
"configurar opciones adicionales."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:13 contrib/auth/forms.py:50
msgid "Username"
msgstr "Nombre de usuario:"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:16 contrib/auth/forms.py:51 contrib/auth/forms.py:167
msgid "Password"
msgstr "Contraseña:"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:168
msgid "Password (again)"
msgstr "Contraseña (de nuevo)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr ""
"Para verificación, introduzca la misma contraseña que introdujo arriba."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr ""
@@ -638,7 +811,7 @@ msgstr "Editar este objeto (nueva ventana)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
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."
+"Ãdem, pero abre la página de administración en una nueva ventana."
#: contrib/admin/templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today."
@@ -648,23 +821,23 @@ msgstr "Gracias por el tiempo que ha dedicado al sitio web hoy."
msgid "Log in again"
msgstr "Identificarse de nuevo"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 contraseña"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: 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 contraseña exitoso"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Su contraseña ha sido cambiada."
-#: contrib/admin/templates/registration/password_change_form.html:11
+#: 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."
@@ -673,19 +846,19 @@ msgstr ""
"luego introduzca la nueva contraseña dos veces para verificar que la ha "
"escrito correctamente."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Contraseña antigua:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Contraseña nueva:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Confirme contraseña:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Cambiar mi contraseña"
@@ -706,8 +879,8 @@ msgid ""
"We've e-mailed a new password to the e-mail address you submitted. You "
"should be receiving it shortly."
msgstr ""
-"Le hemos enviado una nueva contraseña a la dirección que ha suministrado. "
-"Debería recibirla en breve."
+"Le hemos enviado una nueva contraseña a la dirección de correo electrónico "
+"que ha suministrado. Debería recibir la misma en breve."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
@@ -746,8 +919,8 @@ msgid ""
"Forgotten your password? Enter your e-mail address below, and we'll reset "
"your password and e-mail the new one to you."
msgstr ""
-"¿Ha olvidado su contraseña? Introduzca su dirección de correo electrónico, y "
-"crearemos una nueva que le enviaremos por correo."
+"¿Ha olvidado su contraseña?. Introduzca su dirección de correo electrónico, y "
+"crearemos una nueva la que le será enviada por dicho medio."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -757,339 +930,222 @@ msgstr "Dirección de correo electrónico:"
msgid "Reset my password"
msgstr "Recuperar mi contraseña"
-#: 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/widget/file.html:2
-msgid "Currently:"
-msgstr "Actualmente"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Modificar:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Todas las fechas"
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
+#: contrib/admin/views/main.py:66
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "Se agregó con éxito %(name)s \"%(obj)s\"."
-
-#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "Puede modificarlo nuevamente abajo."
-
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Agregar usuario"
-
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Cambio de contraseña exitoso"
-
-#: contrib/admin/views/auth.py:65
-#, python-format
-msgid "Change password: %s"
-msgstr "Cambiar contraseña: %s"
-
-#: contrib/admin/views/decorators.py:11 contrib/auth/forms.py:60
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"Por favor introduzca un nombre de usuario y una contraseña correctos. Note "
-"que ambos campos son sensibles a mayúsculas/minúsculas."
-
-#: contrib/admin/views/decorators.py:63
-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:70
-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:84
-msgid "Usernames cannot contain the '@' character."
-msgstr "Los nombres de usuario no pueden contener el carácter '@'."
+msgid "Select %s"
+msgstr "Seleccione %s"
-#: contrib/admin/views/decorators.py:86
+#: contrib/admin/views/main.py:66
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr ""
-"Su dirección de correo no es su nombre de usuario. Intente nuevamente usando "
-"'%s'."
+msgid "Select %s to change"
+msgstr "Seleccione %s a modificar"
-#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53 contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "etiqueta:"
-#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87 contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filtrar:"
-#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153 contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "ver:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Aplicación %r no encontrada"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Modelo %(name)r no encontrado en aplicación %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Modelo %(model_name)r no encontrado en aplicación %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "el objeto `%(label)s.%(type)s` relacionado"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "el objeto `%(app_label)s.%(data_type)s` relacionado"
-#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206 contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242 contrib/admindocs/views.py:247
msgid "model:"
msgstr "modelo:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "objetos `%(label)s.%(name)s` relacionados"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "objetos `%(app_label)s.%(object_name)s` relacionados"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "todos los %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "número de %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Campos en objetos %s"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317 contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330 contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337 contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Entero"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Booleano (Verdadero o Falso)"
-#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319 contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Cadena (máximo %(max_length)s)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Enteros separados por comas"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Fecha (sin hora)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Fecha (con hora)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Número decimal"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "Dirección de correo electrónico"
-#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325 contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Ruta de archivo"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Número de punto flotante"
-#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331 contrib/comments/models.py:89
msgid "IP address"
msgstr "Dirección IP"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Booleano (Verdadero, Falso o Nulo)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Relación con el modelo padre"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Número de teléfono"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Texto"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Hora"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:7
+#: contrib/admindocs/views.py:342 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Estado de los EE.UU. (dos letras mayúsculas)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "Texto XML"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s no parece ser un objeto urlpattern"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Administración de sitio"
-
-#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "Puede agregar otro %s abajo."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Agregar %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "Agregado %s."
-
-#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348 core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "y"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Información personal"
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "Modifica %s."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Permisos"
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "Eliminó %s."
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Fechas importantes"
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "No ha modificado ningún campo."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Grupos"
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "Se modificó con éxito %(name)s \"%(obj)s\"."
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Agregar usuario"
-#: contrib/admin/views/main.py:362
-#, python-format
+#: contrib/auth/forms.py:14 contrib/auth/models.py:134
msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
msgstr ""
-"Se agregó con éxito %(name)s \"%(obj)s\". Puede modificarlo nuevamente abajo."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Modificar %s"
-
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Uno o más %(fieldname)s en %(name)s: %(obj)s"
-
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Uno o más %(fieldname)s en %(name)s:"
-
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "Se eliminó con éxito %(name)s \"%(obj)s\"."
-
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "¿Está seguro?"
-
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Historia de modificaciones: %s"
+"Obligatorio. Longitud máxima 30 caracteres alfanuméricos (letras, dígitos y "
+"guiones bajos)."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Seleccione %s"
+#: contrib/auth/forms.py:15 core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Este valor debe contener sólo letras, números y guiones bajos."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Seleccione %s a modificar"
+#: contrib/auth/forms.py:17
+msgid "Password confirmation"
+msgstr "Confirmación de contraseña"
-#: contrib/admin/views/main.py:784
-msgid "Database error"
-msgstr "Error de base de datos"
+#: contrib/auth/forms.py:29
+msgid "A user with that username already exists."
+msgstr "Ya existe un usuario con ese nombre."
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+#: contrib/auth/forms.py:35 contrib/auth/forms.py:154
+#: contrib/auth/forms.py:179
msgid "The two password fields didn't match."
msgstr "Los dos campos de contraseñas no coinciden entre si."
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "Ya existe un usuario con ese nombre."
+#: contrib/auth/forms.py:73 contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "Esta cuenta está inactiva"
-#: contrib/auth/forms.py:53
+#: contrib/auth/forms.py:78 contrib/comments/views/comments.py:49
msgid ""
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
"required for logging in."
msgstr ""
-"Su navegador Web aparenta no tener cookies activas. Las cookies son un "
-"requerimiento para poder ingresar."
+"Su navegador Web aparenta no estar configurado para aceptar cookies. Las "
+"cookies son un requerimiento para poder ingresar."
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Esta cuenta está inactiva"
+#: contrib/auth/forms.py:91
+msgid "E-mail"
+msgstr "Correo electrónico"
-#: contrib/auth/forms.py:84
+#: contrib/auth/forms.py:100
msgid ""
"That e-mail address doesn't have an associated user account. Are you sure "
"you've registered?"
@@ -1097,16 +1153,24 @@ msgstr ""
"Esa dirección de e-mail no está asociada a ninguna cuenta de usuario. ¿Está "
"seguro de que ya se ha registrado?"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:125
#, python-format
msgid "Password reset on %s"
msgstr "Reinicialización de contraseña en %s"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "Los dos campos 'nueva contraseña' no coinciden entre si."
+#: contrib/auth/forms.py:132
+msgid "Old password"
+msgstr "Contraseña antigua"
+
+#: contrib/auth/forms.py:133
+msgid "New password"
+msgstr "Contraseña nueva"
+
+#: contrib/auth/forms.py:134
+msgid "New password confirmation"
+msgstr "Confirmación de contraseña nueva"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:146
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr ""
"La antigua contraseña introducida es incorrecta. Por favor introdúzcala "
@@ -1132,39 +1196,31 @@ msgstr "permisos"
msgid "group"
msgstr "grupo"
-#: contrib/auth/models.py:98 contrib/auth/models.py:141
+#: contrib/auth/models.py:98 contrib/auth/models.py:144
msgid "groups"
msgstr "grupos"
-#: contrib/auth/models.py:131
+#: contrib/auth/models.py:134
msgid "username"
msgstr "nombre de usuario"
-#: contrib/auth/models.py:131
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr ""
-"Requerido. Longitud máxima 30 caracteres alfanuméricos (letras, dígitos y "
-"guiones bajos)."
-
-#: contrib/auth/models.py:132
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "nombre"
-#: contrib/auth/models.py:133
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "apellido"
-#: contrib/auth/models.py:134
+#: contrib/auth/models.py:137
msgid "e-mail address"
-msgstr "dirección de correo"
+msgstr "dirección de correo electrónico"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:138
msgid "password"
msgstr "contraseña"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:138
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -1172,47 +1228,47 @@ msgstr ""
"Use '[algo]$[salt]$[hexdigest]' o use el <a href=\"password/\">formulario de "
"cambio de contraseña</a>."
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "es staff"
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
msgstr "Indica si el usuario puede ingresar a este sitio de administración."
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:140
msgid "active"
msgstr "activo"
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:140
msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
+"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
-"Indica si el usuario puede ingresar al sitio de administración Django. "
-"Desactive este campo en lugar de eliminar usuarios."
+"Indica si el usuario debe ser tratado como un usuario activo. Desactive este "
+"campo en lugar de eliminar usuarios."
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "es superusuario"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:141
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
msgstr ""
-"Indica que este usuario posee todos los permisos, sin que sea necesario "
+"Indica que este usuario posee todos los permisos sin que sea necesario "
"asignarle los mismos en forma explícita."
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "último ingreso"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "fecha de creación"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:145
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -1220,43 +1276,36 @@ msgstr ""
"Además de los permisos asignados manualmente, este usuario también poseerá "
"todos los permisos de los grupos a los que pertenezca."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "permisos de usuario"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:150
msgid "user"
msgstr "usuario"
-#: contrib/auth/models.py:148
+#: contrib/auth/models.py:151
msgid "users"
msgstr "usuarios"
-#: contrib/auth/models.py:154
-msgid "Personal info"
-msgstr "Información personal"
-
-#: contrib/auth/models.py:155
-msgid "Permissions"
-msgstr "Permisos"
-
-#: contrib/auth/models.py:156
-msgid "Important dates"
-msgstr "Fechas importantes"
-
-#: contrib/auth/models.py:157
-msgid "Groups"
-msgstr "Grupos"
-
-#: contrib/auth/models.py:316
+#: contrib/auth/models.py:306
msgid "message"
msgstr "mensaje"
-#: contrib/auth/views.py:47
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "Sesión cerrada"
-#: contrib/comments/models.py:71 contrib/comments/models.py:176
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "Cambio de contraseña exitoso"
+
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Cambiar contraseña: %s"
+
+#: contrib/comments/models.py:71 contrib/comments/models.py:164
msgid "object ID"
msgstr "ID de objeto"
@@ -1265,7 +1314,7 @@ msgid "headline"
msgstr "encabezado"
#: contrib/comments/models.py:73 contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "comentario"
@@ -1305,11 +1354,11 @@ msgstr "calificación 8"
msgid "is valid rating"
msgstr "es calificación válida"
-#: contrib/comments/models.py:87 contrib/comments/models.py:179
+#: contrib/comments/models.py:87 contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "fecha/hora de envío"
-#: contrib/comments/models.py:88 contrib/comments/models.py:180
+#: contrib/comments/models.py:88 contrib/comments/models.py:168
msgid "is public"
msgstr "es público"
@@ -1329,11 +1378,11 @@ msgstr ""
msgid "comments"
msgstr "comentarios"
-#: contrib/comments/models.py:140 contrib/comments/models.py:222
+#: contrib/comments/models.py:128 contrib/comments/models.py:199
msgid "Content object"
msgstr "Objeto contenido"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1348,48 +1397,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "nombre de la persona"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "dirección ip"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "aprobado por el staff"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "comentario libre"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "comentarios libres"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "puntuación"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "fecha de la puntuación"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "punto karma"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "puntos karma"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "puntuado %(score)d por %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1400,36 +1449,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "fecha de la marca"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "marca de usuario"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "marcas de usuario"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Marca de %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "fecha de eliminación"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
-msgstr "Eliminación por moderador"
+msgstr "eliminación por moderador"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "eliminaciones por moderador"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Eliminación del moderador %r"
@@ -1445,7 +1494,7 @@ msgstr "Calificaciones"
#: contrib/comments/templates/comments/form.html:12
#: contrib/comments/templates/comments/form.html:23
msgid "Required"
-msgstr "Requerido"
+msgstr "Obligatorio"
#: contrib/comments/templates/comments/form.html:12
#: contrib/comments/templates/comments/form.html:23
@@ -1470,12 +1519,12 @@ msgstr "Previsualizar comentario"
msgid "Your name:"
msgstr "Su nombre:"
-#: contrib/comments/views/comments.py:28
+#: contrib/comments/views/comments.py:76
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
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
"This comment was posted by a user who has posted fewer than %(count)s "
@@ -1498,7 +1547,7 @@ msgstr[1] ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1509,25 +1558,25 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Sólo se admiten POSTs"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
msgid "One or more of the required fields wasn't submitted"
-msgstr "No se proporcionó uno o más de los siguientes campos requeridos"
+msgstr "No se proporcionó uno o más de los campos obligatorios"
-#: contrib/comments/views/comments.py:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
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:208
-#: contrib/comments/views/comments.py:295
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
msgid ""
"The comment form had an invalid 'target' parameter -- the object ID was "
"invalid"
@@ -1535,10 +1584,10 @@ 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:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
-msgstr "El formulario de comentario no proporcionó 'previsualizar' ni 'enviar'"
+msgstr "El formulario de comentarios no proporcionó 'previsualizar' ni 'enviar'"
#: contrib/comments/views/karma.py:21
msgid "Anonymous users cannot vote"
@@ -1552,42 +1601,46 @@ msgstr "ID de comentario no válido"
msgid "No voting for yourself"
msgstr "Ud. no puede votarse a sí mismo"
-#: contrib/contenttypes/models.py:37
+#: contrib/contenttypes/models.py:67
msgid "python model class name"
msgstr "nombre de la clase python del modelo"
-#: contrib/contenttypes/models.py:40
+#: contrib/contenttypes/models.py:71
msgid "content type"
msgstr "tipo de contenido"
-#: contrib/contenttypes/models.py:41
+#: contrib/contenttypes/models.py:72
msgid "content types"
msgstr "tipos de contenido"
-#: contrib/flatpages/models.py:8
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Opciones avanzadas"
+
+#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
"Ejemplo: '/about/contact/'. Asegúrese de usar barras '/' al principio y al "
"final."
-#: contrib/flatpages/models.py:9
+#: contrib/flatpages/models.py:10
msgid "title"
msgstr "título"
-#: contrib/flatpages/models.py:10
+#: contrib/flatpages/models.py:11
msgid "content"
msgstr "contenido"
-#: contrib/flatpages/models.py:11
+#: contrib/flatpages/models.py:12
msgid "enable comments"
msgstr "activar comentarios"
-#: contrib/flatpages/models.py:12
+#: contrib/flatpages/models.py:13
msgid "template name"
msgstr "nombre de plantilla"
-#: contrib/flatpages/models.py:13
+#: contrib/flatpages/models.py:14
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
@@ -1595,126 +1648,126 @@ msgstr ""
"Ejemplo: 'flatpages/contact_page.html'. Si no lo proporciona, el sistema "
"usará 'flatpages/default.html'."
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "registration required"
msgstr "debe estar registrado"
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
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
+#: contrib/flatpages/models.py:20
msgid "flat page"
msgstr "página estática"
-#: contrib/flatpages/models.py:19
+#: contrib/flatpages/models.py:21
msgid "flat pages"
msgstr "páginas estáticas"
-#: contrib/humanize/templatetags/humanize.py:20
+#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "th"
-#: contrib/humanize/templatetags/humanize.py:20
+#: contrib/humanize/templatetags/humanize.py:19
msgid "st"
msgstr "st"
-#: contrib/humanize/templatetags/humanize.py:20
+#: contrib/humanize/templatetags/humanize.py:19
msgid "nd"
msgstr "nd"
-#: contrib/humanize/templatetags/humanize.py:20
+#: contrib/humanize/templatetags/humanize.py:19
msgid "rd"
msgstr "rd"
-#: contrib/humanize/templatetags/humanize.py:52
+#: contrib/humanize/templatetags/humanize.py:51
#, python-format
msgid "%(value).1f million"
msgid_plural "%(value).1f million"
msgstr[0] "%(value).1f millón"
msgstr[1] "%(value).1f millones"
-#: contrib/humanize/templatetags/humanize.py:55
+#: contrib/humanize/templatetags/humanize.py:54
#, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
msgstr[0] "%(value).1f millardo"
msgstr[1] "%(value).1f millardos"
-#: contrib/humanize/templatetags/humanize.py:58
+#: contrib/humanize/templatetags/humanize.py:57
#, python-format
msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion"
msgstr[0] "%(value).1f billón"
msgstr[1] "%(value).1f billones"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "one"
msgstr "uno"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "two"
msgstr "dos"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "three"
msgstr "tres"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "four"
msgstr "cuatro"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "five"
msgstr "cinco"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "six"
msgstr "seis"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "seven"
msgstr "siete"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "eight"
msgstr "ocho"
-#: contrib/humanize/templatetags/humanize.py:74
+#: contrib/humanize/templatetags/humanize.py:73
msgid "nine"
msgstr "nueve"
-#: contrib/humanize/templatetags/humanize.py:94
+#: contrib/humanize/templatetags/humanize.py:93
msgid "today"
msgstr "hoy"
-#: contrib/humanize/templatetags/humanize.py:96
+#: contrib/humanize/templatetags/humanize.py:95
msgid "tomorrow"
msgstr "mañana"
-#: contrib/humanize/templatetags/humanize.py:98
+#: contrib/humanize/templatetags/humanize.py:97
msgid "yesterday"
msgstr "ayer"
-#: contrib/localflavor/ar/forms.py:28
+#: contrib/localflavor/ar/forms.py:27
msgid "Enter a postal code in the format NNNN or ANNNNAAA."
msgstr "Introduzca un código postal en formato NNNN o ANNNNAAA."
-#: contrib/localflavor/ar/forms.py:50 contrib/localflavor/br/forms.py:96
+#: contrib/localflavor/ar/forms.py:49 contrib/localflavor/br/forms.py:96
#: contrib/localflavor/br/forms.py:135 contrib/localflavor/pe/forms.py:23
#: contrib/localflavor/pe/forms.py:51
msgid "This field requires only numbers."
msgstr "Este campo permite sólo valores numéricos."
-#: contrib/localflavor/ar/forms.py:51
+#: contrib/localflavor/ar/forms.py:50
msgid "This field requires 7 or 8 digits."
msgstr "Este campo requiere 7 u 8 dígitos."
-#: contrib/localflavor/ar/forms.py:80
+#: contrib/localflavor/ar/forms.py:79
msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
msgstr "Introduzca un CUIT válido en formato XX-XXXXXXXX-X o XXXXXXXXXXX."
-#: contrib/localflavor/ar/forms.py:81
+#: contrib/localflavor/ar/forms.py:80
msgid "Invalid CUIT."
msgstr "CUIT inválido."
@@ -1869,7 +1922,7 @@ msgstr "Zurich"
#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
msgid "Enter a zip code in the format XXXX."
-msgstr "Introduzca un zip code en formato XXX."
+msgstr "Introduzca un zip code en formato XXXX."
#: contrib/localflavor/ch/forms.py:64
msgid ""
@@ -2311,7 +2364,7 @@ msgstr "Introduzca un número de Seguridad Social válido."
msgid "Enter a valid VAT number."
msgstr "Introduzca un número VAT válido."
-#: contrib/localflavor/jp/forms.py:19
+#: contrib/localflavor/jp/forms.py:17
msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
msgstr "Introduzca un código postal en formato XXXXXX o XXX-XXXX."
@@ -3156,7 +3209,7 @@ msgstr "region Zilina"
#: contrib/localflavor/uk/forms.py:21
msgid "Enter a valid postcode."
-msgstr "Introduzca un postcde válido."
+msgstr "Introduzca un postcode válido."
#: contrib/localflavor/uk/uk_regions.py:11
msgid "Bedfordshire"
@@ -3327,10 +3380,13 @@ msgid "County Armagh"
msgstr "County Armagh"
#: contrib/localflavor/uk/uk_regions.py:57
-#: contrib/localflavor/uk/uk_regions.py:58
msgid "County Down"
msgstr "County Down"
+#: contrib/localflavor/uk/uk_regions.py:58
+msgid "County Fermanagh"
+msgstr "County Fermarmagh"
+
#: contrib/localflavor/uk/uk_regions.py:59
msgid "County Londonderry"
msgstr "County Londonderry"
@@ -3496,7 +3552,7 @@ 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. Ejemplo: '/"
+"Esta ruta debe ser absoluta, excluyendo el nombre de dominio. Ejemplo: '/"
"events/search/'."
#: contrib/redirects/models.py:9
@@ -3519,7 +3575,7 @@ msgstr "redirección"
msgid "redirects"
msgstr "redirecciones"
-#: contrib/sessions/models.py:46
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "clave de sesión"
@@ -3547,18 +3603,14 @@ msgstr "nombre de dominio"
msgid "display name"
msgstr "nombre para visualizar"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "sitio"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "sitios"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Este valor debe contener sólo letras, números y guiones bajos."
-
#: core/validators.py:76
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
@@ -3604,7 +3656,7 @@ msgstr "No se admiten caracteres no numéricos."
msgid "This value can't be comprised solely of digits."
msgstr "Este valor no puede estar formado sólo por dígitos."
-#: core/validators.py:128 newforms/fields.py:151
+#: core/validators.py:128 forms/fields.py:157
msgid "Enter a whole number."
msgstr "Introduzca un número entero."
@@ -3613,37 +3665,32 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Sólo se admiten caracteres alfabéticos."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "El año debe ser 1900 o posterior."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Fecha no válida: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:509
+#: core/validators.py:152 db/models/fields/__init__.py:550
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Introduzca una fecha válida en formato AAAA-MM-DD."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Introduzca una hora válida en formato HH:MM."
-#: core/validators.py:165 db/models/fields/__init__.py:583
+#: core/validators.py:161 db/models/fields/__init__.py:631
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."
-#: core/validators.py:170 newforms/fields.py:402
+#: core/validators.py:166 forms/fields.py:408
msgid "Enter a valid e-mail address."
msgstr "Introduzca una dirección de correo electrónico válida"
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:432
-#: oldforms/__init__.py:687
+#: core/validators.py:178 core/validators.py:470 forms/fields.py:426
msgid "No file was submitted. Check the encoding type on the form."
msgstr ""
"No se envió un archivo. Verifique el tipo de codificación en el formulario."
-#: core/validators.py:193 newforms/fields.py:458
+#: core/validators.py:189 forms/fields.py:466
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
@@ -3651,28 +3698,28 @@ msgstr ""
"Envíe una imagen válida. El archivo que ha enviado no era una imagen o se "
"trataba de una imagen corrupta."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "La URL %s no apunta a una imagen válida."
-#: core/validators.py:204
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
"Los números telefónicos deben respetar el formato XXX-XXX-XXXX. \"%s\" no es "
"válido."
-#: core/validators.py:212
+#: core/validators.py:208
#, 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."
+msgstr "La URL %s no apunta a un video QuickTime válido."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Se precisa una URL válida."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3681,84 +3728,84 @@ msgstr ""
"Se precisa HTML válido. Los errores específicos son:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "XML mal formado: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "URL no válida: %s"
-#: core/validators.py:259 core/validators.py:261
+#: core/validators.py:255 core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "La URL %s es un enlace roto."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Introduzca una abreviatura válida de estado de los EE.UU."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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] "¡Vigila tu boca! Aquí no admitimos la palabra %s."
msgstr[1] "¡Vigila tu boca! Aquí no admitimos las palabras %s."
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Este campo debe concordar con el campo '%s'."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Por favor, introduzca algo en al menos un campo."
-#: core/validators.py:316 core/validators.py:327
+#: core/validators.py:312 core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Por favor, rellene ambos campos o deje ambos vacíos."
-#: core/validators.py:335
+#: core/validators.py:331
#, 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"
-#: core/validators.py:348
+#: core/validators.py:344
#, 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"
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "No se admiten valores duplicados."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Este valor debe estar entre %(lower)s y %(upper)s."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Este valor debe ser al menos %s."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Este valor debe ser no mayor que %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Este valor debe ser una potencia de %s."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Por favor, introduzca un número decimal válido."
-#: core/validators.py:444
+#: core/validators.py:440
#, python-format
msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
@@ -3770,7 +3817,7 @@ msgstr[1] ""
"Por favor, introduzca un número decimal válido con un maximo de %s dígitos "
"en total."
-#: core/validators.py:447
+#: core/validators.py:443
#, python-format
msgid ""
"Please enter a valid decimal number with a whole part of at most %s digit."
@@ -3783,7 +3830,7 @@ msgstr[1] ""
"Por favor, introduzca un número decimal válido con un máximo de %s dígitos "
"enteros."
-#: core/validators.py:450
+#: core/validators.py:446
#, python-format
msgid "Please enter a valid decimal number with at most %s decimal place."
msgid_plural ""
@@ -3795,36 +3842,36 @@ msgstr[1] ""
"Por favor, introduzca un número decimal válido con un máximo de %s "
"posiciones decimales."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Por favor introduzca un número de punto flotante válido."
-#: core/validators.py:467
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr ""
"Asegúrese de que el archivo que envía es de un tamaño mínimo de %s bytes."
-#: core/validators.py:468
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr ""
"Asegúrese de que el archivo que envía es de un tamaño máximo de %s bytes."
-#: core/validators.py:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "El formato de este campo es incorrecto."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Este campo no es válido."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "No se pudo obtener nada de %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, python-format
msgid ""
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
@@ -3832,7 +3879,7 @@ msgstr ""
"La URL %(url)s devolvió la cabecera Content-Type '%(contenttype)s', que no "
"es válida."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
@@ -3841,7 +3888,7 @@ msgstr ""
"Por favor, cierre la etiqueta %(tag)s de la línea %(line)s. (La línea "
"empieza con \"%(start)s\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
@@ -3850,7 +3897,7 @@ msgstr ""
"Parte del texto que comienza en la línea %(line)s no está permitido en ese "
"contexto. (La línea empieza con \"%(start)s\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
@@ -3859,7 +3906,7 @@ msgstr ""
"El \"%(attr)s\" de la línea %(line)s no es un atributo válido. (La línea "
"empieza con \"%(start)s\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
@@ -3868,7 +3915,7 @@ msgstr ""
"La \"<%(tag)s>\" de la línea %(line)s no es una etiqueta válida. (La línea "
"empieza con \"%(start)s\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
@@ -3877,7 +3924,7 @@ msgstr ""
"A una etiqueta de la línea %(line)s le faltan uno o más atributos "
"requeridos. (La línea empieza con \"%(start)s\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
@@ -3886,63 +3933,59 @@ msgstr ""
"El atributo \"%(attr)s\" de la línea %(line)s tiene un valor que no es "
"válido. (La línea empieza con \"%(start)s\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "Ya existe un(a) %(object)s con este/a %(type)s para %(field)s."
-#: db/models/fields/__init__.py:52
+#: db/models/fields/__init__.py:47
#, 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:161 db/models/fields/__init__.py:318
-#: db/models/fields/__init__.py:735 db/models/fields/__init__.py:746
-#: newforms/fields.py:45 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:175 db/models/fields/__init__.py:343
+#: db/models/fields/__init__.py:793 db/models/fields/__init__.py:804
+#: forms/fields.py:51 oldforms/__init__.py:374
msgid "This field is required."
msgstr "Este campo es obligatorio."
-#: db/models/fields/__init__.py:418
+#: db/models/fields/__init__.py:450
msgid "This value must be an integer."
msgstr "Este valor debe ser un número entero."
-#: db/models/fields/__init__.py:454
+#: db/models/fields/__init__.py:489
msgid "This value must be either True or False."
msgstr "Este valor debe ser True o False."
-#: db/models/fields/__init__.py:475
+#: db/models/fields/__init__.py:513
msgid "This field cannot be null."
msgstr "Este campo no puede ser nulo."
-#: db/models/fields/__init__.py:644
+#: db/models/fields/__init__.py:700
msgid "This value must be a decimal number."
msgstr "Este valor debe ser un número decimal."
-#: db/models/fields/__init__.py:755
+#: db/models/fields/__init__.py:813
msgid "Enter a valid filename."
msgstr "Introduzca un nombre de archivo válido."
-#: db/models/fields/__init__.py:908
+#: db/models/fields/__init__.py:1004
msgid "This value must be either None, True or False."
msgstr "Este valor debe ser None, True o False."
-#: db/models/fields/related.py:55
+#: db/models/fields/related.py:94
#, python-format
msgid "Please enter a valid %s."
msgstr "Por favor, introduzca un %s válido."
-#: db/models/fields/related.py:658
-msgid "Separate multiple IDs with commas."
-msgstr "Separe múltiples identificadores con comas."
-
-#: db/models/fields/related.py:660
+#: db/models/fields/related.py:729
msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr ""
"Mantenga presionada \"Control\" (\"Command\" en una Mac) para seleccionar "
"más de uno."
-#: db/models/fields/related.py:707
+#: db/models/fields/related.py:773
#, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural ""
@@ -3954,103 +3997,103 @@ msgstr[1] ""
"Por favor, introduzca IDs de %(self)s válidos. Los valores %(value)r no son "
"válidos."
-#: newforms/fields.py:46
+#: forms/fields.py:52
msgid "Enter a valid value."
msgstr "Introduzca un valor válido."
-#: newforms/fields.py:123
+#: forms/fields.py:129
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr ""
"Asegúrese de que este valor tenga como máximo %(max)d caracteres (tiene %"
"(length)d)."
-#: newforms/fields.py:124
+#: forms/fields.py:130
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr ""
"Asegúrese de que este valor tenga al menos %(min)d caracteres (tiene %"
"(length)d)."
-#: newforms/fields.py:152 newforms/fields.py:181 newforms/fields.py:210
+#: forms/fields.py:158 forms/fields.py:187 forms/fields.py:216
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Asegúrese de que este valor sea menor o igual a %s."
-#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
+#: forms/fields.py:159 forms/fields.py:188 forms/fields.py:217
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Asegúrese de que este valor sea mayor o igual a %s."
-#: newforms/fields.py:180 newforms/fields.py:209
+#: forms/fields.py:186 forms/fields.py:215
msgid "Enter a number."
msgstr "Introduzca un número."
-#: newforms/fields.py:212
+#: forms/fields.py:218
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "Asegúrese de que no existan en total mas de %s dígitos."
-#: newforms/fields.py:213
+#: forms/fields.py:219
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "Asegúrese de que no existan mas de %s lugares decimales."
-#: newforms/fields.py:214
+#: forms/fields.py:220
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Asegúrese de que no existan mas de %s dígitos antes del punto decimal."
-#: newforms/fields.py:262 newforms/fields.py:723
+#: forms/fields.py:268 forms/fields.py:790
msgid "Enter a valid date."
msgstr "Introduzca una fecha válida."
-#: newforms/fields.py:295 newforms/fields.py:724
+#: forms/fields.py:301 forms/fields.py:791
msgid "Enter a valid time."
msgstr "Introduzca una hora válida."
-#: newforms/fields.py:334
+#: forms/fields.py:340
msgid "Enter a valid date/time."
msgstr "Introduzca una fecha/hora válida."
-#: newforms/fields.py:433
+#: forms/fields.py:427
msgid "No file was submitted."
msgstr "No se envió ningún archivo."
-#: newforms/fields.py:434 oldforms/__init__.py:689
+#: forms/fields.py:428 oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "El archivo enviado está vacío."
-#: newforms/fields.py:496
+#: forms/fields.py:522
msgid "Enter a valid URL."
msgstr "Introduzca una URL válida."
-#: newforms/fields.py:497
+#: forms/fields.py:523
msgid "This URL appears to be a broken link."
msgstr "La URL parece ser un enlace roto."
-#: newforms/fields.py:559 newforms/models.py:317
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr ""
-"Seleccione una opción válida. Esa opción no es una de las opciones "
-"disponibles."
-
-#: newforms/fields.py:598
+#: forms/fields.py:588 forms/fields.py:639
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr ""
"Seleccione una opción válida. %(value)s no es una de las opciones "
"disponibles."
-#: newforms/fields.py:599 newforms/fields.py:661 newforms/models.py:377
+#: forms/fields.py:640 forms/fields.py:701 forms/models.py:581
msgid "Enter a list of values."
msgstr "Introduzca una lista de valores."
-#: newforms/fields.py:752
+#: forms/fields.py:819
msgid "Enter a valid IPv4 address."
msgstr "Introduzca una dirección IPv4 válida"
-#: newforms/models.py:378
+#: forms/models.py:514
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr ""
+"Seleccione una opción válida. Esa opción no es una de las opciones "
+"disponibles."
+
+#: forms/models.py:582
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr ""
@@ -4072,40 +4115,40 @@ msgstr "No se permiten saltos de línea."
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Seleccione una opción válida; '%(data)s' no está en %(choices)s."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
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:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Introduzca un número positivo."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Introduzca un número entero entre 0 y 32.767."
-#: template/defaultfilters.py:691
+#: template/defaultfilters.py:698
msgid "yes,no,maybe"
msgstr "si,no,talvez"
-#: template/defaultfilters.py:722
+#: template/defaultfilters.py:729
#, python-format
msgid "%(size)d byte"
msgid_plural "%(size)d bytes"
msgstr[0] "%(size)d byte"
msgstr[1] "%(size)d bytes"
-#: template/defaultfilters.py:724
+#: template/defaultfilters.py:731
#, python-format
msgid "%.1f KB"
msgstr "%.1f KB"
-#: template/defaultfilters.py:726
+#: template/defaultfilters.py:733
#, python-format
msgid "%.1f MB"
msgstr "%.1f MB"
-#: template/defaultfilters.py:727
+#: template/defaultfilters.py:734
#, python-format
msgid "%.1f GB"
msgstr "%.1f GB"
@@ -4314,7 +4357,7 @@ msgstr "Nov."
msgid "Dec."
msgstr "Dic."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "o"
@@ -4368,41 +4411,68 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:399
+#: utils/translation/trans_real.py:412
msgid "DATE_FORMAT"
msgstr "j N Y"
-#: utils/translation/trans_real.py:400
+#: utils/translation/trans_real.py:413
msgid "DATETIME_FORMAT"
msgstr "j N Y P"
-#: utils/translation/trans_real.py:401
+#: utils/translation/trans_real.py:414
msgid "TIME_FORMAT"
msgstr "P"
-#: utils/translation/trans_real.py:417
+#: utils/translation/trans_real.py:430
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:418
+#: utils/translation/trans_real.py:431
msgid "MONTH_DAY_FORMAT"
msgstr "j \\de F"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "Se creó con éxito %(verbose_name)s."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "Se actualizó con éxito %(verbose_name)s."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "Se eliminó %(verbose_name)s."
+#~ msgid "Year must be 1900 or later."
+#~ msgstr "El año debe ser 1900 o posterior."
+
+#~ msgid "Gaeilge"
+#~ msgstr "Irlandés"
+
+#~ msgid "Brazilian"
+#~ msgstr "Brasileño"
+
+#~ msgid "Ordering"
+#~ msgstr "Ordenación"
+
+#~ msgid "Order:"
+#~ msgstr "Orden:"
+
+#~ msgid "Added %s."
+#~ msgstr "Agregado %s."
+
+#~ msgid "Deleted %s."
+#~ msgstr "Eliminó %s."
+
+#~ msgid "The two 'new password' fields didn't match."
+#~ msgstr "Los dos campos 'nueva contraseña' no coinciden entre si."
+
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Separe múltiples identificadores con comas."
+
#~ msgid ""
#~ "Enter a postcode. A space is required between the two postcode parts."
#~ msgstr ""
diff --git a/django/conf/locale/fr/LC_MESSAGES/django.mo b/django/conf/locale/fr/LC_MESSAGES/django.mo
index 60b760f7a8..7db70d5cd9 100644
--- a/django/conf/locale/fr/LC_MESSAGES/django.mo
+++ b/django/conf/locale/fr/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/fr/LC_MESSAGES/django.po b/django/conf/locale/fr/LC_MESSAGES/django.po
index 3e133e8ca7..7a88f84ec7 100644
--- a/django/conf/locale/fr/LC_MESSAGES/django.po
+++ b/django/conf/locale/fr/LC_MESSAGES/django.po
@@ -1,7 +1,7 @@
# translation of django.po to french
# This file is distributed under the same license as the PACKAGE package.
# Copyright (C) 2008 THE PACKAGE'S COPYRIGHT HOLDER.
-#
+#
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
@@ -1066,7 +1066,7 @@ msgstr "Sélectionnez %s"
#: contrib/admin/views/main.py:583
#, python-format
msgid "Select %s to change"
-msgstr "Sélectionnez %s pour changer"
+msgstr "Sélectionnez l'objet %s à changer"
#: contrib/admin/views/main.py:784
msgid "Database error"
@@ -4093,107 +4093,107 @@ msgstr "midi"
#: utils/dates.py:6
msgid "Monday"
-msgstr "Lundi"
+msgstr "lundi"
#: utils/dates.py:6
msgid "Tuesday"
-msgstr "Mardi"
+msgstr "mardi"
#: utils/dates.py:6
msgid "Wednesday"
-msgstr "Mercredi"
+msgstr "mercredi"
#: utils/dates.py:6
msgid "Thursday"
-msgstr "Jeudi"
+msgstr "jeudi"
#: utils/dates.py:6
msgid "Friday"
-msgstr "Vendredi"
+msgstr "vendredi"
#: utils/dates.py:7
msgid "Saturday"
-msgstr "Samedi"
+msgstr "samedi"
#: utils/dates.py:7
msgid "Sunday"
-msgstr "Dimanche"
+msgstr "dimanche"
#: utils/dates.py:10
msgid "Mon"
-msgstr "Lun"
+msgstr "lun"
#: utils/dates.py:10
msgid "Tue"
-msgstr "Mar"
+msgstr "mar"
#: utils/dates.py:10
msgid "Wed"
-msgstr "Mer"
+msgstr "mer"
#: utils/dates.py:10
msgid "Thu"
-msgstr "Jeu"
+msgstr "jeu"
#: utils/dates.py:10
msgid "Fri"
-msgstr "Ven"
+msgstr "ven"
#: utils/dates.py:11
msgid "Sat"
-msgstr "Sam"
+msgstr "sam"
#: utils/dates.py:11
msgid "Sun"
-msgstr "Dim"
+msgstr "dim"
#: utils/dates.py:18
msgid "January"
-msgstr "Janvier"
+msgstr "janvier"
#: utils/dates.py:18
msgid "February"
-msgstr "Février"
+msgstr "février"
#: utils/dates.py:18 utils/dates.py:31
msgid "March"
-msgstr "Mars"
+msgstr "mars"
#: utils/dates.py:18 utils/dates.py:31
msgid "April"
-msgstr "Avril"
+msgstr "avril"
#: utils/dates.py:18 utils/dates.py:31
msgid "May"
-msgstr "Mai"
+msgstr "mai"
#: utils/dates.py:18 utils/dates.py:31
msgid "June"
-msgstr "Juin"
+msgstr "juin"
#: utils/dates.py:19 utils/dates.py:31
msgid "July"
-msgstr "Juillet"
+msgstr "juillet"
#: utils/dates.py:19
msgid "August"
-msgstr "Août"
+msgstr "août"
#: utils/dates.py:19
msgid "September"
-msgstr "Septembre"
+msgstr "septembre"
#: utils/dates.py:19
msgid "October"
-msgstr "Octobre"
+msgstr "octobre"
#: utils/dates.py:19
msgid "November"
-msgstr "Novembre"
+msgstr "novembre"
#: utils/dates.py:20
msgid "December"
-msgstr "Décembre"
+msgstr "décembre"
#: utils/dates.py:23
msgid "jan"
@@ -4245,31 +4245,31 @@ msgstr "déc"
#: utils/dates.py:31
msgid "Jan."
-msgstr "Jan."
+msgstr "jan."
#: utils/dates.py:31
msgid "Feb."
-msgstr "Fév."
+msgstr "fév."
#: utils/dates.py:32
msgid "Aug."
-msgstr "Août"
+msgstr "août"
#: utils/dates.py:32
msgid "Sept."
-msgstr "Sept."
+msgstr "sept."
#: utils/dates.py:32
msgid "Oct."
-msgstr "Oct."
+msgstr "oct."
#: utils/dates.py:32
msgid "Nov."
-msgstr "Nov."
+msgstr "nov."
#: utils/dates.py:32
msgid "Dec."
-msgstr "Déc."
+msgstr "déc."
#: utils/text.py:127
msgid "or"
diff --git a/django/conf/locale/it/LC_MESSAGES/django.mo b/django/conf/locale/it/LC_MESSAGES/django.mo
index e96764a0a8..b04a32eed4 100644
--- a/django/conf/locale/it/LC_MESSAGES/django.mo
+++ b/django/conf/locale/it/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/it/LC_MESSAGES/django.po b/django/conf/locale/it/LC_MESSAGES/django.po
index 4e87ad549d..4c08a43929 100644
--- a/django/conf/locale/it/LC_MESSAGES/django.po
+++ b/django/conf/locale/it/LC_MESSAGES/django.po
@@ -1,13 +1,14 @@
# translation of django.po to Italiano
+# Nicola Larosa <nico@tekNico.net>, 2008.
# Italian translation of Django.
# Copyright (C) 2006 the Lawrence Journal-World
# This file is distributed under the same license as the Django package.
msgid ""
msgstr ""
-"Project-Id-Version: Django vSVN\n"
+"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-07-12 20:30+0200\n"
-"PO-Revision-Date: 2008-07-12 20:45+0200\n"
+"POT-Creation-Date: 2008-08-04 11:52+0200\n"
+"PO-Revision-Date: 2008-08-04 12:08+0200\n"
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
"Language-Team: Italiano\n"
"MIME-Version: 1.0\n"
@@ -246,49 +247,208 @@ msgstr "Questo mese"
msgid "This year"
msgstr "Quest'anno"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
-#: oldforms/__init__.py:592
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
+#: oldforms/__init__.py:588
msgid "Yes"
msgstr "Sì"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
-#: oldforms/__init__.py:592
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
+#: oldforms/__init__.py:588
msgid "No"
msgstr "No"
-#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
-#: oldforms/__init__.py:592
+#: contrib/admin/filterspecs.py:154 forms/widgets.py:379
+#: oldforms/__init__.py:588
msgid "Unknown"
msgstr "Sconosciuto"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "momento dell'azione"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "id dell'oggetto"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "rappresentazione dell'oggetto"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "flag di azione"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "messaggio di modifica"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "voce di log"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "voci di log"
+#: contrib/admin/options.py:143 contrib/admin/options.py:181
+msgid "None"
+msgstr "Nessuno"
+
+#: contrib/admin/options.py:361 contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "Il %(name)s \"%(obj)s\" è stato aggiunto correttamente."
+
+#: contrib/admin/options.py:365 contrib/admin/options.py:433
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "È possibile modificarlo nuovamente qui sotto."
+
+#: contrib/admin/options.py:375 contrib/admin/options.py:442
+#, python-format
+msgid "You may add another %s below."
+msgstr "È possibile aggiungere un altro %s qui sotto."
+
+#: contrib/admin/options.py:409
+#, python-format
+msgid "Changed %s."
+msgstr "%s modificato."
+
+#: contrib/admin/options.py:409 contrib/admin/options.py:419
+#: core/validators.py:279 db/models/manipulators.py:305
+msgid "and"
+msgstr "e"
+
+#: contrib/admin/options.py:414
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Aggiunti %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:418
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Cambiati %(list)s per %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:423
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Cancellati %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:428
+msgid "No fields changed."
+msgstr "Nessun campo modificato."
+
+#: contrib/admin/options.py:431
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "Il %(name)s \"%(obj)s\" è stato modificato correttamente."
+
+#: contrib/admin/options.py:439
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"Il %(name)s \"%(obj)s\" è stato aggiunto correttamente. È possibile "
+"modificarlo nuovamente qui sotto."
+
+#: contrib/admin/options.py:520
+#, python-format
+msgid "Add %s"
+msgstr "Aggiungi %s"
+
+#: contrib/admin/options.py:582
+#, python-format
+msgid "Change %s"
+msgstr "Modifica %s"
+
+#: contrib/admin/options.py:612
+msgid "Database error"
+msgstr "Errore nel database"
+
+#: contrib/admin/options.py:661
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "Lo %(name)s \"%(obj)s\" è stato cancellato correttamente."
+
+#: contrib/admin/options.py:667
+msgid "Are you sure?"
+msgstr "Sei sicuro?"
+
+#: contrib/admin/options.py:694
+#, python-format
+msgid "Change history: %s"
+msgstr "Tracciato delle modifiche: %s"
+
+#: contrib/admin/sites.py:17 contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:72 contrib/comments/views/comments.py:56
+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/admin/sites.py:229 contrib/admin/views/decorators.py:68
+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/sites.py:236 contrib/admin/views/decorators.py:75
+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/sites.py:250 contrib/admin/sites.py:256
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "I nomi utente non possono contenere il carattere '@'."
+
+#: contrib/admin/sites.py:253 contrib/admin/views/decorators.py:88
+#, 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/sites.py:321
+msgid "Site administration"
+msgstr "Amministrazione sito"
+
+#: contrib/admin/sites.py:343 contrib/admin/templates/admin/login.html:27
+#: contrib/admin/templates/registration/password_reset_complete.html:14
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Accedi"
+
+#: contrib/admin/util.py:126
+#, 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/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Uno o più %(fieldname)s in %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Data:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Ora:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Attualmente:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Modifica:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -299,17 +459,19 @@ 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/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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:4
+#: contrib/admin/templates/registration/password_change_form.html:4
+#: contrib/admin/templates/registration/password_reset_complete.html:4
+#: contrib/admin/templates/registration/password_reset_confirm.html:4
#: contrib/admin/templates/registration/password_reset_done.html:4
#: contrib/admin/templates/registration/password_reset_form.html:4
msgid "Home"
@@ -335,22 +497,28 @@ 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/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Benvenuto,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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 "Documentazione"
-#: contrib/admin/templates/admin/base.html:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Cambia la password"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Esci"
@@ -363,46 +531,43 @@ msgstr "Amministrazione sito Django"
msgid "Django administration"
msgstr "Amministrazione Django"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Aggiungi"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Storia"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Vedi sul sito"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
msgid "Please correct the error below."
msgid_plural "Please correct the errors below."
msgstr[0] "Correggere l'errore qui sotto."
msgstr[1] "Correggere gli errori qui sotto."
-#: contrib/admin/templates/admin/change_form.html:49
-msgid "Ordering"
-msgstr "Ordinamento"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Ordine:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "Aggiungi %(name)s"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filtro"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Cancella"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, python-format
msgid ""
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
@@ -413,7 +578,7 @@ msgstr ""
"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:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, python-format
msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
@@ -422,7 +587,7 @@ 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:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Sì, sono sicuro"
@@ -431,41 +596,37 @@ msgstr "Sì, sono sicuro"
msgid " By %(filter_title)s "
msgstr " Per %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filtro"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "Models available in the %(name)s application."
msgstr "Modelli disponibili nell'applicazione %(name)s."
-#: contrib/admin/templates/admin/index.html:18
+#: contrib/admin/templates/admin/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Modifica"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "Non hai i privilegi per modificare alcunché."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Azioni Recenti"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Azioni Proprie"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Nessuno disponibile"
-#: contrib/admin/templates/admin/invalid_setup.html:8
+#: contrib/admin/templates/admin/invalid_setup.html:7
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 "
@@ -475,39 +636,34 @@ msgstr ""
"appropriate del database siano state create, e che il database sia leggibile "
"dall'utente appropriato."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: 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/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Password:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Accedi"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Data/ora"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Utente"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Azione"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "j F Y, H:i"
-#: contrib/admin/templates/admin/object_history.html:35
+#: contrib/admin/templates/admin/object_history.html:32
msgid ""
"This object doesn't have a change history. It probably wasn't added via this "
"admin site."
@@ -559,26 +715,29 @@ msgstr ""
"Inserire innanzitutto nome utente e password. Si potrà quindi modificare le "
"altre impostazioni dell'utente."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:14 contrib/auth/forms.py:51
msgid "Username"
msgstr "Nome utente"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:17 contrib/auth/forms.py:52 contrib/auth/forms.py:176
msgid "Password"
msgstr "Password"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:177
msgid "Password (again)"
msgstr "Password (di nuovo)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Inserire la stessa password inserita sopra, come verifica."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr "Inserire una nuova password per l'utente <strong>%(username)s</strong>."
@@ -663,23 +822,23 @@ msgstr "Grazie per aver speso il tuo tempo prezioso su questo sito oggi."
msgid "Log in again"
msgstr "Accedi di nuovo"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: 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:11
+#: 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:11
+#: 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."
@@ -687,22 +846,27 @@ msgstr ""
"Inserire la password attuale, 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:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Password attuale:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
+#: contrib/admin/templates/registration/password_reset_confirm.html:18
msgid "New password:"
msgstr "Nuova password:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
+#: contrib/admin/templates/registration/password_reset_confirm.html:20
msgid "Confirm password:"
msgstr "Confermare la password:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
+#: contrib/admin/templates/registration/password_reset_confirm.html:21
msgid "Change my password"
msgstr "Modifica la mia password"
+#: contrib/admin/templates/registration/password_reset_complete.html:4
+#: contrib/admin/templates/registration/password_reset_confirm.html:6
#: 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
@@ -710,6 +874,39 @@ msgstr "Modifica la mia password"
msgid "Password reset"
msgstr "Reimposta la password"
+#: contrib/admin/templates/registration/password_reset_complete.html:6
+#: contrib/admin/templates/registration/password_reset_complete.html:10
+msgid "Password reset complete"
+msgstr "Password reimpostata"
+
+#: contrib/admin/templates/registration/password_reset_complete.html:12
+msgid "Your password has been set. You may go ahead and log in now."
+msgstr "La tua password è stata impostata. Ora puoi effettuare l'accesso."
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:4
+msgid "Password reset confirmation"
+msgstr "Conferma reimpostazione password"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:12
+msgid "Enter new password"
+msgstr "Inserisci la nuova password"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:14
+msgid ""
+"Please enter your new password twice so we can verify you typed it in "
+"correctly."
+msgstr "Inserire la nuova password due volte, per verificare di averla scritta correttamente."
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:26
+msgid "Password reset unsuccessful"
+msgstr "Password NON reimpostata"
+
+#: contrib/admin/templates/registration/password_reset_confirm.html:28
+msgid ""
+"The password reset link was invalid, possibly because it has already been "
+"used. Please request a new password reset."
+msgstr "Il link per la reimpostazione della password non era valido, forse perché era già stato usato. Richiedi una nuova reimpostazione della password."
+
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
@@ -717,11 +914,9 @@ msgstr "Password reimpostata correttamente"
#: 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 ""
-"La nuova password è stata inviata all'indirizzo e-mail inserito. Arriverà a "
-"breve."
+"We've e-mailed you instructions for setting your password to the e-mail "
+"address you submitted. You should be receiving it shortly."
+msgstr "Abbiamo inviato le istruzioni per impostare la tua password all'indirizzo e-mail inserito. Arriverà a breve."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
@@ -733,34 +928,27 @@ msgid "for your user account at %(site_name)s"
msgstr "per il tuo account utente su %(site_name)s"
#: contrib/admin/templates/registration/password_reset_email.html:5
-#, python-format
-msgid "Your new password is: %(new_password)s"
-msgstr "La tua nuova password è: %(new_password)s"
+msgid "Please go to the following page and choose a new password:"
+msgstr "Vai alla pagina seguente e scegli una nuova password:"
-#: contrib/admin/templates/registration/password_reset_email.html:7
-msgid "Feel free to change this password by going to this page:"
-msgstr "Puoi liberamente cambiare la tua password tramite questa pagina:"
-
-#: contrib/admin/templates/registration/password_reset_email.html:11
+#: contrib/admin/templates/registration/password_reset_email.html:9
msgid "Your username, in case you've forgotten:"
msgstr "Il tuo nome utente, in caso l'abbia dimenticato:"
-#: contrib/admin/templates/registration/password_reset_email.html:13
+#: contrib/admin/templates/registration/password_reset_email.html:11
msgid "Thanks for using our site!"
msgstr "Grazie per aver usato il nostro sito!"
-#: contrib/admin/templates/registration/password_reset_email.html:15
+#: contrib/admin/templates/registration/password_reset_email.html:13
#, python-format
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."
+"Forgotten your password? Enter your e-mail address below, and we'll e-mail "
+"instructions for setting a new one."
+msgstr "Dimenticata la password? Inserisci il tuo indirizzo email qui sotto, e ti invieremo per email le istruzioni per impostarne una nuova."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -770,325 +958,210 @@ msgstr "Indirizzo e-mail:"
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 "Ora:"
-
-#: 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:257
msgid "All dates"
msgstr "Tutte le date"
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "Il %(name)s \"%(obj)s\" è stato aggiunto correttamente."
-
-#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "È possibile modificarlo nuovamente qui sotto."
-
-#: 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/views/decorators.py:17 contrib/auth/forms.py:60
-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/admin/views/decorators.py:69
-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/views/decorators.py:76
-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."
+msgid "Select %s"
+msgstr "Scegli %s"
-#: contrib/admin/views/decorators.py:89
+#: contrib/admin/views/main.py:65
#, 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/views/decorators.py:93
-msgid "Usernames cannot contain the '@' character."
-msgstr "I nomi utente non possono contenere il carattere '@'."
+msgid "Select %s to change"
+msgstr "Scegli %s da modificare"
-#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53 contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "tag:"
-#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87 contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filtro:"
-#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153 contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "view:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Appl. %r non trovata"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Modello %(name)r non trovato nell'appl. %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Modello %(model_name)r non trovato nell'appl. %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "l'oggetto `%(label)s.%(type)s` collegato"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "l'oggetto `%(app_label)s.%(data_type)s` collegato"
-#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206 contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242 contrib/admindocs/views.py:247
msgid "model:"
msgstr "modello:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "oggetti `%(label)s.%(name)s` collegati"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "oggetti `%(app_label)s.%(object_name)s` collegati"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "tutti %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "numero di %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Campi sugli oggetti %s"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317 contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330 contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337 contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Intero"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Booleano (True o False)"
-#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319 contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Stringa (fino a %(max_length)s)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Interi separati da virgola"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Data (senza ora)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Data (con ora)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Numero decimale"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "Indirizzo e-mail"
-#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325 contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Percorso di file"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Numero decimale"
-#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331 contrib/comments/models.py:89
msgid "IP address"
msgstr "indirizzo IP"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Booleano (True, False o None)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Collegamento a modello padre"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Numero di telefono"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Testo"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Ora"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
+#: contrib/admindocs/views.py:342 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Stato USA (due lettere maiuscole)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "Testo XML"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s non sembra essere un oggetto urlpattern"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Amministrazione sito"
-
-#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "È possibile aggiungere un altro %s qui sotto."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Aggiungi %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "%s aggiunto."
-
-#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348 core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "e"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Informazioni personali"
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "%s modificato."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Permessi"
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "%s cancellato."
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Date importanti"
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "Nessun campo modificato."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Gruppi"
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "Il %(name)s \"%(obj)s\" è stato modificato correttamente."
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Aggiungi utente"
-#: contrib/admin/views/main.py:362
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+#: contrib/auth/forms.py:15 contrib/auth/models.py:134
+msgid ""
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
msgstr ""
-"Il %(name)s \"%(obj)s\" è stato aggiunto correttamente. È possibile "
-"modificarlo nuovamente qui sotto."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Modifica %s"
-
-#: contrib/admin/views/main.py:487
-#, 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:492
-#, 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:524
-#, 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:527
-msgid "Are you sure?"
-msgstr "Sei sicuro?"
-
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Tracciato delle modifiche: %s"
+"Obbligatorio. 30 caratteri o meno. Solo caratteri alfanumerici (lettere, "
+"cifre e sottolineati)."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Scegli %s"
+#: contrib/auth/forms.py:16 core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Questo valore può contenere solo lettere, cifre e sottolineati."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Scegli %s da modificare"
+#: contrib/auth/forms.py:18
+msgid "Password confirmation"
+msgstr "Conferma password"
-#: contrib/admin/views/main.py:765
-msgid "Database error"
-msgstr "Errore nel database"
+#: contrib/auth/forms.py:30
+msgid "A user with that username already exists."
+msgstr "Un utente con questo nome·è già presente."
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+#: contrib/auth/forms.py:36 contrib/auth/forms.py:146
+#: contrib/auth/forms.py:188
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:74 contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "Questo account non è attivo."
-#: contrib/auth/forms.py:53
+#: contrib/auth/forms.py:79 contrib/comments/views/comments.py:49
msgid ""
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
"required for logging in."
@@ -1096,11 +1169,11 @@ msgstr ""
"Il browser web sembra non avere i cookie abilitati. I cookie sono necessari "
"per poter accedere."
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Questo account non è attivo."
+#: contrib/auth/forms.py:92
+msgid "E-mail"
+msgstr "E-mail"
-#: contrib/auth/forms.py:84
+#: contrib/auth/forms.py:101
msgid ""
"That e-mail address doesn't have an associated user account. Are you sure "
"you've registered?"
@@ -1108,16 +1181,24 @@ msgstr ""
"Questo indirizzo email non è associato ad alcun account utente. Sei sicuro "
"di esserti registrato?"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:126
#, python-format
msgid "Password reset on %s"
msgstr "Password reimpostata su %s"
-#: 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:134
+msgid "New password"
+msgstr "Nuova password"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:135
+msgid "New password confirmation"
+msgstr "Conferma nuova password"
+
+#: contrib/auth/forms.py:160
+msgid "Old password"
+msgstr "Password attuale"
+
+#: contrib/auth/forms.py:168
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "La password attuale non è stata inserita correttamente: va inserita di nuovo."
@@ -1141,39 +1222,31 @@ msgstr "permessi"
msgid "group"
msgstr "gruppo"
-#: contrib/auth/models.py:98 contrib/auth/models.py:148
+#: contrib/auth/models.py:98 contrib/auth/models.py:144
msgid "groups"
msgstr "gruppi"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:134
msgid "username"
msgstr "nome utente"
-#: contrib/auth/models.py:138
-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:139
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "nome"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "cognome"
-#: contrib/auth/models.py:141
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "indirizzo e-mail"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid "password"
msgstr "password"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -1181,31 +1254,31 @@ msgstr ""
"Usare '[algo]$[salt]$[hexdigest]' oppure la <a href=\"password/\">maschera "
"di cambio password</a>."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "privilegi di staff"
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
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:144
+#: contrib/auth/models.py:140
msgid "active"
msgstr "attivo"
-#: contrib/auth/models.py:144
+#: contrib/auth/models.py:140
msgid ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
-"Indica se l'utente debba essere considerato attivo. Deselezionare "
-"qui, piuttosto che cancellare gli account."
+"Indica se l'utente debba essere considerato attivo. Deselezionare qui, "
+"piuttosto che cancellare gli account."
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "privilegi di superutente"
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
@@ -1213,15 +1286,15 @@ msgstr ""
"Indica che l'utente ha tutti i privilegi, senza che siano stati assegnati "
"esplicitamente."
-#: contrib/auth/models.py:146
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "ultimo accesso"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "iscritto in data"
-#: contrib/auth/models.py:149
+#: contrib/auth/models.py:145
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -1229,43 +1302,36 @@ msgstr ""
"In aggiunta ai privilegi assegnati manualmente, l'utente riceverà anche "
"tutti i privilegi assegnati ad ogni gruppo cui appartiene."
-#: contrib/auth/models.py:150
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "privilegi utente"
-#: contrib/auth/models.py:154
+#: contrib/auth/models.py:150
msgid "user"
msgstr "utente"
-#: contrib/auth/models.py:155
+#: contrib/auth/models.py:151
msgid "users"
msgstr "utenti"
-#: contrib/auth/models.py:160
-msgid "Personal info"
-msgstr "Informazioni personali"
-
-#: contrib/auth/models.py:161
-msgid "Permissions"
-msgstr "Permessi"
-
-#: contrib/auth/models.py:162
-msgid "Important dates"
-msgstr "Date importanti"
-
-#: contrib/auth/models.py:163
-msgid "Groups"
-msgstr "Gruppi"
-
-#: contrib/auth/models.py:323
+#: contrib/auth/models.py:306
msgid "message"
msgstr "messaggio"
-#: contrib/auth/views.py:49
+#: contrib/auth/views.py:51
msgid "Logged out"
msgstr "Accesso annullato"
-#: contrib/comments/models.py:71 contrib/comments/models.py:176
+#: contrib/auth/views.py:162
+msgid "Password changed successfully."
+msgstr "La password è stata cambiata correttamente."
+
+#: contrib/auth/views.py:168
+#, python-format
+msgid "Change password: %s"
+msgstr "Cambia la password: %s"
+
+#: contrib/comments/models.py:71 contrib/comments/models.py:164
msgid "object ID"
msgstr "ID dell'oggetto"
@@ -1274,7 +1340,7 @@ msgid "headline"
msgstr "intestazione"
#: contrib/comments/models.py:73 contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "commento"
@@ -1314,11 +1380,11 @@ msgstr "valutazione #8"
msgid "is valid rating"
msgstr "è una valutazione valida"
-#: contrib/comments/models.py:87 contrib/comments/models.py:179
+#: contrib/comments/models.py:87 contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "data/ora di inserimento"
-#: contrib/comments/models.py:88 contrib/comments/models.py:180
+#: contrib/comments/models.py:88 contrib/comments/models.py:168
msgid "is public"
msgstr "è pubblico"
@@ -1338,11 +1404,11 @@ msgstr ""
msgid "comments"
msgstr "commenti"
-#: contrib/comments/models.py:140 contrib/comments/models.py:222
+#: contrib/comments/models.py:128 contrib/comments/models.py:199
msgid "Content object"
msgstr "Oggetto con contenuto"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1357,48 +1423,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "nome della persona"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "indirizzo IP"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "approvato dallo staff"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "commento libero"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "commenti liberi"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "punteggio"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "data punteggio"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "livello karma"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "livelli karma"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "valutazione: %(score)d da %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1409,36 +1475,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "data flag"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "flag utente"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "flag utente"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Flag da %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "data cancellazione"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "cancellazione da moderatore"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "cancellazioni da moderatore"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Cancellazione da moderatore %r"
@@ -1479,13 +1545,13 @@ msgstr "Anteprima commento"
msgid "Your name:"
msgstr "Il tuo nome:"
-#: contrib/comments/views/comments.py:28
+#: contrib/comments/views/comments.py:76
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:112
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
"This comment was posted by a user who has posted fewer than %(count)s "
@@ -1508,7 +1574,7 @@ msgstr[1] ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1519,23 +1585,23 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Sono ammessi solo POST"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
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:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
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:208
-#: contrib/comments/views/comments.py:295
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
msgid ""
"The comment form had an invalid 'target' parameter -- the object ID was "
"invalid"
@@ -1543,8 +1609,8 @@ msgstr ""
"Il modulo di commento ha un parametro 'target' non valido -- l'ID "
"dell'oggetto non è valido"
-#: contrib/comments/views/comments.py:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Il modulo di commento non fornisce né 'anteprima' né 'invia'"
@@ -1572,6 +1638,10 @@ msgstr "content type"
msgid "content types"
msgstr "content type"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Opzioni avanzate"
+
#: contrib/flatpages/models.py:9
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
@@ -1620,10 +1690,6 @@ msgstr "pagina statica"
msgid "flat pages"
msgstr "pagine statiche"
-#: contrib/flatpages/models.py:27
-msgid "Advanced options"
-msgstr "Opzioni avanzate"
-
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "º"
@@ -1731,6 +1797,51 @@ msgstr "Inserire un CUIT valido nel formato XX-XXXXXXXX-X o XXXXXXXXXXXX."
msgid "Invalid CUIT."
msgstr "CUIT non valido."
+#: contrib/localflavor/at/at_states.py:5
+msgid "Burgenland"
+msgstr "Burgenland"
+
+#: contrib/localflavor/at/at_states.py:6
+msgid "Carinthia"
+msgstr "Carinthia"
+
+#: contrib/localflavor/at/at_states.py:7
+msgid "Lower Austria"
+msgstr "Bassa Austria"
+
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr "Alta Austria"
+
+#: contrib/localflavor/at/at_states.py:9
+msgid "Salzburg"
+msgstr "Salisburgo"
+
+#: contrib/localflavor/at/at_states.py:10
+msgid "Styria"
+msgstr "Styria"
+
+#: contrib/localflavor/at/at_states.py:11
+msgid "Tyrol"
+msgstr "Tirolo"
+
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr "Vorarlberg"
+
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr "Vienna"
+
+#: contrib/localflavor/at/forms.py:20 contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Inserire un codice postale nel formato XXXXX ."
+
+#: contrib/localflavor/at/forms.py:48
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
+msgstr "Inserire un Numero di Assistenza Sociale Austriaco valido, nel formato XXXX XXXXXX."
+
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
msgstr "Inserire un codice postale di 4 cifre."
@@ -1881,10 +1992,6 @@ msgstr "Zug"
msgid "Zurich"
msgstr "Zurigo"
-#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
-msgid "Enter a zip code in the format XXXX."
-msgstr "Inserire un codice postale nel formato XXXXX ."
-
#: contrib/localflavor/ch/forms.py:64
msgid ""
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
@@ -2809,6 +2916,26 @@ msgstr "Polonia Maggiore"
msgid "West Pomerania"
msgstr "Pomerania Ovest"
+#: contrib/localflavor/ro/forms.py:19
+msgid "Enter a valid CIF."
+msgstr "Inserire un codice CIF valido."
+
+#: contrib/localflavor/ro/forms.py:56
+msgid "Enter a valid CNP."
+msgstr "Inserire un codice CNP valido."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr "Inserire un codice IBAN valido nel formato ROXX-XXXX-XXXX-XXXX-XXXX-XXXX."
+
+#: contrib/localflavor/ro/forms.py:171
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "I numeri di telefono devono essere in formato XXXX-XXXXXX."
+
+#: contrib/localflavor/ro/forms.py:194
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Inserire un codice postale valido nel formato XXXXXX."
+
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
msgstr "Inserire un codice postale nel formato XXXXX o XXX XX ."
@@ -3559,18 +3686,14 @@ msgstr "nome di dominio"
msgid "display name"
msgstr "nome visualizzato"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "sito"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "siti"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Questo valore può contenere solo lettere, cifre e sottolineati."
-
#: core/validators.py:76
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
@@ -3615,7 +3738,7 @@ msgstr "Sono ammessi soltanto caratteri numerici."
msgid "This value can't be comprised solely of digits."
msgstr "Questo valore non può essere composto solo da cifre."
-#: core/validators.py:128 newforms/fields.py:157
+#: core/validators.py:128 forms/fields.py:161
msgid "Enter a whole number."
msgstr "Inserire un numero intero."
@@ -3624,62 +3747,58 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Sono ammessi solo caratteri alfabetici."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "L'anno deve essere 1900 o successivo."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Data non valida: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:554
+#: core/validators.py:152 db/models/fields/__init__.py:569
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Inserire una data valida in formato AAAA-MM-GG."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Inserire un ora valida in formato OO:MM."
-#: core/validators.py:165 db/models/fields/__init__.py:631
+#: core/validators.py:161
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."
-#: core/validators.py:170 newforms/fields.py:408
+#: core/validators.py:166 forms/fields.py:412
msgid "Enter a valid e-mail address."
msgstr "Inserire un indirizzo e-mail valido."
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:426
+#: core/validators.py:178 core/validators.py:470 forms/fields.py:430
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:193 newforms/fields.py:468
+#: core/validators.py:189 forms/fields.py:470
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:200
+#: core/validators.py:196
#, 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:204
+#: core/validators.py:200
#, 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:212
+#: core/validators.py:208
#, 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:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Inserire una URL valida."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3688,91 +3807,91 @@ msgstr ""
"È richiesto HTML valido. Gli errori sono i seguenti:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "XML malformato: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "URL non valida: %s"
-#: core/validators.py:259 core/validators.py:261
+#: core/validators.py:255 core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "La URL %s è un link non funzionante."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Inserire un valido nome di stato USA abbreviato."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Questo campo deve corrispondere al campo '%s'."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Inserire qualcosa in almeno un campo."
-#: core/validators.py:316 core/validators.py:327
+#: core/validators.py:312 core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Inserire entrambi i campi o lasciarli entrambi vuoti."
-#: core/validators.py:335
+#: core/validators.py:331
#, 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:348
+#: core/validators.py:344
#, 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:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Non sono ammessi valori duplicati."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Questo valore deve essere compreso tra %(lower)s e %(upper)s."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Questo valore deve essere almeno pari a %s."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Questo valore non deve essere maggiore di %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Questo valore deve essere una potenza di %s."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Inserire un numero decimale valido."
-#: core/validators.py:444
+#: core/validators.py:440
#, 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:447
+#: core/validators.py:443
#, 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."
@@ -3783,48 +3902,48 @@ msgstr[1] ""
"Inserire un numero decimale la cui parte intera sia composta da non più di %"
"s cifre."
-#: core/validators.py:450
+#: core/validators.py:446
#, 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:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Inserire un numero decimale valido."
-#: core/validators.py:467
+#: core/validators.py:463
#, 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:468
+#: core/validators.py:464
#, 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:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Il formato di questo campo non è valido."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Questo campo non è valido."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Impossibile recuperare alcunché da %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, 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:572
+#: core/validators.py:568
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
@@ -3833,7 +3952,7 @@ msgstr ""
"Chiudere il tag %(tag)s a linea %(line)s. (La linea inizia con \"%(start)s"
"\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
@@ -3842,7 +3961,7 @@ msgstr ""
"Il testo che comincia a linea %(line)s non e' ammesso in quel contesto. (La "
"linea comincia con \"%(start)s\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
@@ -3851,7 +3970,7 @@ msgstr ""
"\"%(attr)s\" a linea %(line)s non è un attributo valido. (La linea comincia "
"con \"%(start)s\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
@@ -3860,7 +3979,7 @@ msgstr ""
"\"<%(tag)s>\" a linea %(line)s non è un tag valido. (La linea comincia con "
"\"%(start)s\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
@@ -3869,7 +3988,7 @@ msgstr ""
"Un tag a linea %(line)s manca di uno o più attributi richiesti. (La linea "
"comincia con \"%(start)s\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
@@ -3878,192 +3997,196 @@ msgstr ""
"L'attributo \"%(attr)s\" a linea %(line)s ha un valore non valido. (La linea "
"comincia con \"%(start)s\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, 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/fields/__init__.py:52
+#: db/models/fields/__init__.py:46
#, 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:182 db/models/fields/__init__.py:354
-#: db/models/fields/__init__.py:788 db/models/fields/__init__.py:799
-#: newforms/fields.py:51 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:170 db/models/fields/__init__.py:343
+#: db/models/fields/__init__.py:792 db/models/fields/__init__.py:803
+#: forms/fields.py:52 oldforms/__init__.py:370
msgid "This field is required."
msgstr "Questo campo è obbligatorio."
-#: db/models/fields/__init__.py:454
+#: db/models/fields/__init__.py:457
msgid "This value must be an integer."
msgstr "Questo valore deve essere un intero."
-#: db/models/fields/__init__.py:493
+#: db/models/fields/__init__.py:503
msgid "This value must be either True or False."
msgstr "Questo valore deve essere True o False."
-#: db/models/fields/__init__.py:517
+#: db/models/fields/__init__.py:532
msgid "This field cannot be null."
msgstr "Questo campo non può essere nullo."
-#: db/models/fields/__init__.py:695
+#: db/models/fields/__init__.py:634 db/models/fields/__init__.py:651
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format."
+msgstr "Inserire una data/ora valida nel formato AAAA-MM-GG OO:MM[ss[.uuuuuu]]."
+
+#: db/models/fields/__init__.py:707
msgid "This value must be a decimal number."
msgstr "Questo valore deve essere un numero decimale."
-#: db/models/fields/__init__.py:808
+#: db/models/fields/__init__.py:812
msgid "Enter a valid filename."
msgstr "Inserire un nome di file valido."
-#: db/models/fields/__init__.py:999
+#: db/models/fields/__init__.py:1013
msgid "This value must be either None, True or False."
msgstr "Questo valore deve essere None, True o False."
-#: db/models/fields/related.py:94
+#: db/models/fields/__init__.py:1128 db/models/fields/__init__.py:1141
+msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
+msgstr "Inserire un ora valida nel formato OO:MM[ss[.uuuuuu]]."
+
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Inserire un %s valido."
-#: db/models/fields/related.py:756
-msgid "Separate multiple IDs with commas."
-msgstr "Separare gli ID multipli con virgole."
-
-#: db/models/fields/related.py:758
+#: db/models/fields/related.py:753
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:805
+#: db/models/fields/related.py:833
#, 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."
-#: newforms/fields.py:52
+#: forms/fields.py:53
msgid "Enter a valid value."
msgstr "Inserire un valore valido."
-#: newforms/fields.py:129
+#: forms/fields.py:133
#, 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)d)."
-#: newforms/fields.py:130
+#: forms/fields.py:134
#, 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)d)."
-#: newforms/fields.py:158 newforms/fields.py:187 newforms/fields.py:216
+#: forms/fields.py:162 forms/fields.py:191 forms/fields.py:220
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Assicurarsi che questo valore sia minore o uguale a %s."
-#: newforms/fields.py:159 newforms/fields.py:188 newforms/fields.py:217
+#: forms/fields.py:163 forms/fields.py:192 forms/fields.py:221
#, 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:186 newforms/fields.py:215
+#: forms/fields.py:190 forms/fields.py:219
msgid "Enter a number."
msgstr "Inserire un numero."
-#: newforms/fields.py:218
+#: forms/fields.py:222
#, 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:219
+#: forms/fields.py:223
#, 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:220
+#: forms/fields.py:224
#, 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:268 newforms/fields.py:779
+#: forms/fields.py:272 forms/fields.py:802
msgid "Enter a valid date."
msgstr "Inserire una data valida."
-#: newforms/fields.py:301 newforms/fields.py:780
+#: forms/fields.py:305 forms/fields.py:803
msgid "Enter a valid time."
msgstr "Inserire un ora valida."
-#: newforms/fields.py:340
+#: forms/fields.py:344
msgid "Enter a valid date/time."
msgstr "Inserire una coppia data/ora valida."
-#: newforms/fields.py:427
+#: forms/fields.py:431
msgid "No file was submitted."
msgstr "Nessun file è stato inviato."
-#: newforms/fields.py:428 oldforms/__init__.py:693
+#: forms/fields.py:432 oldforms/__init__.py:689
msgid "The submitted file is empty."
msgstr "Il file inviato è vuoto."
-#: newforms/fields.py:522
+#: forms/fields.py:531
msgid "Enter a valid URL."
msgstr "Inserire una URL valida."
-#: newforms/fields.py:523
+#: forms/fields.py:532
msgid "This URL appears to be a broken link."
msgstr "Questa URL non sembra funzionare."
-#: newforms/fields.py:588 newforms/models.py:306
-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:627
+#: forms/fields.py:600 forms/fields.py:651
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "Scegliere un'opzione valida. '%(value)s non compare tra quelle disponibili."
-#: newforms/fields.py:628 newforms/fields.py:690 newforms/models.py:373
+#: forms/fields.py:652 forms/fields.py:713 forms/models.py:589
msgid "Enter a list of values."
msgstr "Inserire una lista di valori."
-#: newforms/fields.py:808
+#: forms/fields.py:831
msgid "Enter a valid IPv4 address."
msgstr "Inserire un indirizzo IPv4 valido."
-#: newforms/models.py:374
+#: forms/models.py:522
+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."
+
+#: forms/models.py:590
#, 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."
-#: oldforms/__init__.py:409
+#: oldforms/__init__.py:405
#, 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:414
+#: oldforms/__init__.py:410
msgid "Line breaks are not allowed here."
msgstr "Non sono ammessi a capo manuali qui."
-#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
+#: oldforms/__init__.py:508 oldforms/__init__.py:582 oldforms/__init__.py:621
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Scegliere un'opzione valida; '%(data)s' non presente in %(choices)s."
-#: oldforms/__init__.py:754
+#: oldforms/__init__.py:750
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Inserire un numero intero compreso tra -32.768 e 32.767 ."
-#: oldforms/__init__.py:764
+#: oldforms/__init__.py:760
msgid "Enter a positive number."
msgstr "Inserire un numero positivo."
-#: oldforms/__init__.py:774
+#: oldforms/__init__.py:770
msgid "Enter a whole number between 0 and 32,767."
msgstr "Inserire un numero intero compreso tra 0 e 32.767 ."
@@ -4351,37 +4474,37 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:412
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "j F Y"
-#: utils/translation/trans_real.py:413
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "j F Y, H:i"
-#: utils/translation/trans_real.py:414
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "H:i"
-#: utils/translation/trans_real.py:430
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "Y F"
-#: utils/translation/trans_real.py:431
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "F j"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "%(verbose_name)s è stato creato correttamente."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "%(verbose_name)s è stato aggiornato correttamente."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s è stato cancellato."
diff --git a/django/conf/locale/ka/LC_MESSAGES/django.mo b/django/conf/locale/ka/LC_MESSAGES/django.mo
index 0b611080d0..91957f682b 100644
--- a/django/conf/locale/ka/LC_MESSAGES/django.mo
+++ b/django/conf/locale/ka/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/ka/LC_MESSAGES/django.po b/django/conf/locale/ka/LC_MESSAGES/django.po
index c189e67a81..0649b56458 100644
--- a/django/conf/locale/ka/LC_MESSAGES/django.po
+++ b/django/conf/locale/ka/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-02-22 21:55+0400\n"
+"POT-Creation-Date: 2008-07-15 21:17+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: David Avsajanishvili <avsd05@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -14,191 +14,199 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: conf/global_settings.py:39
+#: conf/global_settings.py:44
msgid "Arabic"
msgstr "áƒáƒ áƒáƒ‘ული"
-#: conf/global_settings.py:40
+#: conf/global_settings.py:45
msgid "Bengali"
msgstr "ბენგáƒáƒšáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:41
+#: conf/global_settings.py:46
msgid "Bulgarian"
msgstr "ბულგáƒáƒ áƒ£áƒšáƒ˜"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:47
msgid "Catalan"
msgstr "კáƒáƒ¢áƒáƒšáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:48
msgid "Czech"
msgstr "ჩეხური"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:49
msgid "Welsh"
msgstr "უელსური"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:50
msgid "Danish"
msgstr "დáƒáƒœáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:51
msgid "German"
msgstr "გერმáƒáƒœáƒ£áƒšáƒ˜"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:52
msgid "Greek"
msgstr "ბერძნული"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:53
msgid "English"
msgstr "ინგლისური"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:54
msgid "Spanish"
msgstr "ესპáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "ესტáƒáƒœáƒ£áƒ áƒ˜"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
msgstr "áƒáƒ áƒ’ენტინის ესპáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:57
msgid "Basque"
msgstr "ბáƒáƒ¡áƒ™áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:58
msgid "Persian"
msgstr "სპáƒáƒ áƒ¡áƒ£áƒšáƒ˜"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:59
msgid "Finnish"
msgstr "ფინური"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:60
msgid "French"
msgstr "ფრáƒáƒœáƒ’ული"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:61
msgid "Irish"
msgstr "ირლáƒáƒœáƒ“იური"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:62
msgid "Galician"
msgstr "გáƒáƒšáƒ˜áƒªáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:63
msgid "Hungarian"
msgstr "უნგრული"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:64
msgid "Hebrew"
msgstr "ებრáƒáƒ£áƒšáƒ˜"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:65
msgid "Croatian"
msgstr "ხáƒáƒ áƒ•áƒáƒ¢áƒ˜áƒ£áƒšáƒ˜"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:66
msgid "Icelandic"
msgstr "ისლáƒáƒœáƒ“იური"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:67
msgid "Italian"
msgstr "იტáƒáƒšáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:68
msgid "Japanese"
msgstr "იáƒáƒžáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:69
msgid "Georgian"
msgstr "ქáƒáƒ áƒ—ული"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:70
msgid "Korean"
msgstr "კáƒáƒ áƒ”ული"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:71
msgid "Khmer"
msgstr "ხმერული"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:72
msgid "Kannada"
msgstr "კáƒáƒœáƒœáƒáƒ“áƒ"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:73
msgid "Latvian"
msgstr "ლáƒáƒ¢áƒ•áƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "ლიტვური"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
msgstr "მáƒáƒ™áƒ”დáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:76
msgid "Dutch"
msgstr "ჰáƒáƒšáƒáƒœáƒ“იური"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:77
msgid "Norwegian"
msgstr "ნáƒáƒ áƒ•áƒ”გიული"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:78
msgid "Polish"
msgstr "პáƒáƒšáƒáƒœáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:79
msgid "Portugese"
msgstr "პáƒáƒ áƒ¢áƒ£áƒ’áƒáƒšáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:73
-msgid "Brazilian"
-msgstr "ბრáƒáƒ–ილიური"
+#: conf/global_settings.py:80
+msgid "Brazilian Portuguese"
+msgstr "ბრáƒáƒ–ილიური პáƒáƒ áƒ¢áƒ£áƒ’áƒáƒšáƒ˜áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:81
msgid "Romanian"
msgstr "რუმინული"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:82
msgid "Russian"
msgstr "რუსული"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:83
msgid "Slovak"
msgstr "სლáƒáƒ•áƒáƒ áƒ£áƒ áƒ˜"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:84
msgid "Slovenian"
msgstr "სლáƒáƒ•áƒ”ნიური"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:85
msgid "Serbian"
msgstr "სერბული"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:86
msgid "Swedish"
msgstr "შვედური"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:87
msgid "Tamil"
msgstr "თáƒáƒ›áƒ˜áƒšáƒ£áƒ áƒ˜"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:88
msgid "Telugu"
msgstr "ტელუგუ"
-#: conf/global_settings.py:82
+#: conf/global_settings.py:89
msgid "Turkish"
msgstr "თურქული"
-#: conf/global_settings.py:83
+#: conf/global_settings.py:90
msgid "Ukrainian"
msgstr "უკრáƒáƒ˜áƒœáƒ£áƒšáƒ˜"
-#: conf/global_settings.py:84
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
msgstr "გáƒáƒ›áƒáƒ áƒ¢áƒ˜áƒ•áƒ”ბული ჩინური"
-#: conf/global_settings.py:85
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
msgstr "ტრáƒáƒ“იციული ჩინური"
@@ -322,7 +330,7 @@ msgid ""
"There's been an error. It's been reported to the site administrators via e-"
"mail and should be fixed shortly. Thanks for your patience."
msgstr ""
-"áƒáƒ¥ იყრშეცდáƒáƒ›áƒ. იგი გáƒáƒ“áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜áƒ სáƒáƒ˜áƒ¢áƒ˜áƒ¡ áƒáƒ“მინისტრáƒáƒ¢áƒáƒ áƒ˜áƒ¡ ელექტრáƒáƒœáƒ£áƒš ფáƒáƒ¡áƒ¢áƒáƒ–ე "
+"სისტემáƒáƒ¨áƒ˜ მáƒáƒ®áƒ“რშეცდáƒáƒ›áƒ. იგი გáƒáƒ“áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜áƒ სáƒáƒ˜áƒ¢áƒ˜áƒ¡ áƒáƒ“მინისტრáƒáƒ¢áƒáƒ áƒ˜áƒ¡ ელექტრáƒáƒœáƒ£áƒš ფáƒáƒ¡áƒ¢áƒáƒ–ე "
"დრმáƒáƒšáƒ” გáƒáƒ›áƒáƒ¡áƒ¬áƒáƒ áƒ“ებáƒ. გმáƒáƒ“ლáƒáƒ‘თ მáƒáƒ—მინებისáƒáƒ—ვის."
#: contrib/admin/templates/admin/base.html:26
@@ -477,7 +485,7 @@ msgid "Password:"
msgstr "პáƒáƒ áƒáƒšáƒ˜:"
#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:25
+#: contrib/admin/views/decorators.py:31
msgid "Log in"
msgstr "შესვლáƒ"
@@ -799,7 +807,7 @@ msgstr "პáƒáƒ áƒáƒšáƒ˜ წáƒáƒ áƒ›áƒáƒ¢áƒ”ბით შეიცვáƒáƒšá
msgid "Change password: %s"
msgstr "შევცვáƒáƒšáƒáƒ— პáƒáƒ áƒáƒšáƒ˜: %s"
-#: contrib/admin/views/decorators.py:11 contrib/auth/forms.py:60
+#: contrib/admin/views/decorators.py:17 contrib/auth/forms.py:60
msgid ""
"Please enter a correct username and password. Note that both fields are case-"
"sensitive."
@@ -807,7 +815,7 @@ msgstr ""
"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜ მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სáƒáƒ®áƒ”ლი დრპáƒáƒ áƒáƒšáƒ˜. გáƒáƒ˜áƒ—ვáƒáƒšáƒ˜áƒ¡áƒ¬áƒ˜áƒœáƒ”თ, რáƒáƒ› "
"áƒáƒ áƒ˜áƒ•áƒ” ველი დáƒáƒ›áƒáƒ™áƒ˜áƒ“ებულირრეგისტრზე."
-#: contrib/admin/views/decorators.py:63
+#: contrib/admin/views/decorators.py:69
msgid ""
"Please log in again, because your session has expired. Don't worry: Your "
"submission has been saved."
@@ -815,7 +823,7 @@ msgstr ""
"გთხáƒáƒ•áƒ—, შეხვიდეთ კიდევ ერთხელ, რáƒáƒ“გáƒáƒœáƒáƒª თქვენი სესიის დრრáƒáƒ›áƒáƒ˜áƒ¬áƒ£áƒ áƒ. ნუ "
"ღელáƒáƒ•áƒ—: თქვენს მიერ შეტáƒáƒœáƒ˜áƒšáƒ˜ ცვლილებები შენáƒáƒ®áƒ£áƒšáƒ˜áƒ."
-#: contrib/admin/views/decorators.py:70
+#: contrib/admin/views/decorators.py:76
msgid ""
"Looks like your browser isn't configured to accept cookies. Please enable "
"cookies, reload this page, and try again."
@@ -823,17 +831,17 @@ msgstr ""
"რáƒáƒ’áƒáƒ áƒª ჩáƒáƒœáƒ¡, თქვენი ბრáƒáƒ£áƒ–ერი áƒáƒ  ღებულáƒáƒ‘ს cookie-ებს. გთხáƒáƒ•áƒ—, ჩáƒáƒ áƒ—áƒáƒ— cookie-"
"ების მიღების ფუნქციáƒ, გáƒáƒœáƒáƒáƒ®áƒšáƒ”თ ეს გვერდი დრსცáƒáƒ“ეთ კიდევ ერთხელ."
-#: contrib/admin/views/decorators.py:84
-msgid "Usernames cannot contain the '@' character."
-msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სáƒáƒ®áƒ”ლი áƒáƒ  უნდრშეიცáƒáƒ•áƒ“ეს სიმბáƒáƒšáƒáƒ¡ '@'."
-
-#: contrib/admin/views/decorators.py:86
+#: contrib/admin/views/decorators.py:89
#, python-format
msgid "Your e-mail address is not your username. Try '%s' instead."
msgstr ""
"ელ-ფáƒáƒ¡áƒ¢áƒ˜áƒ¡ მისáƒáƒ›áƒáƒ áƒ—ი áƒáƒ  áƒáƒ áƒ˜áƒ¡ თქვენი მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სáƒáƒ®áƒ”ლი. სცáƒáƒ“ეთ '%s' მის "
"ნáƒáƒªáƒ•áƒšáƒáƒ“."
+#: contrib/admin/views/decorators.py:93
+msgid "Usernames cannot contain the '@' character."
+msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სáƒáƒ®áƒ”ლი áƒáƒ  უნდრშეიცáƒáƒ•áƒ“ეს სიმბáƒáƒšáƒáƒ¡ '@'."
+
#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
#: contrib/admin/views/doc.py:52
msgid "tag:"
@@ -957,7 +965,7 @@ msgstr "ტექსტი"
msgid "Time"
msgstr "დრáƒ"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:7
+#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
msgid "URL"
msgstr ""
@@ -1065,7 +1073,7 @@ msgstr "áƒáƒ•áƒ˜áƒ áƒ©áƒ˜áƒáƒ— %s"
msgid "Select %s to change"
msgstr "áƒáƒ˜áƒ áƒ©áƒ˜áƒ”თ %s შესáƒáƒªáƒ•áƒšáƒ”ლáƒáƒ“"
-#: contrib/admin/views/main.py:784
+#: contrib/admin/views/main.py:765
msgid "Database error"
msgstr "მáƒáƒœáƒáƒªáƒ”მთრბáƒáƒ–ის შეცდáƒáƒ›áƒ"
@@ -1129,15 +1137,15 @@ msgstr "უფლებები"
msgid "group"
msgstr "ჯგუფი"
-#: contrib/auth/models.py:98 contrib/auth/models.py:141
+#: contrib/auth/models.py:98 contrib/auth/models.py:148
msgid "groups"
msgstr "ჯგუფები"
-#: contrib/auth/models.py:131
+#: contrib/auth/models.py:138
msgid "username"
msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სáƒáƒ®áƒ”ლი"
-#: contrib/auth/models.py:131
+#: contrib/auth/models.py:138
msgid ""
"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
"digits and underscores)."
@@ -1145,23 +1153,23 @@ msgstr ""
"áƒáƒ£áƒªáƒ˜áƒšáƒ”ბელიáƒ. 30 áƒáƒœ ნáƒáƒ™áƒšáƒ”ბი სიმბáƒáƒšáƒ. მხáƒáƒšáƒáƒ“ ლáƒáƒ—ინური áƒáƒ¡áƒáƒ”ბი, ციფრები დრ"
"ხáƒáƒ–გáƒáƒ¡áƒ›áƒ."
-#: contrib/auth/models.py:132
+#: contrib/auth/models.py:139
msgid "first name"
msgstr "სáƒáƒ®áƒ”ლი"
-#: contrib/auth/models.py:133
+#: contrib/auth/models.py:140
msgid "last name"
msgstr "გვáƒáƒ áƒ˜"
-#: contrib/auth/models.py:134
+#: contrib/auth/models.py:141
msgid "e-mail address"
msgstr "ელ. ფáƒáƒ¡áƒ¢áƒ"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:142
msgid "password"
msgstr "პáƒáƒ áƒáƒšáƒ˜"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:142
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -1169,46 +1177,46 @@ msgstr ""
"გáƒáƒ›áƒáƒ˜áƒ§áƒ”ნეთ '[algo]$[salt]$[hexdigest]' áƒáƒœ <a href=\"password/\">პáƒáƒ áƒáƒšáƒ˜áƒ¡ "
"შეცვლის ფáƒáƒ áƒ›áƒ</a>."
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:143
msgid "staff status"
msgstr "თáƒáƒœáƒáƒ›áƒ¨áƒ áƒáƒ›áƒšáƒáƒ‘ის სტáƒáƒ¢áƒ£áƒ¡áƒ˜"
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:143
msgid "Designates whether the user can log into this admin site."
msgstr ""
"გáƒáƒœáƒ¡áƒáƒ–ღვრáƒáƒ•áƒ¡, áƒáƒ¥áƒ•áƒ¡ თუ áƒáƒ áƒ მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელს áƒáƒ“მინისტრირების სáƒáƒ˜áƒ¢áƒ–ე შესვლის უფლებáƒ."
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:144
msgid "active"
msgstr "áƒáƒ¥áƒ¢áƒ˜áƒ£áƒ áƒ˜áƒ"
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:144
msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
+"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
-"გáƒáƒœáƒ¡áƒáƒ–ღვრáƒáƒ•áƒ¡, áƒáƒ¥áƒ•áƒ¡ თუ áƒáƒ áƒ მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელს Django-ს áƒáƒ“მინისტრირების სáƒáƒ˜áƒ¢áƒ–ე "
-"შესვლის შესáƒáƒ«áƒšáƒ”ბლáƒáƒ‘áƒ. გáƒáƒ“áƒáƒœáƒ˜áƒ¨áƒœáƒ”თ ეს დრáƒáƒ¨áƒ მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის წáƒáƒ¨áƒšáƒ˜áƒ¡ მáƒáƒ’ივრáƒáƒ“."
+"გáƒáƒœáƒ¡áƒáƒ–ღვრáƒáƒ•áƒ¡, რáƒáƒ› მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელი გáƒáƒáƒ¥áƒ¢áƒ˜áƒ£áƒ áƒ”ბულიáƒ. "
+"მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის წáƒáƒ¨áƒšáƒ˜áƒ¡ მáƒáƒ’ივრáƒáƒ“ გáƒáƒ“áƒáƒœáƒ˜áƒ¨áƒœáƒ”თ ეს დრáƒáƒ¨áƒ."
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:145
msgid "superuser status"
msgstr "სუპერმáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის სტáƒáƒ¢áƒ£áƒ¡áƒ˜"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:145
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
msgstr "გáƒáƒœáƒ¡áƒáƒ–ღვრáƒáƒ•áƒ¡, რáƒáƒ› áƒáƒ› მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელს áƒáƒ¥áƒ•áƒ¡ ყველრუფლებáƒ."
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:146
msgid "last login"
msgstr "ბáƒáƒšáƒ შესვლáƒ"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:147
msgid "date joined"
msgstr "გáƒáƒ¬áƒ”ვრიáƒáƒœáƒ”ბის თáƒáƒ áƒ˜áƒ¦áƒ˜"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:149
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -1216,39 +1224,39 @@ msgstr ""
"ინდივიდუáƒáƒšáƒ£áƒ áƒáƒ“ მითითებული უფლებების გáƒáƒ áƒ“áƒ, ეს მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელი მიიღებს áƒáƒ’რეთვე "
"ყველრიმ ჯგუფის უფლებáƒáƒ¡, რáƒáƒ›áƒ”ლშიც იგი გáƒáƒ¬áƒ”ვრიáƒáƒœáƒ”ბულიáƒ."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:150
msgid "user permissions"
msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლის უფლებები"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:154
msgid "user"
msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბელი"
-#: contrib/auth/models.py:148
+#: contrib/auth/models.py:155
msgid "users"
msgstr "მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლები"
-#: contrib/auth/models.py:154
+#: contrib/auth/models.py:160
msgid "Personal info"
msgstr "პირáƒáƒ“ი ინფáƒáƒ áƒ›áƒáƒªáƒ˜áƒ"
-#: contrib/auth/models.py:155
+#: contrib/auth/models.py:161
msgid "Permissions"
msgstr "უფლებები"
-#: contrib/auth/models.py:156
+#: contrib/auth/models.py:162
msgid "Important dates"
msgstr "მნიშვნელáƒáƒ•áƒáƒœáƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ”ბი"
-#: contrib/auth/models.py:157
+#: contrib/auth/models.py:163
msgid "Groups"
msgstr "ჯგუფები"
-#: contrib/auth/models.py:316
+#: contrib/auth/models.py:323
msgid "message"
msgstr "შეტყáƒáƒ‘ინებáƒ"
-#: contrib/auth/views.py:47
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "გáƒáƒ›áƒáƒ¡áƒ£áƒšáƒ˜ ხáƒáƒ áƒ—"
@@ -1546,42 +1554,42 @@ msgstr "კáƒáƒ›áƒ”ნტáƒáƒ áƒ˜áƒ¡ ID áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜áƒ"
msgid "No voting for yourself"
msgstr "სáƒáƒ™áƒ£áƒ—áƒáƒ áƒ˜ თáƒáƒ•áƒ˜áƒ¡áƒáƒ—ვის ხმის მიცემრáƒáƒ™áƒ áƒ«áƒáƒšáƒ£áƒšáƒ˜áƒ"
-#: contrib/contenttypes/models.py:37
+#: contrib/contenttypes/models.py:67
msgid "python model class name"
msgstr "python-ის მáƒáƒ“ელის კლáƒáƒ¡áƒ˜áƒ¡ სáƒáƒ®áƒ”ლი"
-#: contrib/contenttypes/models.py:40
+#: contrib/contenttypes/models.py:71
msgid "content type"
msgstr "კáƒáƒœáƒ¢áƒ”ნტის ტიპი"
-#: contrib/contenttypes/models.py:41
+#: contrib/contenttypes/models.py:72
msgid "content types"
msgstr "კáƒáƒœáƒ¢áƒ”ნტის ტიპები"
-#: contrib/flatpages/models.py:8
+#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
"მáƒáƒ’áƒáƒšáƒ˜áƒ—ი: '/about/contact/'. ყურáƒáƒ“ღებრმიáƒáƒ¥áƒªáƒ˜áƒ”თ დáƒáƒ®áƒ áƒ˜áƒš ხáƒáƒ–ებს თáƒáƒ•áƒ¨áƒ˜ დრ"
"ბáƒáƒšáƒáƒ¨áƒ˜."
-#: contrib/flatpages/models.py:9
+#: contrib/flatpages/models.py:10
msgid "title"
msgstr "სáƒáƒ—áƒáƒ£áƒ áƒ˜"
-#: contrib/flatpages/models.py:10
+#: contrib/flatpages/models.py:11
msgid "content"
msgstr "კáƒáƒœáƒ¢áƒ”ნტი"
-#: contrib/flatpages/models.py:11
+#: contrib/flatpages/models.py:12
msgid "enable comments"
msgstr "ჩáƒáƒ•áƒ áƒ—áƒáƒ— კáƒáƒ›áƒ”ნტáƒáƒ áƒ”ბი"
-#: contrib/flatpages/models.py:12
+#: contrib/flatpages/models.py:13
msgid "template name"
msgstr "შáƒáƒ‘ლáƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლი"
-#: contrib/flatpages/models.py:13
+#: contrib/flatpages/models.py:14
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
@@ -1589,24 +1597,28 @@ msgstr ""
"მáƒáƒ’áƒáƒšáƒ˜áƒ—ი: 'flatpages/contact_page.html'. თუ იგი მითითებული áƒáƒ  áƒáƒ áƒ˜áƒ¡, "
"გáƒáƒ›áƒáƒ§áƒ”ნებული იქნებრ'flatpages/default.html'."
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "registration required"
msgstr "რეგისტრáƒáƒªáƒ˜áƒ áƒáƒ£áƒªáƒ˜áƒšáƒ”ბელიáƒ"
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "If this is checked, only logged-in users will be able to view the page."
msgstr ""
"თუ ეს დრáƒáƒ¨áƒ ჩáƒáƒ áƒ—ულიáƒ, მხáƒáƒšáƒ შემáƒáƒ¡áƒ£áƒš მáƒáƒ›áƒ®áƒ›áƒáƒ áƒ”ბლებს ექნებáƒáƒ— გვერდის "
"დáƒáƒ—ვáƒáƒšáƒ˜áƒ”რების სáƒáƒ¨áƒ£áƒáƒšáƒ”ბáƒ."
-#: contrib/flatpages/models.py:18
+#: contrib/flatpages/models.py:20
msgid "flat page"
msgstr "უბრáƒáƒšáƒ გვერდი"
-#: contrib/flatpages/models.py:19
+#: contrib/flatpages/models.py:21
msgid "flat pages"
msgstr "უბრáƒáƒšáƒ გვერდები"
+#: contrib/flatpages/models.py:27
+msgid "Advanced options"
+msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბითი პáƒáƒ áƒáƒ›áƒ”ტრები"
+
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr ""
@@ -3632,23 +3644,23 @@ msgstr "გáƒáƒ“áƒáƒ›áƒ˜áƒ¡áƒáƒ›áƒáƒ áƒ—ებáƒ"
msgid "redirects"
msgstr "გáƒáƒ“áƒáƒ›áƒ˜áƒ¡áƒáƒ›áƒáƒ áƒ—ებები"
-#: contrib/sessions/models.py:41
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "სესიის გáƒáƒ¡áƒáƒ¦áƒ”ბი"
-#: contrib/sessions/models.py:42
+#: contrib/sessions/models.py:47
msgid "session data"
msgstr "სესიის მáƒáƒœáƒáƒªáƒ”მები"
-#: contrib/sessions/models.py:43
+#: contrib/sessions/models.py:48
msgid "expire date"
msgstr "áƒáƒ›áƒáƒ¬áƒ£áƒ áƒ•áƒ˜áƒ¡ თáƒáƒ áƒ˜áƒ¦áƒ˜"
-#: contrib/sessions/models.py:48
+#: contrib/sessions/models.py:53
msgid "session"
msgstr "სესიáƒ"
-#: contrib/sessions/models.py:49
+#: contrib/sessions/models.py:54
msgid "sessions"
msgstr "სესიები"
@@ -3720,7 +3732,7 @@ msgstr "áƒáƒ áƒáƒªáƒ˜áƒ¤áƒ áƒ£áƒšáƒ˜ სიმბáƒáƒšáƒáƒ”ბი áƒáƒ¥ დ
msgid "This value can't be comprised solely of digits."
msgstr "ეს მნიშვნელáƒáƒ‘რáƒáƒ  უნდრშედგებáƒáƒ“ეს მხáƒáƒšáƒáƒ“ ციფრებისáƒáƒ’áƒáƒœ."
-#: core/validators.py:128 newforms/fields.py:151
+#: core/validators.py:128 newforms/fields.py:157
msgid "Enter a whole number."
msgstr "შეიყვáƒáƒœáƒ”თ მთელი რიცხვი"
@@ -3737,7 +3749,7 @@ msgstr "წელი უნდრიყáƒáƒ¡ 1900 áƒáƒœ მეტი."
msgid "Invalid date: %s"
msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:518
+#: core/validators.py:156 db/models/fields/__init__.py:565
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜ YYYY-MM-DD ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜."
@@ -3745,21 +3757,20 @@ msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜ YYYY-MM-D
msgid "Enter a valid time in HH:MM format."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ დრრHH:MM ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜."
-#: core/validators.py:165 db/models/fields/__init__.py:595
+#: core/validators.py:165 db/models/fields/__init__.py:642
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜ დრდრრYYYY-MM-DD HH:MM ფáƒáƒ áƒ›áƒáƒ¢áƒ¨áƒ˜."
-#: core/validators.py:170 newforms/fields.py:402
+#: core/validators.py:170 newforms/fields.py:408
msgid "Enter a valid e-mail address."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ ელ. ფáƒáƒ¡áƒ¢áƒ˜áƒ¡ მისáƒáƒ›áƒáƒ áƒ—ი."
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:432
-#: oldforms/__init__.py:687
+#: core/validators.py:182 core/validators.py:474 newforms/fields.py:426
msgid "No file was submitted. Check the encoding type on the form."
msgstr ""
"ფáƒáƒ˜áƒšáƒ˜ áƒáƒ  იყრგáƒáƒ›áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜. შეáƒáƒ›áƒáƒ¬áƒ›áƒ”თ კáƒáƒ“ირების ტიპი მáƒáƒªáƒ”მული ფáƒáƒ áƒ›áƒ˜áƒ¡áƒáƒ—ვის."
-#: core/validators.py:193 newforms/fields.py:458
+#: core/validators.py:193 newforms/fields.py:468
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
@@ -3878,9 +3889,9 @@ msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
"Please enter a valid decimal number with at most %s total digits."
msgstr[0] ""
-"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜, áƒáƒ áƒáƒ£áƒ›áƒ”ტეს %s თáƒáƒœáƒ áƒ˜áƒ’ისáƒáƒ’áƒáƒœ შემდგáƒáƒ áƒ˜ áƒáƒ—áƒáƒ‘ითი რიცხვი"
+"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜, áƒáƒ áƒáƒ£áƒ›áƒ”ტეს %s თáƒáƒœáƒ áƒ˜áƒ’ისáƒáƒ’áƒáƒœ შემდგáƒáƒ áƒ˜ áƒáƒ—áƒáƒ‘ითი რიცხვი."
msgstr[1] ""
-"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜, áƒáƒ áƒáƒ£áƒ›áƒ”ტეს %s თáƒáƒœáƒ áƒ˜áƒ’ისáƒáƒ’áƒáƒœ შემდგáƒáƒ áƒ˜ áƒáƒ—áƒáƒ‘ითი რიცხვი"
+"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜, áƒáƒ áƒáƒ£áƒ›áƒ”ტეს %s თáƒáƒœáƒ áƒ˜áƒ’ისáƒáƒ’áƒáƒœ შემდგáƒáƒ áƒ˜ áƒáƒ—áƒáƒ‘ითი რიცხვი."
#: core/validators.py:447
#, python-format
@@ -4009,53 +4020,53 @@ msgstr "%(object)s მáƒáƒªáƒ”მული %(type)s-ით უკვე áƒáƒ á
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "%(optname)s მáƒáƒªáƒ”მული %(fieldname)s-ით უკვე áƒáƒ áƒ¡áƒ”ბáƒáƒ‘ს."
-#: db/models/fields/__init__.py:161 db/models/fields/__init__.py:318
-#: db/models/fields/__init__.py:750 db/models/fields/__init__.py:761
-#: newforms/fields.py:45 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:184 db/models/fields/__init__.py:356
+#: db/models/fields/__init__.py:799 db/models/fields/__init__.py:810
+#: newforms/fields.py:51 oldforms/__init__.py:374
msgid "This field is required."
msgstr "ეს ველი áƒáƒ£áƒªáƒ˜áƒšáƒ”ბელიáƒ."
-#: db/models/fields/__init__.py:418
+#: db/models/fields/__init__.py:465
msgid "This value must be an integer."
msgstr "ეს მნიშვნელáƒáƒ‘რუნდრიყáƒáƒ¡ მთელი."
-#: db/models/fields/__init__.py:457
+#: db/models/fields/__init__.py:504
msgid "This value must be either True or False."
msgstr "ეს მნიშვნელáƒáƒ‘რუნდრიყáƒáƒ¡ True áƒáƒœ False."
-#: db/models/fields/__init__.py:481
+#: db/models/fields/__init__.py:528
msgid "This field cannot be null."
msgstr "ეს მნიშვნელáƒáƒ‘რáƒáƒ  შეიძლებრიყáƒáƒ¡ null."
-#: db/models/fields/__init__.py:659
+#: db/models/fields/__init__.py:706
msgid "This value must be a decimal number."
msgstr "ეს მნიშვნელáƒáƒ‘რუნდრიყáƒáƒ¡ áƒáƒ—áƒáƒ‘ითი რიცხვი."
-#: db/models/fields/__init__.py:770
+#: db/models/fields/__init__.py:819
msgid "Enter a valid filename."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ ფáƒáƒ˜áƒšáƒ˜áƒ¡ სáƒáƒ®áƒ”ლი."
-#: db/models/fields/__init__.py:941
+#: db/models/fields/__init__.py:1013
msgid "This value must be either None, True or False."
msgstr "ეს მნიშვნელáƒáƒ‘რუნდრიყáƒáƒ¡ None, True áƒáƒœ False."
-#: db/models/fields/related.py:55
+#: db/models/fields/related.py:94
#, python-format
msgid "Please enter a valid %s."
msgstr "გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜ %s."
-#: db/models/fields/related.py:658
+#: db/models/fields/related.py:756
msgid "Separate multiple IDs with commas."
msgstr "გáƒáƒ›áƒáƒ§áƒáƒ•áƒ˜áƒ— ID-ები მძიმეებით."
-#: db/models/fields/related.py:660
+#: db/models/fields/related.py:758
msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr ""
"დáƒáƒáƒ­áƒ˜áƒ áƒ”თ \"Control\", áƒáƒœ \"Command\" Mac-ზე, ერთზე მეტი მნიშვნელáƒáƒ‘ის "
"áƒáƒ¡áƒáƒ áƒ©áƒ”ვáƒáƒ“."
-#: db/models/fields/related.py:707
+#: db/models/fields/related.py:805
#, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural ""
@@ -4065,99 +4076,99 @@ msgstr[0] ""
msgstr[1] ""
"გთხáƒáƒ•áƒ—, შეიყვáƒáƒœáƒáƒ— სწáƒáƒ áƒ˜ %(self)s ID-ები. მნიშვნელáƒáƒ‘ები %(value)r áƒáƒ áƒáƒ¡áƒ¬áƒáƒ áƒ˜áƒ."
-#: newforms/fields.py:46
+#: newforms/fields.py:52
msgid "Enter a valid value."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ მნიშვნელáƒáƒ‘áƒ."
-#: newforms/fields.py:123
+#: newforms/fields.py:129
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr ""
"დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მნიშვნელáƒáƒ‘რშედგებრáƒáƒ áƒáƒ£áƒ›áƒ”ტეს %(max)d სიმბáƒáƒšáƒáƒ¡áƒáƒ’áƒáƒœ (áƒáƒ®áƒšáƒ "
"მისი სიგრძერ%(length)d)."
-#: newforms/fields.py:124
+#: newforms/fields.py:130
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr ""
"დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მნიშვნელáƒáƒ‘რშედგებრáƒáƒ áƒáƒœáƒáƒ™áƒšáƒ”ბ %(min)d სიმბáƒáƒšáƒáƒ¡áƒáƒ’áƒáƒœ (áƒáƒ®áƒšáƒ "
"მისი სიგრძერ%(length)d)."
-#: newforms/fields.py:152 newforms/fields.py:181 newforms/fields.py:210
+#: newforms/fields.py:158 newforms/fields.py:187 newforms/fields.py:216
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მნიშვნელáƒáƒ‘რნáƒáƒ™áƒšáƒ”ბირáƒáƒœ ტáƒáƒšáƒ˜áƒ %s-ზე."
-#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
+#: newforms/fields.py:159 newforms/fields.py:188 newforms/fields.py:217
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მნიშვნელáƒáƒ‘რმეტირáƒáƒœ ტáƒáƒšáƒ˜áƒ %s-ზე."
-#: newforms/fields.py:180 newforms/fields.py:209
+#: newforms/fields.py:186 newforms/fields.py:215
msgid "Enter a number."
msgstr "შეიყვáƒáƒœáƒ”თ რიცხვი."
-#: newforms/fields.py:212
+#: newforms/fields.py:218
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მნიშვნელáƒáƒ‘რ%s თáƒáƒœáƒ áƒ˜áƒ’ს áƒáƒ  áƒáƒ¦áƒ”მáƒáƒ¢áƒ”ბáƒ."
-#: newforms/fields.py:213
+#: newforms/fields.py:219
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› წილáƒáƒ“ი ნáƒáƒ¬áƒ˜áƒšáƒ˜ %s თáƒáƒœáƒ áƒ˜áƒ’ს áƒáƒ  áƒáƒ¦áƒ”მáƒáƒ¢áƒ”ბáƒ."
-#: newforms/fields.py:214
+#: newforms/fields.py:220
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "დáƒáƒ áƒ¬áƒ›áƒ£áƒœáƒ“ით, რáƒáƒ› მთელი ნáƒáƒ¬áƒ˜áƒšáƒ˜ %s თáƒáƒœáƒ áƒ˜áƒ’ს áƒáƒ  áƒáƒ¦áƒ”მáƒáƒ¢áƒ”ბáƒ."
-#: newforms/fields.py:262 newforms/fields.py:723
+#: newforms/fields.py:268 newforms/fields.py:781
msgid "Enter a valid date."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜."
-#: newforms/fields.py:295 newforms/fields.py:724
+#: newforms/fields.py:301 newforms/fields.py:782
msgid "Enter a valid time."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ დრáƒ."
-#: newforms/fields.py:334
+#: newforms/fields.py:340
msgid "Enter a valid date/time."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ თáƒáƒ áƒ˜áƒ¦áƒ˜ დრდრáƒ."
-#: newforms/fields.py:433
+#: newforms/fields.py:427
msgid "No file was submitted."
msgstr "ფáƒáƒ˜áƒšáƒ˜ áƒáƒ  იყრგáƒáƒ›áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜."
-#: newforms/fields.py:434 oldforms/__init__.py:689
+#: newforms/fields.py:428 oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "გáƒáƒ›áƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ˜ ცáƒáƒ áƒ˜áƒ”ლიáƒ."
-#: newforms/fields.py:496
+#: newforms/fields.py:524
msgid "Enter a valid URL."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ URL."
-#: newforms/fields.py:497
+#: newforms/fields.py:525
msgid "This URL appears to be a broken link."
msgstr "რáƒáƒ’áƒáƒ áƒª ჩáƒáƒœáƒ¡, URL áƒáƒ áƒ˜áƒ¡ გáƒáƒ¬áƒ§áƒ•áƒ”ტილი ბმული."
-#: newforms/fields.py:559 newforms/models.py:300
+#: newforms/fields.py:590 newforms/models.py:306
msgid "Select a valid choice. That choice is not one of the available choices."
msgstr "áƒáƒ˜áƒ áƒ©áƒ˜áƒ”თ დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი მნიშვნელáƒáƒ‘áƒ. ეს áƒáƒ áƒ©áƒ”ვáƒáƒœáƒ˜ დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი áƒáƒ  áƒáƒ áƒ˜áƒ¡."
-#: newforms/fields.py:598
+#: newforms/fields.py:629
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "áƒáƒ˜áƒ áƒ©áƒ˜áƒ”თ დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი მნიშვნელáƒáƒ‘áƒ. %(value)s დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი áƒáƒ  áƒáƒ áƒ˜áƒ¡."
-#: newforms/fields.py:599 newforms/fields.py:661 newforms/models.py:360
+#: newforms/fields.py:630 newforms/fields.py:692 newforms/models.py:373
msgid "Enter a list of values."
msgstr "შეიყვáƒáƒœáƒ”თ მნიშვნელáƒáƒ‘ების სიáƒ."
-#: newforms/fields.py:752
+#: newforms/fields.py:810
msgid "Enter a valid IPv4 address."
msgstr "შეიყვáƒáƒœáƒ”თ სწáƒáƒ áƒ˜ IPv4 მისáƒáƒ›áƒáƒ áƒ—ი."
-#: newforms/models.py:361
+#: newforms/models.py:374
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr "áƒáƒ˜áƒ áƒ©áƒ˜áƒ”თ დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი მნიშვნელáƒáƒ‘áƒ. %s დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი áƒáƒ  áƒáƒ áƒ˜áƒ¡."
@@ -4180,40 +4191,40 @@ msgstr ""
"áƒáƒ˜áƒ áƒ©áƒ˜áƒ”თ დáƒáƒ¡áƒáƒ¨áƒ•áƒ”ბი მნიშვნელáƒáƒ‘áƒ; '%(data)s' áƒáƒ  áƒáƒ áƒ˜áƒ¡ %(choices)s მნიშვნელáƒáƒ‘ების "
"სიáƒáƒ¨áƒ˜."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "შეიყვáƒáƒœáƒ”თ მთელი რიცხვი -32,768-დáƒáƒœ 32,767-მდე."
-#: oldforms/__init__.py:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "შეიყვáƒáƒœáƒ”თ დáƒáƒ“ებითი რიცხვი."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "შეიყვáƒáƒœáƒ”თ მთელი რიცხვი 0-დáƒáƒœ 32,767-მდე."
-#: template/defaultfilters.py:691
+#: template/defaultfilters.py:698
msgid "yes,no,maybe"
msgstr "კი,áƒáƒ áƒ,შესáƒáƒ«áƒšáƒáƒ"
-#: template/defaultfilters.py:722
+#: template/defaultfilters.py:729
#, python-format
msgid "%(size)d byte"
msgid_plural "%(size)d bytes"
msgstr[0] "%(size)d ბáƒáƒ˜áƒ¢áƒ˜"
msgstr[1] "%(size)d ბáƒáƒ˜áƒ¢áƒ˜"
-#: template/defaultfilters.py:724
+#: template/defaultfilters.py:731
#, python-format
msgid "%.1f KB"
msgstr "%.1f კბáƒáƒ˜áƒ¢áƒ˜"
-#: template/defaultfilters.py:726
+#: template/defaultfilters.py:733
#, python-format
msgid "%.1f MB"
msgstr "%.1f მბáƒáƒ˜áƒ¢áƒ˜"
-#: template/defaultfilters.py:727
+#: template/defaultfilters.py:734
#, python-format
msgid "%.1f GB"
msgstr "%.1f გბáƒáƒ˜áƒ¢áƒ˜"
@@ -4422,7 +4433,7 @@ msgstr "ნáƒáƒ”მ."
msgid "Dec."
msgstr "დეკ."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "áƒáƒœ"
@@ -4476,23 +4487,23 @@ msgstr ""
msgid ", %(number)d %(type)s"
msgstr ""
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:412
msgid "DATE_FORMAT"
msgstr "d.m.Y"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:413
msgid "DATETIME_FORMAT"
msgstr "d.m.Y H:i"
-#: utils/translation/trans_real.py:406
+#: utils/translation/trans_real.py:414
msgid "TIME_FORMAT"
msgstr "H:i"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:430
msgid "YEAR_MONTH_FORMAT"
msgstr "d.m.Y"
-#: utils/translation/trans_real.py:423
+#: utils/translation/trans_real.py:431
msgid "MONTH_DAY_FORMAT"
msgstr "d.m.Y"
@@ -4510,3 +4521,6 @@ msgstr "%(verbose_name)s წáƒáƒ áƒ›áƒáƒ¢áƒ”ბით შეიცვáƒáƒšáƒ
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s წáƒáƒ˜áƒ¨áƒáƒšáƒ."
+
+#~ msgid "Brazilian"
+#~ msgstr "ბრáƒáƒ–ილიური"
diff --git a/django/conf/locale/nl/LC_MESSAGES/django.mo b/django/conf/locale/nl/LC_MESSAGES/django.mo
index 3797766bc9..fe68cd416f 100644
--- a/django/conf/locale/nl/LC_MESSAGES/django.mo
+++ b/django/conf/locale/nl/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/nl/LC_MESSAGES/django.po b/django/conf/locale/nl/LC_MESSAGES/django.po
index 13143c5b8b..7aa8d3fe83 100644
--- a/django/conf/locale/nl/LC_MESSAGES/django.po
+++ b/django/conf/locale/nl/LC_MESSAGES/django.po
@@ -1,201 +1,213 @@
+# Dutch translation for Django.
+# Copyright (C) 2008, Django Software Foundation
+# This file is distributed under the same license as the Django package.
+#
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-02-27 08:53+0100\n"
-"PO-Revision-Date: 2008-02-27 11:22+0100\n"
-"Last-Translator: jdetaeye <jdetaeye@frepple.com>\n"
+"POT-Creation-Date: 2008-07-30 02:28+0200\n"
+"PO-Revision-Date: 2008-07-31 23:08+0200\n"
+"Last-Translator: Rudolph Froger <rudolphfroger@estrate.nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: conf/global_settings.py:39
+#: conf/global_settings.py:44
msgid "Arabic"
msgstr "Arabisch"
-#: conf/global_settings.py:40
+#: conf/global_settings.py:45
msgid "Bengali"
msgstr "Bengaals"
-#: conf/global_settings.py:41
+#: conf/global_settings.py:46
msgid "Bulgarian"
msgstr "Bulgaars"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:47
msgid "Catalan"
msgstr "Catalaans"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:48
msgid "Czech"
msgstr "Tjechisch"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:49
msgid "Welsh"
msgstr "Wels"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:50
msgid "Danish"
msgstr "Deens"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:51
msgid "German"
msgstr "Duits"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:52
msgid "Greek"
msgstr "Grieks"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:53
msgid "English"
msgstr "Engels"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:54
msgid "Spanish"
msgstr "Spaans"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "Ests"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
msgstr "Argentijns Spaans"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:57
msgid "Basque"
msgstr "Baskisch"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:58
msgid "Persian"
msgstr "Perzisch"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:59
msgid "Finnish"
msgstr "Fins"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:60
msgid "French"
msgstr "Frans"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:61
msgid "Irish"
msgstr "Iers"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:62
msgid "Galician"
msgstr "Galicisch"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:63
msgid "Hungarian"
msgstr "Hongaars"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:64
msgid "Hebrew"
msgstr "Hebreews"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:65
msgid "Croatian"
msgstr "Kroatisch"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:66
msgid "Icelandic"
msgstr "IJslands"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:67
msgid "Italian"
msgstr "Italiaans"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:68
msgid "Japanese"
msgstr "Japans"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:69
msgid "Georgian"
msgstr "Georgisch"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:70
msgid "Korean"
msgstr "Koreaans"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:71
msgid "Khmer"
msgstr "Khmer"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:72
msgid "Kannada"
msgstr "Kannada"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:73
msgid "Latvian"
msgstr "Lets"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "Litouws"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
msgstr "Macedonisch"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:76
msgid "Dutch"
msgstr "Nederlands"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:77
msgid "Norwegian"
msgstr "Noors"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:78
msgid "Polish"
msgstr "Pools"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:79
msgid "Portugese"
msgstr "Portugees"
-#: conf/global_settings.py:73
-msgid "Brazilian"
-msgstr "Braziliaans"
+#: conf/global_settings.py:80
+msgid "Brazilian Portuguese"
+msgstr "Braziliaans Portugees"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:81
msgid "Romanian"
msgstr "Roemeens"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:82
msgid "Russian"
msgstr "Russisch"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:83
msgid "Slovak"
msgstr "Slovaaks"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:84
msgid "Slovenian"
msgstr "Sloveens"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:85
msgid "Serbian"
msgstr "Servisch"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:86
msgid "Swedish"
msgstr "Zweeds"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:87
msgid "Tamil"
msgstr "Tamil"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:88
msgid "Telugu"
msgstr "Telegu"
-#: conf/global_settings.py:82
+#: conf/global_settings.py:89
msgid "Turkish"
msgstr "Turks"
-#: conf/global_settings.py:83
+#: conf/global_settings.py:90
msgid "Ukrainian"
msgstr "Oekraïens"
-#: conf/global_settings.py:84
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
msgstr "Vereenvoudigd Chinees"
-#: conf/global_settings.py:85
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
msgstr "Traditioneel Chinees"
@@ -208,10 +220,8 @@ msgstr ""
"<h3>Door %s:</h3>\n"
"<ul>\n"
-#: contrib/admin/filterspecs.py:74
-#: contrib/admin/filterspecs.py:92
-#: contrib/admin/filterspecs.py:147
-#: contrib/admin/filterspecs.py:173
+#: contrib/admin/filterspecs.py:74 contrib/admin/filterspecs.py:92
+#: contrib/admin/filterspecs.py:147 contrib/admin/filterspecs.py:173
msgid "All"
msgstr "Alle"
@@ -235,51 +245,205 @@ msgstr "Deze maand"
msgid "This year"
msgstr "Dit jaar"
-#: contrib/admin/filterspecs.py:147
-#: newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Ja"
-#: contrib/admin/filterspecs.py:147
-#: newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "Nee"
-#: contrib/admin/filterspecs.py:154
-#: newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:154 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Onbekend"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
-msgstr "actie tijd"
+msgstr "actietijd"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
-msgstr "object id"
+msgstr "object-id"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
-msgstr "object repr"
+msgstr "object-repr"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
-msgstr "actie vlag"
+msgstr "actievlag"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "wijzig bericht"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
-msgstr "log ingave"
+msgstr "logingave"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
-msgstr "log ingaves"
+msgstr "logingaves"
+
+#: contrib/admin/options.py:161 contrib/admin/options.py:180
+msgid "None"
+msgstr "Geen"
+
+#: contrib/admin/options.py:347 contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "De %(name)s \"%(obj)s\" is toegevoegd."
+
+#: contrib/admin/options.py:351 contrib/admin/options.py:419
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "U kunt dit hieronder weer bewerken."
+
+#: contrib/admin/options.py:361 contrib/admin/options.py:428
+#, python-format
+msgid "You may add another %s below."
+msgstr "U kunt hieronder de volgende %s toevoegen."
+
+#: contrib/admin/options.py:395
+#, python-format
+msgid "Changed %s."
+msgstr "%s gewijzigd."
+
+#: contrib/admin/options.py:395 contrib/admin/options.py:405
+#: core/validators.py:279 db/models/manipulators.py:305
+msgid "and"
+msgstr "en"
+
+#: contrib/admin/options.py:400
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "%(name)s \"%(object)s\" toegevoegd."
+
+#: contrib/admin/options.py:404
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "%(list)s aangepast voor %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:409
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "%(name)s \"%(object)s\" verwijderd."
+
+#: contrib/admin/options.py:414
+msgid "No fields changed."
+msgstr "Geen velden gewijzigd."
+
+#: contrib/admin/options.py:417
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "Het wijzigen van %(name)s \"%(obj)s\" is geslaagd."
+
+#: contrib/admin/options.py:425
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr "De %(name)s \"%(obj)s\" was toegevoegd. U kunt het hieronder wijzigen."
+
+#: contrib/admin/options.py:506
+#, python-format
+msgid "Add %s"
+msgstr "Toevoegen %s"
+
+#: contrib/admin/options.py:568
+#, python-format
+msgid "Change %s"
+msgstr "Wijzig %s"
+
+#: contrib/admin/options.py:598
+msgid "Database error"
+msgstr "Databasefout"
+
+#: contrib/admin/options.py:647
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "De verwijdering van %(name)s \"%(obj)s\" is geslaagd."
+
+#: contrib/admin/options.py:653
+msgid "Are you sure?"
+msgstr "Weet u het zeker?"
+
+#: contrib/admin/options.py:680
+#, python-format
+msgid "Change history: %s"
+msgstr "Wijzigingsgeschiedenis: %s"
+
+#: contrib/admin/sites.py:18 contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:70 contrib/comments/views/comments.py:56
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Voer een correcte gebruikersnaam en wachtwoord in. Let op, de velden zijn "
+"hoofdletter-gevoelig."
+
+#: contrib/admin/sites.py:233 contrib/admin/views/decorators.py:68
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Uw sessie is verlopen, meld u opnieuw aan. Maakt u zich geen zorgen: Uw "
+"bijdrage is opgeslagen."
+
+#: contrib/admin/sites.py:240 contrib/admin/views/decorators.py:75
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Het lijkt erop dat uw browser geen cookies accepteert. Zet het gebruik van "
+"cookies aan in uw browser, laad deze pagina nogmaals en probeer het opnieuw."
+
+#: contrib/admin/sites.py:254 contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Gebruikersnamen mogen geen '@' bevatten."
+
+#: contrib/admin/sites.py:257 contrib/admin/views/decorators.py:88
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "Uw e-mailadres is niet uw gebruikersnaam. Probeer '%s' eens."
+
+#: contrib/admin/sites.py:325
+msgid "Site administration"
+msgstr "Sitebeheer"
+
+#: contrib/admin/sites.py:347 contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Inloggen"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Een of meer %(fieldname)s in %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Een of meer %(fieldname)s in %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Datum:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Tijd:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Huidige:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Wijziging:"
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
@@ -291,17 +455,17 @@ msgid "We're sorry, but the requested page could not be found."
msgstr "Onze excuses, maar de gevraagde pagina bestaat niet."
#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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: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"
@@ -309,98 +473,115 @@ msgstr "Voorpagina"
#: contrib/admin/templates/admin/500.html:4
msgid "Server error"
-msgstr "Server fout"
+msgstr "Serverfout"
#: contrib/admin/templates/admin/500.html:6
msgid "Server error (500)"
-msgstr "Server fout (500)"
+msgstr "Serverfout (500)"
#: contrib/admin/templates/admin/500.html:9
msgid "Server Error <em>(500)</em>"
-msgstr "Server Fout <em>(500)</em>"
+msgstr "Serverfout <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 "Er is een fout opgetreden. Dit is inmiddels doorgegeven aan de sitebeheerder via e-mail en zal spoedig worden gerepareerd. Bedankt voor uw geduld."
+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 ""
+"Er is een fout opgetreden. Dit is inmiddels doorgegeven aan de sitebeheerder "
+"via e-mail en zal spoedig worden gerepareerd. Bedankt voor uw geduld."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Welkom,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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 "Documentatie"
-#: contrib/admin/templates/admin/base.html:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Wachtwoord wijzigen"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Afmelden"
#: contrib/admin/templates/admin/base_site.html:4
msgid "Django site admin"
-msgstr "Django site beheer"
+msgstr "Django sitebeheer"
#: contrib/admin/templates/admin/base_site.html:7
msgid "Django administration"
-msgstr "Django beheer"
+msgstr "Djangobeheer"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Toevoegen"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Geschiedenis"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Toon op site"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
msgid "Please correct the error below."
msgid_plural "Please correct the errors below."
msgstr[0] "Herstel de fout hieronder."
msgstr[1] "Herstel de fouten hieronder."
-#: contrib/admin/templates/admin/change_form.html:49
-msgid "Ordering"
-msgstr "Sortering"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Sortering:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "%(name)s toevoegen"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filter"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Verwijderen"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, 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 "Het verwijderen van %(object_name)s '%(escaped_object)s' zal ook gerelateerde objecten verwijderen. Echter u heeft geen rechten om de volgende typen objecten te verwijderen:"
+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 ""
+"Het verwijderen van %(object_name)s '%(escaped_object)s' zal ook "
+"gerelateerde objecten verwijderen. Echter u heeft geen rechten om de "
+"volgende typen objecten te verwijderen:"
-#: contrib/admin/templates/admin/delete_confirmation.html:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, 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 "Weet u zeker dat u %(object_name)s \"%(escaped_object)s\" wilt verwijderen? Alle volgende objecten worden verwijderd:"
+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 ""
+"Weet u zeker dat u %(object_name)s \"%(escaped_object)s\" wilt verwijderen? "
+"Alle volgende objecten worden verwijderd:"
-#: contrib/admin/templates/admin/delete_confirmation.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Ja, ik weet het zeker"
@@ -409,79 +590,79 @@ msgstr "Ja, ik weet het zeker"
msgid " By %(filter_title)s "
msgstr " Op %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filter"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "Models available in the %(name)s application."
msgstr "Beschikbare modellen in de %(name)s toepassing."
-#: contrib/admin/templates/admin/index.html:18
+#: contrib/admin/templates/admin/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Wijzigen"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "U heeft geen rechten om iets te wijzigen."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Recente acties"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Mijn acties"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Geen beschikbaar"
-#: 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 "Er is iets mis met de database. Verzeker u ervan dat de benodigde tabellen zijn aangemaakt en dat de database toegankelijk is voor de juiste gebruiker."
+#: contrib/admin/templates/admin/invalid_setup.html:7
+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 ""
+"Er is iets mis met de database. Verzeker u ervan dat de benodigde tabellen "
+"zijn aangemaakt en dat de database toegankelijk is voor de juiste gebruiker."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
msgid "Username:"
msgstr "Gebruikersnaam:"
-#: contrib/admin/templates/admin/login.html:20
+#: contrib/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Wachtwoord:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Aanmelden"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Datum/tijd"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Gebruiker"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Actie"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "d-n-Y H:i:s"
-#: contrib/admin/templates/admin/object_history.html:35
-msgid "This object doesn't have a change history. It probably wasn't added via this admin site."
-msgstr "Dit object heeft geen wijzigingsgeschiedenis. Het is mogelijk niet via de admin site toegevoegd."
+#: contrib/admin/templates/admin/object_history.html:32
+msgid ""
+"This object doesn't have a change history. It probably wasn't added via this "
+"admin site."
+msgstr ""
+"Dit object heeft geen wijzigingsgeschiedenis. Het is mogelijk niet via de "
+"admin site toegevoegd."
#: contrib/admin/templates/admin/pagination.html:10
msgid "Show all"
@@ -520,29 +701,36 @@ msgid "Save"
msgstr "Opslaan"
#: 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 "Vul allereerst een gebruikersnaam en wachtwoord in. Vervolgens kunt u de andere opties instellen."
+msgid ""
+"First, enter a username and password. Then, you'll be able to edit more user "
+"options."
+msgstr ""
+"Vul allereerst een gebruikersnaam en wachtwoord in. Vervolgens kunt u de "
+"andere opties instellen."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:12 contrib/auth/forms.py:49
msgid "Username"
msgstr "Gebruikersnaam"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:15 contrib/auth/forms.py:50 contrib/auth/forms.py:166
msgid "Password"
msgstr "Wachtwoord"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:167
msgid "Password (again)"
msgstr "Wachtwoord (nogmaals)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Vul hetzelfde wachtwoord als hierboven in, ter bevestiging."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr "Geef een nieuw passwoord voor gebruiker <strong>%(username)s</strong>."
@@ -566,27 +754,40 @@ msgid ""
"your computer is \"internal\").</p>\n"
msgstr ""
"\n"
-"<p class=\"help\">Om bookmarklets te installeren, sleep de link naar uw bladwijzers\n"
-"werkbalk, of rechtermuis klik op de link en voeg het toe aan de bladwijzer. Nu kan\n"
-"de bookmarklet vanuit elke pagina op de site worden gekozen. Let erop dat het soms\n"
-"noodzakelijk is dat de computer van waaruit de pagina wordt bekeken intern is.\n"
-"(Raadpleeg uw systeembeheerder of uw computer zich op het interne netwerk bevind).<p>\n"
+"<p class=\"help\">Om bookmarklets te installeren, sleep de link naar uw "
+"bladwijzers\n"
+"werkbalk, of rechtermuis klik op de link en voeg het toe aan de bladwijzer. "
+"Nu kan\n"
+"de bookmarklet vanuit elke pagina op de site worden gekozen. Let erop dat "
+"het soms\n"
+"noodzakelijk is dat de computer van waaruit de pagina wordt bekeken intern "
+"is.\n"
+"(Raadpleeg uw systeembeheerder of uw computer zich op het interne netwerk "
+"bevind).<p>\n"
#: contrib/admin/templates/admin_doc/bookmarklets.html:18
msgid "Documentation for this page"
msgstr "Documentatie voor deze pagina"
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
-msgid "Jumps you from any page to the documentation for the view that generates that page."
-msgstr "Springt vanuit elke pagina naar de documentatie voor de view die gegenereerd wordt door die pagina"
+msgid ""
+"Jumps you from any page to the documentation for the view that generates "
+"that page."
+msgstr ""
+"Springt vanuit elke pagina naar de documentatie voor de view die gegenereerd "
+"wordt door die pagina"
#: contrib/admin/templates/admin_doc/bookmarklets.html:21
msgid "Show object ID"
-msgstr "Toon object ID"
+msgstr "Toon object-ID"
#: contrib/admin/templates/admin_doc/bookmarklets.html:22
-msgid "Shows the content-type and unique ID for pages that represent a single object."
-msgstr "Toont de content-type en unieke ID voor pagina's die een enkel object voorstellen."
+msgid ""
+"Shows the content-type and unique ID for pages that represent a single "
+"object."
+msgstr ""
+"Toont het content-type en unieke ID voor pagina's die een enkel object "
+"voorstellen."
#: contrib/admin/templates/admin_doc/bookmarklets.html:24
msgid "Edit this object (current window)"
@@ -594,7 +795,8 @@ msgstr "Bewerk dit object (huidig venster)"
#: contrib/admin/templates/admin_doc/bookmarklets.html:25
msgid "Jumps to the admin page for pages that represent a single object."
-msgstr "Gaat naar de beheerpagina voor pagina's die een enkel object weergeven."
+msgstr ""
+"Gaat naar de beheerpagina voor pagina's die een enkel object weergeven."
#: contrib/admin/templates/admin_doc/bookmarklets.html:27
msgid "Edit this object (new window)"
@@ -610,41 +812,45 @@ msgstr "Bedankt voor de aanwezigheid op de site vandaag."
#: contrib/admin/templates/registration/logged_out.html:10
msgid "Log in again"
-msgstr "Meld u opnieuw aan"
+msgstr "Log opnieuw in"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 "Wachtwoord wijziging"
+msgstr "Wachtwoordwijziging"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: contrib/admin/templates/registration/password_change_done.html:6
+#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
msgstr "Wachtwoord wijzigen is geslaagd"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Uw wachtwoord is gewijzigd."
-#: contrib/admin/templates/registration/password_change_form.html:11
-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 "Vanwege de beveiliging moet u uw oude en twee keer een nieuw wachtwoord invoeren, zodat we kunnen controleren of er geen typefouten zijn gemaakt."
+#: 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 ""
+"Vanwege de beveiliging moet u uw oude en twee keer een nieuw wachtwoord "
+"invoeren, zodat we kunnen controleren of er geen typefouten zijn gemaakt."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Oud wachtwoord:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Nieuw wachtwoord:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Bevestig wachtwoord:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Wijzig mijn wachtwoord"
@@ -661,8 +867,11 @@ msgid "Password reset successful"
msgstr "Wachtwoord herstel geslaagd"
#: 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 "Een nieuw wachtwoord is per e-mail verstuurd. U zult het spoedig ontvangen."
+msgid ""
+"We've e-mailed a new password to the e-mail address you submitted. You "
+"should be receiving it shortly."
+msgstr ""
+"Een nieuw wachtwoord is per e-mail verstuurd. U zult het spoedig ontvangen."
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
@@ -696,8 +905,12 @@ msgid "The %(site_name)s team"
msgstr "Het %(site_name)s team"
#: 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 "Uw wachtwoord vergeten? Geef uw e-mailadres op en er zal een nieuw wachtwoord worden toegekend en aan u worden toegezonden."
+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 ""
+"Uw wachtwoord vergeten? Geef uw e-mailadres op en er zal een nieuw "
+"wachtwoord worden toegekend en aan u worden toegezonden."
#: contrib/admin/templates/registration/password_reset_form.html:16
msgid "E-mail address:"
@@ -707,356 +920,253 @@ msgstr "E-mailadres:"
msgid "Reset my password"
msgstr "Herstel mijn wachtwoord"
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Datum:"
-
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Tijd:"
-
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Huidige:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Wijziging:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Alle data"
-#: contrib/admin/views/auth.py:20
-#: contrib/admin/views/main.py:267
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "De %(name)s \"%(obj)s\" is toegevoegd."
-
-#: contrib/admin/views/auth.py:25
-#: contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "U kunt dit hieronder weer bewerken."
-
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Gebruiker toevoegen"
-
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Wachtwoord wijzigen is geslaagd"
-
-#: contrib/admin/views/auth.py:65
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Change password: %s"
-msgstr "Wijzig wachtwoord: %s"
-
-#: contrib/admin/views/decorators.py:17
-#: contrib/auth/forms.py:60
-msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
-msgstr "Voer een correcte gebruikersnaam en wachtwoord in. Let op, de velden zijn hoofdletter-gevoelig."
-
-#: contrib/admin/views/decorators.py:69
-msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
-msgstr "Uw sessie is verlopen, meld u opnieuw aan. Maakt u zich geen zorgen: Uw bijdrage is opgeslagen."
-
-#: contrib/admin/views/decorators.py:76
-msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
-msgstr "Het lijkt erop dat uw browser geen cookies accepteert. Zet het gebruik van cookies aan in uw browser, laad deze pagina nogmaals en probeer het opnieuw."
-
-#: contrib/admin/views/decorators.py:90
-msgid "Usernames cannot contain the '@' character."
-msgstr "Gebruikersnamen mogen geen '@' bevatten."
+msgid "Select %s"
+msgstr "Selecteer %s"
-#: contrib/admin/views/decorators.py:92
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Uw e-mailadres is niet uw gebruikersnaam. Probeer '%s' eens."
+msgid "Select %s to change"
+msgstr "Selecteer %s om te wijzigen"
-#: contrib/admin/views/doc.py:48
-#: contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53 contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "tag:"
-#: contrib/admin/views/doc.py:79
-#: contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87 contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filter:"
-#: contrib/admin/views/doc.py:137
-#: contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153 contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "view:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
-msgstr "App %r niet gevonden"
+msgstr "Toepassing %r niet gevonden"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Model %(name)r niet gevonden in app %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Model %(model_name)r niet gevonden in toepassing %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "het gerelateerde `%(label)s.%(type)s` object"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "het gerelateerde `%(app_label)s.%(data_type)s` object"
-#: contrib/admin/views/doc.py:185
-#: contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206 contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242 contrib/admindocs/views.py:247
msgid "model:"
msgstr "model:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "de gerelateerde `%(label)s.%(name)s` objecten"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "gerelateerde `%(app_label)s.%(object_name)s` objecten"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "alle %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "aantal %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Velden van %s objecten"
-#: contrib/admin/views/doc.py:293
-#: contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306
-#: contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313
-#: contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317 contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330 contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337 contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Geheel getal"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Boolean (True of False)"
-#: contrib/admin/views/doc.py:295
-#: contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319 contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Karakterreeks (hooguit %(max_length)s)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Komma-gescheiden gehele getallen"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Datum (zonder tijd)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Datum (met tijd)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Decimaal getal"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "E-mailadres"
-#: contrib/admin/views/doc.py:301
-#: contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325 contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Bestandspad"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Decimaal getal"
-#: contrib/admin/views/doc.py:307
-#: contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331 contrib/comments/models.py:89
msgid "IP address"
-msgstr "IP adres"
+msgstr "IP-adres"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Boolean (True, False of None)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
-msgstr "Relatie tot ouder model"
+msgstr "Relatie tot oudermodel"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Telefoonnummer"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Tekst"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Tijd"
-#: contrib/admin/views/doc.py:318
-#: contrib/flatpages/models.py:7
+#: contrib/admindocs/views.py:342 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Staat van de VS (twee hoofdletters)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
-msgstr "XML Tekst"
+msgstr "XML-tekst"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
-msgstr "%s lijkt geen urlpattern object te zijn"
-
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Site beheer"
-
-#: contrib/admin/views/main.py:280
-#: contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "U kunt hieronder de volgende %s toevoegen."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Toevoegen %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "%s toegevoegd."
-
-#: contrib/admin/views/main.py:344
-#: contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348
-#: core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "en"
-
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "Gewijzigd %s"
-
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "%s verwijderd."
-
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "Geen velden gewijzigd."
-
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "Het wijzigen van %(name)s \"%(obj)s\" is geslaagd."
-
-#: contrib/admin/views/main.py:362
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr "De %(name)s \"%(obj)s\" was toegevoegd. U kunt het hieronder wijzigen."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Wijzig %s"
-
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Een of meer %(fieldname)s in %(name)s: %(obj)s"
+msgstr "%s lijkt geen urlpattern-object te zijn"
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Een of meer %(fieldname)s in %(name)s:"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Persoonlijke informatie"
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "De verwijdering van %(name)s \"%(obj)s\" is geslaagd."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Rechten"
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "Weet u het zeker?"
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Belangrijke datums"
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Wijzigingsgeschiedenis: %s"
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Groepen"
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Selecteer %s"
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Gebruiker toevoegen"
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Selecteer %s om te wijzigen"
+#: contrib/auth/forms.py:13 contrib/auth/models.py:134
+msgid ""
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
+msgstr ""
+"Verplicht. 30 tekens of minder. Alleen alfanumerieke tekens (letters, "
+"cijfers en liggende strepen)."
-#: contrib/admin/views/main.py:784
-msgid "Database error"
-msgstr "Database fout"
+#: contrib/auth/forms.py:14 core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Deze waarde mag alleen letters, getallen en liggende strepen bevatten."
-#: contrib/auth/forms.py:17
-#: contrib/auth/forms.py:138
-msgid "The two password fields didn't match."
-msgstr "De twee ingevulde wachtwoorden zijn niet gelijk."
+#: contrib/auth/forms.py:16
+msgid "Password confirmation"
+msgstr "Bevestiging wachtwoord"
-#: contrib/auth/forms.py:25
+#: contrib/auth/forms.py:28
msgid "A user with that username already exists."
msgstr "Een gebruiker met deze gebruikersnaam bestaat al."
-#: contrib/auth/forms.py:53
-msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
-msgstr "Het lijkt erop dat uw browser geen cookies accepteert. Om aan te melden moeten cookies worden geaccepteerd."
+#: contrib/auth/forms.py:34 contrib/auth/forms.py:153
+#: contrib/auth/forms.py:178
+msgid "The two password fields didn't match."
+msgstr "De twee ingevulde wachtwoorden zijn niet gelijk."
-#: contrib/auth/forms.py:62
+#: contrib/auth/forms.py:72 contrib/comments/views/comments.py:58
msgid "This account is inactive."
msgstr "Dit account is inactief."
-#: contrib/auth/forms.py:84
-msgid "That e-mail address doesn't have an associated user account. Are you sure you've registered?"
-msgstr "Dat e-mailadres heeft geen gerelateerd gebruikersaccount. Weet u zeker dat u zich heeft geregistreerd?"
+#: contrib/auth/forms.py:77 contrib/comments/views/comments.py:49
+msgid ""
+"Your Web browser doesn't appear to have cookies enabled. Cookies are "
+"required for logging in."
+msgstr ""
+"Het lijkt erop dat uw browser geen cookies accepteert. Om aan te melden "
+"moeten cookies worden geaccepteerd."
+
+#: contrib/auth/forms.py:90
+msgid "E-mail"
+msgstr "E-mail"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:99
+msgid ""
+"That e-mail address doesn't have an associated user account. Are you sure "
+"you've registered?"
+msgstr ""
+"Dat e-mailadres heeft geen gerelateerd gebruikersaccount. Weet u zeker dat u "
+"zich heeft geregistreerd?"
+
+#: contrib/auth/forms.py:124
#, python-format
msgid "Password reset on %s"
msgstr "Wachtwoord hersteld op %s"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "De twee 'nieuw wachtwoord' velden zijn niet gelijk."
+#: contrib/auth/forms.py:131
+msgid "Old password"
+msgstr "Oud wachtwoord"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:132
+msgid "New password"
+msgstr "Nieuw wachtwoord"
+
+#: contrib/auth/forms.py:133
+msgid "New password confirmation"
+msgstr "Nieuw wachtwoord bevestigen"
+
+#: contrib/auth/forms.py:145
msgid "Your old password was entered incorrectly. Please enter it again."
-msgstr "Uw oude wachtwoord was niet correct ingevoerd. Voert u het alstublieft opnieuw in."
+msgstr ""
+"Uw oude wachtwoord was niet correct ingevoerd. Voert u het alstublieft "
+"opnieuw in."
-#: contrib/auth/models.py:73
-#: contrib/auth/models.py:93
+#: contrib/auth/models.py:73 contrib/auth/models.py:93
msgid "name"
msgstr "naam"
@@ -1068,8 +1178,7 @@ msgstr "codenaam"
msgid "permission"
msgstr "recht"
-#: contrib/auth/models.py:79
-#: contrib/auth/models.py:94
+#: contrib/auth/models.py:79 contrib/auth/models.py:94
msgid "permissions"
msgstr "rechten"
@@ -1077,123 +1186,125 @@ msgstr "rechten"
msgid "group"
msgstr "groep"
-#: contrib/auth/models.py:98
-#: contrib/auth/models.py:141
+#: contrib/auth/models.py:98 contrib/auth/models.py:144
msgid "groups"
msgstr "groepen"
-#: contrib/auth/models.py:131
+#: contrib/auth/models.py:134
msgid "username"
msgstr "gebruikersnaam"
-#: contrib/auth/models.py:131
-msgid "Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."
-msgstr "Verplicht. 30 tekens of minder. Alleen alfanumerieke tekens (letters, cijfers en liggende strepen)."
-
-#: contrib/auth/models.py:132
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "voornaam"
-#: contrib/auth/models.py:133
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "achternaam"
-#: contrib/auth/models.py:134
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "e-mailadres"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:138
msgid "password"
msgstr "wachtwoord"
-#: contrib/auth/models.py:135
-msgid "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."
-msgstr "Gebruik '[algo]$[salt]$[hexdigest]' of gebruik het<a href=\"password/\">wijzig passwoord</a> formulier ."
+#: contrib/auth/models.py:138
+msgid ""
+"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
+"password form</a>."
+msgstr ""
+"Gebruik '[algo]$[salt]$[hexdigest]' of gebruik het<a href=\"password/"
+"\">wijzig passwoord</a> formulier ."
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "staff status"
-msgstr "staf status"
+msgstr "stafstatus"
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
-msgstr "Bepaalt of de gebruiker kan inloggen op deze admin site."
+msgstr "Bepaalt of de gebruiker kan inloggen op deze beheersite."
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:140
msgid "active"
msgstr "actief"
-#: contrib/auth/models.py:137
-msgid "Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."
-msgstr "Bepaalt of de gebruiker kan inloggen op deze admin site. U kunt dit uitvinken in plaats van een gebruiker te verwijderen."
+#: contrib/auth/models.py:140
+msgid ""
+"Designates whether this user should be treated as active. Unselect this "
+"instead of deleting accounts."
+msgstr ""
+"Bepaalt of deze gebruiker als actief dient te worden behandeld. U kunt dit "
+"uitvinken in plaats van een gebruiker te verwijderen."
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:141
msgid "superuser status"
-msgstr "supergebruiker status"
+msgstr "supergebruikerstatus"
-#: contrib/auth/models.py:138
-msgid "Designates that this user has all permissions without explicitly assigning them."
-msgstr "Bepaalt dat deze gebruiker alle rechten heeft, zonder deze expliciet toe te wijzen."
+#: contrib/auth/models.py:141
+msgid ""
+"Designates that this user has all permissions without explicitly assigning "
+"them."
+msgstr ""
+"Bepaalt dat deze gebruiker alle rechten heeft, zonder deze expliciet toe te "
+"wijzen."
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:142
msgid "last login"
-msgstr "laatste aanmelding"
+msgstr "laatste inlog"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "datum toegetreden"
-#: contrib/auth/models.py:142
-msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
-msgstr "Bovenop de rechten welke handmatig zijn toegekend, krijgt deze gebruiker ook alle rechten van de groepen waar hij of zij deel van uitmaakt."
+#: contrib/auth/models.py:145
+msgid ""
+"In addition to the permissions manually assigned, this user will also get "
+"all permissions granted to each group he/she is in."
+msgstr ""
+"Bovenop de rechten welke handmatig zijn toegekend, krijgt deze gebruiker ook "
+"alle rechten van de groepen waar hij of zij deel van uitmaakt."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "gebruikersrechten"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:150
msgid "user"
msgstr "gebruiker"
-#: contrib/auth/models.py:148
+#: contrib/auth/models.py:151
msgid "users"
msgstr "gebruikers"
-#: contrib/auth/models.py:154
-msgid "Personal info"
-msgstr "Persoonlijke informatie"
-
-#: contrib/auth/models.py:155
-msgid "Permissions"
-msgstr "Rechten"
-
-#: contrib/auth/models.py:156
-msgid "Important dates"
-msgstr "Belangrijke datums"
-
-#: contrib/auth/models.py:157
-msgid "Groups"
-msgstr "Groepen"
-
-#: contrib/auth/models.py:316
+#: contrib/auth/models.py:306
msgid "message"
msgstr "bericht"
-#: contrib/auth/views.py:47
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "Afmelden"
-#: contrib/comments/models.py:71
-#: contrib/comments/models.py:176
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "Wachtwoord wijzigen is geslaagd"
+
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Wijzig wachtwoord: %s"
+
+#: contrib/comments/models.py:71 contrib/comments/models.py:164
msgid "object ID"
-msgstr "object ID"
+msgstr "object-ID"
#: contrib/comments/models.py:72
msgid "headline"
msgstr "kop"
-#: contrib/comments/models.py:73
-#: contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:73 contrib/comments/models.py:95
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "opmerking"
@@ -1233,13 +1344,11 @@ msgstr "waardering #8"
msgid "is valid rating"
msgstr "is een geldige waardering"
-#: contrib/comments/models.py:87
-#: contrib/comments/models.py:179
+#: contrib/comments/models.py:87 contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "datum/tijd toegevoegd"
-#: contrib/comments/models.py:88
-#: contrib/comments/models.py:180
+#: contrib/comments/models.py:88 contrib/comments/models.py:168
msgid "is public"
msgstr "is openbaar"
@@ -1248,19 +1357,22 @@ msgid "is removed"
msgstr "is verwijderd"
#: contrib/comments/models.py:90
-msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
-msgstr "Kruis deze box aan indien de opmerking niet gepast is. Een \"Dit commentaar is verwijderd\" bericht wordt dan getoond"
+msgid ""
+"Check this box if the comment is inappropriate. A \"This comment has been "
+"removed\" message will be displayed instead."
+msgstr ""
+"Kruis dit vak aan indien de opmerking niet gepast is. Een \"Dit commentaar "
+"is verwijderd\" bericht wordt dan getoond"
#: contrib/comments/models.py:96
msgid "comments"
msgstr "opmerkingen"
-#: contrib/comments/models.py:140
-#: contrib/comments/models.py:222
+#: contrib/comments/models.py:128 contrib/comments/models.py:199
msgid "Content object"
-msgstr "Inhoud object"
+msgstr "Inhoud-object"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1269,54 +1381,54 @@ msgid ""
"\n"
"http://%(domain)s%(url)s"
msgstr ""
-"Gepost door %(user)s op %(date)s\n"
+"Geplaatst door %(user)s op %(date)s\n"
"\n"
"%(comment)s\n"
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "naam van persoon"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
-msgstr "ip adres"
+msgstr "ip-adres"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "goedgekeurd door de staf"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "vrije opmerking"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "vrije opmerkingen"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "score"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
-msgstr "score datum"
+msgstr "scoredatum"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
-msgstr "karma score"
+msgstr "karmascore"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
-msgstr "karma scores"
+msgstr "karmascores"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "%(score)d waardering door %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1327,36 +1439,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "markeerdatum"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "gebruikersmarkering"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "gebruikersmarkeringen"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Gemarkeerd door %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
-msgstr "datum verwijdering"
+msgstr "verwijderingsdatum"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "verwijderd door moderator"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "verwijderd door moderator"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Verwijderd door moderator %r"
@@ -1391,70 +1503,81 @@ msgstr "Opmerking:"
#: contrib/comments/templates/comments/form.html:35
#: contrib/comments/templates/comments/freeform.html:10
msgid "Preview comment"
-msgstr "Concept opmerking"
+msgstr "Conceptopmerking"
#: contrib/comments/templates/comments/freeform.html:4
msgid "Your name:"
msgstr "Uw gebruikersnaam:"
-#: contrib/comments/views/comments.py:28
-msgid "This rating is required because you've entered at least one other rating."
-msgstr "Deze waardering is verplicht omdat u tenminste één andere waardering hebt ingevoerd."
+#: contrib/comments/views/comments.py:76
+msgid ""
+"This rating is required because you've entered at least one other rating."
+msgstr ""
+"Deze waardering is verplicht omdat u tenminste één andere waardering hebt "
+"ingevoerd."
-#: contrib/comments/views/comments.py:112
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
-"This comment was posted by a user who has posted fewer than %(count)s comment:\n"
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comment:\n"
"\n"
"%(text)s"
msgid_plural ""
-"This comment was posted by a user who has posted fewer than %(count)s comments:\n"
+"This comment was posted by a user who has posted fewer than %(count)s "
+"comments:\n"
"\n"
"%(text)s"
msgstr[0] ""
-"Deze opmerking is gepost door een gebruiker die minder dan %(count)s opmerking heeft gepost:\n"
+"Deze opmerking is gepost door een gebruiker die minder dan %(count)s "
+"opmerking heeft gepost:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"Deze opmerking is gepost door een gebruiker die minder dan %(count)s opmerkingen heeft gepost:\n"
+"Deze opmerking is gepost door een gebruiker die minder dan %(count)s "
+"opmerkingen heeft gepost:\n"
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
"\n"
"%(text)s"
msgstr ""
-"Deze opmerking is gepost door een \"fijne\" gebruiker:\n"
+"Deze opmerking is gepost door een twijfelachtige gebruiker:\n"
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Alleen POSTs zijn toegestaan"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
msgid "One or more of the required fields wasn't submitted"
-msgstr "Een of meerdere verplichte velden zijn niet ingevuld"
+msgstr "Eén of meerdere verplichte velden zijn niet ingevuld"
-#: contrib/comments/views/comments.py:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
msgid "Somebody tampered with the comment form (security violation)"
msgstr "Iemand heeft het opmerkingenformulier gewijzigd (beveilingsinbreuk)"
-#: contrib/comments/views/comments.py:208
-#: contrib/comments/views/comments.py:295
-msgid "The comment form had an invalid 'target' parameter -- the object ID was invalid"
-msgstr "Het opmerkingenformulier heeft een ongeldig 'target' parameter -- het object ID was ongeldig"
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
+msgid ""
+"The comment form had an invalid 'target' parameter -- the object ID was "
+"invalid"
+msgstr ""
+"Het opmerkingenformulier heeft een ongeldige 'target' parameter -- het "
+"object-ID was ongeldig"
-#: contrib/comments/views/comments.py:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
-msgstr "Het opmerkingenformulier heeft geen 'voorbeeld' of 'post'"
+msgstr "Het opmerkingenformulier verschaft geen 'voorbeeld' of 'post'"
#: contrib/comments/views/karma.py:21
msgid "Anonymous users cannot vote"
@@ -1462,61 +1585,72 @@ msgstr "Anonieme gebruikers kunnen niet stemmen"
#: contrib/comments/views/karma.py:25
msgid "Invalid comment ID"
-msgstr "Ongeldige opmerkingen ID"
+msgstr "Ongeldige opmerkingen-ID"
#: contrib/comments/views/karma.py:27
msgid "No voting for yourself"
msgstr "Niet op uzelf stemmen"
-#: contrib/contenttypes/models.py:37
+#: contrib/contenttypes/models.py:67
msgid "python model class name"
-msgstr "python model-class-naam"
+msgstr "klassenaam van pythonmodel"
-#: contrib/contenttypes/models.py:40
+#: contrib/contenttypes/models.py:71
msgid "content type"
msgstr "inhoudstype"
-#: contrib/contenttypes/models.py:41
+#: contrib/contenttypes/models.py:72
msgid "content types"
msgstr "inhoudstypen"
-#: contrib/flatpages/models.py:8
-msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr "Voorbeeld: '/about/contact/'. Zorg voor slashes aan het begin en eind."
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Geavanceerde opties"
#: contrib/flatpages/models.py:9
+msgid ""
+"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
+msgstr "Voorbeeld: '/about/contact/'. Zorg voor slashes aan het begin en eind."
+
+#: contrib/flatpages/models.py:10
msgid "title"
msgstr "titel"
-#: contrib/flatpages/models.py:10
+#: contrib/flatpages/models.py:11
msgid "content"
msgstr "inhoud"
-#: contrib/flatpages/models.py:11
+#: contrib/flatpages/models.py:12
msgid "enable comments"
msgstr "opmerkingen toestaan"
-#: contrib/flatpages/models.py:12
+#: contrib/flatpages/models.py:13
msgid "template name"
msgstr "sjabloonnaam"
-#: contrib/flatpages/models.py:13
-msgid "Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."
-msgstr "Voorbeeld: 'flatpages/contact_page.html'. Als deze niet is opgegeven, dan wordt 'flatpages/default.html' gebruikt."
-
#: contrib/flatpages/models.py:14
+msgid ""
+"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
+"will use 'flatpages/default.html'."
+msgstr ""
+"Voorbeeld: 'flatpages/contact_page.html'. Als deze niet is opgegeven, dan "
+"wordt 'flatpages/default.html' gebruikt."
+
+#: contrib/flatpages/models.py:15
msgid "registration required"
msgstr "registratie verplicht"
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr "Indien dit is aangekruist kunnen alleen ingelogde gebruikers deze pagina bekijken."
+msgstr ""
+"Indien dit is aangekruist kunnen alleen ingelogde gebruikers deze pagina "
+"bekijken."
-#: contrib/flatpages/models.py:18
+#: contrib/flatpages/models.py:20
msgid "flat page"
msgstr "platte pagina"
-#: contrib/flatpages/models.py:19
+#: contrib/flatpages/models.py:21
msgid "flat pages"
msgstr "platte pagina's"
@@ -1547,19 +1681,19 @@ msgstr[1] "%(value).1f miljoen"
#, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
-msgstr[0] "%(value).1f biljoen"
-msgstr[1] "%(value).1f biljoen"
+msgstr[0] "%(value).1f miljard"
+msgstr[1] "%(value).1f miljard"
#: contrib/humanize/templatetags/humanize.py:57
#, python-format
msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion"
-msgstr[0] "%(value).1f triljoen"
-msgstr[1] "%(value).1f triljoen"
+msgstr[0] "%(value).1f biljoen"
+msgstr[1] "%(value).1f biljoen"
#: contrib/humanize/templatetags/humanize.py:73
msgid "one"
-msgstr "een"
+msgstr "één"
#: contrib/humanize/templatetags/humanize.py:73
msgid "two"
@@ -1607,1785 +1741,1881 @@ msgstr "gisteren"
#: contrib/localflavor/ar/forms.py:27
msgid "Enter a postal code in the format NNNN or ANNNNAAA."
-msgstr ""
+msgstr "Geef een postcode op volgens het NNNN of ANNNNAAA formaat."
-#: contrib/localflavor/ar/forms.py:49
-#: contrib/localflavor/br/forms.py:96
-#: contrib/localflavor/br/forms.py:135
-#: contrib/localflavor/pe/forms.py:23
+#: contrib/localflavor/ar/forms.py:49 contrib/localflavor/br/forms.py:96
+#: contrib/localflavor/br/forms.py:135 contrib/localflavor/pe/forms.py:23
#: contrib/localflavor/pe/forms.py:51
msgid "This field requires only numbers."
-msgstr ""
+msgstr "Dit veld dient alleen cijfers te bevatten."
#: contrib/localflavor/ar/forms.py:50
msgid "This field requires 7 or 8 digits."
-msgstr ""
+msgstr "Dit veld dient 7 of 8 cijfers te zijn."
#: contrib/localflavor/ar/forms.py:79
msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
-msgstr ""
+msgstr "Geef een geldige CUIT op in het XX-XXXXXXXX-X of XXXXXXXXXXXX formaat."
#: contrib/localflavor/ar/forms.py:80
msgid "Invalid CUIT."
+msgstr "Ongeldige CUIT."
+
+#: contrib/localflavor/at/at_states.py:5
+msgid "Burgenland"
+msgstr "Burgenland"
+
+#: contrib/localflavor/at/at_states.py:6
+msgid "Carinthia"
+msgstr "Carinthia"
+
+#: contrib/localflavor/at/at_states.py:7
+msgid "Lower Austria"
+msgstr "Lager Australië"
+
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr "Hoger Australië"
+
+#: contrib/localflavor/at/at_states.py:9
+msgid "Salzburg"
+msgstr "Salzburg"
+
+#: contrib/localflavor/at/at_states.py:10
+msgid "Styria"
+msgstr "Styria"
+
+#: contrib/localflavor/at/at_states.py:11
+msgid "Tyrol"
+msgstr "Tirol"
+
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr "Vorarlberg"
+
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr "Wenen"
+
+#: contrib/localflavor/at/forms.py:20 contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Geef een postcode op in het formaat XXXX."
+
+#: contrib/localflavor/at/forms.py:48
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
msgstr ""
+"Geef een geldig Oostenrijks Sociaalnummer op in het XXX-XX-XXXX formaat."
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
-msgstr ""
+msgstr "Geef een vier cijferige postcode op."
#: contrib/localflavor/br/forms.py:21
msgid "Enter a zip code in the format XXXXX-XXX."
-msgstr ""
+msgstr "Geef een postcode op in het formaat XXXXX-XXX."
#: contrib/localflavor/br/forms.py:30
msgid "Phone numbers must be in XX-XXXX-XXXX format."
-msgstr ""
+msgstr "Telefoonnummers dienen volgens het XX-XXXX-XXXX formaat te zijn."
#: contrib/localflavor/br/forms.py:58
-msgid "Select a valid brazilian state. That state is not one of the available states."
-msgstr ""
+msgid ""
+"Select a valid brazilian state. That state is not one of the available "
+"states."
+msgstr "Selecteer een geldige braziliaanse staat. Uw keuze is niet geldig."
#: contrib/localflavor/br/forms.py:94
msgid "Invalid CPF number."
-msgstr ""
+msgstr "Ongeldig CPF nummer."
#: contrib/localflavor/br/forms.py:95
msgid "This field requires at most 11 digits or 14 characters."
-msgstr ""
+msgstr "Dit veld dient maximaal 11 cijfers of 14 letters te bevatten."
#: contrib/localflavor/br/forms.py:134
msgid "Invalid CNPJ number."
-msgstr ""
+msgstr "Ongeldig CNPJ nummer."
#: contrib/localflavor/br/forms.py:136
msgid "This field requires at least 14 digits"
-msgstr ""
+msgstr "Dit vereist minimaal 14 cijfers."
#: contrib/localflavor/ca/forms.py:17
msgid "Enter a postal code in the format XXX XXX."
-msgstr ""
+msgstr "Geef een postcode op in het formaat XXX XXX."
#: contrib/localflavor/ca/forms.py:88
msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format."
msgstr ""
+"Geef een geldig Canadees Sociaal Verzekeringsnummer op volgens het XXX-XXX-"
+"XXX formaat."
#: contrib/localflavor/ch/ch_states.py:5
msgid "Aargau"
-msgstr ""
+msgstr "Aargau"
#: contrib/localflavor/ch/ch_states.py:6
msgid "Appenzell Innerrhoden"
-msgstr ""
+msgstr "Appenzell Innerrhoden"
#: contrib/localflavor/ch/ch_states.py:7
msgid "Appenzell Ausserrhoden"
-msgstr ""
+msgstr "Appenzell Ausserrhoden"
#: contrib/localflavor/ch/ch_states.py:8
msgid "Basel-Stadt"
-msgstr ""
+msgstr "Basel-Stad"
#: contrib/localflavor/ch/ch_states.py:9
msgid "Basel-Land"
-msgstr ""
+msgstr "Basel-Land"
#: contrib/localflavor/ch/ch_states.py:10
msgid "Berne"
-msgstr ""
+msgstr "Bern"
#: contrib/localflavor/ch/ch_states.py:11
msgid "Fribourg"
-msgstr ""
+msgstr "Fribourg"
#: contrib/localflavor/ch/ch_states.py:12
msgid "Geneva"
-msgstr ""
+msgstr "Genève"
#: contrib/localflavor/ch/ch_states.py:13
msgid "Glarus"
-msgstr ""
+msgstr "Glarus"
#: contrib/localflavor/ch/ch_states.py:14
msgid "Graubuenden"
-msgstr ""
+msgstr "Graubuenden"
#: contrib/localflavor/ch/ch_states.py:15
msgid "Jura"
-msgstr ""
+msgstr "Jura"
#: contrib/localflavor/ch/ch_states.py:16
msgid "Lucerne"
-msgstr ""
+msgstr "Lucerne"
#: contrib/localflavor/ch/ch_states.py:17
msgid "Neuchatel"
-msgstr ""
+msgstr "Neuchatel"
#: contrib/localflavor/ch/ch_states.py:18
msgid "Nidwalden"
-msgstr ""
+msgstr "Nidwalden"
#: contrib/localflavor/ch/ch_states.py:19
msgid "Obwalden"
-msgstr ""
+msgstr "Obwalden"
#: contrib/localflavor/ch/ch_states.py:20
msgid "Schaffhausen"
-msgstr ""
+msgstr "Schaffhausen"
#: contrib/localflavor/ch/ch_states.py:21
msgid "Schwyz"
-msgstr ""
+msgstr "Schwyz"
#: contrib/localflavor/ch/ch_states.py:22
msgid "Solothurn"
-msgstr ""
+msgstr "Solothurn"
#: contrib/localflavor/ch/ch_states.py:23
msgid "St. Gallen"
-msgstr ""
+msgstr "St. Gallen"
#: contrib/localflavor/ch/ch_states.py:24
msgid "Thurgau"
-msgstr ""
+msgstr "Thurgau"
#: contrib/localflavor/ch/ch_states.py:25
msgid "Ticino"
-msgstr ""
+msgstr "Ticino"
#: contrib/localflavor/ch/ch_states.py:26
msgid "Uri"
-msgstr ""
+msgstr "Uri"
#: contrib/localflavor/ch/ch_states.py:27
msgid "Valais"
-msgstr ""
+msgstr "Valais"
#: contrib/localflavor/ch/ch_states.py:28
msgid "Vaud"
-msgstr ""
+msgstr "Vaud"
#: contrib/localflavor/ch/ch_states.py:29
msgid "Zug"
-msgstr ""
+msgstr "Zug"
#: contrib/localflavor/ch/ch_states.py:30
msgid "Zurich"
-msgstr ""
-
-#: contrib/localflavor/ch/forms.py:16
-#: contrib/localflavor/no/forms.py:12
-msgid "Enter a zip code in the format XXXX."
-msgstr ""
+msgstr "Zurich"
#: contrib/localflavor/ch/forms.py:64
-msgid "Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format."
+msgid ""
+"Enter a valid Swiss identity or passport card number in X1234567<0 or "
+"1234567890 format."
msgstr ""
+"Geef een geldig Zwitsers identiteits- of paspoortnummer op volgens het "
+"X1234567<0 of 1234567890 formaat"
#: contrib/localflavor/cl/forms.py:29
msgid "Enter a valid Chilean RUT."
-msgstr ""
+msgstr "Geen een geldige Chileense RUT op."
#: contrib/localflavor/cl/forms.py:30
msgid "Enter a valid Chilean RUT. The format is XX.XXX.XXX-X."
-msgstr ""
+msgstr "Geef een geldige Chileense RUT op. Het formaat is XX.XXX.XXX-X."
#: contrib/localflavor/cl/forms.py:31
msgid "The Chilean RUT is not valid."
-msgstr ""
+msgstr "De Chileense RUT is ongeldig."
#: contrib/localflavor/de/de_states.py:5
msgid "Baden-Wuerttemberg"
-msgstr ""
+msgstr "Baden-Wuerttemberg"
#: contrib/localflavor/de/de_states.py:6
msgid "Bavaria"
-msgstr ""
+msgstr "Beieren"
#: contrib/localflavor/de/de_states.py:7
msgid "Berlin"
-msgstr ""
+msgstr "Berlijn"
#: contrib/localflavor/de/de_states.py:8
msgid "Brandenburg"
-msgstr ""
+msgstr "Brandenburg"
#: contrib/localflavor/de/de_states.py:9
msgid "Bremen"
-msgstr ""
+msgstr "Bremen"
#: contrib/localflavor/de/de_states.py:10
msgid "Hamburg"
-msgstr ""
+msgstr "Hamburg"
#: contrib/localflavor/de/de_states.py:11
msgid "Hessen"
-msgstr ""
+msgstr "Hessen"
#: contrib/localflavor/de/de_states.py:12
msgid "Mecklenburg-Western Pomerania"
-msgstr ""
+msgstr "Mecklenburg-Western Pomerania"
#: contrib/localflavor/de/de_states.py:13
msgid "Lower Saxony"
-msgstr ""
+msgstr "Nedersaksen"
#: contrib/localflavor/de/de_states.py:14
msgid "North Rhine-Westphalia"
-msgstr ""
+msgstr "Noord Rijn-Westfalen"
#: contrib/localflavor/de/de_states.py:15
msgid "Rhineland-Palatinate"
-msgstr ""
+msgstr "Rijnland-Palts"
#: contrib/localflavor/de/de_states.py:16
msgid "Saarland"
-msgstr ""
+msgstr "Saarland"
#: contrib/localflavor/de/de_states.py:17
msgid "Saxony"
-msgstr ""
+msgstr "Saksen"
#: contrib/localflavor/de/de_states.py:18
msgid "Saxony-Anhalt"
-msgstr ""
+msgstr "Saksen-Anhalt"
#: contrib/localflavor/de/de_states.py:19
msgid "Schleswig-Holstein"
-msgstr ""
+msgstr "Sleeswijk-Holstein"
#: contrib/localflavor/de/de_states.py:20
msgid "Thuringia"
-msgstr ""
+msgstr "Thüringen"
-#: contrib/localflavor/de/forms.py:14
-#: contrib/localflavor/fi/forms.py:12
+#: contrib/localflavor/de/forms.py:14 contrib/localflavor/fi/forms.py:12
#: contrib/localflavor/fr/forms.py:15
msgid "Enter a zip code in the format XXXXX."
-msgstr ""
+msgstr "Geef een postcode op in het formaat XXXXX."
#: contrib/localflavor/de/forms.py:41
-msgid "Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format."
+msgid ""
+"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
msgstr ""
+"Geef een geldig Duits identiteitsnummer op volgens het XXXXXXXXXXX-XXXXXXX-"
+"XXXXXXX-X formaat."
#: contrib/localflavor/es/es_provinces.py:5
msgid "Arava"
-msgstr ""
+msgstr "Arava"
#: contrib/localflavor/es/es_provinces.py:6
msgid "Albacete"
-msgstr ""
+msgstr "Albacete"
#: contrib/localflavor/es/es_provinces.py:7
msgid "Alacant"
-msgstr ""
+msgstr "Alacant"
#: contrib/localflavor/es/es_provinces.py:8
msgid "Almeria"
-msgstr ""
+msgstr "Almeria"
#: contrib/localflavor/es/es_provinces.py:9
msgid "Avila"
-msgstr ""
+msgstr "Avila"
#: contrib/localflavor/es/es_provinces.py:10
msgid "Badajoz"
-msgstr ""
+msgstr "Badajoz"
#: contrib/localflavor/es/es_provinces.py:11
msgid "Illes Balears"
-msgstr ""
+msgstr "Balearen"
#: contrib/localflavor/es/es_provinces.py:12
msgid "Barcelona"
-msgstr ""
+msgstr "Barcelona"
#: contrib/localflavor/es/es_provinces.py:13
msgid "Burgos"
-msgstr ""
+msgstr "Burgos"
#: contrib/localflavor/es/es_provinces.py:14
msgid "Caceres"
-msgstr ""
+msgstr "Caceres"
#: contrib/localflavor/es/es_provinces.py:15
msgid "Cadiz"
-msgstr ""
+msgstr "Cadiz"
#: contrib/localflavor/es/es_provinces.py:16
msgid "Castello"
-msgstr ""
+msgstr "Castello"
#: contrib/localflavor/es/es_provinces.py:17
msgid "Ciudad Real"
-msgstr ""
+msgstr "Ciudad Real"
#: contrib/localflavor/es/es_provinces.py:18
msgid "Cordoba"
-msgstr ""
+msgstr "Cordoba"
#: contrib/localflavor/es/es_provinces.py:19
msgid "A Coruna"
-msgstr ""
+msgstr "A Coruna"
#: contrib/localflavor/es/es_provinces.py:20
msgid "Cuenca"
-msgstr ""
+msgstr "Cuenca"
#: contrib/localflavor/es/es_provinces.py:21
msgid "Girona"
-msgstr ""
+msgstr "Girona"
#: contrib/localflavor/es/es_provinces.py:22
msgid "Granada"
-msgstr ""
+msgstr "Granada"
#: contrib/localflavor/es/es_provinces.py:23
msgid "Guadalajara"
-msgstr ""
+msgstr "Guadalajara"
#: contrib/localflavor/es/es_provinces.py:24
msgid "Guipuzkoa"
-msgstr ""
+msgstr "Guipuzkoa"
#: contrib/localflavor/es/es_provinces.py:25
msgid "Huelva"
-msgstr ""
+msgstr "Huelva"
#: contrib/localflavor/es/es_provinces.py:26
msgid "Huesca"
-msgstr ""
+msgstr "Huesca"
#: contrib/localflavor/es/es_provinces.py:27
msgid "Jaen"
-msgstr ""
+msgstr "Jaen"
#: contrib/localflavor/es/es_provinces.py:28
msgid "Leon"
-msgstr ""
+msgstr "Leon"
#: contrib/localflavor/es/es_provinces.py:29
msgid "Lleida"
-msgstr ""
+msgstr "Lleida"
#: contrib/localflavor/es/es_provinces.py:30
#: contrib/localflavor/es/es_regions.py:17
msgid "La Rioja"
-msgstr ""
+msgstr "La Rioja"
#: contrib/localflavor/es/es_provinces.py:31
msgid "Lugo"
-msgstr ""
+msgstr "Lugo"
#: contrib/localflavor/es/es_provinces.py:32
#: contrib/localflavor/es/es_regions.py:18
msgid "Madrid"
-msgstr ""
+msgstr "Madrid"
#: contrib/localflavor/es/es_provinces.py:33
msgid "Malaga"
-msgstr ""
+msgstr "Malaga"
#: contrib/localflavor/es/es_provinces.py:34
msgid "Murcia"
-msgstr ""
+msgstr "Murcia"
#: contrib/localflavor/es/es_provinces.py:35
msgid "Navarre"
-msgstr ""
+msgstr "Navarre"
#: contrib/localflavor/es/es_provinces.py:36
msgid "Ourense"
-msgstr ""
+msgstr "Ourense"
#: contrib/localflavor/es/es_provinces.py:37
msgid "Asturias"
-msgstr ""
+msgstr "Asturias"
#: contrib/localflavor/es/es_provinces.py:38
msgid "Palencia"
-msgstr ""
+msgstr "Palencia"
#: contrib/localflavor/es/es_provinces.py:39
msgid "Las Palmas"
-msgstr ""
+msgstr "Las Palmas"
#: contrib/localflavor/es/es_provinces.py:40
msgid "Pontevedra"
-msgstr ""
+msgstr "Pontevedra"
#: contrib/localflavor/es/es_provinces.py:41
msgid "Salamanca"
-msgstr ""
+msgstr "Salamanca"
#: contrib/localflavor/es/es_provinces.py:42
msgid "Santa Cruz de Tenerife"
-msgstr ""
+msgstr "Santa Cruz de Tenerife"
#: contrib/localflavor/es/es_provinces.py:43
#: contrib/localflavor/es/es_regions.py:11
msgid "Cantabria"
-msgstr ""
+msgstr "Cantabria"
#: contrib/localflavor/es/es_provinces.py:44
msgid "Segovia"
-msgstr ""
+msgstr "Segovia"
#: contrib/localflavor/es/es_provinces.py:45
msgid "Seville"
-msgstr ""
+msgstr "Sevilla"
#: contrib/localflavor/es/es_provinces.py:46
msgid "Soria"
-msgstr ""
+msgstr "Soria"
#: contrib/localflavor/es/es_provinces.py:47
msgid "Tarragona"
-msgstr ""
+msgstr "Tarragona"
#: contrib/localflavor/es/es_provinces.py:48
msgid "Teruel"
-msgstr ""
+msgstr "Teruel"
#: contrib/localflavor/es/es_provinces.py:49
msgid "Toledo"
-msgstr ""
+msgstr "Toledo"
#: contrib/localflavor/es/es_provinces.py:50
msgid "Valencia"
-msgstr ""
+msgstr "Valencië"
#: contrib/localflavor/es/es_provinces.py:51
msgid "Valladolid"
-msgstr ""
+msgstr "Valladolid"
#: contrib/localflavor/es/es_provinces.py:52
msgid "Bizkaia"
-msgstr ""
+msgstr "Bizkaia"
#: contrib/localflavor/es/es_provinces.py:53
msgid "Zamora"
-msgstr ""
+msgstr "Zamora"
#: contrib/localflavor/es/es_provinces.py:54
msgid "Zaragoza"
-msgstr ""
+msgstr "Zaragoza"
#: contrib/localflavor/es/es_provinces.py:55
msgid "Ceuta"
-msgstr ""
+msgstr "Ceuta"
#: contrib/localflavor/es/es_provinces.py:56
msgid "Melilla"
-msgstr ""
+msgstr "Melilla"
#: contrib/localflavor/es/es_regions.py:5
msgid "Andalusia"
-msgstr ""
+msgstr "Andalusië"
#: contrib/localflavor/es/es_regions.py:6
msgid "Aragon"
-msgstr ""
+msgstr "Aragon"
#: contrib/localflavor/es/es_regions.py:7
msgid "Principality of Asturias"
-msgstr ""
+msgstr "Prinsdom Asturië"
#: contrib/localflavor/es/es_regions.py:8
msgid "Balearic Islands"
-msgstr ""
+msgstr "Balearen"
#: contrib/localflavor/es/es_regions.py:9
msgid "Basque Country"
-msgstr ""
+msgstr "Baskenland"
#: contrib/localflavor/es/es_regions.py:10
msgid "Canary Islands"
-msgstr ""
+msgstr "Canarische Eilanden"
#: contrib/localflavor/es/es_regions.py:12
msgid "Castile-La Mancha"
-msgstr ""
+msgstr "Castilië-La Mancha"
#: contrib/localflavor/es/es_regions.py:13
msgid "Castile and Leon"
-msgstr ""
+msgstr "Castilië en León"
#: contrib/localflavor/es/es_regions.py:14
msgid "Catalonia"
-msgstr ""
+msgstr "Catalonië"
#: contrib/localflavor/es/es_regions.py:15
msgid "Extremadura"
-msgstr ""
+msgstr "Extremadura"
#: contrib/localflavor/es/es_regions.py:16
msgid "Galicia"
-msgstr ""
+msgstr "Galicië"
#: contrib/localflavor/es/es_regions.py:19
msgid "Region of Murcia"
-msgstr ""
+msgstr "Murcia"
#: contrib/localflavor/es/es_regions.py:20
msgid "Foral Community of Navarre"
-msgstr ""
+msgstr "Navarra"
#: contrib/localflavor/es/es_regions.py:21
msgid "Valencian Community"
-msgstr ""
+msgstr "Valencia"
#: contrib/localflavor/es/forms.py:19
msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
-msgstr ""
+msgstr "Vul een postcode in volgens het 01XXX - 52XXX formaat."
#: contrib/localflavor/es/forms.py:39
-msgid "Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX."
+msgid ""
+"Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or "
+"9XXXXXXXX."
msgstr ""
+"Geef een geldig telefoonnummer op in één van de volgende formaten: "
+"6XXXXXXXX, 8XXXXXXXX of 9XXXXXXXX."
#: contrib/localflavor/es/forms.py:66
msgid "Please enter a valid NIF, NIE, or CIF."
-msgstr ""
+msgstr "Geef een geldige NIF, NIE of CIF op."
#: contrib/localflavor/es/forms.py:67
msgid "Please enter a valid NIF or NIE."
-msgstr ""
+msgstr "Geef een geldige NIF of NIE op."
#: contrib/localflavor/es/forms.py:68
msgid "Invalid checksum for NIF."
-msgstr ""
+msgstr "Ongeldig controlegetal voor NIF."
#: contrib/localflavor/es/forms.py:69
msgid "Invalid checksum for NIE."
-msgstr ""
+msgstr "Ongeldig controlegetal voor NIE."
#: contrib/localflavor/es/forms.py:70
msgid "Invalid checksum for CIF."
-msgstr ""
+msgstr "Ongeldig controlegetal voor CIF."
#: contrib/localflavor/es/forms.py:142
-msgid "Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
+msgid ""
+"Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
msgstr ""
+"Geef een geldig bankrekeningnummer op in het formaat XXXX-XXXX-XX-XXXXXXXXXX."
#: contrib/localflavor/es/forms.py:143
msgid "Invalid checksum for bank account number."
-msgstr ""
+msgstr "Ongeldig controlegetal voor het bankrekeningnummer."
#: contrib/localflavor/fi/forms.py:28
msgid "Enter a valid Finnish social security number."
-msgstr ""
+msgstr "Geef een geldig Fins sociaal nummer op."
#: contrib/localflavor/in_/forms.py:14
msgid "Enter a zip code in the format XXXXXXX."
-msgstr ""
+msgstr "Geef een geldige postcode op in het formaat XXXXXXX."
#: contrib/localflavor/is_/forms.py:17
-msgid "Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
+msgid ""
+"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
msgstr ""
+"Geef een geldig IJslands identificatienummer op. Het formaat is XXXXXX-XXXX."
#: contrib/localflavor/is_/forms.py:18
msgid "The Icelandic identification number is not valid."
-msgstr ""
+msgstr "Het IJslandse identificatienummer is niet geldig."
#: contrib/localflavor/it/forms.py:14
msgid "Enter a valid zip code."
-msgstr ""
+msgstr "Geef een geldige postcode op."
#: contrib/localflavor/it/forms.py:43
msgid "Enter a valid Social Security number."
-msgstr ""
+msgstr "Geef een geldig Sociaal Nummer op."
#: contrib/localflavor/it/forms.py:68
msgid "Enter a valid VAT number."
-msgstr ""
+msgstr "Geef een geldig BTW nummer op."
#: contrib/localflavor/jp/forms.py:17
msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
-msgstr ""
+msgstr "Geef een geldige postcode op in het formaat XXXXXXX of XXX-XXXX."
#: contrib/localflavor/jp/jp_prefectures.py:4
msgid "Hokkaido"
-msgstr ""
+msgstr "Hokkaido"
#: contrib/localflavor/jp/jp_prefectures.py:5
msgid "Aomori"
-msgstr ""
+msgstr "Aomori"
#: contrib/localflavor/jp/jp_prefectures.py:6
msgid "Iwate"
-msgstr ""
+msgstr "Iwate"
#: contrib/localflavor/jp/jp_prefectures.py:7
msgid "Miyagi"
-msgstr ""
+msgstr "Miyagi"
#: contrib/localflavor/jp/jp_prefectures.py:8
msgid "Akita"
-msgstr ""
+msgstr "Akita"
#: contrib/localflavor/jp/jp_prefectures.py:9
msgid "Yamagata"
-msgstr ""
+msgstr "Yamagata"
#: contrib/localflavor/jp/jp_prefectures.py:10
msgid "Fukushima"
-msgstr ""
+msgstr "Fukushima"
#: contrib/localflavor/jp/jp_prefectures.py:11
msgid "Ibaraki"
-msgstr ""
+msgstr "Ibaraki"
#: contrib/localflavor/jp/jp_prefectures.py:12
msgid "Tochigi"
-msgstr ""
+msgstr "Tochigi"
#: contrib/localflavor/jp/jp_prefectures.py:13
msgid "Gunma"
-msgstr ""
+msgstr "Gunma"
#: contrib/localflavor/jp/jp_prefectures.py:14
msgid "Saitama"
-msgstr ""
+msgstr "Saitama"
#: contrib/localflavor/jp/jp_prefectures.py:15
msgid "Chiba"
-msgstr ""
+msgstr "Saitama"
#: contrib/localflavor/jp/jp_prefectures.py:16
msgid "Tokyo"
-msgstr ""
+msgstr "Tokyo"
#: contrib/localflavor/jp/jp_prefectures.py:17
msgid "Kanagawa"
-msgstr ""
+msgstr "Kanagawa"
#: contrib/localflavor/jp/jp_prefectures.py:18
msgid "Yamanashi"
-msgstr ""
+msgstr "Yamanashi"
#: contrib/localflavor/jp/jp_prefectures.py:19
msgid "Nagano"
-msgstr ""
+msgstr "Nagano"
#: contrib/localflavor/jp/jp_prefectures.py:20
msgid "Niigata"
-msgstr ""
+msgstr "Niigata"
#: contrib/localflavor/jp/jp_prefectures.py:21
msgid "Toyama"
-msgstr ""
+msgstr "Toyama"
#: contrib/localflavor/jp/jp_prefectures.py:22
msgid "Ishikawa"
-msgstr ""
+msgstr "Ishikawa"
#: contrib/localflavor/jp/jp_prefectures.py:23
msgid "Fukui"
-msgstr ""
+msgstr "Fukui"
#: contrib/localflavor/jp/jp_prefectures.py:24
msgid "Gifu"
-msgstr ""
+msgstr "Gifu"
#: contrib/localflavor/jp/jp_prefectures.py:25
msgid "Shizuoka"
-msgstr ""
+msgstr "Shizuoka"
#: contrib/localflavor/jp/jp_prefectures.py:26
msgid "Aichi"
-msgstr ""
+msgstr "Aichi"
#: contrib/localflavor/jp/jp_prefectures.py:27
msgid "Mie"
-msgstr ""
+msgstr "Mie"
#: contrib/localflavor/jp/jp_prefectures.py:28
msgid "Shiga"
-msgstr ""
+msgstr "Shiga"
#: contrib/localflavor/jp/jp_prefectures.py:29
msgid "Kyoto"
-msgstr ""
+msgstr "Kyoto"
#: contrib/localflavor/jp/jp_prefectures.py:30
msgid "Osaka"
-msgstr ""
+msgstr "Osaka"
#: contrib/localflavor/jp/jp_prefectures.py:31
msgid "Hyogo"
-msgstr ""
+msgstr "Hyogo"
#: contrib/localflavor/jp/jp_prefectures.py:32
msgid "Nara"
-msgstr ""
+msgstr "Nara"
#: contrib/localflavor/jp/jp_prefectures.py:33
msgid "Wakayama"
-msgstr ""
+msgstr "Wakayama"
#: contrib/localflavor/jp/jp_prefectures.py:34
msgid "Tottori"
-msgstr ""
+msgstr "Tottori"
#: contrib/localflavor/jp/jp_prefectures.py:35
msgid "Shimane"
-msgstr ""
+msgstr "Shimane"
#: contrib/localflavor/jp/jp_prefectures.py:36
msgid "Okayama"
-msgstr ""
+msgstr "Okayama"
#: contrib/localflavor/jp/jp_prefectures.py:37
msgid "Hiroshima"
-msgstr ""
+msgstr "Hiroshima"
#: contrib/localflavor/jp/jp_prefectures.py:38
msgid "Yamaguchi"
-msgstr ""
+msgstr "Yamaguchi"
#: contrib/localflavor/jp/jp_prefectures.py:39
msgid "Tokushima"
-msgstr ""
+msgstr "Tokushima"
#: contrib/localflavor/jp/jp_prefectures.py:40
msgid "Kagawa"
-msgstr ""
+msgstr "Kagawa"
#: contrib/localflavor/jp/jp_prefectures.py:41
msgid "Ehime"
-msgstr ""
+msgstr "Ehime"
#: contrib/localflavor/jp/jp_prefectures.py:42
msgid "Kochi"
-msgstr ""
+msgstr "Kochi"
#: contrib/localflavor/jp/jp_prefectures.py:43
msgid "Fukuoka"
-msgstr ""
+msgstr "Fukuoka"
#: contrib/localflavor/jp/jp_prefectures.py:44
msgid "Saga"
-msgstr ""
+msgstr "Saga"
#: contrib/localflavor/jp/jp_prefectures.py:45
msgid "Nagasaki"
-msgstr ""
+msgstr "Nagasaki"
#: contrib/localflavor/jp/jp_prefectures.py:46
msgid "Kumamoto"
-msgstr ""
+msgstr "Kumamoto"
#: contrib/localflavor/jp/jp_prefectures.py:47
msgid "Oita"
-msgstr ""
+msgstr "Oita"
#: contrib/localflavor/jp/jp_prefectures.py:48
msgid "Miyazaki"
-msgstr ""
+msgstr "Miyazaki"
#: contrib/localflavor/jp/jp_prefectures.py:49
msgid "Kagoshima"
-msgstr ""
+msgstr "Kagoshima"
#: contrib/localflavor/jp/jp_prefectures.py:50
msgid "Okinawa"
-msgstr ""
+msgstr "Okinawa"
#: contrib/localflavor/mx/mx_states.py:12
msgid "Aguascalientes"
-msgstr ""
+msgstr "Aguascalientes"
#: contrib/localflavor/mx/mx_states.py:13
msgid "Baja California"
-msgstr ""
+msgstr "Baja California"
#: contrib/localflavor/mx/mx_states.py:14
msgid "Baja California Sur"
-msgstr ""
+msgstr "Baja California Sur"
#: contrib/localflavor/mx/mx_states.py:15
msgid "Campeche"
-msgstr ""
+msgstr "Campeche"
#: contrib/localflavor/mx/mx_states.py:16
msgid "Chihuahua"
-msgstr ""
+msgstr "Chihuahua"
#: contrib/localflavor/mx/mx_states.py:17
msgid "Chiapas"
-msgstr ""
+msgstr "Chiapas"
#: contrib/localflavor/mx/mx_states.py:18
msgid "Coahuila"
-msgstr ""
+msgstr "Coahuila"
#: contrib/localflavor/mx/mx_states.py:19
msgid "Colima"
-msgstr ""
+msgstr "Colima"
#: contrib/localflavor/mx/mx_states.py:20
msgid "Distrito Federal"
-msgstr ""
+msgstr "Distrito Federal"
#: contrib/localflavor/mx/mx_states.py:21
msgid "Durango"
-msgstr ""
+msgstr "Durango"
#: contrib/localflavor/mx/mx_states.py:22
msgid "Guerrero"
-msgstr ""
+msgstr "Guerrero"
#: contrib/localflavor/mx/mx_states.py:23
msgid "Guanajuato"
-msgstr ""
+msgstr "Guanajuato"
#: contrib/localflavor/mx/mx_states.py:24
msgid "Hidalgo"
-msgstr ""
+msgstr "Hidalgo"
#: contrib/localflavor/mx/mx_states.py:25
msgid "Jalisco"
-msgstr ""
+msgstr "Jalisco"
#: contrib/localflavor/mx/mx_states.py:26
-msgid "Estado de México"
-msgstr ""
+msgid "Estado de México"
+msgstr "de Staat Mexico"
#: contrib/localflavor/mx/mx_states.py:27
-msgid "Michoacán"
-msgstr ""
+msgid "Michoacán"
+msgstr "Michoacán"
#: contrib/localflavor/mx/mx_states.py:28
msgid "Morelos"
-msgstr ""
+msgstr "Morelos"
#: contrib/localflavor/mx/mx_states.py:29
msgid "Nayarit"
-msgstr ""
+msgstr "Nayarit"
#: contrib/localflavor/mx/mx_states.py:30
-msgid "Nuevo León"
-msgstr ""
+msgid "Nuevo León"
+msgstr "Nuevo León"
#: contrib/localflavor/mx/mx_states.py:31
msgid "Oaxaca"
-msgstr ""
+msgstr "Oaxaca"
#: contrib/localflavor/mx/mx_states.py:32
msgid "Puebla"
-msgstr ""
+msgstr "Puebla"
#: contrib/localflavor/mx/mx_states.py:33
-msgid "Querétaro"
-msgstr ""
+msgid "Querétaro"
+msgstr "Querétaro"
#: contrib/localflavor/mx/mx_states.py:34
msgid "Quintana Roo"
-msgstr ""
+msgstr "Quintana Roo"
#: contrib/localflavor/mx/mx_states.py:35
msgid "Sinaloa"
-msgstr ""
+msgstr "Sinaloa"
#: contrib/localflavor/mx/mx_states.py:36
-msgid "San Luis Potosí"
-msgstr ""
+msgid "San Luis Potosí"
+msgstr "San Luis Potosí"
#: contrib/localflavor/mx/mx_states.py:37
msgid "Sonora"
-msgstr ""
+msgstr "Sonora"
#: contrib/localflavor/mx/mx_states.py:38
msgid "Tabasco"
-msgstr ""
+msgstr "Tabasco"
#: contrib/localflavor/mx/mx_states.py:39
msgid "Tamaulipas"
-msgstr ""
+msgstr "Tamaulipas"
#: contrib/localflavor/mx/mx_states.py:40
msgid "Tlaxcala"
-msgstr ""
+msgstr "Tlaxcala"
#: contrib/localflavor/mx/mx_states.py:41
msgid "Veracruz"
-msgstr ""
+msgstr "Veracruz"
#: contrib/localflavor/mx/mx_states.py:42
-msgid "Yucatán"
-msgstr ""
+msgid "Yucatán"
+msgstr "Yucatán"
#: contrib/localflavor/mx/mx_states.py:43
msgid "Zacatecas"
-msgstr ""
+msgstr "Zacatecas"
-#: contrib/localflavor/nl/forms.py:21
+#: contrib/localflavor/nl/forms.py:22
msgid "Enter a valid postal code"
-msgstr "Geef een geldige postcode"
+msgstr "Geef een geldige postcode op"
-#: contrib/localflavor/nl/forms.py:52
+#: contrib/localflavor/nl/forms.py:53
msgid "Enter a valid phone number"
-msgstr "Geef een geldig telefoonnummer"
+msgstr "Geef een geldig telefoonnummer op"
-#: contrib/localflavor/nl/forms.py:78
+#: contrib/localflavor/nl/forms.py:79
msgid "Enter a valid SoFi number"
msgstr "Geef een geldig SoFi nummer"
+#: contrib/localflavor/nl/forms.py:115
+msgid "Enter a valid Dutch bank account number"
+msgstr "Geef een geldig Nederlands bankrekeningnummer op"
+
#: contrib/localflavor/nl/nl_provinces.py:4
msgid "Drente"
-msgstr ""
+msgstr "Drente"
#: contrib/localflavor/nl/nl_provinces.py:5
msgid "Flevoland"
-msgstr ""
+msgstr "Flevoland"
#: contrib/localflavor/nl/nl_provinces.py:6
msgid "Friesland"
-msgstr ""
+msgstr "Friesland"
#: contrib/localflavor/nl/nl_provinces.py:7
msgid "Gelderland"
-msgstr ""
+msgstr "Gelderland"
#: contrib/localflavor/nl/nl_provinces.py:8
msgid "Groningen"
-msgstr ""
+msgstr "Groningen"
#: contrib/localflavor/nl/nl_provinces.py:9
msgid "Limburg"
-msgstr ""
+msgstr "Limburg"
#: contrib/localflavor/nl/nl_provinces.py:10
msgid "Noord-Brabant"
-msgstr ""
+msgstr "Noord-Brabant"
#: contrib/localflavor/nl/nl_provinces.py:11
msgid "Noord-Holland"
-msgstr ""
+msgstr "Noord-Holland"
#: contrib/localflavor/nl/nl_provinces.py:12
msgid "Overijssel"
-msgstr ""
+msgstr "Overijssel"
#: contrib/localflavor/nl/nl_provinces.py:13
msgid "Utrecht"
-msgstr ""
+msgstr "Utrecht"
#: contrib/localflavor/nl/nl_provinces.py:14
msgid "Zeeland"
-msgstr ""
+msgstr "Zeeland"
#: contrib/localflavor/nl/nl_provinces.py:15
msgid "Zuid-Holland"
-msgstr ""
+msgstr "Zuid-Holland"
#: contrib/localflavor/no/forms.py:33
msgid "Enter a valid Norwegian social security number."
-msgstr ""
+msgstr "Geef een geldig Noors Sociaal Nummer op."
#: contrib/localflavor/pe/forms.py:24
msgid "This field requires 8 digits."
-msgstr ""
+msgstr "Dit veld vereist 8 cijfers."
#: contrib/localflavor/pe/forms.py:52
msgid "This field requires 11 digits."
-msgstr ""
+msgstr "Dit veld vereist 11 cijfers."
#: contrib/localflavor/pl/forms.py:39
msgid "National Identification Number consists of 11 digits."
-msgstr ""
+msgstr "Het Nationaal Identificatie Nummer bestaat uit 11 cijfers."
#: contrib/localflavor/pl/forms.py:40
msgid "Wrong checksum for the National Identification Number."
-msgstr ""
+msgstr "Verkeerd controlecijfer voor het Nationaal Identificatie Nummer."
#: contrib/localflavor/pl/forms.py:72
-msgid "Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
+msgid ""
+"Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
msgstr ""
+"Geef een fiscaal nummer (NIP) op volgens het formaat XXX-XXX-XX-XX or XX-XX-"
+"XXX-XXX."
#: contrib/localflavor/pl/forms.py:73
msgid "Wrong checksum for the Tax Number (NIP)."
-msgstr ""
+msgstr "Verkeerd controlecijfer voor het fiscaal nummer (NIP)."
#: contrib/localflavor/pl/forms.py:112
msgid "National Business Register Number (REGON) consists of 7 or 9 digits."
msgstr ""
+"Het Nationaal Zakelijk Registratie Nummer (REGON) bestaat uit 7 of 9 cijfers."
#: contrib/localflavor/pl/forms.py:113
msgid "Wrong checksum for the National Business Register Number (REGON)."
msgstr ""
+"Verkeerd controlecijfer op het Nationaal Zakelijk Registratie Nummer (REGON)."
#: contrib/localflavor/pl/forms.py:156
msgid "Enter a postal code in the format XX-XXX."
-msgstr ""
+msgstr "Geef een postcode op in het formaat XX-XXX."
#: contrib/localflavor/pl/pl_voivodeships.py:8
msgid "Lower Silesia"
-msgstr ""
+msgstr "Neder-Silezië"
#: contrib/localflavor/pl/pl_voivodeships.py:9
msgid "Kuyavia-Pomerania"
-msgstr ""
+msgstr "Kuyavia-Pomerania"
#: contrib/localflavor/pl/pl_voivodeships.py:10
msgid "Lublin"
-msgstr ""
+msgstr "Lublin"
#: contrib/localflavor/pl/pl_voivodeships.py:11
msgid "Lubusz"
-msgstr ""
+msgstr "Lubusz"
#: contrib/localflavor/pl/pl_voivodeships.py:12
msgid "Lodz"
-msgstr ""
+msgstr "Lodz"
#: contrib/localflavor/pl/pl_voivodeships.py:13
msgid "Lesser Poland"
-msgstr ""
+msgstr "Klein-Polen"
#: contrib/localflavor/pl/pl_voivodeships.py:14
msgid "Masovia"
-msgstr ""
+msgstr "Masovia"
#: contrib/localflavor/pl/pl_voivodeships.py:15
msgid "Opole"
-msgstr ""
+msgstr "Opole"
#: contrib/localflavor/pl/pl_voivodeships.py:16
msgid "Subcarpatia"
-msgstr ""
+msgstr "Subcarpatia"
#: contrib/localflavor/pl/pl_voivodeships.py:17
msgid "Podlasie"
-msgstr ""
+msgstr "Podlasie"
#: contrib/localflavor/pl/pl_voivodeships.py:18
msgid "Pomerania"
-msgstr ""
+msgstr "Pomerania"
#: contrib/localflavor/pl/pl_voivodeships.py:19
msgid "Silesia"
-msgstr ""
+msgstr "Silesia"
#: contrib/localflavor/pl/pl_voivodeships.py:20
msgid "Swietokrzyskie"
-msgstr ""
+msgstr "Swietokrzyskie"
#: contrib/localflavor/pl/pl_voivodeships.py:21
msgid "Warmia-Masuria"
-msgstr ""
+msgstr "Warmia-Masuria"
#: contrib/localflavor/pl/pl_voivodeships.py:22
msgid "Greater Poland"
-msgstr ""
+msgstr "Groot-Polen"
#: contrib/localflavor/pl/pl_voivodeships.py:23
msgid "West Pomerania"
+msgstr "West Pomerania"
+
+#: contrib/localflavor/ro/forms.py:19
+msgid "Enter a valid CIF."
+msgstr "Geef een geldige CIF op."
+
+#: contrib/localflavor/ro/forms.py:56
+msgid "Enter a valid CNP."
+msgstr "Geef een geldige CNP op."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
msgstr ""
+"Geef een geldige IBAN volgens het ROXX-XXXX-XXXX-XXXX-XXXX-XXXX formaat"
+
+#: contrib/localflavor/ro/forms.py:171
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Telefoonnummers moeten volgens het XXXX-XXXXXX formaat te zijn."
+
+#: contrib/localflavor/ro/forms.py:194
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Geef een geldige postcode in het formaat XXXXXX"
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
-msgstr ""
+msgstr "Geef een postcode op in het formaat XXXXX of XXX XX."
#: contrib/localflavor/sk/sk_districts.py:8
msgid "Banska Bystrica"
-msgstr ""
+msgstr "Banska Bystrica"
#: contrib/localflavor/sk/sk_districts.py:9
msgid "Banska Stiavnica"
-msgstr ""
+msgstr "Banska Stiavnica"
#: contrib/localflavor/sk/sk_districts.py:10
msgid "Bardejov"
-msgstr ""
+msgstr "Bardejov"
#: contrib/localflavor/sk/sk_districts.py:11
msgid "Banovce nad Bebravou"
-msgstr ""
+msgstr "Banovce nad Bebravou"
#: contrib/localflavor/sk/sk_districts.py:12
msgid "Brezno"
-msgstr ""
+msgstr "Brezno"
#: contrib/localflavor/sk/sk_districts.py:13
msgid "Bratislava I"
-msgstr ""
+msgstr "Bratislava I"
#: contrib/localflavor/sk/sk_districts.py:14
msgid "Bratislava II"
-msgstr ""
+msgstr "Bratislava II"
#: contrib/localflavor/sk/sk_districts.py:15
msgid "Bratislava III"
-msgstr ""
+msgstr "Bratislava III"
#: contrib/localflavor/sk/sk_districts.py:16
msgid "Bratislava IV"
-msgstr ""
+msgstr "Bratislava IV"
#: contrib/localflavor/sk/sk_districts.py:17
msgid "Bratislava V"
-msgstr ""
+msgstr "Bratislava V"
#: contrib/localflavor/sk/sk_districts.py:18
msgid "Bytca"
-msgstr ""
+msgstr "Bytca"
#: contrib/localflavor/sk/sk_districts.py:19
msgid "Cadca"
-msgstr ""
+msgstr "Cadca"
#: contrib/localflavor/sk/sk_districts.py:20
msgid "Detva"
-msgstr ""
+msgstr "Detva"
#: contrib/localflavor/sk/sk_districts.py:21
msgid "Dolny Kubin"
-msgstr ""
+msgstr "Dolny Kubin"
#: contrib/localflavor/sk/sk_districts.py:22
msgid "Dunajska Streda"
-msgstr ""
+msgstr "Dunajska Streda"
#: contrib/localflavor/sk/sk_districts.py:23
msgid "Galanta"
-msgstr ""
+msgstr "Galanta"
#: contrib/localflavor/sk/sk_districts.py:24
msgid "Gelnica"
-msgstr ""
+msgstr "Gelnica"
#: contrib/localflavor/sk/sk_districts.py:25
msgid "Hlohovec"
-msgstr ""
+msgstr "Hlohovec"
#: contrib/localflavor/sk/sk_districts.py:26
msgid "Humenne"
-msgstr ""
+msgstr "Humenne"
#: contrib/localflavor/sk/sk_districts.py:27
msgid "Ilava"
-msgstr ""
+msgstr "Ilava"
#: contrib/localflavor/sk/sk_districts.py:28
msgid "Kezmarok"
-msgstr ""
+msgstr "Kezmarok"
#: contrib/localflavor/sk/sk_districts.py:29
msgid "Komarno"
-msgstr ""
+msgstr "Komarno"
#: contrib/localflavor/sk/sk_districts.py:30
msgid "Kosice I"
-msgstr ""
+msgstr "Kosice I"
#: contrib/localflavor/sk/sk_districts.py:31
msgid "Kosice II"
-msgstr ""
+msgstr "Kosice II"
#: contrib/localflavor/sk/sk_districts.py:32
msgid "Kosice III"
-msgstr ""
+msgstr "Kosice III"
#: contrib/localflavor/sk/sk_districts.py:33
msgid "Kosice IV"
-msgstr ""
+msgstr "Kosice IV"
#: contrib/localflavor/sk/sk_districts.py:34
msgid "Kosice - okolie"
-msgstr ""
+msgstr "Kosice - okolie"
#: contrib/localflavor/sk/sk_districts.py:35
msgid "Krupina"
-msgstr ""
+msgstr "Krupina"
#: contrib/localflavor/sk/sk_districts.py:36
msgid "Kysucke Nove Mesto"
-msgstr ""
+msgstr "Kysucke Nove Mesto"
#: contrib/localflavor/sk/sk_districts.py:37
msgid "Levice"
-msgstr ""
+msgstr "Levice"
#: contrib/localflavor/sk/sk_districts.py:38
msgid "Levoca"
-msgstr ""
+msgstr "Levoca"
#: contrib/localflavor/sk/sk_districts.py:39
msgid "Liptovsky Mikulas"
-msgstr ""
+msgstr "Liptovsky Mikulas"
#: contrib/localflavor/sk/sk_districts.py:40
msgid "Lucenec"
-msgstr ""
+msgstr "Lucenec"
#: contrib/localflavor/sk/sk_districts.py:41
msgid "Malacky"
-msgstr ""
+msgstr "Malacky"
#: contrib/localflavor/sk/sk_districts.py:42
msgid "Martin"
-msgstr ""
+msgstr "Martin"
#: contrib/localflavor/sk/sk_districts.py:43
msgid "Medzilaborce"
-msgstr ""
+msgstr "Medzilaborce"
#: contrib/localflavor/sk/sk_districts.py:44
msgid "Michalovce"
-msgstr ""
+msgstr "Michalovce"
#: contrib/localflavor/sk/sk_districts.py:45
msgid "Myjava"
-msgstr ""
+msgstr "Myjava"
#: contrib/localflavor/sk/sk_districts.py:46
msgid "Namestovo"
-msgstr ""
+msgstr "Namestovo"
#: contrib/localflavor/sk/sk_districts.py:47
msgid "Nitra"
-msgstr ""
+msgstr "Nitra"
#: contrib/localflavor/sk/sk_districts.py:48
msgid "Nove Mesto nad Vahom"
-msgstr ""
+msgstr "Nove Mesto nad Vahom"
#: contrib/localflavor/sk/sk_districts.py:49
msgid "Nove Zamky"
-msgstr ""
+msgstr "Nove Zamky"
#: contrib/localflavor/sk/sk_districts.py:50
msgid "Partizanske"
-msgstr ""
+msgstr "Partizanske"
#: contrib/localflavor/sk/sk_districts.py:51
msgid "Pezinok"
-msgstr ""
+msgstr "Pezinok"
#: contrib/localflavor/sk/sk_districts.py:52
msgid "Piestany"
-msgstr ""
+msgstr "Piestany"
#: contrib/localflavor/sk/sk_districts.py:53
msgid "Poltar"
-msgstr ""
+msgstr "Poltar"
#: contrib/localflavor/sk/sk_districts.py:54
msgid "Poprad"
-msgstr ""
+msgstr "Poprad"
#: contrib/localflavor/sk/sk_districts.py:55
msgid "Povazska Bystrica"
-msgstr ""
+msgstr "Povazska Bystrica"
#: contrib/localflavor/sk/sk_districts.py:56
msgid "Presov"
-msgstr ""
+msgstr "Presov"
#: contrib/localflavor/sk/sk_districts.py:57
msgid "Prievidza"
-msgstr ""
+msgstr "Prievidza"
#: contrib/localflavor/sk/sk_districts.py:58
msgid "Puchov"
-msgstr ""
+msgstr "Puchov"
#: contrib/localflavor/sk/sk_districts.py:59
msgid "Revuca"
-msgstr ""
+msgstr "Revuca"
#: contrib/localflavor/sk/sk_districts.py:60
msgid "Rimavska Sobota"
-msgstr ""
+msgstr "Rimavska Sobota"
#: contrib/localflavor/sk/sk_districts.py:61
msgid "Roznava"
-msgstr ""
+msgstr "Roznava"
#: contrib/localflavor/sk/sk_districts.py:62
msgid "Ruzomberok"
-msgstr ""
+msgstr "Ruzomberok"
#: contrib/localflavor/sk/sk_districts.py:63
msgid "Sabinov"
-msgstr ""
+msgstr "Sabinov"
#: contrib/localflavor/sk/sk_districts.py:64
msgid "Senec"
-msgstr ""
+msgstr "Senec"
#: contrib/localflavor/sk/sk_districts.py:65
msgid "Senica"
-msgstr ""
+msgstr "Senica"
#: contrib/localflavor/sk/sk_districts.py:66
msgid "Skalica"
-msgstr ""
+msgstr "Skalica"
#: contrib/localflavor/sk/sk_districts.py:67
msgid "Snina"
-msgstr ""
+msgstr "Snina"
#: contrib/localflavor/sk/sk_districts.py:68
msgid "Sobrance"
-msgstr ""
+msgstr "Sobrance"
#: contrib/localflavor/sk/sk_districts.py:69
msgid "Spisska Nova Ves"
-msgstr ""
+msgstr "Spisska Nova Ves"
#: contrib/localflavor/sk/sk_districts.py:70
msgid "Stara Lubovna"
-msgstr ""
+msgstr "Stara Lubovna"
#: contrib/localflavor/sk/sk_districts.py:71
msgid "Stropkov"
-msgstr ""
+msgstr "Stropkov"
#: contrib/localflavor/sk/sk_districts.py:72
msgid "Svidnik"
-msgstr ""
+msgstr "Svidnik"
#: contrib/localflavor/sk/sk_districts.py:73
msgid "Sala"
-msgstr ""
+msgstr "Sala"
#: contrib/localflavor/sk/sk_districts.py:74
msgid "Topolcany"
-msgstr ""
+msgstr "Topolcany"
#: contrib/localflavor/sk/sk_districts.py:75
msgid "Trebisov"
-msgstr ""
+msgstr "Trebisov"
#: contrib/localflavor/sk/sk_districts.py:76
msgid "Trencin"
-msgstr ""
+msgstr "Trencin"
#: contrib/localflavor/sk/sk_districts.py:77
msgid "Trnava"
-msgstr ""
+msgstr "Trnava"
#: contrib/localflavor/sk/sk_districts.py:78
msgid "Turcianske Teplice"
-msgstr ""
+msgstr "Turcianske Teplice"
#: contrib/localflavor/sk/sk_districts.py:79
msgid "Tvrdosin"
-msgstr ""
+msgstr "Tvrdosin"
#: contrib/localflavor/sk/sk_districts.py:80
msgid "Velky Krtis"
-msgstr ""
+msgstr "Velky Krtis"
#: contrib/localflavor/sk/sk_districts.py:81
msgid "Vranov nad Toplou"
-msgstr ""
+msgstr "Vranov nad Toplou"
#: contrib/localflavor/sk/sk_districts.py:82
msgid "Zlate Moravce"
-msgstr ""
+msgstr "Zlate Moravce"
#: contrib/localflavor/sk/sk_districts.py:83
msgid "Zvolen"
-msgstr ""
+msgstr "Zvolen"
#: contrib/localflavor/sk/sk_districts.py:84
msgid "Zarnovica"
-msgstr ""
+msgstr "Zarnovica"
#: contrib/localflavor/sk/sk_districts.py:85
msgid "Ziar nad Hronom"
-msgstr ""
+msgstr "Ziar nad Hronom"
#: contrib/localflavor/sk/sk_districts.py:86
msgid "Zilina"
-msgstr ""
+msgstr "Zilina"
#: contrib/localflavor/sk/sk_regions.py:8
msgid "Banska Bystrica region"
-msgstr ""
+msgstr "Regio Banská Bystrica"
#: contrib/localflavor/sk/sk_regions.py:9
msgid "Bratislava region"
-msgstr ""
+msgstr "Regio Bratislava"
#: contrib/localflavor/sk/sk_regions.py:10
msgid "Kosice region"
-msgstr ""
+msgstr "Regio Košice"
#: contrib/localflavor/sk/sk_regions.py:11
msgid "Nitra region"
-msgstr ""
+msgstr "Regio Nitra"
#: contrib/localflavor/sk/sk_regions.py:12
msgid "Presov region"
-msgstr ""
+msgstr "Regio Prešov"
#: contrib/localflavor/sk/sk_regions.py:13
msgid "Trencin region"
-msgstr ""
+msgstr "Regio TrenÄín"
#: contrib/localflavor/sk/sk_regions.py:14
msgid "Trnava region"
-msgstr ""
+msgstr "Regio Trnava"
#: contrib/localflavor/sk/sk_regions.py:15
msgid "Zilina region"
-msgstr ""
+msgstr "Regio Žilina"
#: contrib/localflavor/uk/forms.py:21
msgid "Enter a valid postcode."
-msgstr ""
+msgstr "Geef een geldige postcode op."
#: contrib/localflavor/uk/uk_regions.py:11
msgid "Bedfordshire"
-msgstr ""
+msgstr "Bedfordshire"
#: contrib/localflavor/uk/uk_regions.py:12
msgid "Buckinghamshire"
-msgstr ""
+msgstr "Buckinghamshire"
#: contrib/localflavor/uk/uk_regions.py:14
msgid "Cheshire"
-msgstr ""
+msgstr "Cheshire"
#: contrib/localflavor/uk/uk_regions.py:15
msgid "Cornwall and Isles of Scilly"
-msgstr ""
+msgstr "Cornwall en de Scilly-Eilanden"
#: contrib/localflavor/uk/uk_regions.py:16
msgid "Cumbria"
-msgstr ""
+msgstr "Cumbria"
#: contrib/localflavor/uk/uk_regions.py:17
msgid "Derbyshire"
-msgstr ""
+msgstr "Derbyshire"
#: contrib/localflavor/uk/uk_regions.py:18
msgid "Devon"
-msgstr ""
+msgstr "Devon"
#: contrib/localflavor/uk/uk_regions.py:19
msgid "Dorset"
-msgstr ""
+msgstr "Dorset"
#: contrib/localflavor/uk/uk_regions.py:20
msgid "Durham"
-msgstr ""
+msgstr "Durham"
#: contrib/localflavor/uk/uk_regions.py:21
msgid "East Sussex"
-msgstr ""
+msgstr "Oost-Sussex"
#: contrib/localflavor/uk/uk_regions.py:22
msgid "Essex"
-msgstr ""
+msgstr "Essex"
#: contrib/localflavor/uk/uk_regions.py:23
msgid "Gloucestershire"
-msgstr ""
+msgstr "Gloucestershire"
#: contrib/localflavor/uk/uk_regions.py:24
msgid "Greater London"
-msgstr ""
+msgstr "Groot-Londen"
#: contrib/localflavor/uk/uk_regions.py:25
msgid "Greater Manchester"
-msgstr ""
+msgstr "Groot-Manchester"
#: contrib/localflavor/uk/uk_regions.py:26
msgid "Hampshire"
-msgstr ""
+msgstr "Hampshire"
#: contrib/localflavor/uk/uk_regions.py:27
msgid "Hertfordshire"
-msgstr ""
+msgstr "Hertfordshire"
#: contrib/localflavor/uk/uk_regions.py:28
msgid "Kent"
-msgstr ""
+msgstr "Kent"
#: contrib/localflavor/uk/uk_regions.py:29
msgid "Lancashire"
-msgstr ""
+msgstr "Lancashire"
#: contrib/localflavor/uk/uk_regions.py:30
msgid "Leicestershire"
-msgstr ""
+msgstr "Leicestershire"
#: contrib/localflavor/uk/uk_regions.py:31
msgid "Lincolnshire"
-msgstr ""
+msgstr "Lincolnshire"
#: contrib/localflavor/uk/uk_regions.py:32
msgid "Merseyside"
-msgstr ""
+msgstr "Merseyside"
#: contrib/localflavor/uk/uk_regions.py:33
msgid "Norfolk"
-msgstr ""
+msgstr "Norfolk"
#: contrib/localflavor/uk/uk_regions.py:34
msgid "North Yorkshire"
-msgstr ""
+msgstr "Noord-Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:35
msgid "Northamptonshire"
-msgstr ""
+msgstr "Northamptonshire"
#: contrib/localflavor/uk/uk_regions.py:36
msgid "Northumberland"
-msgstr ""
+msgstr "Northumberland"
#: contrib/localflavor/uk/uk_regions.py:37
msgid "Nottinghamshire"
-msgstr ""
+msgstr "Nottinghamshire"
#: contrib/localflavor/uk/uk_regions.py:38
msgid "Oxfordshire"
-msgstr ""
+msgstr "Oxfordshire"
#: contrib/localflavor/uk/uk_regions.py:39
msgid "Shropshire"
-msgstr ""
+msgstr "Shropshire"
#: contrib/localflavor/uk/uk_regions.py:40
msgid "Somerset"
-msgstr ""
+msgstr "Somerset"
#: contrib/localflavor/uk/uk_regions.py:41
msgid "South Yorkshire"
-msgstr ""
+msgstr "Zuid-Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:42
msgid "Staffordshire"
-msgstr ""
+msgstr "Staffordshire"
#: contrib/localflavor/uk/uk_regions.py:43
msgid "Suffolk"
-msgstr ""
+msgstr "Suffolk"
#: contrib/localflavor/uk/uk_regions.py:44
msgid "Surrey"
-msgstr ""
+msgstr "Surrey"
#: contrib/localflavor/uk/uk_regions.py:45
msgid "Tyne and Wear"
-msgstr ""
+msgstr "Tyne and Wear"
#: contrib/localflavor/uk/uk_regions.py:46
msgid "Warwickshire"
-msgstr ""
+msgstr "Warwickshire"
#: contrib/localflavor/uk/uk_regions.py:47
msgid "West Midlands"
-msgstr ""
+msgstr "West-Midlands"
#: contrib/localflavor/uk/uk_regions.py:48
msgid "West Sussex"
-msgstr ""
+msgstr "West-Sussex"
#: contrib/localflavor/uk/uk_regions.py:49
msgid "West Yorkshire"
-msgstr ""
+msgstr "West-Yorkshire"
#: contrib/localflavor/uk/uk_regions.py:50
msgid "Wiltshire"
-msgstr ""
+msgstr "Wiltshire"
#: contrib/localflavor/uk/uk_regions.py:51
msgid "Worcestershire"
-msgstr ""
+msgstr "Worcestershire"
#: contrib/localflavor/uk/uk_regions.py:55
msgid "County Antrim"
-msgstr ""
+msgstr "Graafschap Antrim"
#: contrib/localflavor/uk/uk_regions.py:56
msgid "County Armagh"
-msgstr ""
+msgstr "Graafschap Armagh"
#: contrib/localflavor/uk/uk_regions.py:57
msgid "County Down"
-msgstr ""
+msgstr "Graafschap Down"
#: contrib/localflavor/uk/uk_regions.py:58
msgid "County Fermanagh"
-msgstr ""
+msgstr "Graafschap Fermanagh"
#: contrib/localflavor/uk/uk_regions.py:59
msgid "County Londonderry"
-msgstr ""
+msgstr "Graafschap Londonderry"
#: contrib/localflavor/uk/uk_regions.py:60
msgid "County Tyrone"
-msgstr ""
+msgstr "Graafschap Tyrone"
#: contrib/localflavor/uk/uk_regions.py:64
msgid "Clwyd"
-msgstr ""
+msgstr "Clwyd"
#: contrib/localflavor/uk/uk_regions.py:65
msgid "Dyfed"
-msgstr ""
+msgstr "Dyfed"
#: contrib/localflavor/uk/uk_regions.py:66
msgid "Gwent"
-msgstr ""
+msgstr "Gwent"
#: contrib/localflavor/uk/uk_regions.py:67
msgid "Gwynedd"
-msgstr ""
+msgstr "Gwynedd"
#: contrib/localflavor/uk/uk_regions.py:68
msgid "Mid Glamorgan"
-msgstr ""
+msgstr "Mid Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:69
msgid "Powys"
-msgstr ""
+msgstr "Powys"
#: contrib/localflavor/uk/uk_regions.py:70
msgid "South Glamorgan"
-msgstr ""
+msgstr "Zuid-Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:71
msgid "West Glamorgan"
-msgstr ""
+msgstr "West-Glamorgan"
#: contrib/localflavor/uk/uk_regions.py:75
msgid "Borders"
-msgstr ""
+msgstr "Schotse-Borders"
#: contrib/localflavor/uk/uk_regions.py:76
msgid "Central Scotland"
-msgstr ""
+msgstr "Centraal-Schotland"
#: contrib/localflavor/uk/uk_regions.py:77
msgid "Dumfries and Galloway"
-msgstr ""
+msgstr "Dumfries en Galloway"
#: contrib/localflavor/uk/uk_regions.py:78
msgid "Fife"
-msgstr ""
+msgstr "Fife"
#: contrib/localflavor/uk/uk_regions.py:79
msgid "Grampian"
-msgstr ""
+msgstr "Grampian"
#: contrib/localflavor/uk/uk_regions.py:80
msgid "Highland"
-msgstr ""
+msgstr "Highland"
#: contrib/localflavor/uk/uk_regions.py:81
msgid "Lothian"
-msgstr ""
+msgstr "Lothian"
#: contrib/localflavor/uk/uk_regions.py:82
msgid "Orkney Islands"
-msgstr ""
+msgstr "Orkneyeilanden"
#: contrib/localflavor/uk/uk_regions.py:83
msgid "Shetland Islands"
-msgstr ""
+msgstr "Shetlandeilanden"
#: contrib/localflavor/uk/uk_regions.py:84
msgid "Strathclyde"
-msgstr ""
+msgstr "Strathclyde"
#: contrib/localflavor/uk/uk_regions.py:85
msgid "Tayside"
-msgstr ""
+msgstr "Tayside"
#: contrib/localflavor/uk/uk_regions.py:86
msgid "Western Isles"
-msgstr ""
+msgstr "Buiten-Hebriden"
#: contrib/localflavor/uk/uk_regions.py:90
msgid "England"
-msgstr ""
+msgstr "Engeland"
#: contrib/localflavor/uk/uk_regions.py:91
msgid "Northern Ireland"
-msgstr ""
+msgstr "Noord-Ierland"
#: contrib/localflavor/uk/uk_regions.py:92
msgid "Scotland"
-msgstr ""
+msgstr "Schotland"
#: contrib/localflavor/uk/uk_regions.py:93
msgid "Wales"
-msgstr ""
+msgstr "Wales"
#: contrib/localflavor/us/forms.py:16
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
-msgstr ""
+msgstr "Geef een geldige postcode op volgens het XXXXX of XXXXX-XXXX formaat."
#: contrib/localflavor/us/forms.py:54
msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
-msgstr ""
+msgstr "Geef een geldig V.S. Sociaalnummer op in het XXX-XX-XXXX formaat."
#: contrib/localflavor/za/forms.py:20
msgid "Enter a valid South African ID number"
-msgstr ""
+msgstr "Geef een geldig Zuid-Afrikaans identificatienummer op"
#: contrib/localflavor/za/forms.py:54
msgid "Enter a valid South African postal code"
-msgstr ""
+msgstr "Geef een geldige Zuid-Afrikaanse postcode op"
#: contrib/localflavor/za/za_provinces.py:4
msgid "Eastern Cape"
-msgstr ""
+msgstr "Oost-Kaap"
#: contrib/localflavor/za/za_provinces.py:5
msgid "Free State"
-msgstr ""
+msgstr "Vrijstaat"
#: contrib/localflavor/za/za_provinces.py:6
msgid "Gauteng"
-msgstr ""
+msgstr "Gauteng"
#: contrib/localflavor/za/za_provinces.py:7
msgid "KwaZulu-Natal"
-msgstr ""
+msgstr "KwaZulu-Natal"
#: contrib/localflavor/za/za_provinces.py:8
msgid "Limpopo"
-msgstr ""
+msgstr "Limpopo"
#: contrib/localflavor/za/za_provinces.py:9
msgid "Mpumalanga"
-msgstr ""
+msgstr "Mpumalanga"
#: contrib/localflavor/za/za_provinces.py:10
msgid "Northern Cape"
-msgstr ""
+msgstr "Noord-Kaap"
#: contrib/localflavor/za/za_provinces.py:11
msgid "North West"
-msgstr ""
+msgstr "Noordwest"
#: contrib/localflavor/za/za_provinces.py:12
msgid "Western Cape"
-msgstr ""
+msgstr "West-Kaap"
#: contrib/redirects/models.py:7
msgid "redirect from"
msgstr "omgeleid via"
#: contrib/redirects/models.py:8
-msgid "This should be an absolute path, excluding the domain name. Example: '/events/search/'."
-msgstr "Dit moet een absoluut pad zijn, zonder de domein naam. Bijvoorbeeld: '/events/search/'."
+msgid ""
+"This should be an absolute path, excluding the domain name. Example: '/"
+"events/search/'."
+msgstr ""
+"Dit moet een absoluut pad zijn, zonder de domeinnaam. Bijvoorbeeld: '/events/"
+"search/'."
#: contrib/redirects/models.py:9
msgid "redirect to"
msgstr "omleiden naar"
#: contrib/redirects/models.py:10
-msgid "This can be either an absolute path (as above) or a full URL starting with 'http://'."
-msgstr "Dit kan een absoluut pad (zoals hierboven) zijn of een volledige URL beginnend met 'http://'."
+msgid ""
+"This can be either an absolute path (as above) or a full URL starting with "
+"'http://'."
+msgstr ""
+"Dit kan een absoluut pad (zoals hierboven) zijn of een volledige URL "
+"beginnend met 'http://'."
#: contrib/redirects/models.py:13
msgid "redirect"
@@ -3395,23 +3625,23 @@ msgstr "omleiding"
msgid "redirects"
msgstr "omleidingen"
-#: contrib/sessions/models.py:41
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "sessiesleutel"
-#: contrib/sessions/models.py:42
+#: contrib/sessions/models.py:47
msgid "session data"
msgstr "sessiegegevens"
-#: contrib/sessions/models.py:43
+#: contrib/sessions/models.py:48
msgid "expire date"
msgstr "verloopdatum"
-#: contrib/sessions/models.py:48
+#: contrib/sessions/models.py:53
msgid "session"
msgstr "sessie"
-#: contrib/sessions/models.py:49
+#: contrib/sessions/models.py:54
msgid "sessions"
msgstr "sessies"
@@ -3423,25 +3653,27 @@ msgstr "domeinnaam"
msgid "display name"
msgstr "weergavenaam"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "site"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "sites"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Deze waarde mag alleen letters, getallen en liggende strepen bevatten."
-
#: core/validators.py:76
-msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
-msgstr "Deze waarde mag alleen letters, cijfers, liggende strepen en schuine strepen bevatten."
+msgid ""
+"This value must contain only letters, numbers, underscores, dashes or "
+"slashes."
+msgstr ""
+"Deze waarde mag alleen letters, cijfers, liggende strepen en schuine strepen "
+"bevatten."
#: core/validators.py:80
msgid "This value must contain only letters, numbers, underscores or hyphens."
-msgstr "Deze waarde mag alleen letters, cijfers, liggende strepen en verbindingsstrepen bevatten."
+msgstr ""
+"Deze waarde mag alleen letters, cijfers, liggende strepen en "
+"verbindingsstrepen bevatten."
#: core/validators.py:84
msgid "Uppercase letters are not allowed here."
@@ -3461,7 +3693,7 @@ msgstr "Geef geldige e-mailadressen op, gescheiden door komma's."
#: core/validators.py:111
msgid "Please enter a valid IP address."
-msgstr "Geef een geldig IP adres op."
+msgstr "Geef een geldig IP-adres op."
#: core/validators.py:115
msgid "Empty values are not allowed here."
@@ -3475,8 +3707,7 @@ msgstr "Niet-numerieke karakters zijn hier niet toegestaan."
msgid "This value can't be comprised solely of digits."
msgstr "Deze waarde kan niet alleen uit cijfers bestaan."
-#: core/validators.py:128
-#: newforms/fields.py:151
+#: core/validators.py:128 forms/fields.py:158
msgid "Enter a whole number."
msgstr "Geef een geheel getal op."
@@ -3485,65 +3716,62 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Alleen alfabetische karakters zijn toegestaan"
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "Het jaartal moet 1900 of later zijn."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Ongeldige datum: %s"
-#: core/validators.py:156
-#: db/models/fields/__init__.py:522
+#: core/validators.py:152 db/models/fields/__init__.py:560
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Geef een geldige datum in JJJJ-MM-DD formaat."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Geef een geldige tijd in UU:MM formaat."
-#: core/validators.py:165
-#: db/models/fields/__init__.py:599
+#: core/validators.py:161 db/models/fields/__init__.py:641
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Geef geldige datum/tijd in JJJJ-MM-DD UU:MM formaat."
-#: core/validators.py:170
-#: newforms/fields.py:402
+#: core/validators.py:166 forms/fields.py:409
msgid "Enter a valid e-mail address."
msgstr "Geef een geldig e-mailadres op."
-#: core/validators.py:182
-#: core/validators.py:474
-#: newforms/fields.py:432
-#: oldforms/__init__.py:687
+#: core/validators.py:178 core/validators.py:470 forms/fields.py:427
msgid "No file was submitted. Check the encoding type on the form."
-msgstr "Er was geen bestand verstuurd. Controleer het coderings type van het formulier."
+msgstr ""
+"Er was geen bestand verstuurd. Controleer het coderingstype van het "
+"formulier."
-#: core/validators.py:193
-#: newforms/fields.py:458
-msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
-msgstr "Bestand ongeldig. Het bestand dat is gegeven is geen afbeelding of is beschadigd."
+#: core/validators.py:189 forms/fields.py:467
+msgid ""
+"Upload a valid image. The file you uploaded was either not an image or a "
+"corrupted image."
+msgstr ""
+"Bestand ongeldig. Het bestand dat is gegeven is geen afbeelding of is "
+"beschadigd."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "De URL %s wijst niet naar een geldige afbeelding."
-#: core/validators.py:204
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
-msgstr "Telefoonnummers moeten volgens het XXX-XXX-XXXX formaat zijn. \"%s\" is ongeldig."
+msgstr ""
+"Telefoonnummers moeten volgens het XXX-XXX-XXXX formaat zijn. \"%s\" is "
+"ongeldig."
-#: core/validators.py:212
+#: core/validators.py:208
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "De URL %s wijst niet naar een geldige QuickTime video."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Een geldige URL is vereist."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3552,208 +3780,240 @@ msgstr ""
"Geldige HTML is vereist. De specifieke fouten zijn:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "Foute XML: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "Ongeldige URL: %s"
-#: core/validators.py:259
-#: core/validators.py:261
+#: core/validators.py:255 core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "De URL %s is niet een werkende link."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Geef een geldige afkorting van een staat in de VS."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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] "Pas op uw taalgebruik! Gebruik van %s niet toegestaan."
-msgstr[1] "Pas op uw taalgebruik! Gebruik van de woorden %s is niet toegestaan."
+msgstr[1] ""
+"Pas op uw taalgebruik! Gebruik van de woorden %s is niet toegestaan."
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
-msgstr "Dit veld moet overeenkomen met het '%s' veld."
+msgstr "Dit veld moet overeenkomen met het '%s'-veld."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
-msgstr "Voer tenminste 1 veld in."
+msgstr "Voer tenminste één veld in."
-#: core/validators.py:316
-#: core/validators.py:327
+#: core/validators.py:312 core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Voer waarden in beide velden in of laat beide leeg."
-#: core/validators.py:335
+#: core/validators.py:331
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "Dit veld moet opgegeven worden indien %(field)s %(value)s is"
-#: core/validators.py:348
+#: core/validators.py:344
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr "Dit veld moet worden opgegeven indien %(field)s niet %(value)s is"
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Dubbele waarden zijn niet toegestaan."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "De waarde moet tussen %(lower)s en %(upper)s zijn."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "De waarde moet minimaal %s zijn."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "De waarde mag niet meer zijn dan %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "De waarde moet een macht van %s zijn."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Geef een geldig decimaal getal."
-#: core/validators.py:444
+#: core/validators.py:440
#, 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."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s total digits."
msgstr[0] "Geef een geldig decimaal getal met hooguit %s cijfer."
msgstr[1] "Geef een geldig decimaal getal met hooguit %s cijfers."
-#: core/validators.py:447
+#: core/validators.py:443
#, 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] "Geef een geldig decimaal getal waarbij het gehele getal minimaal %s cijfer heeft."
-msgstr[1] "Geef een geldig decimaal getal waarbij het gehele getal minimaal %s cijfers heeft."
+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] ""
+"Geef een geldig decimaal getal waarbij het gehele getal minimaal %s cijfer "
+"heeft."
+msgstr[1] ""
+"Geef een geldig decimaal getal waarbij het gehele getal minimaal %s cijfers "
+"heeft."
-#: core/validators.py:450
+#: core/validators.py:446
#, 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."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s decimal places."
msgstr[0] "Geef een decimaal getal met hooguit %s cijfer achter de komma."
msgstr[1] "Geef een decimaal getal met hooguit %s cijfers achter de komma."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Geef een geldig decimaal getal."
-#: core/validators.py:467
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "Zorg ervoor dat het bestand minstens %s bytes groot is."
-#: core/validators.py:468
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "Zorg ervoor dat het bestand hoogstens %s bytes groot is."
-#: core/validators.py:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Het formaat van dit veld is foutief."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Dit veld is ongeldig."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Kan niks ophalen van %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, python-format
-msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
-msgstr "De geretourneerde URL %(url)s bevat een ongeldige Content-Type '%(contenttype)s."
+msgid ""
+"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
+msgstr ""
+"De geretourneerde URL %(url)s bevat een ongeldige Content-Type '%"
+"(contenttype)s."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
-msgid "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with \"%(start)s\".)"
-msgstr "Sluit de niet gesloten %(tag)s tag op regel %(line)s. (Regel start met \"%(start)s\".)"
+msgid ""
+"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
+"\"%(start)s\".)"
+msgstr ""
+"Sluit de niet gesloten %(tag)s tag op regel %(line)s. (Regel start met \"%"
+"(start)s\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
-msgid "Some text starting on line %(line)s is not allowed in that context. (Line starts with \"%(start)s\".)"
-msgstr "Tekst beginnend op regel %(line)s is in deze context niet toegestaan. (Regel start met \"%(start)s\".)"
+msgid ""
+"Some text starting on line %(line)s is not allowed in that context. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Tekst beginnend op regel %(line)s is in deze context niet toegestaan. (Regel "
+"start met \"%(start)s\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
-msgid "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%(start)s\".)"
-msgstr "\"%(attr)s\" op regel %(line)s is een ongeldig attribuut. (Regel start met \"%(start)s\".)"
+msgid ""
+"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"%(attr)s\" op regel %(line)s is een ongeldig attribuut. (Regel start met "
+"\"%(start)s\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
-msgid "\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%(start)s\".)"
-msgstr "\"<%(tag)s>\" op regel %(line)s is een ongeldige tag. (Regel start met \"%(start)s\".)"
+msgid ""
+"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"<%(tag)s>\" op regel %(line)s is een ongeldige tag. (Regel start met \"%"
+"(start)s\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
-msgid "A tag on line %(line)s is missing one or more required attributes. (Line starts with \"%(start)s\".)"
-msgstr "Een of meerdere attributen ontbreken bij een tag op regel %(line)s. (Regel start met \"%(start)s\".)"
+msgid ""
+"A tag on line %(line)s is missing one or more required attributes. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Een of meerdere attributen ontbreken bij een tag op regel %(line)s. (Regel "
+"start met \"%(start)s\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
-msgid "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line starts with \"%(start)s\".)"
-msgstr "De \"%(attr)s\" attribuut op regel %(line)s heeft een ongeldige waarde. (Regel start met \"%(start)s\".)"
+msgid ""
+"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"De \"%(attr)s\" attribuut op regel %(line)s heeft een ongeldige waarde. "
+"(Regel start met \"%(start)s\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
-msgstr "%(object)s van het type %(type)s bestaat al voor het gegeven %(field)s."
+msgstr ""
+"%(object)s van het type %(type)s bestaat al voor het gegeven %(field)s."
-#: db/models/fields/__init__.py:52
+#: db/models/fields/__init__.py:47
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "%(optname)s met deze %(fieldname)s bestaat al."
-#: db/models/fields/__init__.py:161
-#: db/models/fields/__init__.py:322
-#: db/models/fields/__init__.py:754
-#: db/models/fields/__init__.py:765
-#: newforms/fields.py:45
-#: oldforms/__init__.py:374
+#: db/models/fields/__init__.py:175 db/models/fields/__init__.py:344
+#: db/models/fields/__init__.py:803 db/models/fields/__init__.py:814
+#: forms/fields.py:52 oldforms/__init__.py:374
msgid "This field is required."
msgstr "Dit veld is verplicht."
-#: db/models/fields/__init__.py:422
+#: db/models/fields/__init__.py:458
msgid "This value must be an integer."
msgstr "De waarde moet een geheel getal zijn."
-#: db/models/fields/__init__.py:461
+#: db/models/fields/__init__.py:499
msgid "This value must be either True or False."
msgstr "De waarde moet of True (Waar) of False (Onwaar) zijn."
-#: db/models/fields/__init__.py:485
+#: db/models/fields/__init__.py:523
msgid "This field cannot be null."
msgstr "Dit veld mag niet leeg zijn."
-#: db/models/fields/__init__.py:663
+#: db/models/fields/__init__.py:710
msgid "This value must be a decimal number."
msgstr "De waarde moet een getal zijn."
-#: db/models/fields/__init__.py:774
+#: db/models/fields/__init__.py:823
msgid "Enter a valid filename."
msgstr "Geef een geldige bestandsnaam."
-#: db/models/fields/__init__.py:945
+#: db/models/fields/__init__.py:1014
msgid "This value must be either None, True or False."
msgstr "De waarde moet of None (leeg), True (Waar) of False (Onwaar) zijn."
@@ -3762,121 +4022,114 @@ msgstr "De waarde moet of None (leeg), True (Waar) of False (Onwaar) zijn."
msgid "Please enter a valid %s."
msgstr "Geef een geldig %s veld."
-#: db/models/fields/related.py:694
-msgid "Separate multiple IDs with commas."
-msgstr "Scheid meerdere ID's door komma's."
-
-#: db/models/fields/related.py:696
-msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr "Houd \"Control\", of \"Command\" op een Mac, ingedrukt om meerdere te selecteren."
+#: db/models/fields/related.py:729
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr ""
+"Houd \"Control\", of \"Command\" op een Mac, ingedrukt om meerdere te "
+"selecteren."
-#: db/models/fields/related.py:743
+#: db/models/fields/related.py:773
#, 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."
+msgid_plural ""
+"Please enter valid %(self)s IDs. The values %(value)r are invalid."
msgstr[0] "Geef een geldig %(self)s IDs. De waarde %(value)r is ongeldig."
msgstr[1] "Geef een geldig %(self)s IDs. De waarden %(value)r zijn ongeldig."
-#: newforms/fields.py:46
+#: forms/fields.py:53
msgid "Enter a valid value."
msgstr "Geef een geldige waarde."
-#: newforms/fields.py:123
+#: forms/fields.py:130
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
-msgstr "Zorg ervoor de waarde korter is dan %(max)d tekens (huidige lengte %(length)d)."
+msgstr ""
+"Zorg ervoor dat waarde korter is dan %(max)d tekens (huidige lengte %(length)"
+"d)."
-#: newforms/fields.py:124
+#: forms/fields.py:131
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
-msgstr "Zorg ervoor dat uw tekst langer is dan %(min)d tekens (huidige lengte %(length)d)."
+msgstr ""
+"Zorg ervoor dat uw tekst langer is dan %(min)d tekens (huidige lengte %"
+"(length)d)."
-#: newforms/fields.py:152
-#: newforms/fields.py:181
-#: newforms/fields.py:210
+#: forms/fields.py:159 forms/fields.py:188 forms/fields.py:217
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Zorg ervoor dat de waarde kleiner of gelijk is aan %s."
-#: newforms/fields.py:153
-#: newforms/fields.py:182
-#: newforms/fields.py:211
+#: forms/fields.py:160 forms/fields.py:189 forms/fields.py:218
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Zorg ervoor de waarde groter of gelijk is aan %s."
-#: newforms/fields.py:180
-#: newforms/fields.py:209
+#: forms/fields.py:187 forms/fields.py:216
msgid "Enter a number."
msgstr "Geef een getal op."
-#: newforms/fields.py:212
+#: forms/fields.py:219
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "Zorg dat er minder dan %s cijfers zijn."
-#: newforms/fields.py:213
+#: forms/fields.py:220
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "Zorg dat er minder dan %s cijfers na de komma zijn."
-#: newforms/fields.py:214
+#: forms/fields.py:221
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Zorg dat er minder dan %s cijfers voor de komma zijn."
-#: newforms/fields.py:262
-#: newforms/fields.py:723
+#: forms/fields.py:269 forms/fields.py:799
msgid "Enter a valid date."
msgstr "Geef een geldige datum op."
-#: newforms/fields.py:295
-#: newforms/fields.py:724
+#: forms/fields.py:302 forms/fields.py:800
msgid "Enter a valid time."
-msgstr "Geef een geldige datum op."
+msgstr "Geef een geldige tijd op."
-#: newforms/fields.py:334
+#: forms/fields.py:341
msgid "Enter a valid date/time."
msgstr "Geef een geldige datum/tijd op."
-#: newforms/fields.py:433
+#: forms/fields.py:428
msgid "No file was submitted."
-msgstr "Geen file werd aangeboden."
+msgstr "Geen bestand werd aangeboden."
-#: newforms/fields.py:434
-#: oldforms/__init__.py:689
+#: forms/fields.py:429 oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "Het gegeven bestand is leeg."
-#: newforms/fields.py:496
+#: forms/fields.py:528
msgid "Enter a valid URL."
msgstr "Geef een geldige URL op."
-#: newforms/fields.py:497
+#: forms/fields.py:529
msgid "This URL appears to be a broken link."
-msgstr "Deze URL schijnt niet te werken."
+msgstr "Deze URL lijkt niet te werken."
-#: newforms/fields.py:559
-#: newforms/models.py:300
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Selecteer een geldige keuze. Deze keuze is niet beschikbaar."
-
-#: newforms/fields.py:598
+#: forms/fields.py:597 forms/fields.py:648
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "Selecteer een geldige keuze. %(value)s is geen beschikbare keuze."
-#: newforms/fields.py:599
-#: newforms/fields.py:661
-#: newforms/models.py:360
+#: forms/fields.py:649 forms/fields.py:710 forms/models.py:581
msgid "Enter a list of values."
msgstr "Geef een lijst op met waardes."
-#: newforms/fields.py:752
+#: forms/fields.py:828
msgid "Enter a valid IPv4 address."
-msgstr "Geef een geldig IPv4 adres op."
+msgstr "Geef een geldig IPv4-adres op."
+
+#: forms/models.py:514
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Selecteer een geldige keuze. Deze keuze is niet beschikbaar."
-#: newforms/models.py:361
+#: forms/models.py:582
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr "Selecteer een geldige keuze. %s is geen beschikbare keuze."
@@ -3892,66 +4145,64 @@ msgstr[1] "Zorg ervoor dat uw tekst korter is dan %s karakters."
msgid "Line breaks are not allowed here."
msgstr "Regeleindes zijn niet toegestaan."
-#: oldforms/__init__.py:512
-#: oldforms/__init__.py:586
-#: oldforms/__init__.py:625
+#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Selecteer een geldige keuze; '%(data)s is niet in %(choices)s."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Geef een geheel getal op tussen -32.768 en 32.767."
-#: oldforms/__init__.py:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Geef een geheel getal op."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Geef een geheel getal op tussen 0 en 32.767."
-#: template/defaultfilters.py:695
+#: template/defaultfilters.py:698
msgid "yes,no,maybe"
msgstr "ja,nee,misschien"
-#: template/defaultfilters.py:726
+#: template/defaultfilters.py:729
#, python-format
msgid "%(size)d byte"
msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%(size)d byte"
+msgstr[1] "%(size)d bytes"
-#: template/defaultfilters.py:728
+#: template/defaultfilters.py:731
#, python-format
msgid "%.1f KB"
-msgstr ""
+msgstr "%.1f KB"
-#: template/defaultfilters.py:730
+#: template/defaultfilters.py:733
#, python-format
msgid "%.1f MB"
-msgstr ""
+msgstr "%.1f MB"
-#: template/defaultfilters.py:731
+#: template/defaultfilters.py:734
#, python-format
msgid "%.1f GB"
-msgstr ""
+msgstr "%.1f GB"
#: utils/dateformat.py:41
msgid "p.m."
-msgstr ""
+msgstr "p.m."
#: utils/dateformat.py:42
msgid "a.m."
-msgstr ""
+msgstr "a.m."
#: utils/dateformat.py:47
msgid "PM"
-msgstr ""
+msgstr "PM"
#: utils/dateformat.py:48
msgid "AM"
-msgstr ""
+msgstr "AM"
#: utils/dateformat.py:97
msgid "midnight"
@@ -4025,28 +4276,23 @@ msgstr "januari"
msgid "February"
msgstr "februari"
-#: utils/dates.py:18
-#: utils/dates.py:31
+#: utils/dates.py:18 utils/dates.py:31
msgid "March"
msgstr "maart"
-#: utils/dates.py:18
-#: utils/dates.py:31
+#: utils/dates.py:18 utils/dates.py:31
msgid "April"
msgstr "april"
-#: utils/dates.py:18
-#: utils/dates.py:31
+#: utils/dates.py:18 utils/dates.py:31
msgid "May"
msgstr "mei"
-#: utils/dates.py:18
-#: utils/dates.py:31
+#: utils/dates.py:18 utils/dates.py:31
msgid "June"
msgstr "juni"
-#: utils/dates.py:19
-#: utils/dates.py:31
+#: utils/dates.py:19 utils/dates.py:31
msgid "July"
msgstr "juli"
@@ -4080,7 +4326,7 @@ msgstr "feb"
#: utils/dates.py:23
msgid "mar"
-msgstr "mar"
+msgstr "mrt"
#: utils/dates.py:23
msgid "apr"
@@ -4146,7 +4392,7 @@ msgstr "nov."
msgid "Dec."
msgstr "dec."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "of"
@@ -4195,48 +4441,44 @@ msgstr "minuut"
#: utils/timesince.py:51
#, python-format
msgid "%(number)d %(type)s"
-msgstr ""
+msgstr "%(number)d %(type)s"
#: utils/timesince.py:57
#, python-format
msgid ", %(number)d %(type)s"
-msgstr ""
+msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "j-n-Y"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "j-n-Y H:i"
-#: utils/translation/trans_real.py:406
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "H:i"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:423
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "j F"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "De %(verbose_name)s is succesvol aangemaakt."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "De %(verbose_name)s is succesvol aangepast."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "De %(verbose_name)s is verwijderd."
-
-#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
-#~ msgstr "Gebruik '[algo]$[salt]$[hexdigest]'"
-
diff --git a/django/conf/locale/no/LC_MESSAGES/django.mo b/django/conf/locale/no/LC_MESSAGES/django.mo
index 1009491ba6..9dd1ec2500 100644
--- a/django/conf/locale/no/LC_MESSAGES/django.mo
+++ b/django/conf/locale/no/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/no/LC_MESSAGES/django.po b/django/conf/locale/no/LC_MESSAGES/django.po
index 75f3d45188..573cb2ae05 100644
--- a/django/conf/locale/no/LC_MESSAGES/django.po
+++ b/django/conf/locale/no/LC_MESSAGES/django.po
@@ -7,1255 +7,1333 @@ msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-05-16 10:12+0200\n"
-"PO-Revision-Date: 2007-08-29 18:22+0200\n"
+"PO-Revision-Date: 2008-07-15 19:10+0200\n"
"Last-Translator: jonklo\n"
"Language-Team: Norsk <no@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: db/models/manipulators.py:309
-#, python-format
-msgid "%(object)s with this %(type)s already exists for the given %(field)s."
-msgstr "%(object)s med %(type)s finnes allerede for angitt %(field)s."
-
-#: db/models/manipulators.py:310 core/validators.py:275
-#: contrib/admin/views/main.py:342 contrib/admin/views/main.py:344
-#: contrib/admin/views/main.py:346
-msgid "and"
-msgstr "og"
-
-#: db/models/fields/__init__.py:49
-#, python-format
-msgid "%(optname)s with this %(fieldname)s already exists."
-msgstr "%(optname)s med %(fieldname)s finnes allerede."
-
-#: 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/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 "Dette feltet er påkrevd."
-
-#: db/models/fields/__init__.py:411
-msgid "This value must be an integer."
-msgstr "Denne verdien må være et heltall."
-
-#: db/models/fields/__init__.py:446
-msgid "This value must be either True or False."
-msgstr "Denne verdien må være enten \"True\" eller \"False\"."
-
-#: db/models/fields/__init__.py:467
-msgid "This field cannot be null."
-msgstr "Dette feltet kan ikke være null/tom."
-
-#: db/models/fields/__init__.py:501 core/validators.py:155
-msgid "Enter a valid date in YYYY-MM-DD format."
-msgstr "Skriv inn en dato i Ã…Ã…Ã…Ã…-MM-DD format."
-
-#: db/models/fields/__init__.py:570 core/validators.py:164
-msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
-msgstr "Skriv inn dato og tid i Ã…Ã…Ã…Ã…-MM-DD TT:MM format."
-
-#: db/models/fields/__init__.py:631
-msgid "This value must be a decimal number."
-msgstr "Denne verdien må være et desimaltall."
-
-#: db/models/fields/__init__.py:741
-msgid "Enter a valid filename."
-msgstr "Skriv inn et godkjent filnavn."
-
-#: db/models/fields/__init__.py:883
-msgid "This value must be either None, True or False."
-msgstr "Denne verdien må være enten None, True eller False."
-
-#: db/models/fields/related.py:55
-#, python-format
-msgid "Please enter a valid %s."
-msgstr "Vennligst skriv inn en/et gyldig %s."
-
-#: db/models/fields/related.py:658
-msgid "Separate multiple IDs with commas."
-msgstr "Separer flere ID-er med komma."
-
-#: db/models/fields/related.py:660
-msgid ""
-"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr ""
-"Hold nede \"Control\", eller \"Command\" på en Mac, for å velge mer enn en."
-
-#: db/models/fields/related.py:707
-#, 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] "Skriv inn gyldige %(self)s ID-er. Verdien %(value)r er ikke gyldig."
-msgstr[1] ""
-"Skriv inn gyldige %(self)s ID-er. Verdiene %(value)r er ikke gyldige."
-
-#: conf/global_settings.py:39
+#: conf/global_settings.py:44
msgid "Arabic"
msgstr "Arabisk"
-#: conf/global_settings.py:40
+#: conf/global_settings.py:45
msgid "Bengali"
msgstr "Bengalsk"
-#: conf/global_settings.py:41
+#: conf/global_settings.py:46
msgid "Bulgarian"
msgstr "Bulgarsk"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:47
msgid "Catalan"
msgstr "Katalansk"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:48
msgid "Czech"
msgstr "Tsjekkisk"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:49
msgid "Welsh"
msgstr "Walisisk"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:50
msgid "Danish"
msgstr "Dansk"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:51
msgid "German"
msgstr "Tysk"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:52
msgid "Greek"
msgstr "Gresk"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:53
msgid "English"
msgstr "Engelsk"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:54
msgid "Spanish"
msgstr "Spansk"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "Estisk"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
msgstr "Argentinsk spansk"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:57
+msgid "Basque"
+msgstr "Baskisk"
+
+#: conf/global_settings.py:58
msgid "Persian"
msgstr "Persisk"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:59
msgid "Finnish"
msgstr "Finsk"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:60
msgid "French"
msgstr "Fransk"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:61
+msgid "Irish"
+msgstr "Irsk"
+
+#: conf/global_settings.py:62
msgid "Galician"
msgstr "Galisisk"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:63
msgid "Hungarian"
msgstr "Ungarsk"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:64
msgid "Hebrew"
-msgstr "Hebraiske"
+msgstr "Hebraisk"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:65
msgid "Croatian"
msgstr "Kroatisk"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:66
msgid "Icelandic"
msgstr "Islandsk"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:67
msgid "Italian"
msgstr "Italiensk"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:68
msgid "Japanese"
msgstr "Japansk"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:69
+msgid "Georgian"
+msgstr "Georgisk"
+
+#: conf/global_settings.py:70
msgid "Korean"
msgstr "Koreansk"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:71
+msgid "Khmer"
+msgstr "Khmer"
+
+#: conf/global_settings.py:72
msgid "Kannada"
-msgstr ""
+msgstr "Kannada"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:73
msgid "Latvian"
msgstr "Latvisk"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "Litauisk"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
msgstr "Makedonsk"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:76
msgid "Dutch"
msgstr "Nederlandsk"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:77
msgid "Norwegian"
msgstr "Norsk"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:78
msgid "Polish"
msgstr "Polsk"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:79
msgid "Portugese"
msgstr "Portugisisk"
-#: conf/global_settings.py:69
-msgid "Brazilian"
-msgstr "Brasiliansk"
+#: conf/global_settings.py:80
+msgid "Brazilian Portuguese"
+msgstr "Brasiliansk portugisisk"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:81
msgid "Romanian"
msgstr "Rumensk"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:82
msgid "Russian"
msgstr "Russisk"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:83
msgid "Slovak"
msgstr "Slovakisk"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:84
msgid "Slovenian"
msgstr "Slovensk"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:85
msgid "Serbian"
msgstr "Serbisk"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:86
msgid "Swedish"
msgstr "Svensk"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:87
msgid "Tamil"
-msgstr ""
+msgstr "Tamil"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:88
msgid "Telugu"
-msgstr ""
+msgstr "Telugu"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:89
msgid "Turkish"
msgstr "Tyrkisk"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:90
msgid "Ukrainian"
msgstr "Ukrainsk"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
msgstr "Simplifisert kinesisk"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
msgstr "Tradisjonell kinesisk"
-#: core/validators.py:71
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Dette feltet kan bare inneholde bokstaver, nummer eller understreker."
-
-#: core/validators.py:75
+#: contrib/admin/filterspecs.py:44
+#, python-format
msgid ""
-"This value must contain only letters, numbers, underscores, dashes or "
-"slashes."
+"<h3>By %s:</h3>\n"
+"<ul>\n"
msgstr ""
-"Dette feltet kan bare inneholde bokstaver, nummer, understreker, bindestreker"
-" eller skråstreker."
+"<h3>Av %s:</h3>\n"
+"<ul>\n"
-#: core/validators.py:79
-msgid "This value must contain only letters, numbers, underscores or hyphens."
-msgstr "Dette feltet kan bare inneholde bokstaver, nummer, understreker eller "
-"bindestreker."
+#: contrib/admin/filterspecs.py:74 contrib/admin/filterspecs.py:92
+#: contrib/admin/filterspecs.py:147 contrib/admin/filterspecs.py:173
+msgid "All"
+msgstr "Alle"
-#: core/validators.py:83
-msgid "Uppercase letters are not allowed here."
-msgstr "Store bokstaver er ikke tillatt her."
+#: contrib/admin/filterspecs.py:113
+msgid "Any date"
+msgstr "NÃ¥r som helst"
-#: core/validators.py:87
-msgid "Lowercase letters are not allowed here."
-msgstr "Små bokstaver er ikke tillatt her."
+#: contrib/admin/filterspecs.py:114
+msgid "Today"
+msgstr "I dag"
-#: core/validators.py:94
-msgid "Enter only digits separated by commas."
-msgstr "Skriv inn bare tall, adskilt med komma."
+#: contrib/admin/filterspecs.py:117
+msgid "Past 7 days"
+msgstr "Siste 7 dager"
-#: core/validators.py:106
-msgid "Enter valid e-mail addresses separated by commas."
-msgstr "Skriv inn e-postadresser, adskilt med komma."
+#: contrib/admin/filterspecs.py:119
+msgid "This month"
+msgstr "Denne måneden"
-#: core/validators.py:110
-msgid "Please enter a valid IP address."
-msgstr "Vennligst skriv inn en gyldig IP-adresse."
+#: contrib/admin/filterspecs.py:121
+msgid "This year"
+msgstr "I år"
-#: core/validators.py:114
-msgid "Empty values are not allowed here."
-msgstr "Dette felte kan ikke være tomt."
+#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: oldforms/__init__.py:592
+msgid "Yes"
+msgstr "Ja"
-#: core/validators.py:118
-msgid "Non-numeric characters aren't allowed here."
-msgstr "Dette feltet kan kun bestå av tall."
+#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: oldforms/__init__.py:592
+msgid "No"
+msgstr "Nei"
-#: core/validators.py:122
-msgid "This value can't be comprised solely of digits."
-msgstr "Dette feltet kan ikke bare bestå av nummer."
+#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
+#: oldforms/__init__.py:592
+msgid "Unknown"
+msgstr "Ukjent"
-#: core/validators.py:127 newforms/fields.py:142
-msgid "Enter a whole number."
-msgstr "Skriv inn et helt nummer."
+#: contrib/admin/models.py:18
+msgid "action time"
+msgstr "tid for handling"
-#: core/validators.py:131
-msgid "Only alphabetical characters are allowed here."
-msgstr "Bare alfabetiske tegn er tillatt her."
+#: contrib/admin/models.py:21
+msgid "object id"
+msgstr "objekt-ID"
-#: core/validators.py:146
-msgid "Year must be 1900 or later."
-msgstr "År må være 1900 eller senere."
+#: contrib/admin/models.py:22
+msgid "object repr"
+msgstr "objekt repr"
-#: core/validators.py:150
-#, python-format
-msgid "Invalid date: %s"
-msgstr "Ugyldig dato: %s"
+#: contrib/admin/models.py:23
+msgid "action flag"
+msgstr "handlingsflagg"
-#: core/validators.py:160
-msgid "Enter a valid time in HH:MM format."
-msgstr "Skriv inn tiden i TT:MM format."
+#: contrib/admin/models.py:24
+msgid "change message"
+msgstr "endre melding"
-#: core/validators.py:169 newforms/fields.py:336
-msgid "Enter a valid e-mail address."
-msgstr "Skriv inn en godkjent e-postadresse."
+#: contrib/admin/models.py:27
+msgid "log entry"
+msgstr "logginnlegg"
-#: 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 "Ingen fil ble "
+#: contrib/admin/models.py:28
+msgid "log entries"
+msgstr "logginnlegg"
+
+#: contrib/admin/templates/admin/404.html:4
+#: contrib/admin/templates/admin/404.html:8
+msgid "Page not found"
+msgstr "Fant ikke siden"
+
+#: contrib/admin/templates/admin/404.html:10
+msgid "We're sorry, but the requested page could not be found."
+msgstr "Beklager, men siden du spør etter finnes ikke."
+
+#: contrib/admin/templates/admin/500.html:4
+#: contrib/admin/templates/admin/base.html:37
+#: contrib/admin/templates/admin/change_form.html:12
+#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/invalid_setup.html:4
+#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+#: contrib/admin/templates/registration/logged_out.html:4
+#: contrib/admin/templates/registration/password_change_done.html:3
+#: contrib/admin/templates/registration/password_change_form.html:3
+#: contrib/admin/templates/registration/password_reset_done.html:4
+#: contrib/admin/templates/registration/password_reset_form.html:4
+msgid "Home"
+msgstr "Hjem"
-#: core/validators.py:185 newforms/fields.py:397
+#: contrib/admin/templates/admin/500.html:4
+msgid "Server error"
+msgstr "Tjenerfeil"
+
+#: contrib/admin/templates/admin/500.html:6
+msgid "Server error (500)"
+msgstr "Tjenerfeil (500)"
+
+#: contrib/admin/templates/admin/500.html:9
+msgid "Server Error <em>(500)</em>"
+msgstr "Tjenerfeil <em>(500)</em>"
+
+#: contrib/admin/templates/admin/500.html:10
msgid ""
-"Upload a valid image. The file you uploaded was either not an image or a "
-"corrupted image."
+"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 ""
-"Last opp et gyldig bilde. Filen du lastet opp var ikke et bilde, eller så var"
-" det det ødelagt."
+"Det har oppstått en feil. Feilen er blitt rapportert til administrator via e-"
+"post, og vil bli fikset snart. Takk for din tålmodighet."
-#: core/validators.py:192
-#, python-format
-msgid "The URL %s does not point to a valid image."
-msgstr "Internettadressen %s peker ikke til et gyldig bilde."
+#: contrib/admin/templates/admin/base.html:26
+msgid "Welcome,"
+msgstr "Velkommen,"
-#: core/validators.py:196
-#, python-format
-msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
-msgstr ""
-"Telefonnummeret må være i XXX-XXX-XXXX format. \"%s\" er ugyldig."
+#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+msgid "Documentation"
+msgstr "Dokumentasjon"
-#: core/validators.py:204
+#: contrib/admin/templates/admin/base.html:29
+#: contrib/admin/templates/admin/auth/user/change_password.html:14
+#: contrib/admin/templates/admin/auth/user/change_password.html:45
+msgid "Change password"
+msgstr "Endre passord"
+
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/comments/templates/comments/form.html:6
+msgid "Log out"
+msgstr "Logg ut"
+
+#: contrib/admin/templates/admin/base_site.html:4
+msgid "Django site admin"
+msgstr "Django administrasjonsside"
+
+#: contrib/admin/templates/admin/base_site.html:7
+msgid "Django administration"
+msgstr "Django-administrasjon"
+
+#: contrib/admin/templates/admin/change_form.html:14
+#: contrib/admin/templates/admin/index.html:28
+msgid "Add"
+msgstr "Legg til"
+
+#: contrib/admin/templates/admin/change_form.html:20
+#: contrib/admin/templates/admin/object_history.html:4
+msgid "History"
+msgstr "Historikk"
+
+#: contrib/admin/templates/admin/change_form.html:21
+msgid "View on site"
+msgstr "Vis på nettsted"
+
+#: contrib/admin/templates/admin/change_form.html:31
+#: contrib/admin/templates/admin/auth/user/change_password.html:23
+msgid "Please correct the error below."
+msgid_plural "Please correct the errors below."
+msgstr[0] "Vennligst fiks feilen under."
+msgstr[1] "Vennligst fiks feilene under."
+
+#: contrib/admin/templates/admin/change_form.html:49
+msgid "Ordering"
+msgstr "Rekkefølge"
+
+#: contrib/admin/templates/admin/change_form.html:52
+msgid "Order:"
+msgstr "Rekkefølge:"
+
+#: contrib/admin/templates/admin/change_list.html:11
#, python-format
-msgid "The URL %s does not point to a valid QuickTime video."
-msgstr "Internettadressen %s peker ikke til en gyldig QuickTime-video."
+msgid "Add %(name)s"
+msgstr "Legg til %(name)s"
-#: core/validators.py:208
-msgid "A valid URL is required."
-msgstr "En gyldig internettadresse er påkrevd."
+#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/submit_line.html:3
+msgid "Delete"
+msgstr "Slett"
-#: core/validators.py:222
+#: contrib/admin/templates/admin/delete_confirmation.html:13
#, python-format
msgid ""
-"Valid HTML is required. Specific errors are:\n"
-"%s"
+"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 ""
-"Gyldig HTML er påkrevd. Feilene var:\n"
-"%s"
+"Hvis du sletter %(object_name)s '%(escaped_object)s', vil også slette "
+"relaterte objekter, men du har ikke tillatelse til å slette følgende "
+"objekttyper:"
-#: core/validators.py:229
+#: contrib/admin/templates/admin/delete_confirmation.html:20
#, python-format
-msgid "Badly formed XML: %s"
-msgstr "Ikke velformet XML: %s"
+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 ""
+"Er du sikker på at du vil slette %(object_name)s \"%(escaped_object)s\"? "
+"Alle de følgende relaterte objektene vil bli slettet:"
-#: core/validators.py:246
-#, python-format
-msgid "Invalid URL: %s"
-msgstr "Ugyldig URL: %s"
+#: contrib/admin/templates/admin/delete_confirmation.html:25
+msgid "Yes, I'm sure"
+msgstr "Ja, jeg er sikker"
-#: core/validators.py:251 core/validators.py:253
+#: contrib/admin/templates/admin/filter.html:2
#, python-format
-msgid "The URL %s is a broken link."
-msgstr "Internettadresse %s fører til en side som ikke eksisterer."
+msgid " By %(filter_title)s "
+msgstr "Av %(filter_title)s "
-#: core/validators.py:259
-msgid "Enter a valid U.S. state abbreviation."
-msgstr "Skriv inn en godkjent amerikansk delstatsforkortelse."
+#: contrib/admin/templates/admin/filters.html:4
+msgid "Filter"
+msgstr "Filtrering"
-#: core/validators.py:273
+#: contrib/admin/templates/admin/index.html:17
#, 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] "Pass munnen din! Ordet %s er ikke tillatt her."
-msgstr[1] "Pass munnen din! Ordene %s er ikke tillatt her."
+msgid "Models available in the %(name)s application."
+msgstr "Modeller tilgjengelig i %(name)s-applikasjonen."
-#: core/validators.py:280
+#: contrib/admin/templates/admin/index.html:18
#, python-format
-msgid "This field must match the '%s' field."
-msgstr "Dette feltet må være det samme som i '%s'-feltet."
+msgid "%(name)s"
+msgstr "%(name)s"
-#: core/validators.py:299
-msgid "Please enter something for at least one field."
-msgstr "Vennligst skriv inn noe i minst et felt."
+#: contrib/admin/templates/admin/index.html:34
+msgid "Change"
+msgstr "Endre"
-#: core/validators.py:308 core/validators.py:319
-msgid "Please enter both fields or leave them both empty."
-msgstr "Vennligst skriv inn noe i begge felta, eller la dem stå blanke."
+#: contrib/admin/templates/admin/index.html:44
+msgid "You don't have permission to edit anything."
+msgstr "Du har ikke rettigheter til å endre noe."
-#: core/validators.py:327
-#, python-format
-msgid "This field must be given if %(field)s is %(value)s"
-msgstr "Dette feltet må bare brukes hvis %(field)s er lik %(value)s"
+#: contrib/admin/templates/admin/index.html:52
+msgid "Recent Actions"
+msgstr "Siste handlinger"
-#: core/validators.py:340
-#, python-format
-msgid "This field must be given if %(field)s is not %(value)s"
-msgstr "Dette feltet må bare brukes hvis %(field)s ikke er lik %(value)s"
+#: contrib/admin/templates/admin/index.html:53
+msgid "My Actions"
+msgstr "Mine handlinger"
-#: core/validators.py:359
-msgid "Duplicate values are not allowed."
-msgstr "Like verdier er ikke tillatt."
+#: contrib/admin/templates/admin/index.html:57
+msgid "None available"
+msgstr "Ingen tilgjengelige"
-#: core/validators.py:374
-#, python-format
-msgid "This value must be between %(lower)s and %(upper)s."
-msgstr "Denne verdien må være mellom %(lower)s og %(upper)s."
+#: 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 ""
+"Noe er galt med databaseinstallasjonen din. Sørg for at databasetabellene er "
+"opprettet og at brukeren har de nødvendige rettigheter."
-#: core/validators.py:376
-#, python-format
-msgid "This value must be at least %s."
-msgstr "Denne verdien må minst være %s."
+#: contrib/admin/templates/admin/login.html:17
+#: contrib/comments/templates/comments/form.html:6
+#: contrib/comments/templates/comments/form.html:8
+msgid "Username:"
+msgstr "Brukernavn:"
-#: core/validators.py:378
-#, python-format
-msgid "This value must be no more than %s."
-msgstr "Denne verdien kan ikke være mer enn %s."
+#: contrib/admin/templates/admin/login.html:20
+#: contrib/comments/templates/comments/form.html:8
+msgid "Password:"
+msgstr "Passord:"
-#: core/validators.py:414
-#, python-format
-msgid "This value must be a power of %s."
-msgstr "Denne verdien må være et kvadrat av %s."
+#: contrib/admin/templates/admin/login.html:25
+#: contrib/admin/views/decorators.py:31
+msgid "Log in"
+msgstr "Logg inn"
-#: core/validators.py:424
-msgid "Please enter a valid decimal number."
-msgstr "Vennligst skriv inn et gyldig desimaltall."
+#: contrib/admin/templates/admin/object_history.html:17
+msgid "Date/time"
+msgstr "Dato/tid"
-#: 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] "Skriv inn et desimaltall med maks %s siffer."
-msgstr[1] "Skriv inn et desimaltall med maks %s siffer."
+#: contrib/admin/templates/admin/object_history.html:18
+msgid "User"
+msgstr "Bruker"
-#: core/validators.py:434
-#, python-format
+#: contrib/admin/templates/admin/object_history.html:19
+msgid "Action"
+msgstr "Handling"
+
+#: contrib/admin/templates/admin/object_history.html:25
+msgid "DATE_WITH_TIME_FULL"
+msgstr "H:i, j. M Y"
+
+#: contrib/admin/templates/admin/object_history.html:35
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] "Skriv inn et desimaltall hvor heltallsdelen er maks %s siffer."
-msgstr[1] "Skriv inn et desimaltall hvor heltallsdelen er maks %s siffer."
+"This object doesn't have a change history. It probably wasn't added via this "
+"admin site."
+msgstr ""
+"Dette objektet har ingen endringshistorikk. Det var sannsynligvis ikke lagt "
+"til via denne administrasjonssiden."
-#: 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] "Skriv inn et desimaltall med maks %s siffer bak komma."
-msgstr[1] "Skriv inn et desimaltall med maks %s siffer bak komma."
+#: contrib/admin/templates/admin/pagination.html:10
+msgid "Show all"
+msgstr "Vis alle"
-#: core/validators.py:445
-msgid "Please enter a valid floating point number."
-msgstr "Vennligst skriv inn et gyldig flyttall."
+#: contrib/admin/templates/admin/search_form.html:8
+msgid "Go"
+msgstr "GÃ¥"
-#: core/validators.py:454
+#: contrib/admin/templates/admin/search_form.html:10
#, python-format
-msgid "Make sure your uploaded file is at least %s bytes big."
-msgstr "Vær sikker på at fila du prøver å laste opp minst er %s bytes stor."
+msgid "1 result"
+msgid_plural "%(counter)s results"
+msgstr[0] "Ett resultat"
+msgstr[1] "%(counter)s resultat"
-#: core/validators.py:455
+#: contrib/admin/templates/admin/search_form.html:10
#, python-format
-msgid "Make sure your uploaded file is at most %s bytes big."
-msgstr "Vær sikker på at fila du prøver å laste opp ikke er mer enn %s bytes"
-" stor."
+msgid "%(full_result_count)s total"
+msgstr "%(full_result_count)s totalt"
-#: core/validators.py:472
-msgid "The format for this field is wrong."
-msgstr "Formatet i dette feltet er feil."
+#: contrib/admin/templates/admin/submit_line.html:4
+msgid "Save as new"
+msgstr "Lagre som ny"
-#: core/validators.py:487
-msgid "This field is invalid."
-msgstr "Dette feltet er ugyldig."
+#: contrib/admin/templates/admin/submit_line.html:5
+msgid "Save and add another"
+msgstr "Lagre og legg til ny"
-#: core/validators.py:523
-#, python-format
-msgid "Could not retrieve anything from %s."
-msgstr "Klarte ikke å hente noe fra %s."
+#: contrib/admin/templates/admin/submit_line.html:6
+msgid "Save and continue editing"
+msgstr "Lagre og fortsett å endre"
-#: core/validators.py:526
-#, python-format
-msgid ""
-"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
-msgstr ""
-"Internettadressen %(url)s returnerte den ugyldige Content-Type-headeren "
-"'%(contenttype)s'."
+#: contrib/admin/templates/admin/submit_line.html:7
+msgid "Save"
+msgstr "Lagre"
-#: core/validators.py:559
-#, python-format
+#: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid ""
-"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
-"\"%(start)s\".)"
+"First, enter a username and password. Then, you'll be able to edit more user "
+"options."
msgstr ""
-"Vennligst lukk taggen %(tag)s på linje %(line)s. (Linjen starer med "
-"\"%(start)s\".)"
+"Skriv først inn brukernavn og passord. Deretter vil du få mulighet til å "
+"endre flere brukerinnstillinger."
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:12
+msgid "Username"
+msgstr "Brukernavn"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/change_password.html:33
+msgid "Password"
+msgstr "Passord"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:23
+#: contrib/admin/templates/admin/auth/user/change_password.html:38
+msgid "Password (again)"
+msgstr "Passord (gjenta)"
-#: core/validators.py:563
+#: contrib/admin/templates/admin/auth/user/add_form.html:24
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+msgid "Enter the same password as above, for verification."
+msgstr "Skriv inn det samme passordet som ovenfor, for verifisering."
+
+#: contrib/admin/templates/admin/auth/user/change_password.html:27
#, python-format
+msgid "Enter a new password for the user <strong>%(username)s</strong>."
+msgstr "Skriv inn et nytt passord for brukeren <strong>%(username)s</strong>."
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+msgid "Bookmarklets"
+msgstr "Bokmerker"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
+msgid "Documentation bookmarklets"
+msgstr "Dokumentasjonsbokmerker"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:8
msgid ""
-"Some text starting on line %(line)s is not allowed in that context. (Line "
-"starts with \"%(start)s\".)"
+"\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 ""
-"Noe av teksten som starter på linje %(line)s er ikke tillatt. (Linjen "
-"starter med \"%(start)s\".)"
+"\n"
+"<p class=\"help\">For å installere bokmerker, dra linken til verktøylinja\n"
+"for bokmerker, eller høyreklikk og legg til i bokmerker. Nå kan du du velge\n"
+"bokmerket fra hvilken som helst side på nettstedet. Noen av disse\n"
+"bokmerkene krever at datamaskinen du bruker er markert som \"intern\"\n"
+"(kontakt din systemadministrator hvis du er usikker på om maskinen din er "
+"\"intern\").</p>\n"
-#: core/validators.py:568
-#, python-format
+#: contrib/admin/templates/admin_doc/bookmarklets.html:18
+msgid "Documentation for this page"
+msgstr "Dokumentasjon for denne siden"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:19
msgid ""
-"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
-"(start)s\".)"
+"Jumps you from any page to the documentation for the view that generates "
+"that page."
msgstr ""
-"\"%(attr)s\" på linje %(line)s er et ugyldig attributt. (Linjen starter "
-"med \"%(start)s\".)"
+"Hopp fra hvilken som helst side til dokumentasjonen for visningsfunksjonen "
+"som genererte den siden."
-#: core/validators.py:573
-#, python-format
+#: contrib/admin/templates/admin_doc/bookmarklets.html:21
+msgid "Show object ID"
+msgstr "Vis objekt-ID"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:22
msgid ""
-"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
-"(start)s\".)"
+"Shows the content-type and unique ID for pages that represent a single "
+"object."
msgstr ""
-"\"<%(tag)s>\" på linje %(line)s er et ugyldig element. (Linjen starter med "
-"\"%(start)s\".)"
+"Viser \"content-type\" og en unik ID for sider som representerer et enkelt "
+"objekt."
-#: 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\".)"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:24
+msgid "Edit this object (current window)"
+msgstr "Endre dette objektet (nåværende vindu)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:25
+msgid "Jumps to the admin page for pages that represent a single object."
msgstr ""
-"Et element på linje %(line)s mangler et av de påkrevde attributtene. (Linjen "
-"starter med \"%(start)s\".)"
+"Hopper til administrasjonssiden for sider som representerer et enkelt objekt."
-#: core/validators.py:582
-#, python-format
+#: contrib/admin/templates/admin_doc/bookmarklets.html:27
+msgid "Edit this object (new window)"
+msgstr "Endre dette objektet (nytt vindu)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:28
+msgid "As above, but opens the admin page in a new window."
+msgstr "Samme som over, men åpner administrasjonssiden i et nytt vindu."
+
+#: contrib/admin/templates/registration/logged_out.html:8
+msgid "Thanks for spending some quality time with the Web site today."
+msgstr "Takk for at du valgte å bruke kvalitetstid på nettstedet i dag."
+
+#: contrib/admin/templates/registration/logged_out.html:10
+msgid "Log in again"
+msgstr "Logg inn igjen"
+
+#: contrib/admin/templates/registration/password_change_done.html:3
+#: contrib/admin/templates/registration/password_change_form.html:3
+#: contrib/admin/templates/registration/password_change_form.html:5
+#: contrib/admin/templates/registration/password_change_form.html:9
+msgid "Password change"
+msgstr "Endre passord"
+
+#: contrib/admin/templates/registration/password_change_done.html:5
+#: contrib/admin/templates/registration/password_change_done.html:9
+msgid "Password change successful"
+msgstr "Passordet er endret"
+
+#: contrib/admin/templates/registration/password_change_done.html:11
+msgid "Your password was changed."
+msgstr "Ditt passord er endret."
+
+#: contrib/admin/templates/registration/password_change_form.html:11
msgid ""
-"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
-"starts with \"%(start)s\".)"
+"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 ""
-"\"%(attr)s\"-attributtet på linje %(line)s har en ugyldig verdi. (Linjen "
-"starter med \"%(start)s\".)"
-
-#: views/generic/create_update.py:43
-#, python-format
-msgid "The %(verbose_name)s was created successfully."
-msgstr "%(verbose_name)s ble opprettet."
+"Venligst skriv inn ditt gamle passord, av sikkerthetsårsaker. Skriv deretter "
+"inn ditt nye passord to ganger, slik at vi kan kontrollere at det er korrekt."
-#: views/generic/create_update.py:117
-#, python-format
-msgid "The %(verbose_name)s was updated successfully."
-msgstr "%(verbose_name)s ble oppdatert."
+#: contrib/admin/templates/registration/password_change_form.html:16
+msgid "Old password:"
+msgstr "Gammelt passord:"
-#: views/generic/create_update.py:184
-#, python-format
-msgid "The %(verbose_name)s was deleted."
-msgstr "%(verbose_name)s ble slettet."
+#: contrib/admin/templates/registration/password_change_form.html:18
+msgid "New password:"
+msgstr "Nytt passord:"
-#: utils/dates.py:6
-msgid "Monday"
-msgstr "Mandag"
+#: contrib/admin/templates/registration/password_change_form.html:20
+msgid "Confirm password:"
+msgstr "Gjenta nytt passord:"
-#: utils/dates.py:6
-msgid "Tuesday"
-msgstr "Tirsdag"
+#: contrib/admin/templates/registration/password_change_form.html:22
+msgid "Change my password"
+msgstr "Endre passord"
-#: utils/dates.py:6
-msgid "Wednesday"
-msgstr "Onsdag"
+#: 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
+msgid "Password reset"
+msgstr "Tilbakestill passord"
-#: utils/dates.py:6
-msgid "Thursday"
-msgstr "Torsdag"
+#: contrib/admin/templates/registration/password_reset_done.html:6
+#: contrib/admin/templates/registration/password_reset_done.html:10
+msgid "Password reset successful"
+msgstr "Passordet ble tilbakestilt"
-#: utils/dates.py:6
-msgid "Friday"
-msgstr "Fredag"
+#: 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 ""
+"Vi har sendt deg et nytt passord til e-postadressen du oppgav. Du vil "
+"forhåpentligvis motta det snart."
-#: utils/dates.py:7
-msgid "Saturday"
-msgstr "Lørdag"
+#: contrib/admin/templates/registration/password_reset_email.html:2
+msgid "You're receiving this e-mail because you requested a password reset"
+msgstr ""
+"Du har mottatt denne e-posten fordi du har bedt om tilbakestillelse av "
+"passordet ditt"
-#: utils/dates.py:7
-msgid "Sunday"
-msgstr "Søndag"
+#: contrib/admin/templates/registration/password_reset_email.html:3
+#, python-format
+msgid "for your user account at %(site_name)s"
+msgstr "for din konto hos %(site_name)s"
-#: utils/dates.py:10
-msgid "Mon"
-msgstr "Man"
+#: contrib/admin/templates/registration/password_reset_email.html:5
+#, python-format
+msgid "Your new password is: %(new_password)s"
+msgstr "Ditt nye passord er: %(new_password)s"
-#: utils/dates.py:10
-msgid "Tue"
-msgstr "Tirs"
+#: contrib/admin/templates/registration/password_reset_email.html:7
+msgid "Feel free to change this password by going to this page:"
+msgstr "Du kan endre dette passordet ved å gå til denne siden:"
-#: utils/dates.py:10
-msgid "Wed"
-msgstr "Ons"
+#: contrib/admin/templates/registration/password_reset_email.html:11
+msgid "Your username, in case you've forgotten:"
+msgstr "Brukernavnet ditt, i tilfelle du har glemt det:"
-#: utils/dates.py:10
-msgid "Thu"
-msgstr "Tors"
+#: contrib/admin/templates/registration/password_reset_email.html:13
+msgid "Thanks for using our site!"
+msgstr "Takk for at du bruker siden vår!"
-#: utils/dates.py:10
-msgid "Fri"
-msgstr "Fre"
+#: contrib/admin/templates/registration/password_reset_email.html:15
+#, python-format
+msgid "The %(site_name)s team"
+msgstr "Hilsen %(site_name)s"
-#: utils/dates.py:11
-msgid "Sat"
-msgstr "Lør"
+#: 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 ""
+"Har du glemt passordet ditt? Skriv inn e-postadressen din under, så sender "
+"vi deg et nytt passord."
-#: utils/dates.py:11
-msgid "Sun"
-msgstr "Søn"
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "E-mail address:"
+msgstr "E-postadresse:"
-#: utils/dates.py:18
-msgid "January"
-msgstr "Januar"
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "Reset my password"
+msgstr "Tilbakestill mitt passord"
-#: utils/dates.py:18
-msgid "February"
-msgstr "Februar"
+#: contrib/admin/templates/widget/date_time.html:3
+msgid "Date:"
+msgstr "Dato:"
-#: utils/dates.py:18 utils/dates.py:31
-msgid "March"
-msgstr "Mars"
+#: contrib/admin/templates/widget/date_time.html:4
+msgid "Time:"
+msgstr "Tid:"
-#: utils/dates.py:18 utils/dates.py:31
-msgid "April"
-msgstr "April"
+#: contrib/admin/templates/widget/file.html:2
+msgid "Currently:"
+msgstr "NÃ¥:"
-#: utils/dates.py:18 utils/dates.py:31
-msgid "May"
-msgstr "Mai"
+#: contrib/admin/templates/widget/file.html:3
+msgid "Change:"
+msgstr "Endre:"
-#: utils/dates.py:18 utils/dates.py:31
-msgid "June"
-msgstr "Juni"
+#: contrib/admin/templatetags/admin_list.py:257
+msgid "All dates"
+msgstr "Alle datoer"
-#: utils/dates.py:19 utils/dates.py:31
-msgid "July"
-msgstr "Juli"
+#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "%(name)s \"%(obj)s\" ble opprettet."
-#: utils/dates.py:19
-msgid "August"
-msgstr "August"
+#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
+#: contrib/admin/views/main.py:356
+msgid "You may edit it again below."
+msgstr "Du kan endre igjen under."
-#: utils/dates.py:19
-msgid "September"
-msgstr "September"
+#: contrib/admin/views/auth.py:31
+msgid "Add user"
+msgstr "Ny bruker"
-#: utils/dates.py:19
-msgid "October"
-msgstr "Oktober"
+#: contrib/admin/views/auth.py:58
+msgid "Password changed successfully."
+msgstr "Passordet er endret."
-#: utils/dates.py:19
-msgid "November"
-msgstr "November"
+#: contrib/admin/views/auth.py:65
+#, python-format
+msgid "Change password: %s"
+msgstr "Endre passord: %s"
-#: utils/dates.py:20
-msgid "December"
-msgstr "Desember"
+#: contrib/admin/views/decorators.py:17 contrib/auth/forms.py:60
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Vennligst angi korrekt brukernavn og passord. Merk at det er forskjell på "
+"små og store bokstaver."
-#: utils/dates.py:23
-msgid "jan"
-msgstr "jan"
+#: contrib/admin/views/decorators.py:69
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Du må logge inn igjen, fordi økten din har gått ut. Slapp av, innlegget ditt "
+"ble lagret."
-#: utils/dates.py:23
-msgid "feb"
-msgstr "feb"
+#: contrib/admin/views/decorators.py:76
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Det ser ut som om nettleseren din ikke støtter informasjonskapsler "
+"('cookies'). Vennligst konfigurer nettleseren din og prøv igjen."
-#: utils/dates.py:23
-msgid "mar"
-msgstr "mar"
+#: contrib/admin/views/decorators.py:89
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "E-postadressen din er ikke brukernavnet ditt, prøv '%s' i stede."
-#: utils/dates.py:23
-msgid "apr"
-msgstr "apr"
+#: contrib/admin/views/decorators.py:93
+msgid "Usernames cannot contain the '@' character."
+msgstr "Brukernavnet kan ikke inneholde '@'."
-#: utils/dates.py:23
-msgid "may"
-msgstr "mai"
+#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
+#: contrib/admin/views/doc.py:52
+msgid "tag:"
+msgstr "tag:"
-#: utils/dates.py:23
-msgid "jun"
-msgstr "jun"
+#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
+#: contrib/admin/views/doc.py:83
+msgid "filter:"
+msgstr "filter:"
-#: utils/dates.py:24
-msgid "jul"
-msgstr "jul"
+#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
+#: contrib/admin/views/doc.py:141
+msgid "view:"
+msgstr "view:"
-#: utils/dates.py:24
-msgid "aug"
-msgstr "aug"
+#: contrib/admin/views/doc.py:166
+#, python-format
+msgid "App %r not found"
+msgstr "Fant ikke applikasjonen %r"
-#: utils/dates.py:24
-msgid "sep"
-msgstr "sep"
+#: contrib/admin/views/doc.py:173
+#, python-format
+msgid "Model %(name)r not found in app %(label)r"
+msgstr "Fant ikke modellen %(name)r i applikasjonen %(label)r"
-#: utils/dates.py:24
-msgid "oct"
-msgstr "okt"
+#: contrib/admin/views/doc.py:185
+#, python-format
+msgid "the related `%(label)s.%(type)s` object"
+msgstr "det relaterte `%(label)s.%(type)s`-objektet"
-#: utils/dates.py:24
-msgid "nov"
-msgstr "nov"
+#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
+#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+msgid "model:"
+msgstr "modell:"
-#: utils/dates.py:24
-msgid "dec"
-msgstr "des"
+#: contrib/admin/views/doc.py:216
+#, python-format
+msgid "related `%(label)s.%(name)s` objects"
+msgstr "relaterte `%(label)s.%(name)s`-objekter"
-#: utils/dates.py:31
-msgid "Jan."
-msgstr "Jan."
+#: contrib/admin/views/doc.py:221
+#, python-format
+msgid "all %s"
+msgstr "alle %s"
-#: utils/dates.py:31
-msgid "Feb."
-msgstr "Feb."
+#: contrib/admin/views/doc.py:226
+#, python-format
+msgid "number of %s"
+msgstr "antall %s"
-#: utils/dates.py:32
-msgid "Aug."
-msgstr "Aug."
+#: contrib/admin/views/doc.py:231
+#, python-format
+msgid "Fields on %s objects"
+msgstr "Felter på %s-objekter"
-#: utils/dates.py:32
-msgid "Sept."
-msgstr "Sept."
+#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
+#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
+#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+msgid "Integer"
+msgstr "Heltall"
-#: utils/dates.py:32
-msgid "Oct."
-msgstr "Okt."
+#: contrib/admin/views/doc.py:294
+msgid "Boolean (Either True or False)"
+msgstr "Boolsk (\"True\" eller \"False\")"
-#: utils/dates.py:32
-msgid "Nov."
-msgstr "Nov."
+#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#, python-format
+msgid "String (up to %(max_length)s)"
+msgstr "Tekst (opp til %(max_length)s tegn)"
-#: utils/dates.py:32
-msgid "Dec."
-msgstr "Des."
+#: contrib/admin/views/doc.py:296
+msgid "Comma-separated integers"
+msgstr "Heltall adskilt med komma"
-#: utils/timesince.py:12
-msgid "year"
-msgid_plural "years"
-msgstr[0] "Ã¥r"
-msgstr[1] "Ã¥r"
+#: contrib/admin/views/doc.py:297
+msgid "Date (without time)"
+msgstr "Dato (uten tid)"
-#: utils/timesince.py:13
-msgid "month"
-msgid_plural "months"
-msgstr[0] "måned"
-msgstr[1] "måndeder"
+#: contrib/admin/views/doc.py:298
+msgid "Date (with time)"
+msgstr "Dato/tid"
-#: utils/timesince.py:14
-msgid "week"
-msgid_plural "weeks"
-msgstr[0] "uke"
-msgstr[1] "uker"
+#: contrib/admin/views/doc.py:299
+msgid "Decimal number"
+msgstr "Desimaltall"
-#: utils/timesince.py:15
-msgid "day"
-msgid_plural "days"
-msgstr[0] "dag"
-msgstr[1] "dager"
+#: contrib/admin/views/doc.py:300
+msgid "E-mail address"
+msgstr "E-postadresse"
-#: utils/timesince.py:16
-msgid "hour"
-msgid_plural "hours"
-msgstr[0] "time"
-msgstr[1] "timer"
+#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
+#: contrib/admin/views/doc.py:305
+msgid "File path"
+msgstr "Filsti"
-#: utils/timesince.py:17
-msgid "minute"
-msgid_plural "minutes"
-msgstr[0] "minutt"
-msgstr[1] "minutter"
+#: contrib/admin/views/doc.py:303
+msgid "Floating point number"
+msgstr "Flyttall"
-#: utils/timesince.py:39
-#, python-format
-msgid "%(number)d %(type)s"
-msgstr ""
+#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+msgid "IP address"
+msgstr "IP-adresse"
-#: utils/timesince.py:45
-#, python-format
-msgid ", %(number)d %(type)s"
-msgstr ""
+#: contrib/admin/views/doc.py:309
+msgid "Boolean (Either True, False or None)"
+msgstr "Boolsk (\"True\", \"False\" eller \"None\")"
-#: utils/text.py:127
-msgid "or"
-msgstr "eller"
+#: contrib/admin/views/doc.py:310
+msgid "Relation to parent model"
+msgstr "Relasjon til foreldermodell"
-#: utils/dateformat.py:41
-msgid "p.m."
-msgstr ""
+#: contrib/admin/views/doc.py:311
+msgid "Phone number"
+msgstr "Telefonnummer"
-#: utils/dateformat.py:42
-msgid "a.m."
-msgstr ""
+#: contrib/admin/views/doc.py:316
+msgid "Text"
+msgstr "Tekst"
-#: utils/dateformat.py:47
-msgid "PM"
-msgstr ""
+#: contrib/admin/views/doc.py:317
+msgid "Time"
+msgstr "Tid"
-#: utils/dateformat.py:48
-msgid "AM"
-msgstr ""
+#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
+msgid "URL"
+msgstr "Nettadresse"
-#: utils/dateformat.py:97
-msgid "midnight"
-msgstr "midnatt"
+#: contrib/admin/views/doc.py:319
+msgid "U.S. state (two uppercase letters)"
+msgstr "Stat (i USA, to store bokstaver)"
-#: utils/dateformat.py:99
-msgid "noon"
-msgstr "middag"
+#: contrib/admin/views/doc.py:320
+msgid "XML text"
+msgstr "XML-tekst"
-#: utils/translation/trans_real.py:391
-msgid "DATE_FORMAT"
-msgstr "j. M Y"
+#: contrib/admin/views/doc.py:346
+#, python-format
+msgid "%s does not appear to be a urlpattern object"
+msgstr "%s ser ikke ut til å være et urlpattern-objekt"
-#: utils/translation/trans_real.py:392
-msgid "DATETIME_FORMAT"
-msgstr "h:i, j. M Y"
+#: contrib/admin/views/main.py:233
+msgid "Site administration"
+msgstr "Nettstedsadministrasjon"
-#: utils/translation/trans_real.py:393
-msgid "TIME_FORMAT"
-msgstr "h:i"
+#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
+#, python-format
+msgid "You may add another %s below."
+msgstr "Du kan legge til en ny %s under."
-#: utils/translation/trans_real.py:409
-msgid "YEAR_MONTH_FORMAT"
-msgstr "Y M"
+#: contrib/admin/views/main.py:298
+#, python-format
+msgid "Add %s"
+msgstr "Ny %s"
-#: utils/translation/trans_real.py:410
-msgid "MONTH_DAY_FORMAT"
-msgstr "j. M"
+#: contrib/admin/views/main.py:344
+#, python-format
+msgid "Added %s."
+msgstr "La til %s."
-#: contrib/contenttypes/models.py:37
-msgid "python model class name"
-msgstr "python modell klasse navn"
+#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
+#: contrib/admin/views/main.py:348 core/validators.py:283
+#: db/models/manipulators.py:309
+msgid "and"
+msgstr "og"
-#: contrib/contenttypes/models.py:40
-msgid "content type"
-msgstr "innholdstype"
+#: contrib/admin/views/main.py:346
+#, python-format
+msgid "Changed %s."
+msgstr "Endret %s."
-#: contrib/contenttypes/models.py:41
-msgid "content types"
-msgstr "innholdstyper"
+#: contrib/admin/views/main.py:348
+#, python-format
+msgid "Deleted %s."
+msgstr "Slettet %s."
-#: contrib/humanize/templatetags/humanize.py:20
-msgid "th"
-msgstr ""
+#: contrib/admin/views/main.py:351
+msgid "No fields changed."
+msgstr "Ingen felt endret."
-#: contrib/humanize/templatetags/humanize.py:20
-msgid "st"
-msgstr ""
+#: contrib/admin/views/main.py:354
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "%(name)s \"%(obj)s\" ble endret."
-#: contrib/humanize/templatetags/humanize.py:20
-msgid "nd"
-msgstr ""
+#: contrib/admin/views/main.py:362
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr "%(name)s \"%(obj)s\" ble endret. Du kan endre det igjen under."
-#: contrib/humanize/templatetags/humanize.py:20
-msgid "rd"
-msgstr ""
+#: contrib/admin/views/main.py:400
+#, python-format
+msgid "Change %s"
+msgstr "Endre %s"
-#: contrib/humanize/templatetags/humanize.py:50
+#: contrib/admin/views/main.py:487
#, python-format
-msgid "%(value).1f million"
-msgid_plural "%(value).1f million"
-msgstr[0] "%(value).1f million"
-msgstr[1] "%(value).1f millioner"
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "En eller flere %(fieldname)s i %(name)s: %(obj)s"
-#: contrib/humanize/templatetags/humanize.py:53
+#: contrib/admin/views/main.py:492
#, python-format
-msgid "%(value).1f billion"
-msgid_plural "%(value).1f billion"
-msgstr[0] "%(value).1f milliard"
-msgstr[1] "%(value).1f milliarder"
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "En eller flere %(fieldname)s i %(name)s:"
-#: contrib/humanize/templatetags/humanize.py:56
+#: contrib/admin/views/main.py:524
#, python-format
-msgid "%(value).1f trillion"
-msgid_plural "%(value).1f trillion"
-msgstr[0] "%(value).1f billion"
-msgstr[1] "%(value).1f billioner"
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "%(name)s \"%(obj)s\" ble slettet."
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "one"
-msgstr "en"
+#: contrib/admin/views/main.py:527
+msgid "Are you sure?"
+msgstr "Er du sikker?"
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "two"
-msgstr "to"
+#: contrib/admin/views/main.py:549
+#, python-format
+msgid "Change history: %s"
+msgstr "Endringshistorikk: %s"
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "three"
-msgstr "tre"
+#: contrib/admin/views/main.py:583
+#, python-format
+msgid "Select %s"
+msgstr "Velg %s"
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "four"
-msgstr "fire"
+#: contrib/admin/views/main.py:583
+#, python-format
+msgid "Select %s to change"
+msgstr "Velg %s du ønsker å endre"
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "five"
-msgstr "fem"
+#: contrib/admin/views/main.py:765
+msgid "Database error"
+msgstr "Databasefeil"
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "six"
-msgstr "seks"
+#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+msgid "The two password fields didn't match."
+msgstr "De to passordfeltene er ikke like."
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "seven"
-msgstr "sju"
+#: contrib/auth/forms.py:25
+msgid "A user with that username already exists."
+msgstr "Det eksisterer allerede en bruker med dette brukernavnet."
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "eight"
-msgstr "Ã¥tte"
+#: contrib/auth/forms.py:53
+msgid ""
+"Your Web browser doesn't appear to have cookies enabled. Cookies are "
+"required for logging in."
+msgstr ""
+"Din nettleser ser ikke ut til å støtte informasjonskapsler (cookies). "
+"Informasjonskapsler er påkrevd for å logge inn."
-#: contrib/humanize/templatetags/humanize.py:71
-msgid "nine"
-msgstr "ni"
+#: contrib/auth/forms.py:62
+msgid "This account is inactive."
+msgstr "Denne kontoen er inaktiv."
-#: contrib/humanize/templatetags/humanize.py:90
-msgid "today"
-msgstr "i dag"
+#: contrib/auth/forms.py:84
+msgid ""
+"That e-mail address doesn't have an associated user account. Are you sure "
+"you've registered?"
+msgstr ""
+"Den oppgitte e-postadressen er ikke registrert hos oss. Er du sikker på at "
+"du har en konto her?"
-#: contrib/humanize/templatetags/humanize.py:92
-msgid "tomorrow"
-msgstr "i morgen"
+#: contrib/auth/forms.py:107
+#, python-format
+msgid "Password reset on %s"
+msgstr "Tilbakestilling av passord på %s"
-#: contrib/humanize/templatetags/humanize.py:94
-msgid "yesterday"
-msgstr "i går"
+#: contrib/auth/forms.py:117
+msgid "The two 'new password' fields didn't match."
+msgstr "De to feltene for nytt passord er ikke like."
-#: contrib/auth/views.py:47
-msgid "Logged out"
-msgstr "Logget ut"
+#: contrib/auth/forms.py:124
+msgid "Your old password was entered incorrectly. Please enter it again."
+msgstr "Ditt gamle passord er feil. Vennligst prøv igjen."
-#: contrib/auth/models.py:53 contrib/auth/models.py:73
+#: contrib/auth/models.py:73 contrib/auth/models.py:93
msgid "name"
msgstr "navn"
-#: contrib/auth/models.py:55
+#: contrib/auth/models.py:75
msgid "codename"
msgstr "kodenavn"
-#: contrib/auth/models.py:58
+#: contrib/auth/models.py:78
msgid "permission"
msgstr "rettighet"
-#: contrib/auth/models.py:59 contrib/auth/models.py:74
+#: contrib/auth/models.py:79 contrib/auth/models.py:94
msgid "permissions"
msgstr "rettigheter"
-#: contrib/auth/models.py:77
+#: contrib/auth/models.py:97
msgid "group"
msgstr "gruppe"
-#: contrib/auth/models.py:78 contrib/auth/models.py:121
+#: contrib/auth/models.py:98 contrib/auth/models.py:148
msgid "groups"
msgstr "grupper"
-#: contrib/auth/models.py:111
+#: contrib/auth/models.py:138
msgid "username"
msgstr "brukernavn"
-#: contrib/auth/models.py:111
+#: contrib/auth/models.py:138
msgid ""
"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
"digits and underscores)."
-msgstr "Påkrevd. 30 tegn eller færre. Kun alfanumeriske tegn (bokstaver, "
-"tall og understreker)."
+msgstr ""
+"Påkrevd. 30 tegn eller færre. Kun alfanumeriske tegn (bokstaver, tall og "
+"understreker)."
-#: contrib/auth/models.py:112
+#: contrib/auth/models.py:139
msgid "first name"
msgstr "fornavn"
-#: contrib/auth/models.py:113
+#: contrib/auth/models.py:140
msgid "last name"
msgstr "etternavn"
-#: contrib/auth/models.py:114
+#: contrib/auth/models.py:141
msgid "e-mail address"
msgstr "e-postadresse"
-#: contrib/auth/models.py:115
+#: contrib/auth/models.py:142
msgid "password"
msgstr "passord"
-#: contrib/auth/models.py:115
+#: contrib/auth/models.py:142
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
-msgstr "Bruk '[algo]$[salt]$[hexdigest]' eller <a href=\"password/\">endre "
-"passord-skjemaet</a>."
+msgstr ""
+"Bruk '[algo]$[salt]$[hexdigest]' eller <a href=\"password/\">endre passord-"
+"skjemaet</a>."
-#: contrib/auth/models.py:116
+#: contrib/auth/models.py:143
msgid "staff status"
msgstr "administrasjonsstatus"
-#: contrib/auth/models.py:116
+#: contrib/auth/models.py:143
msgid "Designates whether the user can log into this admin site."
-msgstr "Bestemmer om brukeren kan logge inn på disse administrasjonssidene."
+msgstr "Angir at brukeren kan logge inn på disse administrasjonssidene."
-#: contrib/auth/models.py:117
+#: contrib/auth/models.py:144
msgid "active"
msgstr "aktiv"
-#: contrib/auth/models.py:117
+#: contrib/auth/models.py:144
msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
+"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
-msgstr "Bestemmer om brukeren kan logge inn på disse sidene. Huk av denne "
-"i stedet for å slette kontoen."
+msgstr ""
+"Angir at denne brukeren er aktiv. Huk av denne i stedet for å slette kontoen."
-#: contrib/auth/models.py:118
+#: contrib/auth/models.py:145
msgid "superuser status"
msgstr "superbruker"
-#: contrib/auth/models.py:118
+#: contrib/auth/models.py:145
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
-msgstr "Bestemmer om denne brukeren har alle rettigheter, uten å sette de "
-"eksplisitt."
+msgstr ""
+"Angir at denne brukeren har alle rettigheter, uten å sette de eksplisitt."
-#: contrib/auth/models.py:119
+#: contrib/auth/models.py:146
msgid "last login"
msgstr "siste innlogging"
-#: contrib/auth/models.py:120
+#: contrib/auth/models.py:147
msgid "date joined"
-msgstr "registreringsdato"
+msgstr "registrert"
-#: contrib/auth/models.py:122
+#: contrib/auth/models.py:149
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
msgstr ""
-"I tillegg til rettighetene som blir gitt manuelt, får brukeren også full "
-"tilgang til rettighetene til gruppene han/hun er i."
+"I tillegg til de rettighetene som blir angitt manuelt, får brukeren også "
+"rettighetene gitt til gruppene han/hun er med i."
-#: contrib/auth/models.py:123
+#: contrib/auth/models.py:150
msgid "user permissions"
msgstr "Brukerrettigheter"
-#: contrib/auth/models.py:127
+#: contrib/auth/models.py:154
msgid "user"
msgstr "bruker"
-#: contrib/auth/models.py:128
+#: contrib/auth/models.py:155
msgid "users"
msgstr "brukere"
-#: contrib/auth/models.py:134
+#: contrib/auth/models.py:160
msgid "Personal info"
msgstr "Personlig informasjon"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:161
msgid "Permissions"
msgstr "Rettigheter"
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:162
msgid "Important dates"
msgstr "Viktige datoer"
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:163
msgid "Groups"
msgstr "Grupper"
-#: contrib/auth/models.py:288
+#: contrib/auth/models.py:323
msgid "message"
msgstr "melding"
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
-msgid "The two password fields didn't match."
-msgstr "De to passordfeltene er ikke like."
-
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "Det eksisterer en bruker med dette brukernavnet."
-
-#: contrib/auth/forms.py:53
-msgid ""
-"Your Web browser doesn't appear to have cookies enabled. Cookies are "
-"required for logging in."
-msgstr ""
-"Din nettleser ser ikke ut til å støtte informasjonskapsler (cookies). "
-"Informasjonskapsler er påkrevd for å logge inn."
-
-#: 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 ""
-"Vennligst angi korrekt brukernavn og passord. Merk at det er forskjell på "
-"små og store bokstaver."
-
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Denne kontoen er inaktiv."
-
-#: contrib/auth/forms.py:84
-msgid ""
-"That e-mail address doesn't have an associated user account. Are you sure "
-"you've registered?"
-msgstr "Den oppgitte e-postadressen er ikke registrert hos oss. Er du sikker"
-"på at du har en konto her?"
-
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "De to feltene for nytt passord er ikke like."
-
-#: contrib/auth/forms.py:124
-msgid "Your old password was entered incorrectly. Please enter it again."
-msgstr "Ditt gamle passord er feil. Vennligst prøv igjen."
-
-#: contrib/redirects/models.py:7
-msgid "redirect from"
-msgstr "omadresser fra"
-
-#: contrib/redirects/models.py:8
-msgid ""
-"This should be an absolute path, excluding the domain name. Example: '/"
-"events/search/'."
-msgstr ""
-"Dette burde vært en fullstendig sti, uten domenenavnet. Eksempel: '/"
-"nyheter/les/"
-
-#: contrib/redirects/models.py:9
-msgid "redirect to"
-msgstr "omadresser til"
-
-#: contrib/redirects/models.py:10
-msgid ""
-"This can be either an absolute path (as above) or a full URL starting with "
-"'http://'."
-msgstr ""
-"Dette kan enten være en fullstendig sti (som over), eller en hel "
-"internettadresse som starter med 'http://'"
-
-#: contrib/redirects/models.py:13
-msgid "redirect"
-msgstr "omadressering"
-
-#: contrib/redirects/models.py:14
-msgid "redirects"
-msgstr "omadresserelser"
+#: contrib/auth/views.py:49
+msgid "Logged out"
+msgstr "Logget ut"
-#: contrib/comments/models.py:67 contrib/comments/models.py:169
+#: contrib/comments/models.py:71 contrib/comments/models.py:176
msgid "object ID"
msgstr "objekt-ID"
-#: contrib/comments/models.py:68
+#: contrib/comments/models.py:72
msgid "headline"
msgstr "overskrift"
-#: contrib/comments/models.py:69 contrib/comments/models.py:90
-#: contrib/comments/models.py:170
+#: contrib/comments/models.py:73 contrib/comments/models.py:95
+#: contrib/comments/models.py:177
msgid "comment"
msgstr "kommentar"
-#: contrib/comments/models.py:70
+#: contrib/comments/models.py:74
msgid "rating #1"
msgstr "rangering #1 "
-#: contrib/comments/models.py:71
+#: contrib/comments/models.py:75
msgid "rating #2"
msgstr "rangering #2"
-#: contrib/comments/models.py:72
+#: contrib/comments/models.py:76
msgid "rating #3"
msgstr "rangering #3"
-#: contrib/comments/models.py:73
+#: contrib/comments/models.py:77
msgid "rating #4"
msgstr "rangering #4"
-#: contrib/comments/models.py:74
+#: contrib/comments/models.py:78
msgid "rating #5"
msgstr "rangering #5"
-#: contrib/comments/models.py:75
+#: contrib/comments/models.py:79
msgid "rating #6"
msgstr "rangering #6"
-#: contrib/comments/models.py:76
+#: contrib/comments/models.py:80
msgid "rating #7"
msgstr "rangering #7"
-#: contrib/comments/models.py:77
+#: contrib/comments/models.py:81
msgid "rating #8"
msgstr "rangering #8"
-#: contrib/comments/models.py:82
+#: contrib/comments/models.py:86
msgid "is valid rating"
msgstr "er gyldig rangering"
-#: contrib/comments/models.py:83 contrib/comments/models.py:172
+#: contrib/comments/models.py:87 contrib/comments/models.py:179
msgid "date/time submitted"
msgstr "dato/tid for innsendelse"
-#: contrib/comments/models.py:84 contrib/comments/models.py:173
+#: contrib/comments/models.py:88 contrib/comments/models.py:180
msgid "is public"
msgstr "er tilgjengelig for alle"
-#: contrib/comments/models.py:85 contrib/admin/views/doc.py:306
-msgid "IP address"
-msgstr "IP-adresse"
-
-#: contrib/comments/models.py:86
+#: contrib/comments/models.py:90
msgid "is removed"
msgstr "er fjernet"
-#: contrib/comments/models.py:86
+#: contrib/comments/models.py:90
msgid ""
"Check this box if the comment is inappropriate. A \"This comment has been "
"removed\" message will be displayed instead."
msgstr ""
"Huk av denne avkryssningsboksen hvis kommentaren er upasende. Beskjeden "
-"\"Denne kommentaren er blitt fjernet\" vil bli vist istedet."
+"\"Denne kommentaren har blitt fjernet\" vil bli vist i stedet."
-#: contrib/comments/models.py:91
+#: contrib/comments/models.py:96
msgid "comments"
msgstr "kommentarer"
-#: contrib/comments/models.py:134 contrib/comments/models.py:213
+#: contrib/comments/models.py:140 contrib/comments/models.py:222
msgid "Content object"
msgstr "innholdsobjekt"
-#: contrib/comments/models.py:162
+#: contrib/comments/models.py:168
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1264,54 +1342,54 @@ msgid ""
"\n"
"http://%(domain)s%(url)s"
msgstr ""
-"Sendt av %(user)s på %(date)s\n"
+"Skrevet av %(user)s, %(date)s\n"
"\n"
"%(comment)s\n"
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:171
+#: contrib/comments/models.py:178
msgid "person's name"
msgstr "personens navn"
-#: contrib/comments/models.py:174
+#: contrib/comments/models.py:181
msgid "ip address"
msgstr "IP-adresse"
-#: contrib/comments/models.py:176
+#: contrib/comments/models.py:183
msgid "approved by staff"
msgstr "godkjent av moderator"
-#: contrib/comments/models.py:179
+#: contrib/comments/models.py:187
msgid "free comment"
msgstr "Ã¥pen kommentar"
-#: contrib/comments/models.py:180
+#: contrib/comments/models.py:188
msgid "free comments"
msgstr "Ã¥pne kommentarer"
-#: contrib/comments/models.py:239
+#: contrib/comments/models.py:250
msgid "score"
msgstr "poeng"
-#: contrib/comments/models.py:240
+#: contrib/comments/models.py:251
msgid "score date"
msgstr "poengdato"
-#: contrib/comments/models.py:243
+#: contrib/comments/models.py:255
msgid "karma score"
msgstr "karmapoeng"
-#: contrib/comments/models.py:244
+#: contrib/comments/models.py:256
msgid "karma scores"
msgstr "karmapoeng"
-#: contrib/comments/models.py:248
+#: contrib/comments/models.py:260
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "%(score)d rangering av %(user)s"
-#: contrib/comments/models.py:264
+#: contrib/comments/models.py:277
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1322,58 +1400,82 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:271
+#: contrib/comments/models.py:285
msgid "flag date"
msgstr "flaggdato"
-#: contrib/comments/models.py:274
+#: contrib/comments/models.py:289
msgid "user flag"
msgstr "brukerflag"
-#: contrib/comments/models.py:275
+#: contrib/comments/models.py:290
msgid "user flags"
msgstr "brukerflag"
-#: contrib/comments/models.py:279
+#: contrib/comments/models.py:294
#, python-format
msgid "Flag by %r"
msgstr "Flagg med %r"
-#: contrib/comments/models.py:284
+#: contrib/comments/models.py:300
msgid "deletion date"
msgstr "dato fjernet"
-#: contrib/comments/models.py:286
+#: contrib/comments/models.py:303
msgid "moderator deletion"
msgstr "fjernet av moderator"
-#: contrib/comments/models.py:287
+#: contrib/comments/models.py:304
msgid "moderator deletions"
msgstr "fjernet av moderator"
-#: contrib/comments/models.py:291
+#: contrib/comments/models.py:308
#, python-format
msgid "Moderator deletion by %r"
-msgstr "Fjernet av moderator med %r"
+msgstr "Fjernet av moderator %r"
-#: contrib/comments/views/karma.py:20
-msgid "Anonymous users cannot vote"
-msgstr "Anonyme brukere kan ikke stemme"
+#: contrib/comments/templates/comments/form.html:8
+msgid "Forgotten your password?"
+msgstr "Har du glemt passordet ditt?"
-#: contrib/comments/views/karma.py:24
-msgid "Invalid comment ID"
-msgstr "Ikke gyldig kommentar-ID"
+#: contrib/comments/templates/comments/form.html:12
+msgid "Ratings"
+msgstr "Rangeringer"
-#: contrib/comments/views/karma.py:26
-msgid "No voting for yourself"
-msgstr "Du kan ikke stemme på deg selv"
+#: contrib/comments/templates/comments/form.html:12
+#: contrib/comments/templates/comments/form.html:23
+msgid "Required"
+msgstr "PÃ¥krevd"
+
+#: contrib/comments/templates/comments/form.html:12
+#: contrib/comments/templates/comments/form.html:23
+msgid "Optional"
+msgstr "Valgfri"
+
+#: contrib/comments/templates/comments/form.html:23
+msgid "Post a photo"
+msgstr "Send et bilde"
+
+#: contrib/comments/templates/comments/form.html:28
+#: contrib/comments/templates/comments/freeform.html:5
+msgid "Comment:"
+msgstr "Kommentar:"
+
+#: contrib/comments/templates/comments/form.html:35
+#: contrib/comments/templates/comments/freeform.html:10
+msgid "Preview comment"
+msgstr "Forhåndvis kommentar"
+
+#: contrib/comments/templates/comments/freeform.html:4
+msgid "Your name:"
+msgstr "Ditt navn:"
#: contrib/comments/views/comments.py:28
msgid ""
"This rating is required because you've entered at least one other rating."
msgstr ""
"Denne rangeringen er påkrevd, fordi du har rangert en eller flere ting fra "
-"før "
+"før."
#: contrib/comments/views/comments.py:112
#, python-format
@@ -1388,13 +1490,13 @@ msgid_plural ""
"\n"
"%(text)s"
msgstr[0] ""
-"Denne kommentaren var skrevet av en bruker som har fra før skrevet under %"
-"(count)s kommentarer:\n"
+"Denne kommentaren var skrevet av en bruker som har skrevet mindre enn "
+"%(count)s kommentarer:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"Denne kommentaren var skrevet av en bruker som har fra før skrevet under %"
-"(count)s kommentarer:\n"
+"Denne kommentaren var skrevet av en bruker som har skrevet mindre enn "
+"%(count)s kommentarer:\n"
"\n"
"%(text)s"
@@ -1409,1178 +1511,1084 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:189
-#: contrib/comments/views/comments.py:281
+#: contrib/comments/views/comments.py:190
+#: contrib/comments/views/comments.py:283
msgid "Only POSTs are allowed"
msgstr "Kun POST er tillatt"
-#: contrib/comments/views/comments.py:193
-#: contrib/comments/views/comments.py:285
+#: contrib/comments/views/comments.py:194
+#: contrib/comments/views/comments.py:287
msgid "One or more of the required fields wasn't submitted"
msgstr "En eller flere av feltene som er påkrevd ble ikke sendt."
-#: contrib/comments/views/comments.py:197
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:198
+#: contrib/comments/views/comments.py:289
msgid "Somebody tampered with the comment form (security violation)"
msgstr "Noen har endret på komentarfeltene (sikkerhetsadvarsel)"
-#: contrib/comments/views/comments.py:207
-#: contrib/comments/views/comments.py:293
+#: contrib/comments/views/comments.py:208
+#: contrib/comments/views/comments.py:295
msgid ""
"The comment form had an invalid 'target' parameter -- the object ID was "
"invalid"
msgstr "Skjemaet hadde en ugyldig 'target'-verdi - objekt-IDen var ugyldig"
-#: contrib/comments/views/comments.py:258
-#: contrib/comments/views/comments.py:322
+#: contrib/comments/views/comments.py:259
+#: contrib/comments/views/comments.py:324
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Kommentarskjemaet la ikke ved 'preview'- eller 'post'-element"
-#: contrib/comments/templates/comments/freeform.html:4
-msgid "Your name:"
-msgstr "Ditt navn:"
-
-#: contrib/comments/templates/comments/freeform.html:5
-#: contrib/comments/templates/comments/form.html:28
-msgid "Comment:"
-msgstr "Kommentar:"
-
-#: contrib/comments/templates/comments/freeform.html:10
-#: contrib/comments/templates/comments/form.html:35
-msgid "Preview comment"
-msgstr "Forhåndvis kommentar"
-
-#: contrib/comments/templates/comments/form.html:6
-#: contrib/comments/templates/comments/form.html:8
-#: contrib/admin/templates/admin/login.html:17
-msgid "Username:"
-msgstr "Brukernavn:"
-
-#: contrib/comments/templates/comments/form.html:6
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/auth/user/change_password.html:9
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
-#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_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/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
-msgid "Log out"
-msgstr "Logg ut"
-
-#: contrib/comments/templates/comments/form.html:8
-#: contrib/admin/templates/admin/login.html:20
-msgid "Password:"
-msgstr "Passord:"
-
-#: contrib/comments/templates/comments/form.html:8
-msgid "Forgotten your password?"
-msgstr "Har du glemt passordet ditt?"
+#: contrib/comments/views/karma.py:21
+msgid "Anonymous users cannot vote"
+msgstr "Anonyme brukere kan ikke stemme"
-#: contrib/comments/templates/comments/form.html:12
-msgid "Ratings"
-msgstr "Rangeringer"
+#: contrib/comments/views/karma.py:25
+msgid "Invalid comment ID"
+msgstr "Ugyldig kommentar-ID"
-#: contrib/comments/templates/comments/form.html:12
-#: contrib/comments/templates/comments/form.html:23
-msgid "Required"
-msgstr "PÃ¥krevd"
+#: contrib/comments/views/karma.py:27
+msgid "No voting for yourself"
+msgstr "Du kan ikke stemme på deg selv"
-#: contrib/comments/templates/comments/form.html:12
-#: contrib/comments/templates/comments/form.html:23
-msgid "Optional"
-msgstr "Valgfri"
+#: contrib/contenttypes/models.py:67
+msgid "python model class name"
+msgstr "python-modell klassenavn"
-#: contrib/comments/templates/comments/form.html:23
-msgid "Post a photo"
-msgstr "Send et bilde"
+#: contrib/contenttypes/models.py:71
+msgid "content type"
+msgstr "innholdstype"
-#: contrib/flatpages/models.py:7 contrib/admin/views/doc.py:317
-msgid "URL"
-msgstr "URL"
+#: contrib/contenttypes/models.py:72
+msgid "content types"
+msgstr "innholdstyper"
-#: contrib/flatpages/models.py:8
+#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
"Eksempel: '/om/kontakt/'. Vær sikker på at det er en skråstrek foran og bak."
-#: contrib/flatpages/models.py:9
+#: contrib/flatpages/models.py:10
msgid "title"
msgstr "tittel"
-#: contrib/flatpages/models.py:10
+#: contrib/flatpages/models.py:11
msgid "content"
msgstr "innhold"
-#: contrib/flatpages/models.py:11
+#: contrib/flatpages/models.py:12
msgid "enable comments"
msgstr "tillat kommentarer"
-#: contrib/flatpages/models.py:12
+#: contrib/flatpages/models.py:13
msgid "template name"
-msgstr "navn på mal"
+msgstr "malnavn"
-#: contrib/flatpages/models.py:13
+#: contrib/flatpages/models.py:14
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
msgstr ""
-"Eksempel: 'flatpages/kontakt_side.html'. Hvis denne ikke denne er gitt, vil "
+"Eksempel: 'flatpages/kontakt_side.html'. Hvis denne ikke er gitt, vil "
"'flatpages/default.html' bli brukt."
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "registration required"
msgstr "registrering kreves"
-#: contrib/flatpages/models.py:14
+#: contrib/flatpages/models.py:15
msgid "If this is checked, only logged-in users will be able to view the page."
msgstr ""
"Hvis denne er krysset av, er det kun innloggede brukere som kan se siden."
-#: contrib/flatpages/models.py:18
+#: contrib/flatpages/models.py:20
msgid "flat page"
msgstr "flatside"
-#: contrib/flatpages/models.py:19
+#: contrib/flatpages/models.py:21
msgid "flat pages"
msgstr "flatsider"
-#: contrib/sessions/models.py:68
+#: contrib/flatpages/models.py:27
+msgid "Advanced options"
+msgstr "Avanserte innstillinger"
+
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "th"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "st"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "nd"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "rd"
+msgstr ""
+
+#: contrib/humanize/templatetags/humanize.py:51
+#, python-format
+msgid "%(value).1f million"
+msgid_plural "%(value).1f million"
+msgstr[0] "%(value).1f million"
+msgstr[1] "%(value).1f millioner"
+
+#: contrib/humanize/templatetags/humanize.py:54
+#, python-format
+msgid "%(value).1f billion"
+msgid_plural "%(value).1f billion"
+msgstr[0] "%(value).1f milliard"
+msgstr[1] "%(value).1f milliarder"
+
+#: contrib/humanize/templatetags/humanize.py:57
+#, python-format
+msgid "%(value).1f trillion"
+msgid_plural "%(value).1f trillion"
+msgstr[0] "%(value).1f billion"
+msgstr[1] "%(value).1f billioner"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "one"
+msgstr "én"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "two"
+msgstr "to"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "three"
+msgstr "tre"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "four"
+msgstr "fire"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "five"
+msgstr "fem"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "six"
+msgstr "seks"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "seven"
+msgstr "sju"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "eight"
+msgstr "Ã¥tte"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "nine"
+msgstr "ni"
+
+#: contrib/humanize/templatetags/humanize.py:93
+msgid "today"
+msgstr "i dag"
+
+#: contrib/humanize/templatetags/humanize.py:95
+msgid "tomorrow"
+msgstr "i morgen"
+
+#: contrib/humanize/templatetags/humanize.py:97
+msgid "yesterday"
+msgstr "i går"
+
+#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Skriv inn et postnummer som XXXX."
+
+#: contrib/localflavor/no/forms.py:33
+msgid "Enter a valid Norwegian social security number."
+msgstr "Skriv et gyldig norsk personnummer."
+
+#: contrib/redirects/models.py:7
+msgid "redirect from"
+msgstr "omadresser fra"
+
+#: contrib/redirects/models.py:8
+msgid ""
+"This should be an absolute path, excluding the domain name. Example: '/"
+"events/search/'."
+msgstr ""
+"Dette burde vært en fullstendig sti, uten domenenavnet. Eksempel: '/nyheter/"
+"les/"
+
+#: contrib/redirects/models.py:9
+msgid "redirect to"
+msgstr "omadresser til"
+
+#: contrib/redirects/models.py:10
+msgid ""
+"This can be either an absolute path (as above) or a full URL starting with "
+"'http://'."
+msgstr ""
+"Dette kan enten være en fullstendig sti (som over), eller en fullstendig "
+"nettadresse som starter med 'http://'"
+
+#: contrib/redirects/models.py:13
+msgid "redirect"
+msgstr "omadressering"
+
+#: contrib/redirects/models.py:14
+msgid "redirects"
+msgstr "omadresserelser"
+
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "sesjonsnøkkel"
-#: contrib/sessions/models.py:69
+#: contrib/sessions/models.py:47
msgid "session data"
msgstr "sesjonsdata"
-#: contrib/sessions/models.py:70
+#: contrib/sessions/models.py:48
msgid "expire date"
msgstr "utløpsdato"
-#: contrib/sessions/models.py:74
+#: contrib/sessions/models.py:53
msgid "session"
msgstr "sesjon"
-#: contrib/sessions/models.py:75
+#: contrib/sessions/models.py:54
msgid "sessions"
msgstr "sesjoner"
-#: contrib/sites/models.py:15
+#: contrib/sites/models.py:32
msgid "domain name"
msgstr "domenenavn"
-#: contrib/sites/models.py:16
+#: contrib/sites/models.py:33
msgid "display name"
msgstr "visningsnavn"
-#: contrib/sites/models.py:20
+#: contrib/sites/models.py:37
msgid "site"
msgstr "nettsted"
-#: contrib/sites/models.py:21
+#: contrib/sites/models.py:38
msgid "sites"
msgstr "nettsteder"
-#: contrib/admin/filterspecs.py:42
-#, python-format
+#: core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Dette feltet kan bare inneholde bokstaver, nummer og understreker."
+
+#: core/validators.py:76
msgid ""
-"<h3>By %s:</h3>\n"
-"<ul>\n"
+"This value must contain only letters, numbers, underscores, dashes or "
+"slashes."
msgstr ""
-"<h3>Av %s:</h3>\n"
-"<ul>\n"
+"Dette feltet kan bare inneholde bokstaver, nummer, understreker, "
+"bindestreker eller skråstreker."
-#: 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:111
-msgid "Any date"
-msgstr "NÃ¥r som helst"
+#: core/validators.py:80
+msgid "This value must contain only letters, numbers, underscores or hyphens."
+msgstr ""
+"Dette feltet kan bare inneholde bokstaver, nummer, understreker eller "
+"bindestreker."
-#: contrib/admin/filterspecs.py:112
-msgid "Today"
-msgstr "I dag"
+#: core/validators.py:84
+msgid "Uppercase letters are not allowed here."
+msgstr "Store bokstaver er ikke tillatt her."
-#: contrib/admin/filterspecs.py:115
-msgid "Past 7 days"
-msgstr "Siste 7 dager"
+#: core/validators.py:88
+msgid "Lowercase letters are not allowed here."
+msgstr "Små bokstaver er ikke tillatt her."
-#: contrib/admin/filterspecs.py:117
-msgid "This month"
-msgstr "Denne måneden"
+#: core/validators.py:95
+msgid "Enter only digits separated by commas."
+msgstr "Skriv inn kun tall adskilt med komma."
-#: contrib/admin/filterspecs.py:119
-msgid "This year"
-msgstr "I år"
+#: core/validators.py:107
+msgid "Enter valid e-mail addresses separated by commas."
+msgstr "Skriv inn gyldige e-postadresser, adskilt med komma."
-#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:591
-#: newforms/widgets.py:188
-msgid "Yes"
-msgstr "Ja"
+#: core/validators.py:111
+msgid "Please enter a valid IP address."
+msgstr "Vennligst skriv inn en gyldig IP-adresse."
-#: contrib/admin/filterspecs.py:145 oldforms/__init__.py:591
-#: newforms/widgets.py:188
-msgid "No"
-msgstr "Nei"
+#: core/validators.py:115
+msgid "Empty values are not allowed here."
+msgstr "Dette feltet kan ikke være tomt."
-#: contrib/admin/filterspecs.py:152 oldforms/__init__.py:591
-#: newforms/widgets.py:188
-msgid "Unknown"
-msgstr "Ukjent"
+#: core/validators.py:119
+msgid "Non-numeric characters aren't allowed here."
+msgstr "Dette feltet kan kun bestå av tall."
-#: contrib/admin/models.py:17
-msgid "action time"
-msgstr "tid for handling"
+#: core/validators.py:123
+msgid "This value can't be comprised solely of digits."
+msgstr "Dette feltet kan ikke bare bestå av siffer."
-#: contrib/admin/models.py:20
-msgid "object id"
-msgstr "objekt-ID"
+#: core/validators.py:128 newforms/fields.py:157
+msgid "Enter a whole number."
+msgstr "Skriv inn et helt nummer."
-#: contrib/admin/models.py:21
-msgid "object repr"
-msgstr "objekt repr"
+#: core/validators.py:132
+msgid "Only alphabetical characters are allowed here."
+msgstr "Bare alfabetiske tegn er tillatt her."
-#: contrib/admin/models.py:22
-msgid "action flag"
-msgstr "handlingsflagg"
+#: core/validators.py:147
+msgid "Year must be 1900 or later."
+msgstr "År må være 1900 eller senere."
-#: contrib/admin/models.py:23
-msgid "change message"
-msgstr "endre melding"
+#: core/validators.py:151
+#, python-format
+msgid "Invalid date: %s"
+msgstr "Ugyldig dato: %s"
-#: contrib/admin/models.py:26
-msgid "log entry"
-msgstr "logginnlegg"
+#: core/validators.py:156 db/models/fields/__init__.py:554
+msgid "Enter a valid date in YYYY-MM-DD format."
+msgstr "Skriv inn en gyldig dato som Ã…Ã…Ã…Ã…-MM-DD."
-#: contrib/admin/models.py:27
-msgid "log entries"
-msgstr "logginnlegg"
+#: core/validators.py:161
+msgid "Enter a valid time in HH:MM format."
+msgstr "Skriv inn tiden som TT:MM."
-#: contrib/admin/templatetags/admin_list.py:254
-msgid "All dates"
-msgstr "Alle datoer"
+#: core/validators.py:165 db/models/fields/__init__.py:631
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
+msgstr "Skriv inn dato og tid som Ã…Ã…Ã…Ã…-MM-DD TT:MM."
-#: contrib/admin/views/decorators.py:24
-#: contrib/admin/templates/admin/login.html:25
-msgid "Log in"
-msgstr "Logg inn"
+#: core/validators.py:170 newforms/fields.py:408
+msgid "Enter a valid e-mail address."
+msgstr "Skriv inn en gyldig e-postadresse."
-#: 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 ""
-"Du må logge inn igjen, fordi økten din har gått ut. Slapp av, innlegget ditt "
-"ble lagret."
+#: core/validators.py:182 core/validators.py:474 newforms/fields.py:426
+msgid "No file was submitted. Check the encoding type on the form."
+msgstr "Ingen fil ble sendt. Sjekk \"encoding\"-typen på skjemaet."
-#: contrib/admin/views/decorators.py:69
+#: core/validators.py:193 newforms/fields.py:468
msgid ""
-"Looks like your browser isn't configured to accept cookies. Please enable "
-"cookies, reload this page, and try again."
+"Upload a valid image. The file you uploaded was either not an image or a "
+"corrupted image."
msgstr ""
-"Det ser ut som om nettleseren din ikke støtter informasjonskapsler "
-"('cookies'). Vennligst konfigurer nettleseren din, og prøv igjen."
-
-#: contrib/admin/views/decorators.py:83
-msgid "Usernames cannot contain the '@' character."
-msgstr "Brukernavnet kan ikke inneholde '@'"
+"Last opp et gyldig bilde. Filen du lastet opp var ikke et bilde eller "
+"var ødelagt."
-#: contrib/admin/views/decorators.py:85
+#: core/validators.py:200
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "E-postadressen din er ikke brukernavnet ditt, prøv '%s' i stede."
+msgid "The URL %s does not point to a valid image."
+msgstr "Nettadressen %s peker ikke på et gyldig bilde."
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:264
+#: core/validators.py:204
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "%(name)s \"%(obj)s\" ble lagt inn i databasen."
-
-#: 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 "Du kan endre under"
+msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
+msgstr "Telefonnummeret må være i XXX-XXX-XXXX format. \"%s\" er ugyldig."
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Ny bruker"
+#: core/validators.py:212
+#, python-format
+msgid "The URL %s does not point to a valid QuickTime video."
+msgstr "Nettadressen %s peker ikke på en gyldig QuickTime-video."
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Passordet er endret."
+#: core/validators.py:216
+msgid "A valid URL is required."
+msgstr "En gyldig nettadresse er påkrevd."
-#: contrib/admin/views/auth.py:65
+#: core/validators.py:230
#, python-format
-msgid "Change password: %s"
-msgstr "Endre passord: %s"
-
-#: contrib/admin/views/main.py:230
-msgid "Site administration"
-msgstr "Nettstedsadministrasjon"
+msgid ""
+"Valid HTML is required. Specific errors are:\n"
+"%s"
+msgstr ""
+"Gyldig HTML er påkrevd. Feilene var:\n"
+"%s"
-#: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363
+#: core/validators.py:237
#, python-format
-msgid "You may add another %s below."
-msgstr "Du kan legge til en ny %s under."
+msgid "Badly formed XML: %s"
+msgstr "Ikke velformet XML: %s"
-#: contrib/admin/views/main.py:296
+#: core/validators.py:254
#, python-format
-msgid "Add %s"
-msgstr "Ny %s"
+msgid "Invalid URL: %s"
+msgstr "Ugyldig nettadresse: %s"
-#: contrib/admin/views/main.py:342
+#: core/validators.py:259 core/validators.py:261
#, python-format
-msgid "Added %s."
-msgstr "La til %s"
+msgid "The URL %s is a broken link."
+msgstr "Nettadressen %s fører til en side som ikke eksisterer."
-#: contrib/admin/views/main.py:344
+#: core/validators.py:267
+msgid "Enter a valid U.S. state abbreviation."
+msgstr "Skriv inn en gyldig amerikansk delstatsforkortelse."
+
+#: core/validators.py:281
#, python-format
-msgid "Changed %s."
-msgstr "Endret %s."
+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] "Pass munnen din! Ordet %s er ikke tillatt her."
+msgstr[1] "Pass munnen din! Ordene %s er ikke tillatt her."
-#: contrib/admin/views/main.py:346
+#: core/validators.py:288
#, python-format
-msgid "Deleted %s."
-msgstr "Slettet %s."
+msgid "This field must match the '%s' field."
+msgstr "Dette feltet må være det samme som '%s'-feltet."
-#: contrib/admin/views/main.py:349
-msgid "No fields changed."
-msgstr "Ingen felt endret."
+#: core/validators.py:307
+msgid "Please enter something for at least one field."
+msgstr "Vennligst skriv inn noe i minst ett felt."
+
+#: core/validators.py:316 core/validators.py:327
+msgid "Please enter both fields or leave them both empty."
+msgstr "Vennligst skriv inn noe i begge feltene, eller la begge være blanke."
-#: contrib/admin/views/main.py:352
+#: core/validators.py:335
#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "%(name)s \"%(obj)s\" ble endret."
+msgid "This field must be given if %(field)s is %(value)s"
+msgstr "Dette feltet kreves hvis %(field)s er lik %(value)s"
-#: contrib/admin/views/main.py:360
+#: core/validators.py:348
#, python-format
-msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr "%(name)s \"%(obj)s\" ble endret. Du kan endre det igjen under."
+msgid "This field must be given if %(field)s is not %(value)s"
+msgstr "Dette feltet kreves hvis %(field)s ikke er lik %(value)s"
-#: contrib/admin/views/main.py:398
+#: core/validators.py:367
+msgid "Duplicate values are not allowed."
+msgstr "Like verdier er ikke tillatt."
+
+#: core/validators.py:382
#, python-format
-msgid "Change %s"
-msgstr "Endre %s"
+msgid "This value must be between %(lower)s and %(upper)s."
+msgstr "Denne verdien må være mellom %(lower)s og %(upper)s."
-#: contrib/admin/views/main.py:483
+#: core/validators.py:384
#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "En eller flere %(fieldname)s i %(name)s: %(obj)s"
+msgid "This value must be at least %s."
+msgstr "Denne verdien må minst være %s."
-#: contrib/admin/views/main.py:488
+#: core/validators.py:386
#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "En eller flere %(fieldname)s i %(name)s:"
+msgid "This value must be no more than %s."
+msgstr "Denne verdien kan ikke være mer enn %s."
-#: contrib/admin/views/main.py:520
+#: core/validators.py:427
#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "%(name)s \"%(obj)s\" ble slettet."
+msgid "This value must be a power of %s."
+msgstr "Denne verdien må være et kvadrat av %s."
-#: contrib/admin/views/main.py:523
-msgid "Are you sure?"
-msgstr "Er du sikker?"
+#: core/validators.py:437
+msgid "Please enter a valid decimal number."
+msgstr "Vennligst skriv inn et gyldig desimaltall."
-#: contrib/admin/views/main.py:545
+#: core/validators.py:444
#, python-format
-msgid "Change history: %s"
-msgstr "Endringshistorikk: %s"
+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] "Skriv inn et desimaltall med maks %s siffer."
+msgstr[1] "Skriv inn et desimaltall med maks %s siffer."
-#: contrib/admin/views/main.py:579
+#: core/validators.py:447
#, python-format
-msgid "Select %s"
-msgstr "Velg %s"
+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] "Skriv inn et desimaltall hvor heltallsdelen er maks %s siffer."
+msgstr[1] "Skriv inn et desimaltall hvor heltallsdelen er maks %s siffer."
-#: contrib/admin/views/main.py:579
+#: core/validators.py:450
#, python-format
-msgid "Select %s to change"
-msgstr "Velg %s for å endre"
+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] "Skriv inn et desimaltall med maks %s siffer bak komma."
+msgstr[1] "Skriv inn et desimaltall med maks %s siffer bak komma."
-#: contrib/admin/views/main.py:780
-msgid "Database error"
-msgstr "Databasefeil"
+#: core/validators.py:458
+msgid "Please enter a valid floating point number."
+msgstr "Vennligst skriv inn et gyldig flyttall."
-#: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49
-#: contrib/admin/views/doc.py:51
-msgid "tag:"
-msgstr ""
+#: core/validators.py:467
+#, python-format
+msgid "Make sure your uploaded file is at least %s bytes big."
+msgstr "Vær sikker på at filen du prøver å laste opp minst er %s bytes."
-#: contrib/admin/views/doc.py:78 contrib/admin/views/doc.py:80
-#: contrib/admin/views/doc.py:82
-msgid "filter:"
+#: core/validators.py:468
+#, python-format
+msgid "Make sure your uploaded file is at most %s bytes big."
msgstr ""
+"Vær sikker på at filen du prøver å laste opp ikke er mer enn %s bytes."
-#: contrib/admin/views/doc.py:136 contrib/admin/views/doc.py:138
-#: contrib/admin/views/doc.py:140
-msgid "view:"
-msgstr ""
+#: core/validators.py:485
+msgid "The format for this field is wrong."
+msgstr "Formatet i dette feltet er feil."
-#: contrib/admin/views/doc.py:165
-#, python-format
-msgid "App %r not found"
-msgstr "Fan ikke applikasjonen %r"
+#: core/validators.py:500
+msgid "This field is invalid."
+msgstr "Dette feltet er ugyldig."
-#: contrib/admin/views/doc.py:172
+#: core/validators.py:536
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Fant ikke %(name)r-modellen i applikasjonen %(label)r"
+msgid "Could not retrieve anything from %s."
+msgstr "Klarte ikke å hente noe fra %s."
-#: contrib/admin/views/doc.py:184
+#: core/validators.py:539
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "det relaterte `%(label)s.%(type)s`-objektet"
-
-#: 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:"
+msgid ""
+"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
msgstr ""
+"Nettadressen %(url)s returnerte den ugyldige Content-Type-headeren "
+"'%(contenttype)s'."
-#: contrib/admin/views/doc.py:215
+#: core/validators.py:572
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "relaterte `%(label)s.%(name)s`-objekter"
+msgid ""
+"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
+"\"%(start)s\".)"
+msgstr ""
+"Vennligst lukk taggen %(tag)s på linje %(line)s. (Linjen starer med "
+"\"%(start)s\".)"
-#: contrib/admin/views/doc.py:220
+#: core/validators.py:576
#, python-format
-msgid "all %s"
-msgstr "alle %s"
+msgid ""
+"Some text starting on line %(line)s is not allowed in that context. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Noe av teksten som starter på linje %(line)s er ikke tillatt. (Linjen "
+"starter med \"%(start)s\".)"
-#: contrib/admin/views/doc.py:225
+#: core/validators.py:581
#, python-format
-msgid "number of %s"
-msgstr "antall %s"
+msgid ""
+"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"%(attr)s\" på linje %(line)s er et ugyldig attributt. (Linjen starter med "
+"\"%(start)s\".)"
-#: contrib/admin/views/doc.py:230
+#: core/validators.py:586
#, python-format
-msgid "Fields on %s objects"
-msgstr "Felter på %s objekter"
+msgid ""
+"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
+"(start)s\".)"
+msgstr ""
+"\"<%(tag)s>\" på linje %(line)s er et ugyldig element. (Linjen starter med "
+"\"%(start)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 "Heltall"
+#: core/validators.py:590
+#, python-format
+msgid ""
+"A tag on line %(line)s is missing one or more required attributes. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"Et element på linje %(line)s mangler et av de påkrevde attributtene. (Linjen "
+"starter med \"%(start)s\".)"
-#: contrib/admin/views/doc.py:293
-msgid "Boolean (Either True or False)"
-msgstr "Boolean (enten \"True\" eller \"False\")"
+#: core/validators.py:595
+#, python-format
+msgid ""
+"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
+"starts with \"%(start)s\".)"
+msgstr ""
+"\"%(attr)s\"-attributtet på linje %(line)s har en ugyldig verdi. (Linjen "
+"starter med \"%(start)s\".)"
-#: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313
+#: db/models/manipulators.py:308
#, python-format
-msgid "String (up to %(max_length)s)"
-msgstr "Tekst (opp til %(max_length)s tegn)"
+msgid "%(object)s with this %(type)s already exists for the given %(field)s."
+msgstr "%(object)s med %(type)s finnes allerede for angitt %(field)s."
-#: contrib/admin/views/doc.py:295
-msgid "Comma-separated integers"
-msgstr "Heltall adskilt med komma"
+#: db/models/fields/__init__.py:52
+#, python-format
+msgid "%(optname)s with this %(fieldname)s already exists."
+msgstr "%(optname)s med %(fieldname)s finnes allerede."
-#: contrib/admin/views/doc.py:296
-msgid "Date (without time)"
-msgstr "Dato (uten tid)"
+#: db/models/fields/__init__.py:182 db/models/fields/__init__.py:354
+#: db/models/fields/__init__.py:788 db/models/fields/__init__.py:799
+#: newforms/fields.py:51 oldforms/__init__.py:374
+msgid "This field is required."
+msgstr "Dette feltet er påkrevd."
-#: contrib/admin/views/doc.py:297
-msgid "Date (with time)"
-msgstr "Dato/tid"
+#: db/models/fields/__init__.py:454
+msgid "This value must be an integer."
+msgstr "Denne verdien må være et heltall."
-#: contrib/admin/views/doc.py:298
-msgid "Decimal number"
-msgstr "Desimaltall"
+#: db/models/fields/__init__.py:493
+msgid "This value must be either True or False."
+msgstr "Denne verdien må være \"True\" eller \"False\"."
-#: contrib/admin/views/doc.py:299
-msgid "E-mail address"
-msgstr "E-postadresse"
+#: db/models/fields/__init__.py:517
+msgid "This field cannot be null."
+msgstr "Dette feltet kan ikke være tomt."
-#: contrib/admin/views/doc.py:300 contrib/admin/views/doc.py:301
-#: contrib/admin/views/doc.py:304
-msgid "File path"
-msgstr "Filsti"
+#: db/models/fields/__init__.py:695
+msgid "This value must be a decimal number."
+msgstr "Denne verdien må være et desimaltall."
-#: contrib/admin/views/doc.py:302
-msgid "Floating point number"
-msgstr "Flyttall"
+#: db/models/fields/__init__.py:808
+msgid "Enter a valid filename."
+msgstr "Skriv inn et gyldig filnavn."
-#: contrib/admin/views/doc.py:308
-msgid "Boolean (Either True, False or None)"
-msgstr "Boolean (enten \"True\", \"False\" eller \"None\")"
+#: db/models/fields/__init__.py:1002
+msgid "This value must be either None, True or False."
+msgstr "Denne verdien må være None, True eller False."
-#: contrib/admin/views/doc.py:309
-msgid "Relation to parent model"
-msgstr "Relasjon til foreldermodell"
+#: db/models/fields/related.py:94
+#, python-format
+msgid "Please enter a valid %s."
+msgstr "Vennligst skriv inn en/et gyldig %s."
-#: contrib/admin/views/doc.py:310
-msgid "Phone number"
-msgstr "Telefonnummer"
+#: db/models/fields/related.py:756
+msgid "Separate multiple IDs with commas."
+msgstr "Separer flere ID-er med komma."
-#: contrib/admin/views/doc.py:315
-msgid "Text"
-msgstr "Tekst"
+#: db/models/fields/related.py:758
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr ""
+"Hold nede \"Control\", eller \"Command\" på en Mac, for å velge mer enn en."
-#: contrib/admin/views/doc.py:316
-msgid "Time"
-msgstr "Tid"
+#: db/models/fields/related.py:805
+#, 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] "Skriv inn gyldige %(self)s ID-er. Verdien %(value)r er ikke gyldig."
+msgstr[1] ""
+"Skriv inn gyldige %(self)s ID-er. Verdiene %(value)r er ikke gyldige."
-#: contrib/admin/views/doc.py:318
-msgid "U.S. state (two uppercase letters)"
-msgstr "Stat (i USA, to store bokstaver)"
+#: newforms/fields.py:52
+msgid "Enter a valid value."
+msgstr "Skriv inn en gyldig verdi."
-#: contrib/admin/views/doc.py:319
-msgid "XML text"
-msgstr "XML-tekst"
+#: newforms/fields.py:129
+#, python-format
+msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
+msgstr "Pass på at denne er på maks %(max)d tegn (den er %(length)d)."
-#: contrib/admin/views/doc.py:345
+#: newforms/fields.py:130
#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr "%s ser ikke ut til å være et urlpattern-objekt"
+msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
+msgstr "Pass på at denne er på minst %(min)d tegn (den er %(length)d)."
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "NÃ¥:"
+#: newforms/fields.py:158 newforms/fields.py:187 newforms/fields.py:216
+#, python-format
+msgid "Ensure this value is less than or equal to %s."
+msgstr "Pass på at denne er mindre eller lik %s."
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Endre:"
+#: newforms/fields.py:159 newforms/fields.py:188 newforms/fields.py:217
+#, python-format
+msgid "Ensure this value is greater than or equal to %s."
+msgstr "Pass på at denne er større eller lik %s."
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Dato:"
+#: newforms/fields.py:186 newforms/fields.py:215
+msgid "Enter a number."
+msgstr "Skriv inn et tall."
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Tid:"
+#: newforms/fields.py:218
+#, python-format
+msgid "Ensure that there are no more than %s digits in total."
+msgstr "Pass på at det ikke er mer enn %s siffer totalt."
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/auth/user/change_password.html:9
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-msgid "Documentation"
-msgstr "Dokumentasjon"
+#: newforms/fields.py:219
+#, python-format
+msgid "Ensure that there are no more than %s decimal places."
+msgstr "Pass på at ikke er mer enn %s desimaler."
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/auth/user/change_password.html:9
-#: contrib/admin/templates/admin/auth/user/change_password.html:15
-#: contrib/admin/templates/admin/auth/user/change_password.html:46
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
-#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_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/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
-msgid "Change password"
-msgstr "Endre passord"
+#: newforms/fields.py:220
+#, python-format
+msgid "Ensure that there are no more than %s digits before the decimal point."
+msgstr "Pass på at det ikke er mer enn %s siffer foran komma."
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/change_list.html:6
-#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/change_form.html:13
-#: contrib/admin/templates/admin/base.html:30
-#: contrib/admin/templates/admin/delete_confirmation.html:6
-#: contrib/admin/templates/admin/auth/user/change_password.html:12
-#: contrib/admin/templates/registration/password_change_done.html:4
-#: contrib/admin/templates/registration/password_reset_form.html:4
-#: contrib/admin/templates/registration/logged_out.html:4
-#: 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 "Hjem"
+#: newforms/fields.py:268 newforms/fields.py:781
+msgid "Enter a valid date."
+msgstr "Skriv inn en gyldig dato."
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/change_form.html:21
-msgid "History"
-msgstr "Historikk"
+#: newforms/fields.py:301 newforms/fields.py:782
+msgid "Enter a valid time."
+msgstr "Skriv inn et gyldig tidspunkt."
-#: contrib/admin/templates/admin/object_history.html:18
-msgid "Date/time"
-msgstr "Dato/tid"
+#: newforms/fields.py:340
+msgid "Enter a valid date/time."
+msgstr "Skriv inn et gyldig tidspunkt."
-#: contrib/admin/templates/admin/object_history.html:19
-msgid "User"
-msgstr "Bruker"
+#: newforms/fields.py:427
+msgid "No file was submitted."
+msgstr "Ingen fil ble sendt."
-#: contrib/admin/templates/admin/object_history.html:20
-msgid "Action"
-msgstr "Handling"
+#: newforms/fields.py:428 oldforms/__init__.py:693
+msgid "The submitted file is empty."
+msgstr "Filen er tom."
-#: contrib/admin/templates/admin/object_history.html:26
-msgid "DATE_WITH_TIME_FULL"
-msgstr "h:i, j. M Y"
+#: newforms/fields.py:524
+msgid "Enter a valid URL."
+msgstr "Skriv inn en gyldig nettadresse."
-#: 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 ""
-"Dette objektet har ingen endringshistorikk. Det var sannsynligvis ikke lagt "
-"til via denne siden."
+#: newforms/fields.py:525
+msgid "This URL appears to be a broken link."
+msgstr "Denne nettadressen fører til en side som ikke eksisterer."
-#: contrib/admin/templates/admin/change_list.html:12
-#, python-format
-msgid "Add %(name)s"
-msgstr "Legg til %(name)s"
+#: newforms/fields.py:590 newforms/models.py:306
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Velg et gyldig valg. Ditt valg er ikke et av de tilgjengelige valgene."
-#: contrib/admin/templates/admin/filter.html:2
+#: newforms/fields.py:629
#, python-format
-msgid " By %(filter_title)s "
-msgstr "Av %(filter_title)s "
-
-#: contrib/admin/templates/admin/500.html:4
-msgid "Server error"
-msgstr "Tjenerfeil"
-
-#: contrib/admin/templates/admin/500.html:6
-msgid "Server error (500)"
-msgstr "Tjenerfeil (500)"
+msgid "Select a valid choice. %(value)s is not one of the available choices."
+msgstr "Velg et gyldig valg. %(value)s er ikke et av de tilgjengelige valgene."
-#: contrib/admin/templates/admin/500.html:9
-msgid "Server Error <em>(500)</em>"
-msgstr "Tjenerfeil <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 ""
-"Det har oppstått en feil. Feilen er blitt rapportert til administrator via e-"
-"post, og vil bli fikset snart. Takk for din tålmodighet."
-
-#: 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 "Noe er galt med databaseinstallasjonen din. Sørg for at "
-"databasetabellene er opprett, og at brukeren har de nødvendige rettigheter."
+#: newforms/fields.py:630 newforms/fields.py:692 newforms/models.py:373
+msgid "Enter a list of values."
+msgstr "Skriv inn en liste med verdier."
-#: contrib/admin/templates/admin/search_form.html:8
-msgid "Go"
-msgstr "GÃ¥"
+#: newforms/fields.py:810
+msgid "Enter a valid IPv4 address."
+msgstr "Skriv inn en gyldig IPv4-adresse."
-#: contrib/admin/templates/admin/search_form.html:10
+#: newforms/models.py:374
#, python-format
-msgid "1 result"
-msgid_plural "%(counter)s results"
-msgstr[0] "Ett resultat"
-msgstr[1] "(counter)s resultat"
+msgid "Select a valid choice. %s is not one of the available choices."
+msgstr "Velg et gyldig valg. %s er ikke et av de tilgjengelige valgene."
-#: contrib/admin/templates/admin/search_form.html:10
+#: oldforms/__init__.py:409
#, python-format
-msgid "%(full_result_count)s total"
-msgstr "%(full_result_count)s totalt"
+msgid "Ensure your text is less than %s character."
+msgid_plural "Ensure your text is less than %s characters."
+msgstr[0] "Pass på at teksten er kortere enn %s tegn."
+msgstr[1] "Pass på at teksten er kortere enn %s tegn."
-#: contrib/admin/templates/admin/pagination.html:10
-msgid "Show all"
-msgstr "Vis alle"
+#: oldforms/__init__.py:414
+msgid "Line breaks are not allowed here."
+msgstr "Det er ikke tillatt med linjeskift her."
-#: contrib/admin/templates/admin/base_site.html:4
-msgid "Django site admin"
-msgstr "Django administrasjonsside"
+#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
+#, python-format
+msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
+msgstr "Velg et gyldig valg. '%(data)s' er ikke i %(choices)s."
-#: contrib/admin/templates/admin/base_site.html:7
-msgid "Django administration"
-msgstr "Django-administrasjon"
+#: oldforms/__init__.py:754
+msgid "Enter a whole number between -32,768 and 32,767."
+msgstr "Skriv inn et heltall mellom -32768 og 32767."
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filter"
+#: oldforms/__init__.py:764
+msgid "Enter a positive number."
+msgstr "Skriv inn et positivt heltall."
-#: contrib/admin/templates/admin/404.html:4
-#: contrib/admin/templates/admin/404.html:8
-msgid "Page not found"
-msgstr "Fant ikke siden"
+#: oldforms/__init__.py:774
+msgid "Enter a whole number between 0 and 32,767."
+msgstr "Skriv inn et heltall mellom 0 og 32767."
-#: contrib/admin/templates/admin/404.html:10
-msgid "We're sorry, but the requested page could not be found."
-msgstr "Beklager, men siden du spør etter finnes ikke."
+#: template/defaultfilters.py:698
+msgid "yes,no,maybe"
+msgstr "ja,nei,kanskje"
-#: contrib/admin/templates/admin/index.html:17
+#: template/defaultfilters.py:729
#, python-format
-msgid "Models available in the %(name)s application."
-msgstr "Modeller tilgjengelig i %(name)s-applikasjonen."
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] ""
+msgstr[1] ""
-#: contrib/admin/templates/admin/index.html:18
+#: template/defaultfilters.py:731
#, python-format
-msgid "%(name)s"
+msgid "%.1f KB"
msgstr ""
-#: contrib/admin/templates/admin/index.html:28
-#: contrib/admin/templates/admin/change_form.html:15
-msgid "Add"
-msgstr "Legg til"
-
-#: contrib/admin/templates/admin/index.html:34
-msgid "Change"
-msgstr "Endre"
-
-#: contrib/admin/templates/admin/index.html:44
-msgid "You don't have permission to edit anything."
-msgstr "Du har ikke rettigheter til å endre noe."
-
-#: contrib/admin/templates/admin/index.html:52
-msgid "Recent Actions"
-msgstr "Siste handlinger"
-
-#: contrib/admin/templates/admin/index.html:53
-msgid "My Actions"
-msgstr "Mine handlinger"
-
-#: contrib/admin/templates/admin/index.html:57
-msgid "None available"
-msgstr "Ingen tilgjengelige"
-
-#: contrib/admin/templates/admin/change_form.html:22
-msgid "View on site"
-msgstr "Vis på nettsted"
-
-#: 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] "Vennligst fiks feilen under."
-msgstr[1] "Vennligst fiks feilene under."
-
-#: contrib/admin/templates/admin/change_form.html:50
-msgid "Ordering"
-msgstr "Rekkefølge"
-
-#: contrib/admin/templates/admin/change_form.html:53
-msgid "Order:"
-msgstr "Rekkefølge:"
-
-#: contrib/admin/templates/admin/base.html:25
-msgid "Welcome,"
-msgstr "Velkommen,"
-
-#: contrib/admin/templates/admin/delete_confirmation.html:9
-#: contrib/admin/templates/admin/submit_line.html:3
-msgid "Delete"
-msgstr "Slett"
-
-#: contrib/admin/templates/admin/delete_confirmation.html:14
+#: template/defaultfilters.py:733
#, 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:"
+msgid "%.1f MB"
msgstr ""
-"Hivs du sletter %(object_name)s '%(escaped_object)s', vil du også slette "
-"relaterte objekter, men du har ikke tillatelse til å slette følgende "
-"objektene:"
-#: contrib/admin/templates/admin/delete_confirmation.html:21
+#: template/defaultfilters.py:734
#, 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:"
+msgid "%.1f GB"
msgstr ""
-"Er du sikker på at du vill slette %(object_name)s \"%(escaped_object)s\"? "
-"Alle de følgende relaterte objektene vil bli slettet:"
-
-#: contrib/admin/templates/admin/delete_confirmation.html:26
-msgid "Yes, I'm sure"
-msgstr "Ja, jeg er sikker"
-#: contrib/admin/templates/admin/submit_line.html:4
-msgid "Save as new"
-msgstr "Lagre som ny"
-
-#: contrib/admin/templates/admin/submit_line.html:5
-msgid "Save and add another"
-msgstr "Lagre og legg til ny"
+#: utils/dateformat.py:41
+msgid "p.m."
+msgstr ""
-#: contrib/admin/templates/admin/submit_line.html:6
-msgid "Save and continue editing"
-msgstr "Lagre og fortsett å endre"
+#: utils/dateformat.py:42
+msgid "a.m."
+msgstr ""
-#: contrib/admin/templates/admin/submit_line.html:7
-msgid "Save"
-msgstr "Lagre"
+#: utils/dateformat.py:47
+msgid "PM"
+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 "Skriv inn et nytt passord for brukeren <strong>%(username)s</strong>."
+#: utils/dateformat.py:48
+msgid "AM"
+msgstr ""
-#: contrib/admin/templates/admin/auth/user/change_password.html:34
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
-msgid "Password"
-msgstr "Passord"
+#: utils/dateformat.py:97
+msgid "midnight"
+msgstr "midnatt"
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-msgid "Password (again)"
-msgstr "Passord (gjenta)"
+#: utils/dateformat.py:99
+msgid "noon"
+msgstr "middag"
-#: 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 "Skriv inn det samme passordet som ovenfor, for verifisering."
+#: utils/dates.py:6
+msgid "Monday"
+msgstr "Mandag"
-#: 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 "Skriv først inn brukernavn og passord. Deretter vil du få mulighet "
-"til å endre flere brukerinnstillinger."
+#: utils/dates.py:6
+msgid "Tuesday"
+msgstr "Tirsdag"
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
-msgid "Username"
-msgstr "Brukernavn"
+#: utils/dates.py:6
+msgid "Wednesday"
+msgstr "Onsdag"
-#: 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 "Endre passord"
+#: utils/dates.py:6
+msgid "Thursday"
+msgstr "Torsdag"
-#: contrib/admin/templates/registration/password_change_done.html:6
-#: contrib/admin/templates/registration/password_change_done.html:10
-msgid "Password change successful"
-msgstr "Passordet er endret"
+#: utils/dates.py:6
+msgid "Friday"
+msgstr "Fredag"
-#: contrib/admin/templates/registration/password_change_done.html:12
-msgid "Your password was changed."
-msgstr "Ditt passord er endret."
+#: utils/dates.py:7
+msgid "Saturday"
+msgstr "Lørdag"
-#: 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 "Tilbakestill passord"
+#: utils/dates.py:7
+msgid "Sunday"
+msgstr "Søndag"
-#: 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 ""
-"Har du glemt passordet ditt? Skriv inn e-postadressen din under, så sender "
-"vi deg et nytt passord til deg."
+#: utils/dates.py:10
+msgid "Mon"
+msgstr "Man"
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "E-mail address:"
-msgstr "E-postadresse:"
+#: utils/dates.py:10
+msgid "Tue"
+msgstr "Tirs"
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "Reset my password"
-msgstr "Tilbakestill mitt passord"
+#: utils/dates.py:10
+msgid "Wed"
+msgstr "Ons"
-#: contrib/admin/templates/registration/logged_out.html:8
-msgid "Thanks for spending some quality time with the Web site today."
-msgstr "Takk for at du valgte å bruke kvalitetstid på nettstedet i dag."
+#: utils/dates.py:10
+msgid "Thu"
+msgstr "Tors"
-#: contrib/admin/templates/registration/logged_out.html:10
-msgid "Log in again"
-msgstr "Logg inn igjen"
+#: utils/dates.py:10
+msgid "Fri"
+msgstr "Fre"
-#: contrib/admin/templates/registration/password_reset_done.html:6
-#: contrib/admin/templates/registration/password_reset_done.html:10
-msgid "Password reset successful"
-msgstr "Passordet ble tilbakestilt"
+#: utils/dates.py:11
+msgid "Sat"
+msgstr "Lør"
-#: 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 ""
-"Vi har sendt deg et nytt passord til e-postadressen du oppgav. Du vil "
-"forhåpentligvis motta det snart."
+#: utils/dates.py:11
+msgid "Sun"
+msgstr "Søn"
-#: 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 ""
-"Venligst skriv inn ditt gamle passord, av sikkerthetsårsaker. Skriv deretter "
-"inn ditt nye passord to ganger, slik at vi kan kontrollere at det er rett."
+#: utils/dates.py:18
+msgid "January"
+msgstr "Januar"
-#: contrib/admin/templates/registration/password_change_form.html:17
-msgid "Old password:"
-msgstr "Gammelt passord:"
+#: utils/dates.py:18
+msgid "February"
+msgstr "Februar"
-#: contrib/admin/templates/registration/password_change_form.html:19
-msgid "New password:"
-msgstr "Nytt passord:"
+#: utils/dates.py:18 utils/dates.py:31
+msgid "March"
+msgstr "Mars"
-#: contrib/admin/templates/registration/password_change_form.html:21
-msgid "Confirm password:"
-msgstr "Gjenta nytt passord:"
+#: utils/dates.py:18 utils/dates.py:31
+msgid "April"
+msgstr "April"
-#: contrib/admin/templates/registration/password_change_form.html:23
-msgid "Change my password"
-msgstr "Endre passord"
+#: utils/dates.py:18 utils/dates.py:31
+msgid "May"
+msgstr "Mai"
-#: contrib/admin/templates/registration/password_reset_email.html:2
-msgid "You're receiving this e-mail because you requested a password reset"
-msgstr ""
-"Du har mottatt denne e-posten fordi du ba om å tilbakestille passordet ditt"
+#: utils/dates.py:18 utils/dates.py:31
+msgid "June"
+msgstr "Juni"
-#: contrib/admin/templates/registration/password_reset_email.html:3
-#, python-format
-msgid "for your user account at %(site_name)s"
-msgstr "for din konto hos %(site_name)s"
+#: utils/dates.py:19 utils/dates.py:31
+msgid "July"
+msgstr "Juli"
-#: contrib/admin/templates/registration/password_reset_email.html:5
-#, python-format
-msgid "Your new password is: %(new_password)s"
-msgstr "Ditt nye passord er: %(new_password)s"
+#: utils/dates.py:19
+msgid "August"
+msgstr "August"
-#: contrib/admin/templates/registration/password_reset_email.html:7
-msgid "Feel free to change this password by going to this page:"
-msgstr "Du kan endre dette passordet ved å gå til denne siden:"
+#: utils/dates.py:19
+msgid "September"
+msgstr "September"
-#: contrib/admin/templates/registration/password_reset_email.html:11
-msgid "Your username, in case you've forgotten:"
-msgstr "I tilfellet du har glemt brukernavnet ditt, så er det:"
+#: utils/dates.py:19
+msgid "October"
+msgstr "Oktober"
-#: contrib/admin/templates/registration/password_reset_email.html:13
-msgid "Thanks for using our site!"
-msgstr "Takk for at du bruker siden vår!"
+#: utils/dates.py:19
+msgid "November"
+msgstr "November"
-#: contrib/admin/templates/registration/password_reset_email.html:15
-#, python-format
-msgid "The %(site_name)s team"
-msgstr "Hilsen %(site_name)s"
+#: utils/dates.py:20
+msgid "December"
+msgstr "Desember"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-msgid "Bookmarklets"
-msgstr "Bokmerker"
+#: utils/dates.py:23
+msgid "jan"
+msgstr "jan"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:5
-msgid "Documentation bookmarklets"
-msgstr "Dokumentasjonsbokmerker"
+#: utils/dates.py:23
+msgid "feb"
+msgstr "feb"
-#: 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\">For å installere bokmerker, dra linken til verktøylinja\n"
-"for bokmerker, eller høyreklikk og legg til i bokmerker. Nå kan du du velge\n"
-"bokmerket fra hvilken som helst side på nettstedet. Noen av disse\n"
-"bokmerkene krever at datamaskinen du bruker er markert som \"intern\"\n"
-"(kontakt din systemadministrator hvis du er usikker på om maskinen din er "
-"\"intern\").</p>\n"
+#: utils/dates.py:23
+msgid "mar"
+msgstr "mar"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:19
-msgid "Documentation for this page"
-msgstr "Dokumentasjon for denne siden"
+#: utils/dates.py:23
+msgid "apr"
+msgstr "apr"
-#: 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 ""
-"Hopp fra hvilken som helst side til dokumentasjonen for visnings funksjonen "
-"som laget siden."
+#: utils/dates.py:23
+msgid "may"
+msgstr "mai"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:22
-msgid "Show object ID"
-msgstr "Vis objekt-ID"
+#: utils/dates.py:23
+msgid "jun"
+msgstr "jun"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:23
-msgid ""
-"Shows the content-type and unique ID for pages that represent a single "
-"object."
-msgstr ""
-"Viser \"content-type\" og en unik ID for sider som representerer et enkelt "
-"objekt."
+#: utils/dates.py:24
+msgid "jul"
+msgstr "jul"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:25
-msgid "Edit this object (current window)"
-msgstr "Endre dette objektet (nåværende vindu)"
+#: utils/dates.py:24
+msgid "aug"
+msgstr "aug"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:26
-msgid "Jumps to the admin page for pages that represent a single object."
-msgstr ""
-"Hopper til administrasjonsiden for sider som representerer et enkelt objekt."
+#: utils/dates.py:24
+msgid "sep"
+msgstr "sep"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:28
-msgid "Edit this object (new window)"
-msgstr "Endre dette objektet (nytt vindu)"
+#: utils/dates.py:24
+msgid "oct"
+msgstr "okt"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:29
-msgid "As above, but opens the admin page in a new window."
-msgstr "Samme som over, men åpner administrasjonsiden i et nytt vindu."
+#: utils/dates.py:24
+msgid "nov"
+msgstr "nov"
-#: contrib/localflavor/no/forms.py:14 contrib/localflavor/ch/forms.py:18
-msgid "Enter a zip code in the format XXXX."
-msgstr "Skriv inn et postnummer som XXXX."
+#: utils/dates.py:24
+msgid "dec"
+msgstr "des"
-#: contrib/localflavor/no/forms.py:35
-msgid "Enter a valid Norwegian social security number."
-msgstr "Skriv et gyldig norsk personnummer."
+#: utils/dates.py:31
+msgid "Jan."
+msgstr "Jan."
-#: template/defaultfilters.py:485
-msgid "yes,no,maybe"
-msgstr "ja,nei,kanskje"
+#: utils/dates.py:31
+msgid "Feb."
+msgstr "Feb."
-#: template/defaultfilters.py:514
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
+#: utils/dates.py:32
+msgid "Aug."
+msgstr "Aug."
-#: template/defaultfilters.py:516
-#, python-format
-msgid "%.1f KB"
-msgstr ""
+#: utils/dates.py:32
+msgid "Sept."
+msgstr "Sept."
-#: template/defaultfilters.py:518
-#, python-format
-msgid "%.1f MB"
-msgstr ""
+#: utils/dates.py:32
+msgid "Oct."
+msgstr "Okt."
-#: template/defaultfilters.py:519
-#, python-format
-msgid "%.1f GB"
-msgstr ""
+#: utils/dates.py:32
+msgid "Nov."
+msgstr "Nov."
-#: 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] "Sjekk at teksten er kortere enn %s tegn."
-msgstr[1] "Sjekk at teksten er kortere enn %s tegn."
+#: utils/dates.py:32
+msgid "Dec."
+msgstr "Des."
-#: oldforms/__init__.py:413
-msgid "Line breaks are not allowed here."
-msgstr "Det er ikke tillatt med linjeskift her."
+#: utils/text.py:128
+msgid "or"
+msgstr "eller"
-#: 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 "Velg et gyldig valg; '%(data)s' er ikke i %(choices)s."
+#: utils/timesince.py:21
+msgid "year"
+msgid_plural "years"
+msgstr[0] "Ã¥r"
+msgstr[1] "Ã¥r"
-#: oldforms/__init__.py:688 newforms/fields.py:380
-msgid "The submitted file is empty."
-msgstr "Filen er tom."
+#: utils/timesince.py:22
+msgid "month"
+msgid_plural "months"
+msgstr[0] "måned"
+msgstr[1] "måneder"
-#: oldforms/__init__.py:744
-msgid "Enter a whole number between -32,768 and 32,767."
-msgstr "Skriv inn et heltall mellom -32768 og 32767."
+#: utils/timesince.py:23
+msgid "week"
+msgid_plural "weeks"
+msgstr[0] "uke"
+msgstr[1] "uker"
-#: oldforms/__init__.py:754
-msgid "Enter a positive number."
-msgstr "Skriv inn et positivt heltall."
+#: utils/timesince.py:24
+msgid "day"
+msgid_plural "days"
+msgstr[0] "dag"
+msgstr[1] "dager"
-#: oldforms/__init__.py:764
-msgid "Enter a whole number between 0 and 32,767."
-msgstr "Skriv inn et heltall mellom 0 og 32767."
+#: utils/timesince.py:25
+msgid "hour"
+msgid_plural "hours"
+msgstr[0] "time"
+msgstr[1] "timer"
-#: newforms/models.py:180 newforms/fields.py:478
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Velg et gyldig valg. Ditt valg er ikke et av de gyldige valgene."
+#: utils/timesince.py:26
+msgid "minute"
+msgid_plural "minutes"
+msgstr[0] "minutt"
+msgstr[1] "minutter"
-#: newforms/models.py:197 newforms/fields.py:494 newforms/fields.py:570
-msgid "Enter a list of values."
-msgstr "Skriv inn en liste med verdier."
+#: utils/timesince.py:46
+msgid "minutes"
+msgstr "minutter"
-#: newforms/models.py:203 newforms/fields.py:500
+#: utils/timesince.py:51
#, python-format
-msgid "Select a valid choice. %s is not one of the available choices."
-msgstr "Velg et gyldig valg; %s er ikke et av de tilgjengelige valgene."
+msgid "%(number)d %(type)s"
+msgstr ""
-#: newforms/fields.py:116
+#: utils/timesince.py:57
#, python-format
-msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
-msgstr "Pass på at denne er på maks %(max)d tegn (den er %(length)d)."
+msgid ", %(number)d %(type)s"
+msgstr ""
-#: newforms/fields.py:118
-#, python-format
-msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
-msgstr "Pass på at denne er på minst %(min)d tegn (den er %(length)d)."
+#: utils/translation/trans_real.py:412
+msgid "DATE_FORMAT"
+msgstr "j. M Y"
-#: 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 "Pass på at denne er mindre eller lik %s."
+#: utils/translation/trans_real.py:413
+msgid "DATETIME_FORMAT"
+msgstr "H:i, j. M Y"
-#: 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 "Pass på at denne er større eller lik %s."
+#: utils/translation/trans_real.py:414
+msgid "TIME_FORMAT"
+msgstr "H:i"
-#: newforms/fields.py:165 newforms/fields.py:192
-msgid "Enter a number."
-msgstr "Skriv inn et tall."
+#: utils/translation/trans_real.py:430
+msgid "YEAR_MONTH_FORMAT"
+msgstr "M Y"
-#: newforms/fields.py:201
-#, python-format
-msgid "Ensure that there are no more than %s digits in total."
-msgstr "Pass på at det ikke er mer enn %s siffer totalt."
+#: utils/translation/trans_real.py:431
+msgid "MONTH_DAY_FORMAT"
+msgstr "j. M"
-#: newforms/fields.py:203
+#: views/generic/create_update.py:43
#, python-format
-msgid "Ensure that there are no more than %s decimal places."
-msgstr "Pass på at ikke er mer enn %s desimaler."
+msgid "The %(verbose_name)s was created successfully."
+msgstr "%(verbose_name)s ble opprettet."
-#: newforms/fields.py:205
+#: views/generic/create_update.py:117
#, python-format
-msgid "Ensure that there are no more than %s digits before the decimal point."
-msgstr "Pass på at det ikke er mer enn %s siffer foran komma."
-
-#: newforms/fields.py:238 newforms/fields.py:610
-msgid "Enter a valid date."
-msgstr "Skriv inn en gyldig dato."
-
-#: newforms/fields.py:265 newforms/fields.py:612
-msgid "Enter a valid time."
-msgstr "Skriv inn et gyldig tidspunkt."
-
-#: newforms/fields.py:301
-msgid "Enter a valid date/time."
-msgstr "Skriv inn et gyldig tidspunkt."
-
-#: newforms/fields.py:314
-msgid "Enter a valid value."
-msgstr "Skriv inn en gyldig verdi."
-
-#: newforms/fields.py:378
-msgid "No file was submitted."
-msgstr "Ingen fil ble sendt."
-
-#: newforms/fields.py:403 newforms/fields.py:425
-msgid "Enter a valid URL."
-msgstr "Skriv inn en gyldig URL."
-
-#: newforms/fields.py:427
-msgid "This URL appears to be a broken link."
-msgstr "Denne URL'en fører til en side som ikke eksisterer."
+msgid "The %(verbose_name)s was updated successfully."
+msgstr "%(verbose_name)s ble oppdatert."
+#: views/generic/create_update.py:184
+#, python-format
+msgid "The %(verbose_name)s was deleted."
+msgstr "%(verbose_name)s ble slettet."
diff --git a/django/conf/locale/pl/LC_MESSAGES/django.mo b/django/conf/locale/pl/LC_MESSAGES/django.mo
index 5cdabb1d11..9ad15e833a 100644
--- a/django/conf/locale/pl/LC_MESSAGES/django.mo
+++ b/django/conf/locale/pl/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/pl/LC_MESSAGES/django.po b/django/conf/locale/pl/LC_MESSAGES/django.po
index 6f73bb45d0..77605f1627 100644
--- a/django/conf/locale/pl/LC_MESSAGES/django.po
+++ b/django/conf/locale/pl/LC_MESSAGES/django.po
@@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-06-24 07:36+0200\n"
+"POT-Creation-Date: 2008-07-27 21:57+0200\n"
"PO-Revision-Date: 2008-02-25 15:53+0100\n"
"Last-Translator: Jarek Zgoda <jarek.zgoda@gmail.com>\n"
"Language-Team: Polish <pl@li.org>\n"
@@ -246,49 +246,207 @@ msgstr "Ten miesiÄ…c"
msgid "This year"
msgstr "Ten rok"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Tak"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "Nie"
-#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:154 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Nieznany"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "czas akcji"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "id obiektu"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "reprezentacja obiektu"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "flaga akcji"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "zmień wiadomość"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "log"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "logi"
+#: contrib/admin/options.py:161 contrib/admin/options.py:180
+msgid "None"
+msgstr "brak"
+
+#: contrib/admin/options.py:347 contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "%(name)s \"%(obj)s\" dodany pomyślnie."
+
+#: contrib/admin/options.py:351 contrib/admin/options.py:419
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "Możesz ponownie edytować wpis poniżej."
+
+#: contrib/admin/options.py:361 contrib/admin/options.py:428
+#, python-format
+msgid "You may add another %s below."
+msgstr "Możesz dodać nowy wpis %s poniżej."
+
+#: contrib/admin/options.py:395
+#, python-format
+msgid "Changed %s."
+msgstr "Zmieniono %s"
+
+#: contrib/admin/options.py:395 contrib/admin/options.py:405
+#: core/validators.py:279 db/models/manipulators.py:305
+msgid "and"
+msgstr "i"
+
+#: contrib/admin/options.py:400
+#, python-format
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Dodano %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:404
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Zmieniono %(list)s w %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:409
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Usunięto %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:414
+msgid "No fields changed."
+msgstr "Żadne pole nie zmienione."
+
+#: contrib/admin/options.py:417
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "%(name)s \"%(obj)s\" zostało pomyślnie zmienione."
+
+#: contrib/admin/options.py:425
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"%(name)s \"%(obj)s\" dodane pomyślnie. Możesz edytować ponownie wpis poniżej."
+
+#: contrib/admin/options.py:506
+#, python-format
+msgid "Add %s"
+msgstr "Dodaj %s"
+
+#: contrib/admin/options.py:568
+#, python-format
+msgid "Change %s"
+msgstr "Zmień %s"
+
+#: contrib/admin/options.py:598
+msgid "Database error"
+msgstr "BÅ‚Ä…d bazy danych"
+
+#: contrib/admin/options.py:647
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "%(name)s \"%(obj)s\" usunięty pomyślnie."
+
+#: contrib/admin/options.py:653
+msgid "Are you sure?"
+msgstr "JesteÅ› pewien?"
+
+#: contrib/admin/options.py:680
+#, python-format
+msgid "Change history: %s"
+msgstr "Historia zmian: %s"
+
+#: contrib/admin/sites.py:18 contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:70 contrib/comments/views/comments.py:56
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Proszę wpisać poprawną nazwę użytkownika i hasło. Uwaga: wielkość liter ma "
+"znaczenie."
+
+#: contrib/admin/sites.py:233 contrib/admin/views/decorators.py:68
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Zaloguj się ponownie. Twoja sesja wygasła lecz twoje zgłoszenie zostało "
+"zapisane."
+
+#: contrib/admin/sites.py:240 contrib/admin/views/decorators.py:75
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Twoja przeglądarka nie chce akceptować ciasteczek. Zmień jej ustawienia i "
+"spróbuj ponownie."
+
+#: contrib/admin/sites.py:254 contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Nazwy użytkowników nie mogą zawierać znaków '@'."
+
+#: contrib/admin/sites.py:257 contrib/admin/views/decorators.py:88
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "Twój adres e-mail to nie jest twój login. Spróbuj '%s'."
+
+#: contrib/admin/sites.py:325
+msgid "Site administration"
+msgstr "Administracja stronÄ…"
+
+#: contrib/admin/sites.py:347 contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Zaloguj siÄ™"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Jedno lub więcej %(fieldname)s w %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Jedno lub więcej %(fieldname)s w %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Data:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Czas:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Teraz:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Zmień:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -299,17 +457,17 @@ msgid "We're sorry, but the requested page could not be found."
msgstr "Niestety, żądana strona nie została znaleziona."
#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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: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"
@@ -335,22 +493,28 @@ msgstr ""
"Wystąpił niespodziewany błąd. Raport został wysłany e-mailem "
"administratorowi strony."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Witaj,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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 "Dokumentacja"
-#: contrib/admin/templates/admin/base.html:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Zmiana hasła"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Wyloguj siÄ™"
@@ -363,47 +527,44 @@ msgstr "Administracja stronÄ… Django"
msgid "Django administration"
msgstr "Administracja Django"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Dodaj"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Historia"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Pokaż na stronie"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
msgid "Please correct the error below."
msgid_plural "Please correct the errors below."
msgstr[0] "Proszę popraw poniższy błąd"
msgstr[1] "Proszę popraw poniższe błędy"
msgstr[2] "Proszę popraw poniższe błędy"
-#: contrib/admin/templates/admin/change_form.html:49
-msgid "Ordering"
-msgstr "Sortowanie"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "PorzÄ…dek:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "Dodaj %(name)s"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filtr"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Usuń"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, python-format
msgid ""
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
@@ -414,7 +575,7 @@ msgstr ""
"zależnych obiektów, lecz nie posiadasz uprawnień do usunięcia następujących "
"typów obiektów:"
-#: contrib/admin/templates/admin/delete_confirmation.html:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, python-format
msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
@@ -423,7 +584,7 @@ msgstr ""
"Czy chcesz skasować %(object_name)s \"%(escaped_object)s\"? Następujące "
"zależne obiekty zostaną skasowane:"
-#: contrib/admin/templates/admin/delete_confirmation.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Tak, na pewno"
@@ -432,41 +593,37 @@ msgstr "Tak, na pewno"
msgid " By %(filter_title)s "
msgstr " Używając %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filtr"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "Models available in the %(name)s application."
msgstr "Modele dostępne w aplikacji %(name)s."
-#: contrib/admin/templates/admin/index.html:18
+#: contrib/admin/templates/admin/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Zmień"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "Nie masz uprawnień by edytować cokolwiek"
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Ostatnie akcje"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Moje akcje"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Brak"
-#: contrib/admin/templates/admin/invalid_setup.html:8
+#: contrib/admin/templates/admin/invalid_setup.html:7
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 "
@@ -476,39 +633,34 @@ msgstr ""
"tabele zostały utworzone i odpowiedni użytkownik jest uprawniony do ich "
"odczytu."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
msgid "Username:"
msgstr "Nazwa użytkownika:"
-#: contrib/admin/templates/admin/login.html:20
+#: contrib/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Hasło:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Zaloguj siÄ™"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Data/czas"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Użytkownik"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Akcja"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "j F Y H:i:s"
-#: contrib/admin/templates/admin/object_history.html:35
+#: contrib/admin/templates/admin/object_history.html:32
msgid ""
"This object doesn't have a change history. It probably wasn't added via this "
"admin site."
@@ -561,26 +713,29 @@ msgstr ""
"Najpierw podaj nazwę użytkownika i hasło. Następnie będziesz mógł edytować "
"więcej opcji użytkownika."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:12 contrib/auth/forms.py:49
msgid "Username"
msgstr "Nazwa użytkownika"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:15 contrib/auth/forms.py:50 contrib/auth/forms.py:166
msgid "Password"
msgstr "Hasło"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:167
msgid "Password (again)"
msgstr "Hasło (powtórz)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Podaj powyższe hasło w celu weryfikacji."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr "Podaj nowe hasło dla użytkownika <strong>%(username)s</strong>."
@@ -661,41 +816,41 @@ msgstr "Dziękujemy za odwiedzenie serwisu."
msgid "Log in again"
msgstr "Zaloguj ponownie"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 "Zmiana hasła"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: contrib/admin/templates/registration/password_change_done.html:6
+#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
msgstr "Hasło zmienione"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Twoje hasło zostało zmienione"
-#: contrib/admin/templates/registration/password_change_form.html:11
+#: 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 "Podaj swoje stare hasło i dwa razy nowe."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Stare hasło:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Nowe hasło:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Potwierdź hasło:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Zmień hasło"
@@ -765,325 +920,210 @@ msgstr "Adres e-mail:"
msgid "Reset my password"
msgstr "Zresetuj moje hasło"
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Data:"
-
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Czas:"
-
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Teraz:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Zmień:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Wszystkie daty"
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "%(name)s \"%(obj)s\" dodany pomyślnie."
-
-#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "Możesz ponownie edytować wpis poniżej."
-
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Dodaj użytkownika"
-
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Hasło zostało zmienione pomyślnie."
-
-#: contrib/admin/views/auth.py:65
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Change password: %s"
-msgstr "Zmień hasło: %s"
-
-#: contrib/admin/views/decorators.py:17 contrib/auth/forms.py:60
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"Proszę wpisać poprawną nazwę użytkownika i hasło. Uwaga: wielkość liter ma "
-"znaczenie."
-
-#: contrib/admin/views/decorators.py:69
-msgid ""
-"Please log in again, because your session has expired. Don't worry: Your "
-"submission has been saved."
-msgstr ""
-"Zaloguj się ponownie. Twoja sesja wygasła lecz twoje zgłoszenie zostało "
-"zapisane."
-
-#: contrib/admin/views/decorators.py:76
-msgid ""
-"Looks like your browser isn't configured to accept cookies. Please enable "
-"cookies, reload this page, and try again."
-msgstr ""
-"Twoja przeglądarka nie chce akceptować ciasteczek. Zmień jej ustawienia i "
-"spróbuj ponownie."
+msgid "Select %s"
+msgstr "Zaznacz %s"
-#: contrib/admin/views/decorators.py:89
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Twój adres e-mail to nie jest twój login. Spróbuj '%s'."
-
-#: contrib/admin/views/decorators.py:93
-msgid "Usernames cannot contain the '@' character."
-msgstr "Nazwy użytkowników nie mogą zawierać znaków '@'."
+msgid "Select %s to change"
+msgstr "Zaznacz %s aby zmienić"
-#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53 contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "tag:"
-#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87 contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filtr:"
-#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153 contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "widok:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Aplikacja %r nie została znaleziona"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Model %(name)r nie został znaleziony w aplikacji %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Model %(model_name)r nie został znaleziony w aplikacji %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "powiÄ…zany obiekt `%(label)s.%(type)s`"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "powiÄ…zany obiekt `%(app_label)s.%(data_type)s`"
-#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206 contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242 contrib/admindocs/views.py:247
msgid "model:"
msgstr "model:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "powiÄ…zane obiekty `%(label)s.%(name)s`"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "powiÄ…zane obiekty `%(app_label)s.%(object_name)s`"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "wszystkie %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "liczba %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Pola obiektów %s"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317 contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330 contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337 contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Liczba całkowita"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Wartość logiczna (True, False - prawda lub fałsz)"
-#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319 contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "ÅaÅ„cuch (do %(max_length)s znaków)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Liczby całkowite rozdzielone przecinkami"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Data (bez godziny)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Data (z godzinÄ…)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Numer dziesiętny"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "Adres e-mail"
-#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325 contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Ścieżka do pliku"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Liczba zmiennoprzecinkowa"
-#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331 contrib/comments/models.py:89
msgid "IP address"
msgstr "Adres IP"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Wartość logiczna (True, False, None - prawda, fałsz lub nic)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Relacja do modelu rodzica"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Numer telefonu"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Tekst"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Czas"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
+#: contrib/admindocs/views.py:342 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Stan USA (dwie duże litery)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "Tekst XML"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s nie jest obiektem urlpattern"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Administracja stronÄ…"
-
-#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "Możesz dodać nowy wpis %s poniżej."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Dodaj %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "Dodano %s"
-
-#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348 core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "i"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Dane osobowe"
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "Zmieniono %s"
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Uprawnienia"
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "Skasowano %s"
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Ważne daty"
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "Żadne pole nie zmienione."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Grupy"
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "%(name)s \"%(obj)s\" zostało pomyślnie zmienione."
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Dodaj użytkownika"
-#: contrib/admin/views/main.py:362
-#, python-format
+#: contrib/auth/forms.py:13 contrib/auth/models.py:134
msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
msgstr ""
-"%(name)s \"%(obj)s\" dodane pomyślnie. Możesz edytować ponownie wpis poniżej."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Zmień %s"
-
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Jedno lub więcej %(fieldname)s w %(name)s: %(obj)s"
-
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Jedno lub więcej %(fieldname)s w %(name)s:"
-
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "%(name)s \"%(obj)s\" usunięty pomyślnie."
-
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "JesteÅ› pewien?"
-
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Historia zmian: %s"
+"Wymagane. 30 znaków lub mniej. Tylko znaki alfanumeryczne (litery, cyfry i "
+"podkreślenia)."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Zaznacz %s"
+#: contrib/auth/forms.py:14 core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "To pole może zawierać tylko litery, cyfry i podkreślenia."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Zaznacz %s aby zmienić"
+#: contrib/auth/forms.py:16
+msgid "Password confirmation"
+msgstr "Potwierdzenie hasła"
-#: contrib/admin/views/main.py:765
-msgid "Database error"
-msgstr "BÅ‚Ä…d bazy danych"
+#: contrib/auth/forms.py:28
+msgid "A user with that username already exists."
+msgstr "Użytkownik o tej nazwie już istnieje."
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+#: contrib/auth/forms.py:34 contrib/auth/forms.py:153
+#: contrib/auth/forms.py:178
msgid "The two password fields didn't match."
msgstr "Hasła się nie zgadzają."
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "Użytkownik o tej nazwie już istnieje."
+#: contrib/auth/forms.py:72 contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "To konto jest nieaktywne."
-#: contrib/auth/forms.py:53
+#: contrib/auth/forms.py:77 contrib/comments/views/comments.py:49
msgid ""
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
"required for logging in."
@@ -1091,11 +1131,11 @@ msgstr ""
"Twoja przeglądarka nie chce akceptować ciasteczek. Są one wymagane do "
"zalogowania siÄ™."
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "To konto jest nieaktywne."
+#: contrib/auth/forms.py:90
+msgid "E-mail"
+msgstr "E-mail"
-#: contrib/auth/forms.py:84
+#: contrib/auth/forms.py:99
msgid ""
"That e-mail address doesn't have an associated user account. Are you sure "
"you've registered?"
@@ -1103,16 +1143,24 @@ msgstr ""
"Ten adres e-mail nie ma przypisanego konta. Jesteś pewien, że "
"zarejestrowałeś się?"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:124
#, python-format
msgid "Password reset on %s"
msgstr "Hasło zresetowane dla %s"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "Pola 'nowe hasło' nie zgadzają się."
+#: contrib/auth/forms.py:131
+msgid "Old password"
+msgstr "Stare hasło"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:132
+msgid "New password"
+msgstr "Nowe hasło"
+
+#: contrib/auth/forms.py:133
+msgid "New password confirmation"
+msgstr "Nowe hasło ponownie"
+
+#: contrib/auth/forms.py:145
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "Podane stare hasło jest niepoprawne. Proszę podać je jeszcze raz."
@@ -1136,39 +1184,31 @@ msgstr "uprawnienia"
msgid "group"
msgstr "grupa"
-#: contrib/auth/models.py:98 contrib/auth/models.py:148
+#: contrib/auth/models.py:98 contrib/auth/models.py:144
msgid "groups"
msgstr "grupy"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:134
msgid "username"
msgstr "użytkownik"
-#: contrib/auth/models.py:138
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr ""
-"Wymagane. 30 znaków lub mniej. Tylko znaki alfanumeryczne (litery, cyfry i "
-"podkreślenia)."
-
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "ImiÄ™"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "Nazwisko"
-#: contrib/auth/models.py:141
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "adres e-mail"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid "password"
msgstr "hasło"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:138
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -1176,19 +1216,19 @@ msgstr ""
"Użyj '[algo]$[salt]$[hexdigest]' lub <a href=\"password/\">formularza zmiany "
"hasła</a>."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "w zespole"
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
msgstr "Oznacza czy użytkownik może zalogować się do panelu admina."
-#: contrib/auth/models.py:144
+#: contrib/auth/models.py:140
msgid "active"
msgstr "aktywny"
-#: contrib/auth/models.py:144
+#: contrib/auth/models.py:140
msgid ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
@@ -1196,11 +1236,11 @@ msgstr ""
"Oznacza czy użytkownika należy uważać za aktywnego. Odznacz tozamiast usuwać "
"konta."
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "Główny Administrator"
-#: contrib/auth/models.py:145
+#: contrib/auth/models.py:141
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
@@ -1208,15 +1248,15 @@ msgstr ""
"Oznacza, że ten użytkownik ma wszystkie uprawnienia bez jawnego "
"przypisywania ich."
-#: contrib/auth/models.py:146
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "ostatnio zalogowany"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "data przyłączenia"
-#: contrib/auth/models.py:149
+#: contrib/auth/models.py:145
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -1224,43 +1264,36 @@ msgstr ""
"Oprócz uprawnień przypisanych bezpośrednio użytkownikowi otrzyma on "
"uprawnienia grup, do których należy."
-#: contrib/auth/models.py:150
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "uprawnienia użytkownika"
-#: contrib/auth/models.py:154
+#: contrib/auth/models.py:150
msgid "user"
msgstr "użytkownik"
-#: contrib/auth/models.py:155
+#: contrib/auth/models.py:151
msgid "users"
msgstr "użytkownicy"
-#: contrib/auth/models.py:161
-msgid "Personal info"
-msgstr "Dane osobowe"
-
-#: contrib/auth/models.py:162
-msgid "Permissions"
-msgstr "Uprawnienia"
-
-#: contrib/auth/models.py:163
-msgid "Important dates"
-msgstr "Ważne daty"
-
-#: contrib/auth/models.py:164
-msgid "Groups"
-msgstr "Grupy"
-
-#: contrib/auth/models.py:323
+#: contrib/auth/models.py:306
msgid "message"
msgstr "wiadomość"
-#: contrib/auth/views.py:48
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "Wylogowany"
-#: contrib/comments/models.py:71 contrib/comments/models.py:176
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "Hasło zostało zmienione pomyślnie."
+
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Zmień hasło: %s"
+
+#: contrib/comments/models.py:71 contrib/comments/models.py:164
msgid "object ID"
msgstr "ID obiektu"
@@ -1269,7 +1302,7 @@ msgid "headline"
msgstr "nagłówek"
#: contrib/comments/models.py:73 contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "komentarz"
@@ -1309,11 +1342,11 @@ msgstr "ocena #8"
msgid "is valid rating"
msgstr "jest poprawnÄ… ocenÄ…"
-#: contrib/comments/models.py:87 contrib/comments/models.py:179
+#: contrib/comments/models.py:87 contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "data/czas dodania"
-#: contrib/comments/models.py:88 contrib/comments/models.py:180
+#: contrib/comments/models.py:88 contrib/comments/models.py:168
msgid "is public"
msgstr "publicznie dostępny"
@@ -1333,11 +1366,11 @@ msgstr ""
msgid "comments"
msgstr "komentarze"
-#: contrib/comments/models.py:140 contrib/comments/models.py:222
+#: contrib/comments/models.py:128 contrib/comments/models.py:199
msgid "Content object"
msgstr "Obiekt treści"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1352,48 +1385,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "Nazwa osoby"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "adres ip"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "zaakceptowano"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "wolny komentarz"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "wolne komentarze"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "ilość punktów"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "data przyznania punktów"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "ilość punktów"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "wyniki"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "%(score)d ocenÄ™ przez %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1404,36 +1437,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "data flagi"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "flaga użytkownika"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "flagi użytkownika"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Flaga %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "data skasowania"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "usunięcie moderatora"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "usunięcia moderatorów"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Usunięcie moderatora przez %r"
@@ -1474,12 +1507,12 @@ msgstr "PodglÄ…d"
msgid "Your name:"
msgstr "Twoje imiÄ™:"
-#: contrib/comments/views/comments.py:28
+#: contrib/comments/views/comments.py:76
msgid ""
"This rating is required because you've entered at least one other rating."
msgstr "Ta ocena jest wymagana gdyż podałeś przynajmniej jedną inną ocenę."
-#: contrib/comments/views/comments.py:112
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
"This comment was posted by a user who has posted fewer than %(count)s "
@@ -1507,7 +1540,7 @@ msgstr[2] ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1518,25 +1551,25 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Dozwolone tylko POSTy"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
msgid "One or more of the required fields wasn't submitted"
msgstr "Jedno lub więcej wymaganych pól nie zostało wypełnionych"
-#: contrib/comments/views/comments.py:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
msgid "Somebody tampered with the comment form (security violation)"
msgstr ""
"Ktoś próbował obejść zabezpieczenia formularza komentarzy (naruszenie "
"bezpieczeństwa)"
-#: contrib/comments/views/comments.py:208
-#: contrib/comments/views/comments.py:295
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
msgid ""
"The comment form had an invalid 'target' parameter -- the object ID was "
"invalid"
@@ -1544,8 +1577,8 @@ msgstr ""
"Formularz komentarza miał niepoprawny parametr 'target' -- ID obiektu było "
"niepoprawne"
-#: contrib/comments/views/comments.py:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Formularz komentarza nie zapewnił obiektów 'preview' ani 'post'"
@@ -1573,6 +1606,10 @@ msgstr "typ zawartości"
msgid "content types"
msgstr "typy zawartości"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Opcje zaawansowane"
+
#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
@@ -1621,10 +1658,6 @@ msgstr "strona statyczna"
msgid "flat pages"
msgstr "strony statyczne"
-#: contrib/flatpages/models.py:27
-msgid "Advanced options"
-msgstr "Opcje zaawansowane"
-
#: contrib/humanize/templatetags/humanize.py:19
msgid "th"
msgstr "-y"
@@ -1735,6 +1768,53 @@ msgstr "Podaj poprawny numer CUIT w formacie XX-XXXXXXXX-X lub XXXXXXXXXXXX."
msgid "Invalid CUIT."
msgstr "Niepoprawny CUIT"
+#: contrib/localflavor/at/at_states.py:5
+#, fuzzy
+msgid "Burgenland"
+msgstr "Fryzja"
+
+#: contrib/localflavor/at/at_states.py:6
+msgid "Carinthia"
+msgstr "Karyntia"
+
+#: contrib/localflavor/at/at_states.py:7
+msgid "Lower Austria"
+msgstr "Dolna Austria"
+
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr "Górna Austria"
+
+#: contrib/localflavor/at/at_states.py:9
+msgid "Salzburg"
+msgstr "Salzburg"
+
+#: contrib/localflavor/at/at_states.py:10
+msgid "Styria"
+msgstr "Styria"
+
+#: contrib/localflavor/at/at_states.py:11
+msgid "Tyrol"
+msgstr "Tyrol"
+
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr "Vorarlberg"
+
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr "Wiedeń"
+
+#: contrib/localflavor/at/forms.py:20 contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Wpisz kod pocztowy w formacie XXXX."
+
+#: contrib/localflavor/at/forms.py:48
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
+msgstr ""
+"Wpisz poprawny numer austriackiego ubezpieczenia w formacie XXXX XXXXXX."
+
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
msgstr "Wpisz czterocyfrowy kod pocztowy."
@@ -1884,10 +1964,6 @@ msgstr "Zug"
msgid "Zurich"
msgstr "Zurych"
-#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
-msgid "Enter a zip code in the format XXXX."
-msgstr "Wpisz kod pocztowy w formacie XXXX."
-
#: contrib/localflavor/ch/forms.py:64
msgid ""
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
@@ -2808,6 +2884,26 @@ msgstr "Wielkopolskie"
msgid "West Pomerania"
msgstr "Zachodniopomorskie"
+#: contrib/localflavor/ro/forms.py:19
+msgid "Enter a valid CIF."
+msgstr "Wpisz poprawny CIF."
+
+#: contrib/localflavor/ro/forms.py:56
+msgid "Enter a valid CNP."
+msgstr "Wpisz poprawny CNP."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr "Podaj poprawny IBAN w formacie ROXX-XXXX-XXXX-XXXX-XXXX-XXXX"
+
+#: contrib/localflavor/ro/forms.py:171
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Numery telefoniczne muszą być w formacie XXXX-XXXXXX."
+
+#: contrib/localflavor/ro/forms.py:194
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Wpisz kod pocztowy w formacie XXXXXX."
+
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
msgstr "Wpisz kod pocztowy w formacie XXXXX or XXX XX."
@@ -3552,18 +3648,14 @@ msgstr "nazwa domeny"
msgid "display name"
msgstr "wyświetlana nazwa"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "strona"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "strony"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "To pole może zawierać tylko litery, cyfry i podkreślenia."
-
#: core/validators.py:76
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
@@ -3608,7 +3700,7 @@ msgstr "Tu mogą być tylko cyfry."
msgid "This value can't be comprised solely of digits."
msgstr "To pole nie może zawierać jedynie cyfr."
-#: core/validators.py:128 newforms/fields.py:152
+#: core/validators.py:128 forms/fields.py:158
msgid "Enter a whole number."
msgstr "Wpisz liczbę całkowitą."
@@ -3617,36 +3709,31 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Tutaj sÄ… dozwolone tylko litery."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "Rok nie może być wcześniejszy niż 1900."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Niepoprawna data: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:548
+#: core/validators.py:152 db/models/fields/__init__.py:559
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Proszę wpisać poprawną datę w formacie RRRR-MM-DD."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Proszę wpisać poprawną godzinę w formacie HH:MM."
-#: core/validators.py:165 db/models/fields/__init__.py:625
+#: core/validators.py:161 db/models/fields/__init__.py:640
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Wprowadź poprawną datę i godzinę w formacie RRRR-MM-DD GG:MM."
-#: core/validators.py:170 newforms/fields.py:403
+#: core/validators.py:166 forms/fields.py:409
msgid "Enter a valid e-mail address."
msgstr "Wprowadź poprawny adres e-mail."
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:433
-#: oldforms/__init__.py:687
+#: core/validators.py:178 core/validators.py:470 forms/fields.py:427
msgid "No file was submitted. Check the encoding type on the form."
msgstr "Nie wysłano żadnego pliku. Sprawdź typ kodowania formularza."
-#: core/validators.py:193 newforms/fields.py:459
+#: core/validators.py:189 forms/fields.py:467
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
@@ -3654,28 +3741,28 @@ msgstr ""
"Wgraj poprawny plik graficzny. Ten, który został wgrany, nie jest obrazem, "
"albo jest uszkodzony."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "Odnośnik %s nie wskazuje na poprawny plik z obrazem."
-#: core/validators.py:204
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
"Numery telefoniczne muszą być w formacie XXX-XXX-XXXX. \"%s\" jest "
"niepoprawny."
-#: core/validators.py:212
+#: core/validators.py:208
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "Odnośnik %s nie wskazuje na poprawne nagranie QuickTime video."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Wymagany jest poprawny URL."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3684,26 +3771,26 @@ msgstr ""
"Wymagany jest poprawny HTML. Błędy, które wystąpiły:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "Nieprawidłowy format XML: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "Niepoprawny odnośnik: %s"
-#: core/validators.py:259 core/validators.py:261
+#: core/validators.py:255 core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "Odnośnik %s jest nieprawidłowy."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Wpisz poprawny kod stanu U.S.A."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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."
@@ -3711,59 +3798,59 @@ msgstr[0] "Nie wolno przeklinać! Słowo %s nie jest dozwolone."
msgstr[1] "Nie wolno przeklinać! Słowa %s nie są dozwolone."
msgstr[2] "Nie wolno przeklinać! Słowa %s nie są dozwolone."
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "To pole musi pasować do pola '%s'."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Proszę uzupełnić przynajmniej jedno pole."
-#: core/validators.py:316 core/validators.py:327
+#: core/validators.py:312 core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Proszę uzupełnić oba pola lub zostawić je puste."
-#: core/validators.py:335
+#: core/validators.py:331
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "To pole musi być uzupełnione, jeśli %(field)s ma wartość %(value)s"
-#: core/validators.py:348
+#: core/validators.py:344
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr ""
"To pole musi być uzupełnione, jeśli %(field)s ma wartość inną niż %(value)s"
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Duplikaty nie sÄ… dozwolone."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Ta wartość musi być pomiędzy %(lower)s a %(upper)s."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Ta wartość nie może być mniejsza od %s."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Ta wartość nie może być większa od %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Ta wartość musi być potęgą %s."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Proszę wpisać poprawną liczbę dziesiętną."
-#: core/validators.py:444
+#: core/validators.py:440
#, python-format
msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
@@ -3775,7 +3862,7 @@ msgstr[1] ""
msgstr[2] ""
"Proszę wpisać poprawną liczbę dziesiętną o nie więcej niż %s cyfrach."
-#: core/validators.py:447
+#: core/validators.py:443
#, python-format
msgid ""
"Please enter a valid decimal number with a whole part of at most %s digit."
@@ -3788,7 +3875,7 @@ msgstr[1] ""
msgstr[2] ""
"Proszę wpisać poprawną liczbę dziesiętną zawierającą nie więcej niż %s cyfr."
-#: core/validators.py:450
+#: core/validators.py:446
#, python-format
msgid "Please enter a valid decimal number with at most %s decimal place."
msgid_plural ""
@@ -3803,41 +3890,41 @@ msgstr[2] ""
"Proszę wpisać poprawną liczbę dziesiętną z dokładnością do %s miejsc po "
"przecinku."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Proszę wpisać poprawną liczbę rzeczywistą."
-#: core/validators.py:467
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "Upewnij się, że wgrany plik ma conajmniej %s bajtów."
-#: core/validators.py:468
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "Upewnij się, że wgrany plik ma co najwyżej %s bajtów."
-#: core/validators.py:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Format tego pola jest nieprawidłowy."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "To pole jest nieprawidłowe."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Nie można nic pobrać z %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, python-format
msgid ""
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
msgstr ""
"URL %(url)s zwrócił niepoprawny nagłówek Content-Type '%(contenttype)s'."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
@@ -3846,7 +3933,7 @@ msgstr ""
"Proszę zamknąć tag %(tag)s z linii %(line)s. (Linia zaczyna się od \"%(start)"
"s\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
@@ -3855,7 +3942,7 @@ msgstr ""
"Część tekstu od linii %(line)s nie jest dozwolony w tym kontekście. (Linia "
"zaczyna siÄ™ od \"%(start)s\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
@@ -3864,7 +3951,7 @@ msgstr ""
"\"%(attr)s\" w linii %(line)s jest niepoprawnym atrybutem. (Linia zaczyna "
"siÄ™ od \"%(start)s\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
@@ -3873,7 +3960,7 @@ msgstr ""
"\"<%(tag)s>\" w linii %(line)s nie jest poprawnym tagiem. (Linia zaczyna siÄ™ "
"od \"%(start)s\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
@@ -3882,7 +3969,7 @@ msgstr ""
"Tag w linii %(line)s nie posiada jednego lub więcej wymaganych atrybutów. "
"(Linia zaczyna siÄ™ od \"%(start)s\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
@@ -3891,65 +3978,61 @@ msgstr ""
"Atrybut \"%(attr)s\" w linii %(line)s ma niepoprawną wartość. (Linia zaczyna "
"siÄ™ od \"%(start)s\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "%(object)s z %(type)s już istnieje dla %(field)s."
-#: db/models/fields/__init__.py:51
+#: db/models/fields/__init__.py:47
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "Już istnieje %(optname)s z %(fieldname)s."
-#: db/models/fields/__init__.py:176 db/models/fields/__init__.py:348
-#: db/models/fields/__init__.py:780 db/models/fields/__init__.py:791
-#: newforms/fields.py:46 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:175 db/models/fields/__init__.py:343
+#: db/models/fields/__init__.py:802 db/models/fields/__init__.py:813
+#: forms/fields.py:52 oldforms/__init__.py:374
msgid "This field is required."
msgstr "To pole jest wymagane."
-#: db/models/fields/__init__.py:448
+#: db/models/fields/__init__.py:457
msgid "This value must be an integer."
msgstr "Ta wartość musi być liczbą całkowitą."
-#: db/models/fields/__init__.py:487
+#: db/models/fields/__init__.py:498
msgid "This value must be either True or False."
msgstr ""
"Ta wartość musi być wartością logiczną (True, False - prawda lub fałsz)."
-#: db/models/fields/__init__.py:511
+#: db/models/fields/__init__.py:522
msgid "This field cannot be null."
msgstr "To pole nie może być puste."
-#: db/models/fields/__init__.py:689
+#: db/models/fields/__init__.py:709
msgid "This value must be a decimal number."
msgstr "Ta wartość musi być liczbą dziesiętną."
-#: db/models/fields/__init__.py:800
+#: db/models/fields/__init__.py:822
msgid "Enter a valid filename."
msgstr "Wpisz poprawnÄ… nazwÄ™ pliku."
-#: db/models/fields/__init__.py:981
+#: db/models/fields/__init__.py:1013
msgid "This value must be either None, True or False."
msgstr ""
"Ta wartość musi być jedną z None (nic), True (prawda) lub False (fałsz)."
-#: db/models/fields/related.py:94
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Proszę wpisać poprawne %s."
-#: db/models/fields/related.py:746
-msgid "Separate multiple IDs with commas."
-msgstr "Oddziel identyfikatory przecinkami."
-
-#: db/models/fields/related.py:748
+#: db/models/fields/related.py:729
msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr ""
"Przytrzymaj wciśnięty klawisz \"Ctrl\" lub \"Command\" na Mac'u aby "
"zaznaczyć więcej niż jeden wybór."
-#: db/models/fields/related.py:795
+#: db/models/fields/related.py:773
#, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural ""
@@ -3964,100 +4047,100 @@ msgstr[2] ""
"Proszę podać poprawne identyfikatory %(self)s. Wartości %(value)r są "
"niepoprawne."
-#: newforms/fields.py:47
+#: forms/fields.py:53
msgid "Enter a valid value."
msgstr "Wpisz poprawną wartość."
-#: newforms/fields.py:124
+#: forms/fields.py:130
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr ""
"Upewnij się, że ta wartość ma co najwyżej %(max)d znaków (ma długość %"
"(length)d)."
-#: newforms/fields.py:125
+#: forms/fields.py:131
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr ""
"Upewnij się, że ta wartość ma co najmniej %(min)d znaków (ma długość %"
"(length)d)."
-#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
+#: forms/fields.py:159 forms/fields.py:188 forms/fields.py:217
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Upewnij się, że ta wartość jest mniejsza lub równa %s."
-#: newforms/fields.py:154 newforms/fields.py:183 newforms/fields.py:212
+#: forms/fields.py:160 forms/fields.py:189 forms/fields.py:218
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Upewnij się, że ta wartość jest większa lub równa %s."
-#: newforms/fields.py:181 newforms/fields.py:210
+#: forms/fields.py:187 forms/fields.py:216
msgid "Enter a number."
msgstr "Wpisz liczbÄ™."
-#: newforms/fields.py:213
+#: forms/fields.py:219
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "Upewnij się, że jest nie więcej niż %s cyfr."
-#: newforms/fields.py:214
+#: forms/fields.py:220
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "Upewnij się, że jest nie więcej niż %s miejsc po przecinku."
-#: newforms/fields.py:215
+#: forms/fields.py:221
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Upewnij się, że jest nie więcej niż %s miejsc przed przecinkiem."
-#: newforms/fields.py:263 newforms/fields.py:750
+#: forms/fields.py:269 forms/fields.py:799
msgid "Enter a valid date."
msgstr "Wpisz poprawnÄ… datÄ™."
-#: newforms/fields.py:296 newforms/fields.py:751
+#: forms/fields.py:302 forms/fields.py:800
msgid "Enter a valid time."
msgstr "Wpisz poprawnÄ… godzinÄ™."
-#: newforms/fields.py:335
+#: forms/fields.py:341
msgid "Enter a valid date/time."
msgstr "Wpisz poprawnÄ… datÄ™/godzinÄ™."
-#: newforms/fields.py:434
+#: forms/fields.py:428
msgid "No file was submitted."
msgstr "Żaden plik nie został przesłany."
-#: newforms/fields.py:435 oldforms/__init__.py:689
+#: forms/fields.py:429 oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "Wysłany plik jest pusty."
-#: newforms/fields.py:497
+#: forms/fields.py:528
msgid "Enter a valid URL."
msgstr "Wpisz poprawny URL."
-#: newforms/fields.py:498
+#: forms/fields.py:529
msgid "This URL appears to be a broken link."
msgstr "Ten odnośnik jest nieprawidłowy."
-#: newforms/fields.py:559 newforms/models.py:305
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Wybierz poprawną wartość. Podana nie jest jednym z dostępnych wyborów."
-
-#: newforms/fields.py:598
+#: forms/fields.py:597 forms/fields.py:648
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr ""
"Wybierz poprawną wartość. %(value)s nie jest jednym z dostępnych wyborów."
-#: newforms/fields.py:599 newforms/fields.py:661 newforms/models.py:372
+#: forms/fields.py:649 forms/fields.py:710 forms/models.py:581
msgid "Enter a list of values."
msgstr "Podaj listę wartości."
-#: newforms/fields.py:779
+#: forms/fields.py:828
msgid "Enter a valid IPv4 address."
msgstr "Wprowadź poprawny adres IPv4."
-#: newforms/models.py:373
+#: forms/models.py:514
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Wybierz poprawną wartość. Podana nie jest jednym z dostępnych wyborów."
+
+#: forms/models.py:582
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr "Wybierz poprawną wartość. %s nie jest jednym z dostępnych wyborów."
@@ -4079,15 +4162,15 @@ msgstr "Znaki nowej linii sÄ… tutaj niedopuszczalne."
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Wybierz poprawną opcję; '%(data)s' nie jest wśród %(choices)s."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Proszę wpisać liczbę całkowitą z zakresu od -32 768 do 32 767"
-#: oldforms/__init__.py:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Proszę wpisać liczbę dodatnią."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Proszę wpisać liczbę całkowitą z zakresu od 0 do 32 767"
@@ -4322,7 +4405,7 @@ msgstr "Lis."
msgid "Dec."
msgstr "Gru."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "lub"
@@ -4382,41 +4465,62 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:403
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "Y-m-d"
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "Y-m-d H:i:s"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "H:i:s"
-#: utils/translation/trans_real.py:421
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "Y-m"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "m-d"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "%(verbose_name)s zostało pomyślnie utworzone."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "%(verbose_name)s zostało pomyślnie zmienione."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s zostało usunięte."
+#~ msgid "Ordering"
+#~ msgstr "Sortowanie"
+
+#~ msgid "Order:"
+#~ msgstr "PorzÄ…dek:"
+
+#~ msgid "Added %s."
+#~ msgstr "Dodano %s"
+
+#~ msgid "Deleted %s."
+#~ msgstr "Skasowano %s"
+
+#~ msgid "The two 'new password' fields didn't match."
+#~ msgstr "Pola 'nowe hasło' nie zgadzają się."
+
+#~ msgid "Year must be 1900 or later."
+#~ msgstr "Rok nie może być wcześniejszy niż 1900."
+
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Oddziel identyfikatory przecinkami."
+
#~ msgid "Brazilian"
#~ msgstr "Brazylijski"
diff --git a/django/conf/locale/pt_BR/LC_MESSAGES/django.mo b/django/conf/locale/pt_BR/LC_MESSAGES/django.mo
index 921eef2230..f254e69e97 100644
--- a/django/conf/locale/pt_BR/LC_MESSAGES/django.mo
+++ b/django/conf/locale/pt_BR/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/pt_BR/LC_MESSAGES/django.po b/django/conf/locale/pt_BR/LC_MESSAGES/django.po
index 264b233bc5..5f4555a5d1 100644
--- a/django/conf/locale/pt_BR/LC_MESSAGES/django.po
+++ b/django/conf/locale/pt_BR/LC_MESSAGES/django.po
@@ -1358,7 +1358,7 @@ msgstr "aprovado pela equipe"
#: contrib/comments/models.py:187
msgid "free comment"
-msgstr "fomentário livre"
+msgstr "comentário livre"
#: contrib/comments/models.py:188
msgid "free comments"
diff --git a/django/conf/locale/sr/LC_MESSAGES/django.mo b/django/conf/locale/sr/LC_MESSAGES/django.mo
index 08ed5b16e5..89e36aad09 100644
--- a/django/conf/locale/sr/LC_MESSAGES/django.mo
+++ b/django/conf/locale/sr/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/sr/LC_MESSAGES/django.po b/django/conf/locale/sr/LC_MESSAGES/django.po
index 4053068d9b..b89345285e 100644
--- a/django/conf/locale/sr/LC_MESSAGES/django.po
+++ b/django/conf/locale/sr/LC_MESSAGES/django.po
@@ -2,350 +2,225 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-05-16 10:11+0200\n"
-"PO-Revision-Date: 2007-02-20 18:50+0100\n"
-"Last-Translator: Petar Marić <petar.maric@gmail.com>\n"
-"Language-Team: Nesh <nesh@studioquatro.co.yu> & Petar <petar.maric@gmail.com>\n"
+"POT-Creation-Date: 2008-07-29 12:06+0200\n"
+"PO-Revision-Date: 2008-07-29 12:52+0100\n"
+"Last-Translator: Nebojsa Djordjevic <djnesh@gmail.com>\n"
+"Language-Team: Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail.com>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Poedit-Country: YUGOSLAVIA\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Poedit-Basepath: ../../../../\n"
+"X-Poedit-Language: Serbian\n"
-#: contrib/comments/models.py:67
-#: contrib/comments/models.py:166
-msgid "object ID"
-msgstr "ID objekta"
-
-#: contrib/comments/models.py:68
-msgid "headline"
-msgstr "naslov"
-
-#: contrib/comments/models.py:69
-#: contrib/comments/models.py:90
-#: contrib/comments/models.py:167
-msgid "comment"
-msgstr "komentar"
+#: conf/global_settings.py:44
+msgid "Arabic"
+msgstr "Arapski"
-#: contrib/comments/models.py:70
-msgid "rating #1"
-msgstr "ocena #1"
+#: conf/global_settings.py:45
+msgid "Bengali"
+msgstr "Bengalski"
-#: contrib/comments/models.py:71
-msgid "rating #2"
-msgstr "ocena #2"
+#: conf/global_settings.py:46
+msgid "Bulgarian"
+msgstr "Bugarski"
-#: contrib/comments/models.py:72
-msgid "rating #3"
-msgstr "ocena #3"
+#: conf/global_settings.py:47
+#, fuzzy
+msgid "Catalan"
+msgstr "Italijanski"
-#: contrib/comments/models.py:73
-msgid "rating #4"
-msgstr "ocena #4"
+#: conf/global_settings.py:48
+msgid "Czech"
+msgstr "Češki"
-#: contrib/comments/models.py:74
-msgid "rating #5"
-msgstr "ocena #5"
+#: conf/global_settings.py:49
+msgid "Welsh"
+msgstr "Welšski"
-#: contrib/comments/models.py:75
-msgid "rating #6"
-msgstr "ocena #6"
+#: conf/global_settings.py:50
+msgid "Danish"
+msgstr "Danski"
-#: contrib/comments/models.py:76
-msgid "rating #7"
-msgstr "ocena #7"
+#: conf/global_settings.py:51
+msgid "German"
+msgstr "NemaÄki"
-#: contrib/comments/models.py:77
-msgid "rating #8"
-msgstr "ocena #8"
+#: conf/global_settings.py:52
+msgid "Greek"
+msgstr "GrÄki"
-#: contrib/comments/models.py:82
-msgid "is valid rating"
-msgstr "da li je ocena validna"
+#: conf/global_settings.py:53
+msgid "English"
+msgstr "Engleski"
-#: contrib/comments/models.py:83
-#: contrib/comments/models.py:169
-msgid "date/time submitted"
-msgstr "datum/vreme slanja"
+#: conf/global_settings.py:54
+msgid "Spanish"
+msgstr "Å panski"
-#: contrib/comments/models.py:84
-#: contrib/comments/models.py:170
-msgid "is public"
-msgstr "da li je javni"
+#: conf/global_settings.py:55
+#, fuzzy
+msgid "Estonian"
+msgstr "Rumunski"
-#: contrib/comments/models.py:85
-#: contrib/admin/views/doc.py:289
-msgid "IP address"
-msgstr "IP adresa"
+#: conf/global_settings.py:56
+msgid "Argentinean Spanish"
+msgstr "Å panski (Argentina)"
-#: contrib/comments/models.py:86
-msgid "is removed"
-msgstr "da li je obrisan"
+#: conf/global_settings.py:57
+msgid "Basque"
+msgstr "Baskijski"
-#: 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 "Izaberite ako je komentar neodgovarajući. Biće ispisano \"Ovaj komentar je obrisan\" umesto teksta komentara."
+#: conf/global_settings.py:58
+msgid "Persian"
+msgstr "Persijski"
-#: contrib/comments/models.py:91
-msgid "comments"
-msgstr "komentari"
+#: conf/global_settings.py:59
+msgid "Finnish"
+msgstr "Finski"
-#: contrib/comments/models.py:131
-#: contrib/comments/models.py:207
-msgid "Content object"
-msgstr "Objekat sa sadržajem"
+#: conf/global_settings.py:60
+msgid "French"
+msgstr "Francuski"
-#: 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 ""
-"Poslao %(user)s dana %(date)s\n"
-"\n"
-"%(comment)s\n"
-"\n"
-"http://%(domain)s%(url)s"
+#: conf/global_settings.py:61
+msgid "Irish"
+msgstr "Irski"
-#: contrib/comments/models.py:168
-msgid "person's name"
-msgstr "ime"
+#: conf/global_settings.py:62
+msgid "Galician"
+msgstr "Galski"
-#: contrib/comments/models.py:171
-msgid "ip address"
-msgstr "ip adresa"
+#: conf/global_settings.py:63
+msgid "Hungarian"
+msgstr "Mađarski"
-#: contrib/comments/models.py:173
-msgid "approved by staff"
-msgstr "odobreno od strane moderatora"
+#: conf/global_settings.py:64
+msgid "Hebrew"
+msgstr "Hebrejski"
-#: contrib/comments/models.py:176
-msgid "free comment"
-msgstr "slobodan komentar"
+#: conf/global_settings.py:65
+msgid "Croatian"
+msgstr "Hrvatski"
-#: contrib/comments/models.py:177
-msgid "free comments"
-msgstr "slobodni komentari"
+#: conf/global_settings.py:66
+msgid "Icelandic"
+msgstr "Islandski"
-#: contrib/comments/models.py:233
-msgid "score"
-msgstr "rezultat"
+#: conf/global_settings.py:67
+msgid "Italian"
+msgstr "Italijanski"
-#: contrib/comments/models.py:234
-msgid "score date"
-msgstr "datum rezultata"
+#: conf/global_settings.py:68
+msgid "Japanese"
+msgstr "Japanski"
-#: contrib/comments/models.py:237
-msgid "karma score"
-msgstr "\"karma\" rezultat"
+#: conf/global_settings.py:69
+#, fuzzy
+msgid "Georgian"
+msgstr "NemaÄki"
-#: contrib/comments/models.py:238
-msgid "karma scores"
-msgstr "\"karma\" rezultati"
+#: conf/global_settings.py:70
+#, fuzzy
+msgid "Korean"
+msgstr "Norveški"
-#: contrib/comments/models.py:242
-#, python-format
-msgid "%(score)d rating by %(user)s"
-msgstr "Ocena %(score)d od strane %(user)s"
+#: conf/global_settings.py:71
+msgid "Khmer"
+msgstr "Kmerski"
-#: contrib/comments/models.py:258
-#, python-format
-msgid ""
-"This comment was flagged by %(user)s:\n"
-"\n"
-"%(text)s"
+# wtf?
+#: conf/global_settings.py:72
+#, fuzzy
+msgid "Kannada"
msgstr ""
-"Ovaj komentar je oznaÄen od %(user)s:\n"
-"\n"
-"%(text)s"
-#: contrib/comments/models.py:265
-msgid "flag date"
-msgstr "datum oznaÄavanja"
+#: conf/global_settings.py:73
+msgid "Latvian"
+msgstr "Latvijski"
-#: contrib/comments/models.py:268
-msgid "user flag"
-msgstr "korisniÄka oznaka"
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "Litvanijski"
-#: contrib/comments/models.py:269
-msgid "user flags"
-msgstr "korisniÄke oznake"
+#: conf/global_settings.py:75
+msgid "Macedonian"
+msgstr "Makedonski"
-#: contrib/comments/models.py:273
-#, python-format
-msgid "Flag by %r"
-msgstr "%r je oznaÄio"
-
-#: contrib/comments/models.py:278
-msgid "deletion date"
-msgstr "datum brisanja"
-
-#: contrib/comments/models.py:280
-msgid "moderator deletion"
-msgstr "brisanje od strane moderatora"
-
-#: contrib/comments/models.py:281
-msgid "moderator deletions"
-msgstr "brisanja od strane moderatora"
-
-#: contrib/comments/models.py:285
-#, python-format
-msgid "Moderator deletion by %r"
-msgstr "Obrisao moderator %r"
-
-#: contrib/comments/views/karma.py:19
-msgid "Anonymous users cannot vote"
-msgstr "Anonimni korisnici ne mogu da glasaju"
-
-#: contrib/comments/views/karma.py:23
-msgid "Invalid comment ID"
-msgstr "Neispravan ID komentara"
-
-#: contrib/comments/views/karma.py:25
-msgid "No voting for yourself"
-msgstr "Ne možete glasati sami za sebe"
-
-# nesh: grrrrr, ala je rogobatno
-# petar: malo sam ga izmenio da bude jasniji
-#: contrib/comments/views/comments.py:28
-msgid "This rating is required because you've entered at least one other rating."
-msgstr "Ova ocena je obavezna pošto ste uneli bar jednu ocenu."
-
-#: 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] ""
-"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
-"\n"
-"%(text)s"
-msgstr[1] ""
-"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
-"\n"
-"%(text)s"
-msgstr[2] ""
-"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
-"\n"
-"%(text)s"
-
-# nesh: skethcy???
-# petar: Pojma nemam sta im to znaci
-#: contrib/comments/views/comments.py:117
-#, python-format
-msgid ""
-"This comment was posted by a sketchy user:\n"
-"\n"
-"%(text)s"
-msgstr ""
-"Komentar je poslat od strane \"sketchy\" korisnika:\n"
-"\n"
-"%(text)s"
+#: conf/global_settings.py:76
+msgid "Dutch"
+msgstr "Holandski"
-#: contrib/comments/views/comments.py:189
-#: contrib/comments/views/comments.py:280
-msgid "Only POSTs are allowed"
-msgstr "Jedino je POST dozvoljen"
+#: conf/global_settings.py:77
+msgid "Norwegian"
+msgstr "Norveški"
-#: contrib/comments/views/comments.py:193
-#: contrib/comments/views/comments.py:284
-msgid "One or more of the required fields wasn't submitted"
-msgstr "Jedno ili više obaveznih polja nije poslato"
+#: conf/global_settings.py:78
+msgid "Polish"
+msgstr "Poljski"
-#: contrib/comments/views/comments.py:197
-#: contrib/comments/views/comments.py:286
-msgid "Somebody tampered with the comment form (security violation)"
-msgstr "Neko je menjao formu za komentare (povreda sigurnosti)"
+#: conf/global_settings.py:79
+msgid "Portugese"
+msgstr "Portugalski"
-#: contrib/comments/views/comments.py:207
-#: contrib/comments/views/comments.py:292
-msgid "The comment form had an invalid 'target' parameter -- the object ID was invalid"
-msgstr "Forma komentara ima neispravni 'target' parametar -- ID objekta je neispravan"
+#: conf/global_settings.py:80
+#, fuzzy
+msgid "Brazilian Portuguese"
+msgstr "Brazilski"
-#: contrib/comments/views/comments.py:257
-#: contrib/comments/views/comments.py:321
-msgid "The comment form didn't provide either 'preview' or 'post'"
-msgstr "Ovaj komentar nije koristio ni 'preview' ni 'post'"
+#: conf/global_settings.py:81
+msgid "Romanian"
+msgstr "Rumunski"
-#: contrib/comments/templates/comments/form.html:6
-#: contrib/comments/templates/comments/form.html:8
-#: contrib/admin/templates/admin/login.html:17
-msgid "Username:"
-msgstr "KorisniÄko ime:"
+#: conf/global_settings.py:82
+msgid "Russian"
+msgstr "Ruski"
-#: contrib/comments/templates/comments/form.html:6
-#: contrib/admin/templates/admin/login.html:20
-msgid "Password:"
-msgstr "Lozinka:"
+#: conf/global_settings.py:83
+msgid "Slovak"
+msgstr "SlovaÄki"
-#: contrib/comments/templates/comments/form.html:6
-msgid "Forgotten your password?"
-msgstr "Zaboravili ste lozinku?"
+#: conf/global_settings.py:84
+msgid "Slovenian"
+msgstr "SlovenaÄki"
-#: contrib/comments/templates/comments/form.html:8
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
-#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_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/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
-msgid "Log out"
-msgstr "Odjavite se"
+#: conf/global_settings.py:85
+msgid "Serbian"
+msgstr "Srpski"
-#: contrib/comments/templates/comments/form.html:12
-msgid "Ratings"
-msgstr "Ocene"
+#: conf/global_settings.py:86
+msgid "Swedish"
+msgstr "Å vedski"
-#: contrib/comments/templates/comments/form.html:12
-#: contrib/comments/templates/comments/form.html:23
-msgid "Required"
-msgstr "Obavezan unos"
+#: conf/global_settings.py:87
+#, fuzzy
+msgid "Tamil"
+msgstr ""
-#: contrib/comments/templates/comments/form.html:12
-#: contrib/comments/templates/comments/form.html:23
-msgid "Optional"
-msgstr "Opcioni unos"
+#: conf/global_settings.py:88
+#, fuzzy
+msgid "Telugu"
+msgstr ""
-#: contrib/comments/templates/comments/form.html:23
-msgid "Post a photo"
-msgstr "Pošaljite sliku"
+#: conf/global_settings.py:89
+msgid "Turkish"
+msgstr "Turski"
-#: contrib/comments/templates/comments/form.html:27
-#: contrib/comments/templates/comments/freeform.html:5
-msgid "Comment:"
-msgstr "Komentar:"
+#: conf/global_settings.py:90
+msgid "Ukrainian"
+msgstr "Ukrajinski"
-#: contrib/comments/templates/comments/form.html:32
-#: contrib/comments/templates/comments/freeform.html:9
-msgid "Preview comment"
-msgstr "Pregled komentara"
+#: conf/global_settings.py:91
+msgid "Simplified Chinese"
+msgstr "Kineski (pojednostavljen)"
-#: contrib/comments/templates/comments/freeform.html:4
-msgid "Your name:"
-msgstr "Vaše ime:"
+#: conf/global_settings.py:92
+msgid "Traditional Chinese"
+msgstr "Tradicionalni Kineski"
-#: contrib/admin/filterspecs.py:40
+#: contrib/admin/filterspecs.py:44
#, python-format
msgid ""
"<h3>By %s:</h3>\n"
@@ -354,350 +229,303 @@ msgstr ""
"<h3>Po %s:</h3>\n"
"<ul>\n"
-#: contrib/admin/filterspecs.py:70
-#: contrib/admin/filterspecs.py:88
-#: contrib/admin/filterspecs.py:143
+#: contrib/admin/filterspecs.py:74
+#: contrib/admin/filterspecs.py:92
+#: contrib/admin/filterspecs.py:147
+#: contrib/admin/filterspecs.py:173
msgid "All"
msgstr "Sve"
-#: contrib/admin/filterspecs.py:109
+#: contrib/admin/filterspecs.py:113
msgid "Any date"
msgstr "Bilo koji datum"
-#: contrib/admin/filterspecs.py:110
+#: contrib/admin/filterspecs.py:114
msgid "Today"
msgstr "Danas"
-#: contrib/admin/filterspecs.py:113
+#: contrib/admin/filterspecs.py:117
msgid "Past 7 days"
msgstr "U zadnjih 7 dana"
-#: contrib/admin/filterspecs.py:115
+#: contrib/admin/filterspecs.py:119
msgid "This month"
msgstr "Ovoga meseca"
-#: contrib/admin/filterspecs.py:117
+#: contrib/admin/filterspecs.py:121
msgid "This year"
msgstr "Ove godine"
-#: contrib/admin/filterspecs.py:143
+#: contrib/admin/filterspecs.py:147
+#: forms/widgets.py:379
+#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Da"
-#: contrib/admin/filterspecs.py:143
+#: contrib/admin/filterspecs.py:147
+#: forms/widgets.py:379
+#: oldforms/__init__.py:592
msgid "No"
msgstr "Ne"
-#: contrib/admin/filterspecs.py:150
+#: contrib/admin/filterspecs.py:154
+#: forms/widgets.py:379
+#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Nepoznato"
-#: contrib/admin/models.py:16
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "vreme aktivnosti"
-#: contrib/admin/models.py:19
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "id objekta"
-#: contrib/admin/models.py:20
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "opis objekta"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "oznaka aktivnosti"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "opis izmene"
-#: contrib/admin/models.py:25
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "unos u dnevniku izmena"
-#: contrib/admin/models.py:26
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "unosi u dnevniku izmena"
-#: contrib/admin/templatetags/admin_list.py:228
-msgid "All dates"
-msgstr "Svi datumi"
-
-#: contrib/admin/views/decorators.py:9
-#: contrib/auth/forms.py:36
-#: contrib/auth/forms.py:41
-msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
-msgstr "Unesite ispravno korisniÄko ime i Å¡ifru. Napomena: oba polja prave razliku izmeÄ‘u velikih i malih slova."
-
-#: contrib/admin/views/decorators.py:23
-#: contrib/admin/templates/admin/login.html:25
-msgid "Log in"
-msgstr "Prijavite se"
-
-#: contrib/admin/views/decorators.py:61
-msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
-msgstr "Ponovo se prijavite poÅ¡to je vaÅ¡a sesija istekla. Ne brinite, vaÅ¡i podaci su saÄuvani."
+#: contrib/admin/options.py:161
+#: contrib/admin/options.py:180
+msgid "None"
+msgstr "None"
-#: contrib/admin/views/decorators.py:68
-msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
-msgstr "VaÅ¡ internet ÄitaÄ nije prihvatio \"cookie\". Nakon aktiviranja odgovarajuće opcije ponovo uÄitajte stranu."
-
-#: contrib/admin/views/decorators.py:82
-msgid "Usernames cannot contain the '@' character."
-msgstr "KorisniÄka imena ne mogu sadržati karakter '@'."
-
-#: contrib/admin/views/decorators.py:84
-#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "VaÅ¡e korisniÄko ime nije data e-mail adresa. PokuÅ¡ajte sa '%s'."
-
-#: contrib/admin/views/main.py:226
-msgid "Site administration"
-msgstr "Administracija sajta"
-
-#: contrib/admin/views/main.py:260
+#: contrib/admin/options.py:347
+#: contrib/auth/admin.py:37
#, python-format
msgid "The %(name)s \"%(obj)s\" was added successfully."
msgstr "Uspešno dodat %(name)s \"%(obj)s\"."
-#: contrib/admin/views/main.py:264
-#: contrib/admin/views/main.py:348
+#: contrib/admin/options.py:351
+#: contrib/admin/options.py:419
+#: contrib/auth/admin.py:42
msgid "You may edit it again below."
msgstr "Možete ga ponovo izmeniti."
-#: contrib/admin/views/main.py:272
-#: contrib/admin/views/main.py:357
+#: contrib/admin/options.py:361
+#: contrib/admin/options.py:428
#, python-format
msgid "You may add another %s below."
msgstr "Možete dodati još jedan %s."
-#: contrib/admin/views/main.py:290
+#: contrib/admin/options.py:395
#, python-format
-msgid "Add %s"
-msgstr "Dodajte %s"
-
-#: contrib/admin/views/main.py:336
-#, python-format
-msgid "Added %s."
-msgstr "Dodat %s"
+msgid "Changed %s."
+msgstr "Izmenjen %s."
-#: contrib/admin/views/main.py:336
-#: contrib/admin/views/main.py:338
-#: contrib/admin/views/main.py:340
+#: contrib/admin/options.py:395
+#: contrib/admin/options.py:405
+#: core/validators.py:279
+#: db/models/manipulators.py:305
msgid "and"
msgstr "i"
-#: contrib/admin/views/main.py:338
+#: contrib/admin/options.py:400
#, python-format
-msgid "Changed %s."
-msgstr "Izmenjen %s."
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Dodato %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:404
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Promenjeno %(list)s za %(name)s \"%(object)s\"."
-#: contrib/admin/views/main.py:340
+#: contrib/admin/options.py:409
#, python-format
-msgid "Deleted %s."
-msgstr "Obrisan %s."
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Obrisano %(name)s \"%(object)s\"."
-#: contrib/admin/views/main.py:343
+#: contrib/admin/options.py:414
msgid "No fields changed."
msgstr "Nijedno polje nije izmenjeno."
-#: contrib/admin/views/main.py:346
+#: contrib/admin/options.py:417
#, python-format
msgid "The %(name)s \"%(obj)s\" was changed successfully."
msgstr "Uspešno izmenjen: %(name)s \"%(obj)s\"."
-#: contrib/admin/views/main.py:354
+#: contrib/admin/options.py:425
#, python-format
msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
msgstr "%(name)s \"%(obj)s\" je uspešno dodat. Možete ga ponovo izmeniti."
-#: contrib/admin/views/main.py:392
+#: contrib/admin/options.py:506
#, python-format
-msgid "Change %s"
-msgstr "Izmeni %s"
+msgid "Add %s"
+msgstr "Dodajte %s"
-#: contrib/admin/views/main.py:470
+#: contrib/admin/options.py:568
#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Jedno ili više %(fieldname)s u %(name)s: %(obj)s"
+msgid "Change %s"
+msgstr "Izmeni %s"
-#: contrib/admin/views/main.py:475
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Jedan ili više %(fieldname)s u %(name)s:"
+#: contrib/admin/options.py:598
+msgid "Database error"
+msgstr "Greška u bazi podataka"
-#: contrib/admin/views/main.py:508
+#: contrib/admin/options.py:647
#, python-format
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
msgstr "Uspešno obrisan: %(name)s \"%(obj)s\"."
-#: contrib/admin/views/main.py:511
+#: contrib/admin/options.py:653
msgid "Are you sure?"
msgstr "Da li ste sigurni?"
-#: contrib/admin/views/main.py:533
+#: contrib/admin/options.py:680
#, python-format
msgid "Change history: %s"
msgstr "Istorija izmena: %s"
-#: contrib/admin/views/main.py:565
-#, python-format
-msgid "Select %s"
-msgstr "Izaberite %s"
+#: contrib/admin/sites.py:18
+#: contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:70
+#: contrib/comments/views/comments.py:56
+msgid "Please enter a correct username and password. Note that both fields are case-sensitive."
+msgstr "Unesite ispravno korisniÄko ime i Å¡ifru. Napomena: oba polja prave razliku izmeÄ‘u velikih i malih slova."
-#: contrib/admin/views/main.py:565
-#, python-format
-msgid "Select %s to change"
-msgstr "Izaberite %s za izmenu"
+#: contrib/admin/sites.py:233
+#: contrib/admin/views/decorators.py:68
+msgid "Please log in again, because your session has expired. Don't worry: Your submission has been saved."
+msgstr "Ponovo se prijavite poÅ¡to je vaÅ¡a sesija istekla. Ne brinite, vaÅ¡i podaci su saÄuvani."
-#: contrib/admin/views/doc.py:277
-#: contrib/admin/views/doc.py:286
-#: contrib/admin/views/doc.py:288
-#: contrib/admin/views/doc.py:294
-#: contrib/admin/views/doc.py:295
-#: contrib/admin/views/doc.py:297
-msgid "Integer"
-msgstr "Ceo broj"
+#: contrib/admin/sites.py:240
+#: contrib/admin/views/decorators.py:75
+msgid "Looks like your browser isn't configured to accept cookies. Please enable cookies, reload this page, and try again."
+msgstr "VaÅ¡ internet ÄitaÄ nije prihvatio \"cookie\". Nakon aktiviranja odgovarajuće opcije ponovo uÄitajte stranu."
-#: contrib/admin/views/doc.py:278
-msgid "Boolean (Either True or False)"
-msgstr "LogiÄka vrednost (TaÄno ili NetaÄno)"
+#: contrib/admin/sites.py:254
+#: contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "KorisniÄka imena ne mogu sadržati karakter '@'."
-#: contrib/admin/views/doc.py:279
-#: contrib/admin/views/doc.py:296
+#: contrib/admin/sites.py:257
+#: contrib/admin/views/decorators.py:88
#, python-format
-msgid "String (up to %(maxlength)s)"
-msgstr "Niz karaktera (maksimalno %(maxlength)s karaktera)"
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "VaÅ¡e korisniÄko ime nije data e-mail adresa. PokuÅ¡ajte sa '%s'."
-#: contrib/admin/views/doc.py:280
-msgid "Comma-separated integers"
-msgstr "Brojevi razdvojeni zarezima"
+#: contrib/admin/sites.py:325
+msgid "Site administration"
+msgstr "Administracija sajta"
-#: contrib/admin/views/doc.py:281
-msgid "Date (without time)"
-msgstr "Datum (bez vremena)"
+#: contrib/admin/sites.py:347
+#: contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Prijavite se"
-#: contrib/admin/views/doc.py:282
-msgid "Date (with time)"
-msgstr "Datum (sa vremenom)"
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Jedno ili više %(fieldname)s u %(name)s: %(obj)s"
-#: contrib/admin/views/doc.py:283
-msgid "E-mail address"
-msgstr "E-mail adresa"
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Jedan ili više %(fieldname)s u %(name)s:"
-#: contrib/admin/views/doc.py:284
-#: contrib/admin/views/doc.py:287
-msgid "File path"
-msgstr "Putanja do datoteke"
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Datum:"
-#: contrib/admin/views/doc.py:285
-msgid "Decimal number"
-msgstr "Decimalni broj"
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Vreme:"
-#: contrib/admin/views/doc.py:291
-msgid "Boolean (Either True, False or None)"
-msgstr "LogiÄka vrednost (TaÄno, NetaÄno ili prazno)"
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Trenutno:"
-#: contrib/admin/views/doc.py:292
-msgid "Relation to parent model"
-msgstr "Relacija ka nadređenom objektu"
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Izmenite:"
-#: contrib/admin/views/doc.py:293
-msgid "Phone number"
-msgstr "Telefonski broj"
+#: contrib/admin/templates/admin/404.html:4
+#: contrib/admin/templates/admin/404.html:8
+msgid "Page not found"
+msgstr "Strana nije pronađena"
-#: contrib/admin/views/doc.py:298
-msgid "Text"
-msgstr "Tekst"
+#: contrib/admin/templates/admin/404.html:10
+msgid "We're sorry, but the requested page could not be found."
+msgstr "Tražena strana ne postoji."
-#: contrib/admin/views/doc.py:299
-msgid "Time"
-msgstr "Vreme"
+#: contrib/admin/templates/admin/500.html:4
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: 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:10
+#: 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 "PoÄetna strana"
-#: contrib/admin/views/doc.py:300
-#: contrib/flatpages/models.py:7
-msgid "URL"
-msgstr "URL"
+#: contrib/admin/templates/admin/500.html:4
+msgid "Server error"
+msgstr "Greška na serveru"
-#: contrib/admin/views/doc.py:301
-msgid "U.S. state (two uppercase letters)"
-msgstr "U.S. država (dva VELIKA slova)"
+#: contrib/admin/templates/admin/500.html:6
+msgid "Server error (500)"
+msgstr "Greška na serveru (500)"
-#: contrib/admin/views/doc.py:302
-msgid "XML text"
-msgstr "XML tekst"
+#: contrib/admin/templates/admin/500.html:9
+msgid "Server Error <em>(500)</em>"
+msgstr "Greška na serveru <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 "Dogodila se greška koja je prijavljena administratorima."
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/base.html:25
+msgid "Welcome,"
+msgstr "Dobrodošli,"
+
+#: contrib/admin/templates/admin/base.html:25
+#: 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_doc/bookmarklets.html:3
msgid "Documentation"
msgstr "Dokumentacija"
-#: contrib/admin/templates/admin/object_history.html:3
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/base.html:23
-#: contrib/admin/templates/admin/delete_confirmation.html:3
-#: contrib/admin/templates/admin/change_form.html:10
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: contrib/admin/templates/admin/auth/user/change_password.html:46
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
-#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_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/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
msgid "Change password"
msgstr "Izmenite lozinku"
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/change_list.html:6
-#: contrib/admin/templates/admin/base.html:28
-#: contrib/admin/templates/admin/delete_confirmation.html:6
-#: contrib/admin/templates/admin/change_form.html:13
-#: 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 "PoÄetna strana"
-
-#: contrib/admin/templates/admin/object_history.html:5
-#: contrib/admin/templates/admin/change_form.html:20
-msgid "History"
-msgstr "Istorija"
-
-#: contrib/admin/templates/admin/object_history.html:18
-msgid "Date/time"
-msgstr "Datum/vreme"
-
-#: contrib/admin/templates/admin/object_history.html:19
-msgid "User"
-msgstr "Korisnik"
-
-#: contrib/admin/templates/admin/object_history.html:20
-msgid "Action"
-msgstr "Aktivnost"
-
-#: 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
-msgid "This object doesn't have a change history. It probably wasn't added via this admin site."
-msgstr "Ovaj objekat nema istoriju promena. Najverovatnije nije dodat korišćenjem administracije sajta."
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Odjavite se"
#: contrib/admin/templates/admin/base_site.html:4
msgid "Django site admin"
@@ -707,120 +535,147 @@ msgstr "Django administracija sajta"
msgid "Django administration"
msgstr "Django administracija"
-#: contrib/admin/templates/admin/500.html:4
-msgid "Server error"
-msgstr "Greška na serveru"
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
+msgid "Add"
+msgstr "Dodajte"
-#: contrib/admin/templates/admin/500.html:6
-msgid "Server error (500)"
-msgstr "Greška na serveru (500)"
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
+msgid "History"
+msgstr "Istorija"
-#: contrib/admin/templates/admin/500.html:9
-msgid "Server Error <em>(500)</em>"
-msgstr "Greška na serveru <em>(500)</em>"
+#: contrib/admin/templates/admin/change_form.html:27
+msgid "View on site"
+msgstr "Pogledaj na sajtu"
-#: 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 "Dogodila se greška koja je prijavljena administratorima."
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
+msgid "Please correct the error below."
+msgid_plural "Please correct the errors below."
+msgstr[0] "Ispravite dole navedenu grešku."
+msgstr[1] "Ispravite dole navedene greške."
+msgstr[2] "Ispravite dole navedene greške."
-#: contrib/admin/templates/admin/404.html:4
-#: contrib/admin/templates/admin/404.html:8
-msgid "Page not found"
-msgstr "Strana nije pronađena"
+#: contrib/admin/templates/admin/change_list.html:16
+#, python-format
+msgid "Add %(name)s"
+msgstr "Dodajte %(name)s"
-#: contrib/admin/templates/admin/404.html:10
-msgid "We're sorry, but the requested page could not be found."
-msgstr "Tražena strana ne postoji."
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filter"
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/delete_confirmation.html:9
+#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
+msgid "Delete"
+msgstr "Obrišite"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:15
+#, 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 "Brisanjem %(object_name)s '%(escaped_object)s' došlo bi do brisanja pridruženih objekata, ali nemate prava da brišete sledeće objekte:"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:22
+#, 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 "Da li ste sigurni da želite da obrišete %(object_name)s \"%(escaped_object)s\"? Takođe će biti obrisani sledeći pridruženi objekti:"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:27
+msgid "Yes, I'm sure"
+msgstr "Da, siguran sam"
+
+#: contrib/admin/templates/admin/filter.html:2
+#, python-format
+msgid " By %(filter_title)s "
+msgstr " Po %(filter_title)s"
+
+#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "Models available in the %(name)s application."
msgstr "Dostupni modeli u aplikaciji %(name)s."
-#: contrib/admin/templates/admin/index.html:28
-#: contrib/admin/templates/admin/change_form.html:15
-msgid "Add"
-msgstr "Dodajte"
+#: contrib/admin/templates/admin/index.html:19
+#, python-format
+msgid "%(name)s"
+msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Izmenite"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "Nemate prava da vršite izmene."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Poslednje aktivnosti"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Moje aktivnosti"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Bez aktivnosti"
-#: contrib/admin/templates/admin/change_list.html:11
-#, python-format
-msgid "Add %(name)s"
-msgstr "Dodajte %(name)s"
+#: contrib/admin/templates/admin/invalid_setup.html:7
+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 "NeÅ¡to nije u redu sa vaÅ¡om istalacijom baze podataka. Proverite da li su sve tabele kreirane i Äitljive od strane definisanog korisnika."
+
+#: contrib/admin/templates/admin/login.html:19
+#: contrib/comments/templates/comments/form.html:6
+#: contrib/comments/templates/comments/form.html:8
+msgid "Username:"
+msgstr "KorisniÄko ime:"
#: contrib/admin/templates/admin/login.html:22
-msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
-msgstr "Da li ste <a href=\"/password_reset/\">zaboravili vašu lozinku?</a>?"
+#: contrib/comments/templates/comments/form.html:8
+msgid "Password:"
+msgstr "Lozinka:"
-#: contrib/admin/templates/admin/base.html:23
-msgid "Welcome,"
-msgstr "Dobrodošli,"
+#: contrib/admin/templates/admin/object_history.html:16
+msgid "Date/time"
+msgstr "Datum/vreme"
-#: contrib/admin/templates/admin/delete_confirmation.html:9
-#: contrib/admin/templates/admin/submit_line.html:3
-msgid "Delete"
-msgstr "Obrišite"
+#: contrib/admin/templates/admin/object_history.html:17
+msgid "User"
+msgstr "Korisnik"
-#: contrib/admin/templates/admin/delete_confirmation.html:14
-#, python-format
-msgid "Deleting the %(object_name)s '%(object)s' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:"
-msgstr "Brisanjem %(object_name)s '%(object)s' došlo bi do brisanja pridruženih objekata, ali nemate prava da brišete sledeće objekte:"
+#: contrib/admin/templates/admin/object_history.html:18
+msgid "Action"
+msgstr "Aktivnost"
-#: contrib/admin/templates/admin/delete_confirmation.html:21
-#, python-format
-msgid "Are you sure you want to delete the %(object_name)s \"%(object)s\"? All of the following related items will be deleted:"
-msgstr "Da li ste sigurni da želite da obrišete %(object_name)s \"%(object)s\"? Takođe će biti obrisani sledeći pridruženi objekti:"
+#: contrib/admin/templates/admin/object_history.html:24
+msgid "DATE_WITH_TIME_FULL"
+msgstr "j. N Y, H:i"
-#: contrib/admin/templates/admin/delete_confirmation.html:26
-msgid "Yes, I'm sure"
-msgstr "Da, siguran sam"
+#: contrib/admin/templates/admin/object_history.html:32
+msgid "This object doesn't have a change history. It probably wasn't added via this admin site."
+msgstr "Ovaj objekat nema istoriju promena. Najverovatnije nije dodat korišćenjem administracije sajta."
-#: contrib/admin/templates/admin/filter.html:2
-#, python-format
-msgid " By %(title)s "
-msgstr " Po %(title)s "
+#: contrib/admin/templates/admin/pagination.html:10
+msgid "Show all"
+msgstr "Prikaži sve"
#: contrib/admin/templates/admin/search_form.html:8
msgid "Go"
msgstr "Nađi"
-#: contrib/admin/templates/admin/change_form.html:21
-msgid "View on site"
-msgstr "Pogledaj na sajtu"
-
-#: contrib/admin/templates/admin/change_form.html:30
-msgid "Please correct the error below."
-msgid_plural "Please correct the errors below."
-msgstr[0] "Ispravite dole navedenu grešku."
-msgstr[1] "Ispravite dole navedene greške."
-msgstr[2] "Ispravite dole navedene greške."
-
-#: contrib/admin/templates/admin/change_form.html:48
-msgid "Ordering"
-msgstr "Redosled"
+#: contrib/admin/templates/admin/search_form.html:10
+#, python-format
+msgid "1 result"
+msgid_plural "%(counter)s results"
+msgstr[0] "1 rezultat"
+msgstr[1] "%(counter)s rezultata"
+msgstr[2] "%(counter)s rezultata"
-#: contrib/admin/templates/admin/change_form.html:51
-msgid "Order:"
-msgstr "Red:"
+#: contrib/admin/templates/admin/search_form.html:10
+#, python-format
+msgid "%(full_result_count)s total"
+msgstr "%(full_result_count)s ukupno"
#: contrib/admin/templates/admin/submit_line.html:4
msgid "Save as new"
@@ -838,40 +693,92 @@ msgstr "Snimite i nastavite sa izmenama"
msgid "Save"
msgstr "Snimite"
-#: 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 "Izmenite lozinku"
+#: 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 "Prvo unesite korisniÄko ime i lozinku da bi ste mogli menjati ostale opcije za korisnika."
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:12
+#: contrib/auth/forms.py:49
+msgid "Username"
+msgstr "KorisniÄko ime"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
+#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:15
+#: contrib/auth/forms.py:50
+#: contrib/auth/forms.py:166
+msgid "Password"
+msgstr "Lozinka"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:167
+msgid "Password (again)"
+msgstr "Lozinka (ponovo)"
+
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
+msgid "Enter the same password as above, for verification."
+msgstr "Zbog provere, ponovite lozinku."
+
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
+#, python-format
+msgid "Enter a new password for the user <strong>%(username)s</strong>."
+msgstr "Unesite novu lozinku za korisnika <strong>%(username)s</strong>."
-#: contrib/admin/templates/registration/password_change_done.html:6
-#: contrib/admin/templates/registration/password_change_done.html:10
-msgid "Password change successful"
-msgstr "Lozinka je uspešno izmenjena"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:3
+msgid "Bookmarklets"
+msgstr "Bookmarklets"
-#: contrib/admin/templates/registration/password_change_done.html:12
-msgid "Your password was changed."
-msgstr "Vaša lozinka je izmenjena."
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
+msgid "Documentation bookmarklets"
+msgstr "Dokumentacioni \"bookmarklets\""
-#: 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 "Resetovanje lozinke"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:8
+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\">Da bi ste instalirali \"bookmarklet\", odvucite link u vaÅ¡e \"bookmark\"-e, ili kliknite desnim tasterom i dodajte ga. Sada možete da izaberete \"bookmark\" sa bilo koje strane na sajtu. Napomena: pristup nekima od strana mora biti sa kompjutera Äija je IP adresa oznaÄena kao \"internal\" (kontaktirajte sistem administratora ako niste sigurni da li je vaÅ¡ IP oznaÄen kao \"internal\").</p>\n"
-#: 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 "Zaboravili ste svoju lozinku? Unesite vašu e-mail adresu i dobićete novu lozinku na dati e-mail."
+#: contrib/admin/templates/admin_doc/bookmarklets.html:18
+msgid "Documentation for this page"
+msgstr "Dokumentacija za ovu stranu"
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "E-mail address:"
-msgstr "E-mail adresa:"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:19
+msgid "Jumps you from any page to the documentation for the view that generates that page."
+msgstr "SkaÄe sa bilo koje strane na stranu sa dokumentacijom za \"view\" koji generiÅ¡e tu stranu."
-#: contrib/admin/templates/registration/password_reset_form.html:16
-msgid "Reset my password"
-msgstr "Resetujte moju lozinku"
+#: contrib/admin/templates/admin_doc/bookmarklets.html:21
+msgid "Show object ID"
+msgstr "Prikažite ID objekta"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:22
+msgid "Shows the content-type and unique ID for pages that represent a single object."
+msgstr "Prikazuje \"content-type\" i jedinstveni ID strane koje predstavlja jedan objekt."
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:24
+msgid "Edit this object (current window)"
+msgstr "Izmena objekta (u aktivnom prozoru)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:25
+msgid "Jumps to the admin page for pages that represent a single object."
+msgstr "SkaÄe na admin stranu za strane koje predstavljaju objekt."
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:27
+msgid "Edit this object (new window)"
+msgstr "Izmeni objekat (novi prozor)"
+
+#: contrib/admin/templates/admin_doc/bookmarklets.html:28
+msgid "As above, but opens the admin page in a new window."
+msgstr "Kao iznad, samo otvara admin stranu u novom prozoru."
#: contrib/admin/templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today."
@@ -881,14 +788,21 @@ msgstr "Hvala Vam na poseti."
msgid "Log in again"
msgstr "Prijavite se ponovo"
-#: contrib/admin/templates/registration/password_reset_done.html:6
-#: contrib/admin/templates/registration/password_reset_done.html:10
-msgid "Password reset successful"
-msgstr "Vaša lozinka je uspešno resetovana"
+#: 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 "Izmenite lozinku"
-#: 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 "Nova lozinka vam je poslata na zadatu e-mail adresu. E-mail bi trebao da stigne u narednih nekoliko minuta."
+#: contrib/admin/templates/registration/password_change_done.html:6
+#: contrib/admin/templates/registration/password_change_done.html:10
+msgid "Password change successful"
+msgstr "Lozinka je uspešno izmenjena"
+
+#: contrib/admin/templates/registration/password_change_done.html:12
+msgid "Your password was changed."
+msgstr "Vaša lozinka je izmenjena."
#: 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."
@@ -910,6 +824,22 @@ msgstr "Potvrdite novu lozinku:"
msgid "Change my password"
msgstr "Izmenite moju lozinku"
+#: 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
+msgid "Password reset"
+msgstr "Resetovanje lozinke"
+
+#: contrib/admin/templates/registration/password_reset_done.html:6
+#: contrib/admin/templates/registration/password_reset_done.html:10
+msgid "Password reset successful"
+msgstr "Vaša lozinka je uspešno resetovana"
+
+#: 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 "Nova lozinka vam je poslata na zadatu e-mail adresu. E-mail bi trebao da stigne u narednih nekoliko minuta."
+
#: contrib/admin/templates/registration/password_reset_email.html:2
msgid "You're receiving this e-mail because you requested a password reset"
msgstr "Primili ste ovaj e-mail jer ste zatražili resetovanje lozinke"
@@ -941,712 +871,2888 @@ msgstr "Hvala Vam na poseti!"
msgid "The %(site_name)s team"
msgstr "%(site_name)s tim"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:3
-msgid "Bookmarklets"
-msgstr "Bookmarklets"
+#: 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 "Zaboravili ste svoju lozinku? Unesite vašu e-mail adresu i dobićete novu lozinku na dati e-mail."
-#: contrib/admin/templates/admin_doc/bookmarklets.html:5
-msgid "Documentation bookmarklets"
-msgstr "Dokumentacioni \"bookmarklets\""
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "E-mail address:"
+msgstr "E-mail adresa:"
-#: 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"
+#: contrib/admin/templates/registration/password_reset_form.html:16
+msgid "Reset my password"
+msgstr "Resetujte moju lozinku"
+
+#: contrib/admin/templatetags/admin_list.py:257
+msgid "All dates"
+msgstr "Svi datumi"
+
+#: contrib/admin/views/main.py:65
+#, python-format
+msgid "Select %s"
+msgstr "Izaberite %s"
+
+#: contrib/admin/views/main.py:65
+#, python-format
+msgid "Select %s to change"
+msgstr "Izaberite %s za izmenu"
+
+#: contrib/admindocs/views.py:53
+#: contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
+msgid "tag:"
msgstr ""
-"\n"
-"<p class=\"help\">Da bi ste instalirali \"bookmarklet\", odvucite link u vaÅ¡e \"bookmark\"-e, ili kliknite desnim tasterom i dodajte ga. Sada možete da izaberete \"bookmark\" sa bilo koje strane na sajtu. Napomena: pristup nekima od strana mora biti sa kompjutera Äija je IP adresa oznaÄena kao \"internal\" (kontaktirajte sistem administratora ako niste sigurni da li je vaÅ¡ IP oznaÄen kao \"internal\").</p>\n"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:19
-msgid "Documentation for this page"
-msgstr "Dokumentacija za ovu stranu"
+#: contrib/admindocs/views.py:87
+#: contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
+msgid "filter:"
+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 "SkaÄe sa bilo koje strane na stranu sa dokumentacijom za \"view\" koji generiÅ¡e tu stranu."
+#: contrib/admindocs/views.py:153
+#: contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
+msgid "view:"
+msgstr ""
-#: contrib/admin/templates/admin_doc/bookmarklets.html:22
-msgid "Show object ID"
-msgstr "Prikažite ID objekta"
+#: contrib/admindocs/views.py:187
+#, python-format
+msgid "App %r not found"
+msgstr "Aplikacija %r nije nađena"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:23
-msgid "Shows the content-type and unique ID for pages that represent a single object."
-msgstr "Prikazuje \"content-type\" i jedinstveni ID strane koje predstavlja jedan objekt."
+#: contrib/admindocs/views.py:194
+#, python-format
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Model %(model_name)r nije nađen u aplikaciji %(app_label)r"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:25
-msgid "Edit this object (current window)"
-msgstr "Izmena objekta (u aktivnom prozoru)"
+#: contrib/admindocs/views.py:206
+#, python-format
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "povezani `%(app_label)s.%(data_type)s` objekti"
+
+#: contrib/admindocs/views.py:206
+#: contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242
+#: contrib/admindocs/views.py:247
+msgid "model:"
+msgstr ""
-#: contrib/admin/templates/admin_doc/bookmarklets.html:26
-msgid "Jumps to the admin page for pages that represent a single object."
-msgstr "SkaÄe na admin stranu za strane koje predstavljaju objekt."
+#: contrib/admindocs/views.py:237
+#, python-format
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "povezani `%(app_label)s.%(object_name)s` objekti"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:28
-msgid "Edit this object (new window)"
-msgstr "Izmeni objekat (novi prozor)"
+#: contrib/admindocs/views.py:242
+#, python-format
+msgid "all %s"
+msgstr "svi %s"
-#: contrib/admin/templates/admin_doc/bookmarklets.html:29
-msgid "As above, but opens the admin page in a new window."
-msgstr "Kao iznad, samo otvara admin stranu u novom prozoru."
+#: contrib/admindocs/views.py:247
+#, python-format
+msgid "number of %s"
+msgstr "broj %s"
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Datum:"
+#: contrib/admindocs/views.py:253
+#, python-format
+msgid "Fields on %s objects"
+msgstr "Polja u %s objekata"
+
+#: contrib/admindocs/views.py:317
+#: contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330
+#: contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337
+#: contrib/admindocs/views.py:339
+msgid "Integer"
+msgstr "Ceo broj"
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Vreme:"
+#: contrib/admindocs/views.py:318
+msgid "Boolean (Either True or False)"
+msgstr "LogiÄka vrednost (TaÄno ili NetaÄno)"
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Trenutno:"
+#: contrib/admindocs/views.py:319
+#: contrib/admindocs/views.py:338
+#, python-format
+msgid "String (up to %(max_length)s)"
+msgstr "Niz karaktera (maksimalno %(max_length)s karaktera)"
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Izmenite:"
+#: contrib/admindocs/views.py:320
+msgid "Comma-separated integers"
+msgstr "Brojevi razdvojeni zarezima"
-#: contrib/redirects/models.py:7
-msgid "redirect from"
-msgstr "preusmeri od"
+#: contrib/admindocs/views.py:321
+msgid "Date (without time)"
+msgstr "Datum (bez vremena)"
-#: contrib/redirects/models.py:8
-msgid "This should be an absolute path, excluding the domain name. Example: '/events/search/'."
-msgstr "Unesite apsolutnu putanju bez imena domena. Primer: '/dogadjaji/pretraga/'."
+#: contrib/admindocs/views.py:322
+msgid "Date (with time)"
+msgstr "Datum (sa vremenom)"
-#: contrib/redirects/models.py:9
-msgid "redirect to"
-msgstr "preusmeri ka"
+#: contrib/admindocs/views.py:323
+msgid "Decimal number"
+msgstr "Decimalni broj"
-#: contrib/redirects/models.py:10
-msgid "This can be either an absolute path (as above) or a full URL starting with 'http://'."
-msgstr "Može biti apsolutna putanja (kao gore) ili puni URL koji poÄinje sa 'http://'."
+#: contrib/admindocs/views.py:324
+msgid "E-mail address"
+msgstr "E-mail adresa"
-#: contrib/redirects/models.py:12
-msgid "redirect"
-msgstr "Preusmeravanje"
+#: contrib/admindocs/views.py:325
+#: contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
+msgid "File path"
+msgstr "Putanja do datoteke"
-#: contrib/redirects/models.py:13
-msgid "redirects"
-msgstr "Preusmeravanja"
+#: contrib/admindocs/views.py:327
+msgid "Floating point number"
+msgstr ""
+#: contrib/admindocs/views.py:331
+#: contrib/comments/models.py:89
+msgid "IP address"
+msgstr "IP adresa"
+
+#: contrib/admindocs/views.py:333
+msgid "Boolean (Either True, False or None)"
+msgstr "LogiÄka vrednost (TaÄno, NetaÄno ili prazno)"
+
+#: contrib/admindocs/views.py:334
+msgid "Relation to parent model"
+msgstr "Relacija ka nadređenom objektu"
+
+#: contrib/admindocs/views.py:335
+msgid "Phone number"
+msgstr "Telefonski broj"
+
+#: contrib/admindocs/views.py:340
+msgid "Text"
+msgstr "Tekst"
+
+#: contrib/admindocs/views.py:341
+msgid "Time"
+msgstr "Vreme"
+
+#: contrib/admindocs/views.py:342
#: contrib/flatpages/models.py:8
-msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr "Primer: '/o-nama/kontakt/'. Proverite da li ste uneli '/' na poÄetku i na kraju."
+msgid "URL"
+msgstr "URL"
-#: contrib/flatpages/models.py:9
-msgid "title"
-msgstr "naslov"
+#: contrib/admindocs/views.py:343
+msgid "U.S. state (two uppercase letters)"
+msgstr "U.S. država (dva VELIKA slova)"
-#: contrib/flatpages/models.py:10
-msgid "content"
-msgstr "sadržaj"
+#: contrib/admindocs/views.py:344
+msgid "XML text"
+msgstr "XML tekst"
-#: contrib/flatpages/models.py:11
-msgid "enable comments"
-msgstr "omogućite komentare"
+#: contrib/admindocs/views.py:370
+#, python-format
+msgid "%s does not appear to be a urlpattern object"
+msgstr "%s nije urlpattern objekt"
-#: contrib/flatpages/models.py:12
-msgid "template name"
-msgstr "naziv templejta"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "LiÄne informacije"
-#: contrib/flatpages/models.py:13
-msgid "Example: 'flatpages/contact_page'. If this isn't provided, the system will use 'flatpages/default'."
-msgstr "Primer: 'flatpages/kontakt-stranica'. Ako ne zadate sistem će koristiti 'flatpages/default'."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Dozvole"
-#: contrib/flatpages/models.py:14
-msgid "registration required"
-msgstr "samo za registrovane korisnike"
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Važni datumi"
-#: contrib/flatpages/models.py:14
-msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr "Ako izaberete ovu opciju samo prijavljeni korisnici će imati pristup datoj strani."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Grupe"
-#: contrib/flatpages/models.py:18
-msgid "flat page"
-msgstr "statiÄna strana"
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Dodajte korisnika"
-#: contrib/flatpages/models.py:19
-msgid "flat pages"
-msgstr "statiÄne strane"
+#: contrib/auth/forms.py:13
+#: contrib/auth/models.py:134
+msgid "Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."
+msgstr "Obavezno. 30 ili manje karaktera. Samo slova, brojevi i donja crta \"_\"."
+
+# nesh: Ovo je opis za stari SlugField
+#: contrib/auth/forms.py:14
+#: core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Ovo polje može sadržati samo slova, brojeve i donju crtu (_)."
-#: contrib/auth/models.py:13
-#: contrib/auth/models.py:26
+#: contrib/auth/forms.py:16
+msgid "Password confirmation"
+msgstr "Potvrdite lozinku"
+
+#: contrib/auth/forms.py:28
+msgid "A user with that username already exists."
+msgstr "Korisnik već postoji."
+
+#: contrib/auth/forms.py:34
+#: contrib/auth/forms.py:153
+#: contrib/auth/forms.py:178
+msgid "The two password fields didn't match."
+msgstr "Polja za lozinku nisu ista."
+
+#: contrib/auth/forms.py:72
+#: contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "Neaktivni nalog."
+
+#: contrib/auth/forms.py:77
+#: contrib/comments/views/comments.py:49
+msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
+msgstr "VaÅ¡ internet ÄitaÄ nije prihvatio \"cookie\". \"Cookie\" podrÅ¡ka je potrebna da bi ste mogli da se prijavite."
+
+#: contrib/auth/forms.py:90
+msgid "E-mail"
+msgstr "E-mail"
+
+#: contrib/auth/forms.py:99
+msgid "That e-mail address doesn't have an associated user account. Are you sure you've registered?"
+msgstr "Ova e-mail adresa nije povezana sa nijednim korisniÄkim nalogom. Da li ste sigurni da ste registrovani?"
+
+#: contrib/auth/forms.py:124
+#, python-format
+msgid "Password reset on %s"
+msgstr "Resetovanje lozinke za %s"
+
+#: contrib/auth/forms.py:131
+msgid "Old password"
+msgstr "Stara lozinka"
+
+#: contrib/auth/forms.py:132
+msgid "New password"
+msgstr "Nova lozinka"
+
+#: contrib/auth/forms.py:133
+msgid "New password confirmation"
+msgstr "Potvrda nove lozinke"
+
+#: contrib/auth/forms.py:145
+msgid "Your old password was entered incorrectly. Please enter it again."
+msgstr "Pogrešna stara lozinka. Unesite je ponovo."
+
+#: contrib/auth/models.py:73
+#: contrib/auth/models.py:93
msgid "name"
msgstr "ime"
-#: contrib/auth/models.py:15
+#: contrib/auth/models.py:75
msgid "codename"
msgstr "Å¡ifra dozvole"
-#: contrib/auth/models.py:17
+#: contrib/auth/models.py:78
msgid "permission"
msgstr "dozvola"
-#: contrib/auth/models.py:18
-#: contrib/auth/models.py:27
+#: contrib/auth/models.py:79
+#: contrib/auth/models.py:94
msgid "permissions"
msgstr "dozvole"
-#: contrib/auth/models.py:29
+#: contrib/auth/models.py:97
msgid "group"
msgstr "grupa"
-#: contrib/auth/models.py:30
-#: contrib/auth/models.py:65
+#: contrib/auth/models.py:98
+#: contrib/auth/models.py:144
msgid "groups"
msgstr "grupe"
-#: contrib/auth/models.py:55
+#: contrib/auth/models.py:134
msgid "username"
msgstr "korisniÄko ime"
-#: contrib/auth/models.py:56
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "ime"
-#: contrib/auth/models.py:57
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "prezime"
-#: contrib/auth/models.py:58
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "e-mail adresa"
-#: contrib/auth/models.py:59
+#: contrib/auth/models.py:138
msgid "password"
msgstr "lozinka"
-#: contrib/auth/models.py:59
-msgid "Use '[algo]$[salt]$[hexdigest]'"
-msgstr "Koristite '[algo]$[salt]$[hexdigest]'"
+#: contrib/auth/models.py:138
+msgid "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."
+msgstr "Koristite '[algo]$[salt]$[hexdigest]' ili <a href=\"password/\">promeni lozinku</a>."
-#: contrib/auth/models.py:60
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "dozvoljen pristup administraciji sajta"
-#: contrib/auth/models.py:60
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
msgstr "Da li korisnik ima pristup administratorskom delu sajta."
-#: contrib/auth/models.py:61
+#: contrib/auth/models.py:140
msgid "active"
msgstr "aktivan"
-#: contrib/auth/models.py:62
+#: contrib/auth/models.py:140
+msgid "Designates whether this user should be treated as active. Unselect this instead of deleting accounts."
+msgstr "OznaÄava aktivne korisnike. Koristite umesto brisanja naloga."
+
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "da li je korisnik administrator"
-#: contrib/auth/models.py:63
+#: contrib/auth/models.py:141
+msgid "Designates that this user has all permissions without explicitly assigning them."
+msgstr "OznaÄava korisnike koji imaju sva prava."
+
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "vreme poslednje posete"
-#: contrib/auth/models.py:64
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "datum otvaranja naloga"
-#: contrib/auth/models.py:66
+#: contrib/auth/models.py:145
msgid "In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."
msgstr "Uz ruÄno dodata prava, korisnik će dobiti sva prava iz grupa kojima pripada."
-#: contrib/auth/models.py:67
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "korisniÄke dozvole"
-#: contrib/auth/models.py:70
+#: contrib/auth/models.py:150
msgid "user"
msgstr "korisnik"
-#: contrib/auth/models.py:71
+#: contrib/auth/models.py:151
msgid "users"
msgstr "korisnici"
-#: contrib/auth/models.py:76
-msgid "Personal info"
-msgstr "LiÄne informacije"
+#: contrib/auth/models.py:306
+msgid "message"
+msgstr "poruka"
-#: contrib/auth/models.py:77
-msgid "Permissions"
-msgstr "Dozvole"
+#: contrib/auth/views.py:49
+msgid "Logged out"
+msgstr "Odjavljeni ste"
-#: contrib/auth/models.py:78
-msgid "Important dates"
-msgstr "Važni datumi"
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "Lozinka je uspešno izmenjena."
-#: contrib/auth/models.py:79
-msgid "Groups"
-msgstr "Grupe"
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Izmenite lozinku: %s"
-#: contrib/auth/models.py:219
-msgid "message"
-msgstr "poruka"
+#: contrib/comments/models.py:71
+#: contrib/comments/models.py:164
+msgid "object ID"
+msgstr "ID objekta"
-#: contrib/auth/forms.py:30
-msgid "Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."
-msgstr "VaÅ¡ internet ÄitaÄ nije prihvatio \"cookie\". \"Cookie\" podrÅ¡ka je potrebna da bi ste mogli da se prijavite."
+#: contrib/comments/models.py:72
+msgid "headline"
+msgstr "naslov"
+
+#: contrib/comments/models.py:73
+#: contrib/comments/models.py:95
+#: contrib/comments/models.py:165
+msgid "comment"
+msgstr "komentar"
+
+#: contrib/comments/models.py:74
+msgid "rating #1"
+msgstr "ocena #1"
+
+#: contrib/comments/models.py:75
+msgid "rating #2"
+msgstr "ocena #2"
+
+#: contrib/comments/models.py:76
+msgid "rating #3"
+msgstr "ocena #3"
+
+#: contrib/comments/models.py:77
+msgid "rating #4"
+msgstr "ocena #4"
-#: contrib/contenttypes/models.py:25
+#: contrib/comments/models.py:78
+msgid "rating #5"
+msgstr "ocena #5"
+
+#: contrib/comments/models.py:79
+msgid "rating #6"
+msgstr "ocena #6"
+
+#: contrib/comments/models.py:80
+msgid "rating #7"
+msgstr "ocena #7"
+
+#: contrib/comments/models.py:81
+msgid "rating #8"
+msgstr "ocena #8"
+
+#: contrib/comments/models.py:86
+msgid "is valid rating"
+msgstr "da li je ocena validna"
+
+#: contrib/comments/models.py:87
+#: contrib/comments/models.py:167
+msgid "date/time submitted"
+msgstr "datum/vreme slanja"
+
+#: contrib/comments/models.py:88
+#: contrib/comments/models.py:168
+msgid "is public"
+msgstr "da li je javni"
+
+#: contrib/comments/models.py:90
+msgid "is removed"
+msgstr "da li je obrisan"
+
+#: contrib/comments/models.py:90
+msgid "Check this box if the comment is inappropriate. A \"This comment has been removed\" message will be displayed instead."
+msgstr "Izaberite ako je komentar neodgovarajući. Biće ispisano \"Ovaj komentar je obrisan\" umesto teksta komentara."
+
+#: contrib/comments/models.py:96
+msgid "comments"
+msgstr "komentari"
+
+#: contrib/comments/models.py:128
+#: contrib/comments/models.py:199
+msgid "Content object"
+msgstr "Objekat sa sadržajem"
+
+#: contrib/comments/models.py:156
+#, python-format
+msgid ""
+"Posted by %(user)s at %(date)s\n"
+"\n"
+"%(comment)s\n"
+"\n"
+"http://%(domain)s%(url)s"
+msgstr ""
+"Poslao %(user)s dana %(date)s\n"
+"\n"
+"%(comment)s\n"
+"\n"
+"http://%(domain)s%(url)s"
+
+#: contrib/comments/models.py:166
+msgid "person's name"
+msgstr "ime"
+
+#: contrib/comments/models.py:169
+msgid "ip address"
+msgstr "ip adresa"
+
+#: contrib/comments/models.py:171
+msgid "approved by staff"
+msgstr "odobreno od strane moderatora"
+
+#: contrib/comments/models.py:175
+msgid "free comment"
+msgstr "slobodan komentar"
+
+#: contrib/comments/models.py:176
+msgid "free comments"
+msgstr "slobodni komentari"
+
+#: contrib/comments/models.py:227
+msgid "score"
+msgstr "rezultat"
+
+#: contrib/comments/models.py:228
+msgid "score date"
+msgstr "datum rezultata"
+
+#: contrib/comments/models.py:232
+msgid "karma score"
+msgstr "\"karma\" rezultat"
+
+#: contrib/comments/models.py:233
+msgid "karma scores"
+msgstr "\"karma\" rezultati"
+
+#: contrib/comments/models.py:237
+#, python-format
+msgid "%(score)d rating by %(user)s"
+msgstr "Ocena %(score)d od strane %(user)s"
+
+#: contrib/comments/models.py:254
+#, python-format
+msgid ""
+"This comment was flagged by %(user)s:\n"
+"\n"
+"%(text)s"
+msgstr ""
+"Ovaj komentar je oznaÄen od %(user)s:\n"
+"\n"
+"%(text)s"
+
+#: contrib/comments/models.py:262
+msgid "flag date"
+msgstr "datum oznaÄavanja"
+
+#: contrib/comments/models.py:266
+msgid "user flag"
+msgstr "korisniÄka oznaka"
+
+#: contrib/comments/models.py:267
+msgid "user flags"
+msgstr "korisniÄke oznake"
+
+#: contrib/comments/models.py:271
+#, python-format
+msgid "Flag by %r"
+msgstr "%r je oznaÄio"
+
+#: contrib/comments/models.py:277
+msgid "deletion date"
+msgstr "datum brisanja"
+
+#: contrib/comments/models.py:280
+msgid "moderator deletion"
+msgstr "brisanje od strane moderatora"
+
+#: contrib/comments/models.py:281
+msgid "moderator deletions"
+msgstr "brisanja od strane moderatora"
+
+#: contrib/comments/models.py:285
+#, python-format
+msgid "Moderator deletion by %r"
+msgstr "Obrisao moderator %r"
+
+#: contrib/comments/templates/comments/form.html:8
+msgid "Forgotten your password?"
+msgstr "Zaboravili ste lozinku?"
+
+#: contrib/comments/templates/comments/form.html:12
+msgid "Ratings"
+msgstr "Ocene"
+
+#: contrib/comments/templates/comments/form.html:12
+#: contrib/comments/templates/comments/form.html:23
+msgid "Required"
+msgstr "Obavezan unos"
+
+#: contrib/comments/templates/comments/form.html:12
+#: contrib/comments/templates/comments/form.html:23
+msgid "Optional"
+msgstr "Opcioni unos"
+
+#: contrib/comments/templates/comments/form.html:23
+msgid "Post a photo"
+msgstr "Pošaljite sliku"
+
+#: contrib/comments/templates/comments/form.html:28
+#: contrib/comments/templates/comments/freeform.html:5
+msgid "Comment:"
+msgstr "Komentar:"
+
+#: contrib/comments/templates/comments/form.html:35
+#: contrib/comments/templates/comments/freeform.html:10
+msgid "Preview comment"
+msgstr "Pregled komentara"
+
+#: contrib/comments/templates/comments/freeform.html:4
+msgid "Your name:"
+msgstr "Vaše ime:"
+
+# nesh: grrrrr, ala je rogobatno
+# petar: malo sam ga izmenio da bude jasniji
+#: contrib/comments/views/comments.py:76
+msgid "This rating is required because you've entered at least one other rating."
+msgstr "Ova ocena je obavezna pošto ste uneli bar jednu ocenu."
+
+#: contrib/comments/views/comments.py:160
+#, 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] ""
+"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
+"\n"
+"%(text)s"
+msgstr[1] ""
+"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
+"\n"
+"%(text)s"
+msgstr[2] ""
+"Ovaj komentar je poslat od korisnika koji je poslao manje od %(count)s komentara:\n"
+"\n"
+"%(text)s"
+
+# nesh: skethcy???
+# petar: Pojma nemam sta im to znaci
+#: contrib/comments/views/comments.py:165
+#, python-format
+msgid ""
+"This comment was posted by a sketchy user:\n"
+"\n"
+"%(text)s"
+msgstr ""
+"Komentar je poslat od strane \"sketchy\" korisnika:\n"
+"\n"
+"%(text)s"
+
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
+msgid "Only POSTs are allowed"
+msgstr "Jedino je POST dozvoljen"
+
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
+msgid "One or more of the required fields wasn't submitted"
+msgstr "Jedno ili više obaveznih polja nije poslato"
+
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
+msgid "Somebody tampered with the comment form (security violation)"
+msgstr "Neko je menjao formu za komentare (povreda sigurnosti)"
+
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
+msgid "The comment form had an invalid 'target' parameter -- the object ID was invalid"
+msgstr "Forma komentara ima neispravni 'target' parametar -- ID objekta je neispravan"
+
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
+msgid "The comment form didn't provide either 'preview' or 'post'"
+msgstr "Ovaj komentar nije koristio ni 'preview' ni 'post'"
+
+#: contrib/comments/views/karma.py:21
+msgid "Anonymous users cannot vote"
+msgstr "Anonimni korisnici ne mogu da glasaju"
+
+#: contrib/comments/views/karma.py:25
+msgid "Invalid comment ID"
+msgstr "Neispravan ID komentara"
+
+#: contrib/comments/views/karma.py:27
+msgid "No voting for yourself"
+msgstr "Ne možete glasati sami za sebe"
+
+#: contrib/contenttypes/models.py:67
msgid "python model class name"
msgstr "naziv python modula"
-#: contrib/contenttypes/models.py:28
+#: contrib/contenttypes/models.py:71
msgid "content type"
msgstr "tip sadržaja"
-#: contrib/contenttypes/models.py:29
+#: contrib/contenttypes/models.py:72
msgid "content types"
msgstr "tipovi sadržaja"
-#: contrib/sessions/models.py:35
-msgid "session key"
-msgstr "kljuÄ sesije"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Napredne opcije"
-#: contrib/sessions/models.py:36
-msgid "session data"
-msgstr "podaci sesije"
+#: contrib/flatpages/models.py:9
+msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
+msgstr "Primer: '/o-nama/kontakt/'. Proverite da li ste uneli '/' na poÄetku i na kraju."
-#: contrib/sessions/models.py:37
-msgid "expire date"
-msgstr "datum prestanka važenja sesije"
+#: contrib/flatpages/models.py:10
+msgid "title"
+msgstr "naslov"
-#: contrib/sessions/models.py:41
-msgid "session"
-msgstr "sesija"
+#: contrib/flatpages/models.py:11
+msgid "content"
+msgstr "sadržaj"
-#: contrib/sessions/models.py:42
-msgid "sessions"
-msgstr "sesije"
+#: contrib/flatpages/models.py:12
+msgid "enable comments"
+msgstr "omogućite komentare"
-#: contrib/sites/models.py:10
-msgid "domain name"
-msgstr "ime domena"
+#: contrib/flatpages/models.py:13
+msgid "template name"
+msgstr "naziv templejta"
-#: contrib/sites/models.py:11
-msgid "display name"
-msgstr "naziv"
+#: contrib/flatpages/models.py:14
+msgid "Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."
+msgstr "Primer: 'flatpages/kontakt-stranica.html'. Ako ne zadate sistem će koristiti 'flatpages/default.html'."
-#: contrib/sites/models.py:15
-msgid "site"
-msgstr "sajt"
+#: contrib/flatpages/models.py:15
+msgid "registration required"
+msgstr "samo za registrovane korisnike"
-#: contrib/sites/models.py:16
-msgid "sites"
-msgstr "sajtovi"
+#: contrib/flatpages/models.py:15
+msgid "If this is checked, only logged-in users will be able to view the page."
+msgstr "Ako izaberete ovu opciju samo prijavljeni korisnici će imati pristup datoj strani."
-#: utils/translation.py:360
-msgid "DATE_FORMAT"
-msgstr "D, d.m.Y."
+#: contrib/flatpages/models.py:20
+msgid "flat page"
+msgstr "statiÄna strana"
-#: utils/translation.py:361
-msgid "DATETIME_FORMAT"
-msgstr "d.m.Y. H:i:s"
+#: contrib/flatpages/models.py:21
+msgid "flat pages"
+msgstr "statiÄne strane"
-#: utils/translation.py:362
-msgid "TIME_FORMAT"
-msgstr "H:i:s"
+# th/rd se ne koriste kod nas
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "th"
+msgstr ""
-#: utils/dates.py:6
-msgid "Monday"
-msgstr "Ponedeljak"
+# vidi "th"
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "st"
+msgstr ""
-#: utils/dates.py:6
-msgid "Tuesday"
-msgstr "Utorak"
+# vidi "th"
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "nd"
+msgstr ""
-#: utils/dates.py:6
-msgid "Wednesday"
-msgstr "Sreda"
+# vidi "th"
+#: contrib/humanize/templatetags/humanize.py:19
+msgid "rd"
+msgstr ""
-#: utils/dates.py:6
-msgid "Thursday"
-msgstr "ÄŒetvrtak"
+#: contrib/humanize/templatetags/humanize.py:51
+#, python-format
+msgid "%(value).1f million"
+msgid_plural "%(value).1f million"
+msgstr[0] "%(value).1f milion"
+msgstr[1] "%(value).1f miliona"
+msgstr[2] "%(value).1f miliona"
-#: utils/dates.py:6
-msgid "Friday"
-msgstr "Petak"
+#: contrib/humanize/templatetags/humanize.py:54
+#, python-format
+msgid "%(value).1f billion"
+msgid_plural "%(value).1f billion"
+msgstr[0] "%(value).1f milijarda"
+msgstr[1] "%(value).1f milijarde"
+msgstr[2] "%(value).1f milijardi"
-#: utils/dates.py:7
-msgid "Saturday"
-msgstr "Subota"
+#: contrib/humanize/templatetags/humanize.py:57
+#, python-format
+msgid "%(value).1f trillion"
+msgid_plural "%(value).1f trillion"
+msgstr[0] "%(value).1f bilion"
+msgstr[1] "%(value).1f biliona"
+msgstr[2] "%(value).1f biliona"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "one"
+msgstr "jedan"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "two"
+msgstr "dva"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "three"
+msgstr "tri"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "four"
+msgstr "Äetiri"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "five"
+msgstr "pet"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "six"
+msgstr "Å¡est"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "seven"
+msgstr "sedam"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "eight"
+msgstr "osam"
+
+#: contrib/humanize/templatetags/humanize.py:73
+msgid "nine"
+msgstr "devet"
+
+#: contrib/humanize/templatetags/humanize.py:93
+msgid "today"
+msgstr "danas"
+
+#: contrib/humanize/templatetags/humanize.py:95
+msgid "tomorrow"
+msgstr "sutra"
+
+#: contrib/humanize/templatetags/humanize.py:97
+msgid "yesterday"
+msgstr "juÄe"
+
+#: contrib/localflavor/ar/forms.py:27
+msgid "Enter a postal code in the format NNNN or ANNNNAAA."
+msgstr ""
-#: utils/dates.py:7
-msgid "Sunday"
-msgstr "Nedelja"
+#: contrib/localflavor/ar/forms.py:49
+#: contrib/localflavor/br/forms.py:96
+#: contrib/localflavor/br/forms.py:135
+#: contrib/localflavor/pe/forms.py:23
+#: contrib/localflavor/pe/forms.py:51
+msgid "This field requires only numbers."
+msgstr "U ovo polje se mogu uneti samo brojevi."
-#: utils/dates.py:14
-msgid "January"
-msgstr "Januar"
+#: contrib/localflavor/ar/forms.py:50
+msgid "This field requires 7 or 8 digits."
+msgstr "Morate unete 7 ili 8 cifara."
-#: utils/dates.py:14
-msgid "February"
-msgstr "Februar"
+#: contrib/localflavor/ar/forms.py:79
+msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
+msgstr ""
-#: utils/dates.py:14
-#: utils/dates.py:27
-msgid "March"
-msgstr "Mart"
+#: contrib/localflavor/ar/forms.py:80
+#, fuzzy
+msgid "Invalid CUIT."
+msgstr "Neispravan URL: %s"
-#: utils/dates.py:14
-#: utils/dates.py:27
-msgid "April"
-msgstr "April"
+#: contrib/localflavor/at/at_states.py:5
+msgid "Burgenland"
+msgstr ""
-#: utils/dates.py:14
-#: utils/dates.py:27
-msgid "May"
-msgstr "Maj"
+#: contrib/localflavor/at/at_states.py:6
+msgid "Carinthia"
+msgstr ""
-#: utils/dates.py:14
-#: utils/dates.py:27
-msgid "June"
-msgstr "Jun"
+#: contrib/localflavor/at/at_states.py:7
+msgid "Lower Austria"
+msgstr ""
-#: utils/dates.py:15
-#: utils/dates.py:27
-msgid "July"
-msgstr "Jul"
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr ""
-#: utils/dates.py:15
-msgid "August"
-msgstr "Avgust"
+#: contrib/localflavor/at/at_states.py:9
+msgid "Salzburg"
+msgstr ""
-#: utils/dates.py:15
-msgid "September"
-msgstr "Septembar"
+#: contrib/localflavor/at/at_states.py:10
+#, fuzzy
+msgid "Styria"
+msgstr "Srpski"
-#: utils/dates.py:15
-msgid "October"
-msgstr "Oktobar"
+#: contrib/localflavor/at/at_states.py:11
+msgid "Tyrol"
+msgstr ""
-#: utils/dates.py:15
-msgid "November"
-msgstr "Novembar"
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr ""
-#: utils/dates.py:16
-msgid "December"
-msgstr "Decembar"
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr ""
-#: utils/dates.py:19
-msgid "jan"
-msgstr "jan"
+#: contrib/localflavor/at/forms.py:20
+#: contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+#, fuzzy
+msgid "Enter a zip code in the format XXXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
-#: utils/dates.py:19
-msgid "feb"
-msgstr "feb"
+#: contrib/localflavor/at/forms.py:48
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
+msgstr ""
-#: utils/dates.py:19
-msgid "mar"
-msgstr "mar"
+#: contrib/localflavor/au/forms.py:16
+msgid "Enter a 4 digit post code."
+msgstr ""
-#: utils/dates.py:19
-msgid "apr"
-msgstr "apr"
+#: contrib/localflavor/br/forms.py:21
+#, fuzzy
+msgid "Enter a zip code in the format XXXXX-XXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
-#: utils/dates.py:19
-msgid "may"
-msgstr "maj"
+# nesh: tel. brojevi su u ameriÄkom formatu, ovo se ionako neće koristiti u i18n delu
+#: contrib/localflavor/br/forms.py:30
+#, fuzzy
+msgid "Phone numbers must be in XX-XXXX-XXXX format."
+msgstr "Telefonski brojevi moraju biti u formatu XXX-XXX-XXXX. \"%s\" je neispravan."
-#: utils/dates.py:19
-msgid "jun"
-msgstr "jun"
+#: contrib/localflavor/br/forms.py:58
+msgid "Select a valid brazilian state. That state is not one of the available states."
+msgstr ""
-#: utils/dates.py:20
-msgid "jul"
-msgstr "jul"
+#: contrib/localflavor/br/forms.py:94
+msgid "Invalid CPF number."
+msgstr ""
-#: utils/dates.py:20
-msgid "aug"
+#: contrib/localflavor/br/forms.py:95
+msgid "This field requires at most 11 digits or 14 characters."
+msgstr ""
+
+#: contrib/localflavor/br/forms.py:134
+msgid "Invalid CNPJ number."
+msgstr ""
+
+#: contrib/localflavor/br/forms.py:136
+#, fuzzy
+msgid "This field requires at least 14 digits"
+msgstr "Obavezno polje."
+
+#: contrib/localflavor/ca/forms.py:17
+#, fuzzy
+msgid "Enter a postal code in the format XXX XXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
+
+#: contrib/localflavor/ca/forms.py:88
+msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format."
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:5
+msgid "Aargau"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:6
+msgid "Appenzell Innerrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:7
+msgid "Appenzell Ausserrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:8
+msgid "Basel-Stadt"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:9
+msgid "Basel-Land"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:10
+#, fuzzy
+msgid "Berne"
+msgstr "korisniÄko ime"
+
+#: contrib/localflavor/ch/ch_states.py:11
+msgid "Fribourg"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:12
+msgid "Geneva"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:13
+#, fuzzy
+msgid "Glarus"
+msgstr "Grupe"
+
+#: contrib/localflavor/ch/ch_states.py:14
+msgid "Graubuenden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:15
+msgid "Jura"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:16
+#, fuzzy
+msgid "Lucerne"
+msgstr "korisniÄko ime"
+
+#: contrib/localflavor/ch/ch_states.py:17
+msgid "Neuchatel"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:18
+msgid "Nidwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:19
+msgid "Obwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:20
+msgid "Schaffhausen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:21
+msgid "Schwyz"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:22
+msgid "Solothurn"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:23
+msgid "St. Gallen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:24
+#, fuzzy
+msgid "Thurgau"
+msgstr "ÄŒetvrtak"
+
+#: contrib/localflavor/ch/ch_states.py:25
+msgid "Ticino"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:26
+msgid "Uri"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:27
+msgid "Valais"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:28
+msgid "Vaud"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:29
+#, fuzzy
+msgid "Zug"
msgstr "avg"
-#: utils/dates.py:20
-msgid "sep"
-msgstr "sep"
+#: contrib/localflavor/ch/ch_states.py:30
+msgid "Zurich"
+msgstr ""
-#: utils/dates.py:20
-msgid "oct"
-msgstr "okt"
+#: contrib/localflavor/ch/forms.py:64
+msgid "Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format."
+msgstr ""
-#: utils/dates.py:20
-msgid "nov"
-msgstr "nov"
+#: contrib/localflavor/cl/forms.py:29
+#, fuzzy
+msgid "Enter a valid Chilean RUT."
+msgstr "Unesite ispravno ime fajla."
-#: utils/dates.py:20
-msgid "dec"
-msgstr "dec"
+#: contrib/localflavor/cl/forms.py:30
+msgid "Enter a valid Chilean RUT. The format is XX.XXX.XXX-X."
+msgstr ""
-#: utils/dates.py:27
-msgid "Jan."
+#: contrib/localflavor/cl/forms.py:31
+#, fuzzy
+msgid "The Chilean RUT is not valid."
+msgstr "Neispravno polje."
+
+#: contrib/localflavor/de/de_states.py:5
+msgid "Baden-Wuerttemberg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:6
+msgid "Bavaria"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:7
+#, fuzzy
+msgid "Berlin"
+msgstr "Brazilski"
+
+#: 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
+#, fuzzy
+msgid "Hessen"
+msgstr "poruka"
+
+#: 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:14
+#: contrib/localflavor/fi/forms.py:12
+#: contrib/localflavor/fr/forms.py:15
+#, fuzzy
+msgid "Enter a zip code in the format XXXXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
+
+#: contrib/localflavor/de/forms.py:41
+msgid "Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format."
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:5
+msgid "Arava"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:6
+msgid "Albacete"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:7
+msgid "Alacant"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:8
+msgid "Almeria"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:9
+msgid "Avila"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:10
+msgid "Badajoz"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:11
+msgid "Illes Balears"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:12
+msgid "Barcelona"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:13
+msgid "Burgos"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:14
+msgid "Caceres"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:15
+msgid "Cadiz"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:16
+msgid "Castello"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:17
+msgid "Ciudad Real"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:18
+msgid "Cordoba"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:19
+msgid "A Coruna"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:20
+msgid "Cuenca"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:21
+msgid "Girona"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:22
+#, fuzzy
+msgid "Granada"
+msgstr "NemaÄki"
+
+#: contrib/localflavor/es/es_provinces.py:23
+msgid "Guadalajara"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:24
+msgid "Guipuzkoa"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:25
+msgid "Huelva"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:26
+#, fuzzy
+msgid "Huesca"
+msgstr "Utorak"
+
+#: contrib/localflavor/es/es_provinces.py:27
+#, fuzzy
+msgid "Jaen"
msgstr "Jan."
-#: utils/dates.py:27
-msgid "Feb."
-msgstr "Feb."
+#: contrib/localflavor/es/es_provinces.py:28
+msgid "Leon"
+msgstr ""
-#: utils/dates.py:28
-msgid "Aug."
-msgstr "Avg."
+#: contrib/localflavor/es/es_provinces.py:29
+msgid "Lleida"
+msgstr ""
-#: utils/dates.py:28
-msgid "Sept."
-msgstr "Sept."
+#: contrib/localflavor/es/es_provinces.py:30
+#: contrib/localflavor/es/es_regions.py:17
+msgid "La Rioja"
+msgstr ""
-#: utils/dates.py:28
-msgid "Oct."
-msgstr "Okt."
+#: contrib/localflavor/es/es_provinces.py:31
+msgid "Lugo"
+msgstr ""
-#: utils/dates.py:28
-msgid "Nov."
-msgstr "Nov."
+#: contrib/localflavor/es/es_provinces.py:32
+#: contrib/localflavor/es/es_regions.py:18
+msgid "Madrid"
+msgstr ""
-#: utils/dates.py:28
-msgid "Dec."
-msgstr "Dec."
+#: contrib/localflavor/es/es_provinces.py:33
+msgid "Malaga"
+msgstr ""
-#: utils/timesince.py:12
-msgid "year"
-msgid_plural "years"
-msgstr[0] "godina"
-msgstr[1] "godine"
-msgstr[2] "godina"
+#: contrib/localflavor/es/es_provinces.py:34
+msgid "Murcia"
+msgstr ""
-#: utils/timesince.py:13
-msgid "month"
-msgid_plural "months"
-msgstr[0] "mesec"
-msgstr[1] "meseca"
-msgstr[2] "meseci"
+#: contrib/localflavor/es/es_provinces.py:35
+msgid "Navarre"
+msgstr ""
-#: utils/timesince.py:14
-msgid "week"
-msgid_plural "weeks"
-msgstr[0] "nedelja"
-msgstr[1] "nedelje"
-msgstr[2] "nedelja"
+#: contrib/localflavor/es/es_provinces.py:36
+msgid "Ourense"
+msgstr ""
-#: utils/timesince.py:15
-msgid "day"
-msgid_plural "days"
-msgstr[0] "dan"
-msgstr[1] "dana"
-msgstr[2] "dana"
+#: contrib/localflavor/es/es_provinces.py:37
+msgid "Asturias"
+msgstr ""
-#: utils/timesince.py:16
-msgid "hour"
-msgid_plural "hours"
-msgstr[0] "sat"
-msgstr[1] "sata"
-msgstr[2] "sati"
+#: contrib/localflavor/es/es_provinces.py:38
+#, fuzzy
+msgid "Palencia"
+msgstr "Galski"
-#: utils/timesince.py:17
-msgid "minute"
-msgid_plural "minutes"
-msgstr[0] "minut"
-msgstr[1] "munuta"
-msgstr[2] "minuta"
+#: contrib/localflavor/es/es_provinces.py:39
+msgid "Las Palmas"
+msgstr ""
-#: conf/global_settings.py:37
-msgid "Bengali"
-msgstr "Bengalski"
+#: contrib/localflavor/es/es_provinces.py:40
+msgid "Pontevedra"
+msgstr ""
-#: conf/global_settings.py:38
-msgid "Czech"
+#: contrib/localflavor/es/es_provinces.py:41
+msgid "Salamanca"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:42
+msgid "Santa Cruz de Tenerife"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:43
+#: contrib/localflavor/es/es_regions.py:11
+msgid "Cantabria"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:44
+#, fuzzy
+msgid "Segovia"
+msgstr "SlovenaÄki"
+
+#: contrib/localflavor/es/es_provinces.py:45
+msgid "Seville"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:46
+#, fuzzy
+msgid "Soria"
+msgstr "Srpski"
+
+#: contrib/localflavor/es/es_provinces.py:47
+msgid "Tarragona"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:48
+msgid "Teruel"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:49
+msgid "Toledo"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:50
+#, fuzzy
+msgid "Valencia"
+msgstr "Galski"
+
+#: contrib/localflavor/es/es_provinces.py:51
+msgid "Valladolid"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:52
+msgid "Bizkaia"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:53
+msgid "Zamora"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:54
+msgid "Zaragoza"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:55
+msgid "Ceuta"
+msgstr ""
+
+#: contrib/localflavor/es/es_provinces.py:56
+msgid "Melilla"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:5
+msgid "Andalusia"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:6
+msgid "Aragon"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:7
+msgid "Principality of Asturias"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:8
+msgid "Balearic Islands"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:9
+msgid "Basque Country"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:10
+msgid "Canary Islands"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:12
+msgid "Castile-La Mancha"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:13
+msgid "Castile and Leon"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:14
+#, fuzzy
+msgid "Catalonia"
+msgstr "Italijanski"
+
+#: contrib/localflavor/es/es_regions.py:15
+msgid "Extremadura"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:16
+#, fuzzy
+msgid "Galicia"
+msgstr "Galski"
+
+#: contrib/localflavor/es/es_regions.py:19
+msgid "Region of Murcia"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:20
+msgid "Foral Community of Navarre"
+msgstr ""
+
+#: contrib/localflavor/es/es_regions.py:21
+msgid "Valencian Community"
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:19
+msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:39
+msgid "Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:66
+#, fuzzy
+msgid "Please enter a valid NIF, NIE, or CIF."
+msgstr "Unesite ispravnu IP adresu."
+
+#: contrib/localflavor/es/forms.py:67
+#, fuzzy
+msgid "Please enter a valid NIF or NIE."
+msgstr "Unesite ispravan %s."
+
+#: contrib/localflavor/es/forms.py:68
+msgid "Invalid checksum for NIF."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:69
+msgid "Invalid checksum for NIE."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:70
+msgid "Invalid checksum for CIF."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:142
+msgid "Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
+msgstr ""
+
+#: contrib/localflavor/es/forms.py:143
+msgid "Invalid checksum for bank account number."
+msgstr ""
+
+#: contrib/localflavor/fi/forms.py:28
+#, fuzzy
+msgid "Enter a valid Finnish social security number."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/in_/forms.py:14
+#, fuzzy
+msgid "Enter a zip code in the format XXXXXXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
+
+#: contrib/localflavor/is_/forms.py:17
+msgid "Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
+msgstr ""
+
+#: contrib/localflavor/is_/forms.py:18
+msgid "The Icelandic identification number is not valid."
+msgstr ""
+
+#: contrib/localflavor/it/forms.py:14
+#, fuzzy
+msgid "Enter a valid zip code."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/it/forms.py:43
+#, fuzzy
+msgid "Enter a valid Social Security number."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/it/forms.py:68
+#, fuzzy
+msgid "Enter a valid VAT number."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/jp/forms.py:17
+msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
+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
+#, fuzzy
+msgid "Shimane"
+msgstr "Izmenite"
+
+#: 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
+#, fuzzy
+msgid "Ehime"
+msgstr "Vreme"
+
+#: 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/mx/mx_states.py:12
+msgid "Aguascalientes"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:13
+msgid "Baja California"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:14
+msgid "Baja California Sur"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:15
+#, fuzzy
+msgid "Campeche"
msgstr "Češki"
-#: conf/global_settings.py:39
-msgid "Welsh"
-msgstr "Welšski"
+#: contrib/localflavor/mx/mx_states.py:16
+msgid "Chihuahua"
+msgstr ""
-#: conf/global_settings.py:40
-msgid "Danish"
-msgstr "Danski"
+#: contrib/localflavor/mx/mx_states.py:17
+msgid "Chiapas"
+msgstr ""
-#: conf/global_settings.py:41
-msgid "German"
+#: contrib/localflavor/mx/mx_states.py:18
+msgid "Coahuila"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:19
+msgid "Colima"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:20
+msgid "Distrito Federal"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:21
+msgid "Durango"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:22
+msgid "Guerrero"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:23
+msgid "Guanajuato"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:24
+msgid "Hidalgo"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:25
+msgid "Jalisco"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:26
+msgid "Estado de México"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:27
+msgid "Michoacán"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:28
+msgid "Morelos"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:29
+msgid "Nayarit"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:30
+msgid "Nuevo León"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:31
+msgid "Oaxaca"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:32
+msgid "Puebla"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:33
+msgid "Querétaro"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:34
+msgid "Quintana Roo"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:35
+#, fuzzy
+msgid "Sinaloa"
+msgstr "SlovaÄki"
+
+#: contrib/localflavor/mx/mx_states.py:36
+msgid "San Luis Potosí"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:37
+msgid "Sonora"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:38
+msgid "Tabasco"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:39
+msgid "Tamaulipas"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:40
+msgid "Tlaxcala"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:41
+msgid "Veracruz"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:42
+msgid "Yucatán"
+msgstr ""
+
+#: contrib/localflavor/mx/mx_states.py:43
+msgid "Zacatecas"
+msgstr ""
+
+#: contrib/localflavor/nl/forms.py:21
+#, fuzzy
+msgid "Enter a valid postal code"
+msgstr "Unesite ispravnu e-mail adresu."
+
+#: contrib/localflavor/nl/forms.py:52
+#, fuzzy
+msgid "Enter a valid phone number"
+msgstr "Unesite celi broj."
+
+#: contrib/localflavor/nl/forms.py:78
+#, fuzzy
+msgid "Enter a valid SoFi number"
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/nl/nl_provinces.py:4
+#, fuzzy
+msgid "Drente"
+msgstr "Obrišite"
+
+#: contrib/localflavor/nl/nl_provinces.py:5
+msgid "Flevoland"
+msgstr ""
+
+#: contrib/localflavor/nl/nl_provinces.py:6
+msgid "Friesland"
+msgstr ""
+
+#: contrib/localflavor/nl/nl_provinces.py:7
+#, fuzzy
+msgid "Gelderland"
msgstr "NemaÄki"
-#: conf/global_settings.py:42
-msgid "Greek"
-msgstr "GrÄki"
+#: contrib/localflavor/nl/nl_provinces.py:8
+msgid "Groningen"
+msgstr ""
-#: conf/global_settings.py:43
-msgid "English"
-msgstr "Engleski"
+#: contrib/localflavor/nl/nl_provinces.py:9
+msgid "Limburg"
+msgstr ""
-#: conf/global_settings.py:44
-msgid "Spanish"
-msgstr "Å panski"
+#: contrib/localflavor/nl/nl_provinces.py:10
+msgid "Noord-Brabant"
+msgstr ""
-#: conf/global_settings.py:45
-msgid "French"
+#: contrib/localflavor/nl/nl_provinces.py:11
+msgid "Noord-Holland"
+msgstr ""
+
+#: contrib/localflavor/nl/nl_provinces.py:12
+msgid "Overijssel"
+msgstr ""
+
+#: contrib/localflavor/nl/nl_provinces.py:13
+#, fuzzy
+msgid "Utrecht"
msgstr "Francuski"
-#: conf/global_settings.py:46
-msgid "Galician"
-msgstr "Galski"
+#: contrib/localflavor/nl/nl_provinces.py:14
+#, fuzzy
+msgid "Zeeland"
+msgstr "Islandski"
-#: conf/global_settings.py:47
-msgid "Hungarian"
-msgstr "Mađarski"
+#: contrib/localflavor/nl/nl_provinces.py:15
+msgid "Zuid-Holland"
+msgstr ""
-#: conf/global_settings.py:48
-msgid "Hebrew"
-msgstr "Hebrejski"
+#: contrib/localflavor/no/forms.py:33
+#, fuzzy
+msgid "Enter a valid Norwegian social security number."
+msgstr "Unesite ispravan decimalni broj."
-#: conf/global_settings.py:49
-msgid "Icelandic"
-msgstr "Islandski"
+#: contrib/localflavor/pe/forms.py:24
+#, fuzzy
+msgid "This field requires 8 digits."
+msgstr "Obavezno polje."
-#: conf/global_settings.py:50
-msgid "Italian"
-msgstr "Italijanski"
+#: contrib/localflavor/pe/forms.py:52
+#, fuzzy
+msgid "This field requires 11 digits."
+msgstr "Obavezno polje."
-#: conf/global_settings.py:51
-msgid "Japanese"
-msgstr "Japanski"
+#: contrib/localflavor/pl/forms.py:39
+msgid "National Identification Number consists of 11 digits."
+msgstr ""
-#: conf/global_settings.py:52
-msgid "Dutch"
-msgstr "Holandski"
+#: contrib/localflavor/pl/forms.py:40
+msgid "Wrong checksum for the National Identification Number."
+msgstr ""
-#: conf/global_settings.py:53
-msgid "Norwegian"
-msgstr "Norveški"
+#: contrib/localflavor/pl/forms.py:72
+msgid "Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
+msgstr ""
-#: conf/global_settings.py:54
-msgid "Brazilian"
-msgstr "Brazilski"
+#: contrib/localflavor/pl/forms.py:73
+msgid "Wrong checksum for the Tax Number (NIP)."
+msgstr ""
-#: conf/global_settings.py:55
-msgid "Romanian"
+#: contrib/localflavor/pl/forms.py:112
+msgid "National Business Register Number (REGON) consists of 7 or 9 digits."
+msgstr ""
+
+#: contrib/localflavor/pl/forms.py:113
+msgid "Wrong checksum for the National Business Register Number (REGON)."
+msgstr ""
+
+#: contrib/localflavor/pl/forms.py:156
+#, fuzzy
+msgid "Enter a postal code in the format XX-XXX."
+msgstr "Unesite ispravno vreme u HH:MM formatu."
+
+#: contrib/localflavor/pl/pl_voivodeships.py:8
+msgid "Lower Silesia"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:9
+msgid "Kuyavia-Pomerania"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:10
+msgid "Lublin"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:11
+msgid "Lubusz"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:12
+msgid "Lodz"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:13
+msgid "Lesser Poland"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:14
+msgid "Masovia"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:15
+#, fuzzy
+msgid "Opole"
+msgstr "Opcioni unos"
+
+#: contrib/localflavor/pl/pl_voivodeships.py:16
+msgid "Subcarpatia"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:17
+msgid "Podlasie"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:18
+#, fuzzy
+msgid "Pomerania"
msgstr "Rumunski"
-#: conf/global_settings.py:56
-msgid "Russian"
-msgstr "Ruski"
+#: contrib/localflavor/pl/pl_voivodeships.py:19
+#, fuzzy
+msgid "Silesia"
+msgstr "SlovenaÄki"
-#: conf/global_settings.py:57
-msgid "Slovak"
-msgstr "SlovaÄki"
+#: contrib/localflavor/pl/pl_voivodeships.py:20
+msgid "Swietokrzyskie"
+msgstr ""
-#: conf/global_settings.py:58
-msgid "Slovenian"
+#: contrib/localflavor/pl/pl_voivodeships.py:21
+msgid "Warmia-Masuria"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:22
+msgid "Greater Poland"
+msgstr ""
+
+#: contrib/localflavor/pl/pl_voivodeships.py:23
+msgid "West Pomerania"
+msgstr ""
+
+#: contrib/localflavor/ro/forms.py:19
+#, fuzzy
+msgid "Enter a valid CIF."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/ro/forms.py:56
+#, fuzzy
+msgid "Enter a valid CNP."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/ro/forms.py:141
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr ""
+
+# nesh: tel. brojevi su u ameriÄkom formatu, ovo se ionako neće koristiti u i18n delu
+#: contrib/localflavor/ro/forms.py:171
+#, fuzzy
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Telefonski brojevi moraju biti u formatu XXX-XXX-XXXX. \"%s\" je neispravan."
+
+#: contrib/localflavor/ro/forms.py:194
+#, fuzzy
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Unesite ispravno vreme u HH:MM formatu."
+
+#: contrib/localflavor/sk/forms.py:30
+msgid "Enter a postal code in the format XXXXX or XXX XX."
+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
+#, fuzzy
+msgid "Galanta"
+msgstr "Galski"
+
+#: contrib/localflavor/sk/sk_districts.py:24
+#, fuzzy
+msgid "Gelnica"
+msgstr "Galski"
+
+#: 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
+#, fuzzy
+msgid "Martin"
+msgstr "Ocene"
+
+#: 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
+#, fuzzy
+msgid "Senica"
msgstr "SlovenaÄki"
-#: conf/global_settings.py:59
-msgid "Serbian"
-msgstr "Srpski"
+#: contrib/localflavor/sk/sk_districts.py:66
+#, fuzzy
+msgid "Skalica"
+msgstr "Galski"
-#: conf/global_settings.py:60
-msgid "Swedish"
-msgstr "Å vedski"
+#: contrib/localflavor/sk/sk_districts.py:67
+msgid "Snina"
+msgstr ""
-#: conf/global_settings.py:61
-msgid "Ukrainian"
-msgstr "Ukrajinski"
+#: contrib/localflavor/sk/sk_districts.py:68
+msgid "Sobrance"
+msgstr ""
-#: conf/global_settings.py:62
-msgid "Simplified Chinese"
-msgstr "Kineski (pojednostavljen)"
+#: contrib/localflavor/sk/sk_districts.py:69
+msgid "Spisska Nova Ves"
+msgstr ""
-#: conf/global_settings.py:63
-msgid "Traditional Chinese"
-msgstr "Tradicionalni Kineski"
+#: contrib/localflavor/sk/sk_districts.py:70
+msgid "Stara Lubovna"
+msgstr ""
-# nesh: Ovo je opis za stari SlugField
-#: core/validators.py:60
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Ovo polje može sadržati samo slova, brojeve i donju crtu (_)."
+#: 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
+#, fuzzy
+msgid "Trencin"
+msgstr "Francuski"
+
+#: 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/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/uk/forms.py:21
+#, fuzzy
+msgid "Enter a valid postcode."
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/uk/uk_regions.py:11
+msgid "Bedfordshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:12
+msgid "Buckinghamshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:14
+msgid "Cheshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:15
+msgid "Cornwall and Isles of Scilly"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:16
+msgid "Cumbria"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:17
+msgid "Derbyshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:18
+msgid "Devon"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:19
+msgid "Dorset"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:20
+msgid "Durham"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:21
+msgid "East Sussex"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:22
+msgid "Essex"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:23
+msgid "Gloucestershire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:24
+msgid "Greater London"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:25
+msgid "Greater Manchester"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:26
+msgid "Hampshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:27
+msgid "Hertfordshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:28
+msgid "Kent"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:29
+msgid "Lancashire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:30
+msgid "Leicestershire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:31
+msgid "Lincolnshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:32
+msgid "Merseyside"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:33
+msgid "Norfolk"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:34
+msgid "North Yorkshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:35
+msgid "Northamptonshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:36
+msgid "Northumberland"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:37
+msgid "Nottinghamshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:38
+msgid "Oxfordshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:39
+msgid "Shropshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:40
+msgid "Somerset"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:41
+msgid "South Yorkshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:42
+msgid "Staffordshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:43
+msgid "Suffolk"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:44
+#, fuzzy
+msgid "Surrey"
+msgstr "Trenutno:"
+
+#: contrib/localflavor/uk/uk_regions.py:45
+msgid "Tyne and Wear"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:46
+msgid "Warwickshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:47
+msgid "West Midlands"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:48
+msgid "West Sussex"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:49
+msgid "West Yorkshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:50
+msgid "Wiltshire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:51
+msgid "Worcestershire"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:55
+msgid "County Antrim"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:56
+msgid "County Armagh"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:57
+msgid "County Down"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:58
+msgid "County Fermanagh"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:59
+msgid "County Londonderry"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:60
+msgid "County Tyrone"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:64
+msgid "Clwyd"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:65
+msgid "Dyfed"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:66
+msgid "Gwent"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:67
+msgid "Gwynedd"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:68
+msgid "Mid Glamorgan"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:69
+msgid "Powys"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:70
+msgid "South Glamorgan"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:71
+msgid "West Glamorgan"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:75
+#, fuzzy
+msgid "Borders"
+msgstr "Red:"
+
+#: contrib/localflavor/uk/uk_regions.py:76
+msgid "Central Scotland"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:77
+msgid "Dumfries and Galloway"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:78
+msgid "Fife"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:79
+#, fuzzy
+msgid "Grampian"
+msgstr "NemaÄki"
+
+#: contrib/localflavor/uk/uk_regions.py:80
+msgid "Highland"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:81
+#, fuzzy
+msgid "Lothian"
+msgstr "Prijavite se"
+
+#: contrib/localflavor/uk/uk_regions.py:82
+msgid "Orkney Islands"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:83
+msgid "Shetland Islands"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:84
+msgid "Strathclyde"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:85
+msgid "Tayside"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:86
+msgid "Western Isles"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:90
+msgid "England"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:91
+msgid "Northern Ireland"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:92
+msgid "Scotland"
+msgstr ""
+
+#: contrib/localflavor/uk/uk_regions.py:93
+msgid "Wales"
+msgstr ""
+
+#: contrib/localflavor/us/forms.py:16
+msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
+msgstr ""
+
+#: contrib/localflavor/us/forms.py:54
+msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
+msgstr ""
+
+#: contrib/localflavor/za/forms.py:20
+#, fuzzy
+msgid "Enter a valid South African ID number"
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/za/forms.py:54
+#, fuzzy
+msgid "Enter a valid South African postal code"
+msgstr "Unesite ispravno ime fajla."
+
+#: contrib/localflavor/za/za_provinces.py:4
+msgid "Eastern Cape"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:5
+msgid "Free State"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:6
+msgid "Gauteng"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:7
+msgid "KwaZulu-Natal"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:8
+msgid "Limpopo"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:9
+msgid "Mpumalanga"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:10
+msgid "Northern Cape"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:11
+msgid "North West"
+msgstr ""
+
+#: contrib/localflavor/za/za_provinces.py:12
+msgid "Western Cape"
+msgstr ""
+
+#: contrib/redirects/models.py:7
+msgid "redirect from"
+msgstr "preusmeri od"
-#: core/validators.py:64
+#: contrib/redirects/models.py:8
+msgid "This should be an absolute path, excluding the domain name. Example: '/events/search/'."
+msgstr "Unesite apsolutnu putanju bez imena domena. Primer: '/dogadjaji/pretraga/'."
+
+#: contrib/redirects/models.py:9
+msgid "redirect to"
+msgstr "preusmeri ka"
+
+#: contrib/redirects/models.py:10
+msgid "This can be either an absolute path (as above) or a full URL starting with 'http://'."
+msgstr "Može biti apsolutna putanja (kao gore) ili puni URL koji poÄinje sa 'http://'."
+
+#: contrib/redirects/models.py:13
+msgid "redirect"
+msgstr "Preusmeravanje"
+
+#: contrib/redirects/models.py:14
+msgid "redirects"
+msgstr "Preusmeravanja"
+
+#: contrib/sessions/models.py:45
+msgid "session key"
+msgstr "kljuÄ sesije"
+
+#: contrib/sessions/models.py:47
+msgid "session data"
+msgstr "podaci sesije"
+
+#: contrib/sessions/models.py:48
+msgid "expire date"
+msgstr "datum prestanka važenja sesije"
+
+#: contrib/sessions/models.py:53
+msgid "session"
+msgstr "sesija"
+
+#: contrib/sessions/models.py:54
+msgid "sessions"
+msgstr "sesije"
+
+#: contrib/sites/models.py:32
+msgid "domain name"
+msgstr "ime domena"
+
+#: contrib/sites/models.py:33
+msgid "display name"
+msgstr "naziv"
+
+#: contrib/sites/models.py:38
+msgid "site"
+msgstr "sajt"
+
+#: contrib/sites/models.py:39
+msgid "sites"
+msgstr "sajtovi"
+
+#: core/validators.py:76
msgid "This value must contain only letters, numbers, underscores, dashes or slashes."
msgstr "Ovo polje može sadržati samo slova, brojeve, donju crtu (_), crtu (-) i kose crte."
-#: core/validators.py:72
+#: core/validators.py:80
+#, fuzzy
+msgid "This value must contain only letters, numbers, underscores or hyphens."
+msgstr "Ovo polje može sadržati samo slova, brojeve, donju crtu (_), crtu (-) i kose crte."
+
+#: core/validators.py:84
msgid "Uppercase letters are not allowed here."
msgstr "Velika slova nisu dozvoljena."
-#: core/validators.py:76
+#: core/validators.py:88
msgid "Lowercase letters are not allowed here."
msgstr "Mala slova nisu dozvoljena."
-#: core/validators.py:83
+#: core/validators.py:95
msgid "Enter only digits separated by commas."
msgstr "Unesite brojeve razdvojene zarezima."
-#: core/validators.py:95
+#: core/validators.py:107
msgid "Enter valid e-mail addresses separated by commas."
msgstr "Unesite ispravne e-mail adrese razdvojene zarezima."
-#: core/validators.py:99
+#: core/validators.py:111
msgid "Please enter a valid IP address."
msgstr "Unesite ispravnu IP adresu."
-#: core/validators.py:103
+#: core/validators.py:115
msgid "Empty values are not allowed here."
msgstr "Prazne vrednosti nisu dozvoljene."
-#: core/validators.py:107
+#: core/validators.py:119
msgid "Non-numeric characters aren't allowed here."
msgstr "Ovde možete uneti samo brojeve."
-#: core/validators.py:111
+#: core/validators.py:123
msgid "This value can't be comprised solely of digits."
msgstr "Podatak se ne može sastojati samo od brojeva."
-#: core/validators.py:116
+#: core/validators.py:128
+#: forms/fields.py:158
msgid "Enter a whole number."
msgstr "Unesite celi broj."
-#: core/validators.py:120
+#: core/validators.py:132
msgid "Only alphabetical characters are allowed here."
msgstr "Ovde možete koristiti samo slova."
-#: core/validators.py:124
+#: core/validators.py:147
+#, python-format
+msgid "Invalid date: %s"
+msgstr "Neispravan datum: %s"
+
+#: core/validators.py:152
+#: db/models/fields/__init__.py:574
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Unesite ispravan datum u YYYY-MM-DD formatu."
-#: core/validators.py:128
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Unesite ispravno vreme u HH:MM formatu."
-#: core/validators.py:132
-#: db/models/fields/__init__.py:468
+#: core/validators.py:161
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Unesite ispravan datum i vreme u YYYY-MM-DD HH:MM formatu."
-#: core/validators.py:136
+#: core/validators.py:166
+#: forms/fields.py:409
msgid "Enter a valid e-mail address."
msgstr "Unesite ispravnu e-mail adresu."
-#: core/validators.py:148
+#: core/validators.py:178
+#: core/validators.py:470
+#: forms/fields.py:427
+msgid "No file was submitted. Check the encoding type on the form."
+msgstr "Fajl nije poslat, proverite tip enkoding form-a."
+
+#: core/validators.py:189
+#: forms/fields.py:467
msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
msgstr "Pošaljite ispravnu sliku. Fajl koji ste poslali ili nije slika ili je sam fajl oštećen."
-#: core/validators.py:155
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "URL %s ne pokazuje na ispravnu sliku"
# nesh: tel. brojevi su u ameriÄkom formatu, ovo se ionako neće koristiti u i18n delu
-#: core/validators.py:159
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr "Telefonski brojevi moraju biti u formatu XXX-XXX-XXXX. \"%s\" je neispravan."
-#: core/validators.py:167
+#: core/validators.py:208
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "URL %s ne pokazuje na ispravni QuickTime video fajl."
-#: core/validators.py:171
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "Unesite ispravan URL."
-#: core/validators.py:185
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -1655,28 +3761,28 @@ msgstr ""
"Unesite ispravan HTML. Greške su:\n"
"%s"
-#: core/validators.py:192
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "Neispravan XML: %s"
-#: core/validators.py:202
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "Neispravan URL: %s"
-#: core/validators.py:206
-#: core/validators.py:208
+#: core/validators.py:255
+#: core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "URL %s je neispravan link."
# nesh: Ni ovo nije interesantno za i18n
-#: core/validators.py:214
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Unesite ispravnu skraćenicu za U.S. državu."
-#: core/validators.py:229
+#: core/validators.py:277
#, 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."
@@ -1684,44 +3790,59 @@ msgstr[0] "Pripazi na jezik! %s reÄ nije ovde dozvoljena."
msgstr[1] "Pripazi na jezik! %s reÄi nisu ovde dozvoljene."
msgstr[2] "Pripazi na jezik! %s reÄi nisu ovde dozvoljene."
-#: core/validators.py:236
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Ovo polje mora biti jednako sa poljem '%s'."
-#: core/validators.py:255
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Morate popuniti barem jedno polje."
-#: core/validators.py:264
-#: core/validators.py:275
+#: core/validators.py:312
+#: core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Popunite oba polja ili oba ostavite prazna."
-#: core/validators.py:282
+#: core/validators.py:331
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "Ovo polje mora biti uneto ako polje %(field)s ima vrednost %(value)s"
-#: core/validators.py:294
+#: core/validators.py:344
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr "Ovo polje mora biti uneto ako polje %(field)s nema vrednost %(value)s"
-#: core/validators.py:313
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Duple vrednosti nisu dozvoljene."
-#: core/validators.py:336
+#: core/validators.py:378
+#, python-format
+msgid "This value must be between %(lower)s and %(upper)s."
+msgstr "Vrednost mora biti između %(lower)s i %(upper)s."
+
+#: core/validators.py:380
+#, python-format
+msgid "This value must be at least %s."
+msgstr "Vrednost mora biti najmanje %s."
+
+#: core/validators.py:382
+#, python-format
+msgid "This value must be no more than %s."
+msgstr "Vrednost ne sme biti veća od %s."
+
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Vrednost mora biti stepena %s."
-#: core/validators.py:347
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Unesite ispravan decimalni broj."
-#: core/validators.py:349
+#: core/validators.py:440
#, 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."
@@ -1729,7 +3850,15 @@ msgstr[0] "Unesite ispravan decimalni broj sa %s cifrom."
msgstr[1] "Unesite ispravan decimalni broj sa %s cifre."
msgstr[2] "Unesite ispravan decimalni broj sa %s cifara."
-#: core/validators.py:352
+#: core/validators.py:443
+#, 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] "Unesite ispravan decimalni broj sa celim delom od najviše %s cifre."
+msgstr[1] "Unesite ispravan decimalni broj sa celim delom od najviše %s cifre."
+msgstr[2] "Unesite ispravan decimalni broj sa celim delom od najviše %s cifara."
+
+#: core/validators.py:446
#, 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."
@@ -1737,112 +3866,131 @@ msgstr[0] "Unesite decimalni broj sa najviše %s decimalnim mestom."
msgstr[1] "Unesite decimalni broj sa najviše %s decimalna mesta."
msgstr[2] "Unesite decimalni broj sa najviše %s decimalnih mesta."
-#: core/validators.py:362
+#: core/validators.py:454
+msgid "Please enter a valid floating point number."
+msgstr "Unesite ispravan decimalni broj."
+
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "VeliÄina fajla mora biti najmanje %s bajtova."
-#: core/validators.py:363
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "VeliÄina fajla mora biti najviÅ¡e %s bajtova."
-#: core/validators.py:376
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Pogrešan format polja."
-#: core/validators.py:391
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Neispravno polje."
-#: core/validators.py:426
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Ništa nije moglo da se skine sa URL-a %s."
-#: core/validators.py:429
+#: core/validators.py:535
#, python-format
msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
msgstr "Sa URL-a %(url)s se vratio pogrešan Content-Type header '%(contenttype)s'."
-#: core/validators.py:462
+#: core/validators.py:568
#, python-format
msgid "Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with \"%(start)s\".)"
msgstr "Zatvorite nezatvoren tag \"%(tag)s\" iz reda %(line)s. (Red poÄinje sa \"%(start)s\".)"
-#: core/validators.py:466
+#: core/validators.py:572
#, python-format
msgid "Some text starting on line %(line)s is not allowed in that context. (Line starts with \"%(start)s\".)"
msgstr "Tekst koji poÄinje u redu %(line)s nije dozvoljen u ovom kontekstu. (Red poÄinje sa \"%(start)s\".)"
-#: core/validators.py:471
+#: core/validators.py:577
#, python-format
msgid "\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%(start)s\".)"
msgstr "Atribut \"%(attr)s\" u red %(line)s je neispravan. (Red poÄinje sa \"%(start)s\".)"
-#: core/validators.py:476
+#: core/validators.py:582
#, python-format
msgid "\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%(start)s\".)"
msgstr "Tag \"<%(tag)s>\" u redu %(line)s je neispravan. (Red poÄinje \"%(start)s\".)"
-#: core/validators.py:480
+#: core/validators.py:586
#, python-format
msgid "A tag on line %(line)s is missing one or more required attributes. (Line starts with \"%(start)s\".)"
msgstr "Tag-u u redu %(line)s nedostaje jedan ili viÅ¡e atributa. (Red poÄinje sa \"%(start)s\".)"
-#: core/validators.py:485
+#: core/validators.py:591
#, python-format
msgid "The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line starts with \"%(start)s\".)"
msgstr "Atribut \"%(attr)s\" u redu %(line)s ima neispravnu vrednost. (Red poÄinje sa \"%(start)s\".)"
-#: db/models/manipulators.py:302
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "%(object)s sa ovim tipom %(type)s već postoji za polje %(field)s."
-#: db/models/fields/__init__.py:40
+#: db/models/fields/__init__.py:47
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "%(optname)s sa ovim %(fieldname)s već postoji."
-#: db/models/fields/__init__.py:114
-#: db/models/fields/__init__.py:265
-#: db/models/fields/__init__.py:542
-#: db/models/fields/__init__.py:553
-#: forms/__init__.py:346
+#: db/models/fields/__init__.py:175
+#: db/models/fields/__init__.py:348
+#: db/models/fields/__init__.py:797
+#: db/models/fields/__init__.py:808
+#: forms/fields.py:52
+#: oldforms/__init__.py:374
msgid "This field is required."
msgstr "Obavezno polje."
-#: db/models/fields/__init__.py:337
+#: db/models/fields/__init__.py:462
msgid "This value must be an integer."
msgstr "Vrednost mora biti celi broj."
-#: db/models/fields/__init__.py:369
+#: db/models/fields/__init__.py:508
msgid "This value must be either True or False."
msgstr "Vrednost mora biti True ili False."
-#: db/models/fields/__init__.py:385
+#: db/models/fields/__init__.py:537
msgid "This field cannot be null."
msgstr "Polje ne može sadržati praznu vrednost."
-#: db/models/fields/__init__.py:562
+#: db/models/fields/__init__.py:639
+#: db/models/fields/__init__.py:656
+msgid "Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format."
+msgstr "Unesite ispravan datum i vreme u YYYY-MM-DD HH:MM[ss[.uuuuuu]] formatu."
+
+#: db/models/fields/__init__.py:712
+msgid "This value must be a decimal number."
+msgstr "Vrednost mora biti decimalni broj."
+
+#: db/models/fields/__init__.py:817
msgid "Enter a valid filename."
msgstr "Unesite ispravno ime fajla."
-#: db/models/fields/related.py:43
+#: db/models/fields/__init__.py:1018
+msgid "This value must be either None, True or False."
+msgstr "Vrednost mora biti None, True ili False."
+
+#: db/models/fields/__init__.py:1133
+#: db/models/fields/__init__.py:1146
+msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
+msgstr "Unesite ispravno vreme u HH:MM[:ss[.uuuuuu]] formatu."
+
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Unesite ispravan %s."
-#: db/models/fields/related.py:579
-msgid "Separate multiple IDs with commas."
-msgstr "Odvojite višestruke ID-ove zarezima."
-
-#: db/models/fields/related.py:581
+#: db/models/fields/related.py:730
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "Koristite \"Ctrl\" (PC) ili \"Jabuku\" (Mek) da bi ste selektovali više stavki."
-#: db/models/fields/related.py:625
+#: db/models/fields/related.py:774
#, 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."
@@ -1850,7 +3998,111 @@ msgstr[0] "Unesite validne %(self)s ID-ove. Vrednost %(value)r je neispravna."
msgstr[1] "Unesite validne %(self)s ID-ove. Vrednost %(value)r je neispravna."
msgstr[2] "Unesite validne %(self)s ID-ove. Vrednost %(value)r je neispravna."
-#: forms/__init__.py:380
+#: forms/fields.py:53
+msgid "Enter a valid value."
+msgstr "Unesite ispravnu vrednost."
+
+#: forms/fields.py:130
+#, python-format
+msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
+msgstr "Proverite dužinu, maksimum je %(max)d karaktera (dobijeno %(length)d)."
+
+#: forms/fields.py:131
+#, python-format
+msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
+msgstr "Proverite dužinu, minimum je %(min)d karaktera (dobijeno %(length)d)."
+
+#: forms/fields.py:159
+#: forms/fields.py:188
+#: forms/fields.py:217
+#, python-format
+msgid "Ensure this value is less than or equal to %s."
+msgstr "Vrednost mora biti manja ili jednaka %s."
+
+#: forms/fields.py:160
+#: forms/fields.py:189
+#: forms/fields.py:218
+#, python-format
+msgid "Ensure this value is greater than or equal to %s."
+msgstr "Proverite da li je vrednost veća ili jednaka %s."
+
+#: forms/fields.py:187
+#: forms/fields.py:216
+msgid "Enter a number."
+msgstr "Unesite broj."
+
+#: forms/fields.py:219
+#, python-format
+msgid "Ensure that there are no more than %s digits in total."
+msgstr "Proverite da nema više od %s cifara."
+
+#: forms/fields.py:220
+#, python-format
+msgid "Ensure that there are no more than %s decimal places."
+msgstr "Proverite da nema više od %s decimalnih mesta."
+
+#: forms/fields.py:221
+#, python-format
+msgid "Ensure that there are no more than %s digits before the decimal point."
+msgstr "Proverite da nema više od %s cifara u celom delu."
+
+#: forms/fields.py:269
+#: forms/fields.py:799
+msgid "Enter a valid date."
+msgstr "Unesite ispravan datum."
+
+#: forms/fields.py:302
+#: forms/fields.py:800
+msgid "Enter a valid time."
+msgstr "Unesite ispravno vreme."
+
+#: forms/fields.py:341
+msgid "Enter a valid date/time."
+msgstr "Unesite ispravan datum i vreme."
+
+#: forms/fields.py:428
+msgid "No file was submitted."
+msgstr "Fajl nije poslat."
+
+#: forms/fields.py:429
+#: oldforms/__init__.py:693
+msgid "The submitted file is empty."
+msgstr "Poslati fajl je prazan."
+
+#: forms/fields.py:528
+msgid "Enter a valid URL."
+msgstr "Unesite ispravan URL."
+
+#: forms/fields.py:529
+msgid "This URL appears to be a broken link."
+msgstr "URL je neispravan link."
+
+#: forms/fields.py:597
+#: forms/fields.py:648
+#, python-format
+msgid "Select a valid choice. %(value)s is not one of the available choices."
+msgstr "Izaberite validnu opciju. %(value)s nije među njima."
+
+#: forms/fields.py:649
+#: forms/fields.py:710
+#: forms/models.py:581
+msgid "Enter a list of values."
+msgstr "Unesite listu vrednosti."
+
+#: forms/fields.py:828
+msgid "Enter a valid IPv4 address."
+msgstr "Unesite IPv4 adresu."
+
+#: forms/models.py:514
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr "Izaberite validnu opciju. Izabrana opcija nije validna."
+
+#: forms/models.py:582
+#, python-format
+msgid "Select a valid choice. %s is not one of the available choices."
+msgstr "Izaberite validnu opciju. Opcija %s nije validna."
+
+#: oldforms/__init__.py:409
#, python-format
msgid "Ensure your text is less than %s character."
msgid_plural "Ensure your text is less than %s characters."
@@ -1858,37 +4110,373 @@ msgstr[0] "Tekst mora imati manje od %s slova."
msgstr[1] "Tekst mora imati manje od %s slova."
msgstr[2] "Tekst mora imati manje od %s slova."
-#: forms/__init__.py:385
+#: oldforms/__init__.py:414
msgid "Line breaks are not allowed here."
msgstr "Novi redovi ovde nisu dozvoljeni."
-#: forms/__init__.py:480
-#: forms/__init__.py:551
-#: forms/__init__.py:589
+#: oldforms/__init__.py:512
+#: oldforms/__init__.py:586
+#: oldforms/__init__.py:625
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Izaberite validnu opciju: '%(data)s' nije u %(choices)s."
-#: forms/__init__.py:645
-msgid "The submitted file is empty."
-msgstr "Poslati fajl je prazan."
-
-#: forms/__init__.py:699
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Unesite celi broj između -32,768 i 32,767."
-#: forms/__init__.py:708
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Unesite pozitivan broj."
-#: forms/__init__.py:717
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Unesite celi broj između 0 i 32,767."
-#: template/defaultfilters.py:379
+#: template/defaultfilters.py:698
msgid "yes,no,maybe"
msgstr "da,ne,možda"
+#: template/defaultfilters.py:729
+#, python-format
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] "%(size)d bajt"
+msgstr[1] "%(size)d bajta"
+msgstr[2] "%(size)d bajtova"
+
+#: template/defaultfilters.py:731
+#, python-format
+msgid "%.1f KB"
+msgstr ""
+
+#: template/defaultfilters.py:733
+#, python-format
+msgid "%.1f MB"
+msgstr ""
+
+#: template/defaultfilters.py:734
+#, python-format
+msgid "%.1f GB"
+msgstr ""
+
+#: utils/dateformat.py:41
+msgid "p.m."
+msgstr "popodne"
+
+#: utils/dateformat.py:42
+msgid "a.m."
+msgstr "prepodne"
+
+#: utils/dateformat.py:47
+msgid "PM"
+msgstr "popodne"
+
+#: utils/dateformat.py:48
+msgid "AM"
+msgstr "prepodne"
+
+#: utils/dateformat.py:97
+msgid "midnight"
+msgstr "ponoć"
+
+#: utils/dateformat.py:99
+msgid "noon"
+msgstr "podne"
+
+#: utils/dates.py:6
+msgid "Monday"
+msgstr "Ponedeljak"
+
+#: utils/dates.py:6
+msgid "Tuesday"
+msgstr "Utorak"
+
+#: utils/dates.py:6
+msgid "Wednesday"
+msgstr "Sreda"
+
+#: utils/dates.py:6
+msgid "Thursday"
+msgstr "ÄŒetvrtak"
+
+#: utils/dates.py:6
+msgid "Friday"
+msgstr "Petak"
+
+#: utils/dates.py:7
+msgid "Saturday"
+msgstr "Subota"
+
+#: utils/dates.py:7
+msgid "Sunday"
+msgstr "Nedelja"
+
+#: utils/dates.py:10
+msgid "Mon"
+msgstr "Pon"
+
+#: utils/dates.py:10
+msgid "Tue"
+msgstr "Uto"
+
+#: utils/dates.py:10
+msgid "Wed"
+msgstr "Sre"
+
+#: utils/dates.py:10
+msgid "Thu"
+msgstr "ÄŒet"
+
+#: utils/dates.py:10
+msgid "Fri"
+msgstr "Pet"
+
+#: utils/dates.py:11
+msgid "Sat"
+msgstr "Sub"
+
+#: utils/dates.py:11
+msgid "Sun"
+msgstr "Ned"
+
+#: utils/dates.py:18
+msgid "January"
+msgstr "Januar"
+
+#: utils/dates.py:18
+msgid "February"
+msgstr "Februar"
+
+#: utils/dates.py:18
+#: utils/dates.py:31
+msgid "March"
+msgstr "Mart"
+
+#: utils/dates.py:18
+#: utils/dates.py:31
+msgid "April"
+msgstr "April"
+
+#: utils/dates.py:18
+#: utils/dates.py:31
+msgid "May"
+msgstr "Maj"
+
+#: utils/dates.py:18
+#: utils/dates.py:31
+msgid "June"
+msgstr "Jun"
+
+#: utils/dates.py:19
+#: utils/dates.py:31
+msgid "July"
+msgstr "Jul"
+
+#: utils/dates.py:19
+msgid "August"
+msgstr "Avgust"
+
+#: utils/dates.py:19
+msgid "September"
+msgstr "Septembar"
+
+#: utils/dates.py:19
+msgid "October"
+msgstr "Oktobar"
+
+#: utils/dates.py:19
+msgid "November"
+msgstr "Novembar"
+
+#: utils/dates.py:20
+msgid "December"
+msgstr "Decembar"
+
+#: utils/dates.py:23
+msgid "jan"
+msgstr "jan"
+
+#: utils/dates.py:23
+msgid "feb"
+msgstr "feb"
+
+#: utils/dates.py:23
+msgid "mar"
+msgstr "mar"
+
+#: utils/dates.py:23
+msgid "apr"
+msgstr "apr"
+
+#: utils/dates.py:23
+msgid "may"
+msgstr "maj"
+
+#: utils/dates.py:23
+msgid "jun"
+msgstr "jun"
+
+#: utils/dates.py:24
+msgid "jul"
+msgstr "jul"
+
+#: utils/dates.py:24
+msgid "aug"
+msgstr "avg"
+
+#: utils/dates.py:24
+msgid "sep"
+msgstr "sep"
+
+#: utils/dates.py:24
+msgid "oct"
+msgstr "okt"
+
+#: utils/dates.py:24
+msgid "nov"
+msgstr "nov"
+
+#: utils/dates.py:24
+msgid "dec"
+msgstr "dec"
+
+#: utils/dates.py:31
+msgid "Jan."
+msgstr "Jan."
+
+#: utils/dates.py:31
+msgid "Feb."
+msgstr "Feb."
+
+#: utils/dates.py:32
+msgid "Aug."
+msgstr "Avg."
+
+#: utils/dates.py:32
+msgid "Sept."
+msgstr "Sept."
+
+#: utils/dates.py:32
+msgid "Oct."
+msgstr "Okt."
+
+#: utils/dates.py:32
+msgid "Nov."
+msgstr "Nov."
+
+#: utils/dates.py:32
+msgid "Dec."
+msgstr "Dec."
+
+#: utils/text.py:128
+msgid "or"
+msgstr "ili"
+
+#: utils/timesince.py:21
+msgid "year"
+msgid_plural "years"
+msgstr[0] "godina"
+msgstr[1] "godine"
+msgstr[2] "godina"
+
+#: utils/timesince.py:22
+msgid "month"
+msgid_plural "months"
+msgstr[0] "mesec"
+msgstr[1] "meseca"
+msgstr[2] "meseci"
+
+#: utils/timesince.py:23
+msgid "week"
+msgid_plural "weeks"
+msgstr[0] "nedelja"
+msgstr[1] "nedelje"
+msgstr[2] "nedelja"
+
+#: utils/timesince.py:24
+msgid "day"
+msgid_plural "days"
+msgstr[0] "dan"
+msgstr[1] "dana"
+msgstr[2] "dana"
+
+#: utils/timesince.py:25
+msgid "hour"
+msgid_plural "hours"
+msgstr[0] "sat"
+msgstr[1] "sata"
+msgstr[2] "sati"
+
+#: utils/timesince.py:26
+msgid "minute"
+msgid_plural "minutes"
+msgstr[0] "minut"
+msgstr[1] "munuta"
+msgstr[2] "minuta"
+
+#: utils/timesince.py:46
+msgid "minutes"
+msgstr "minuta"
+
+#: utils/timesince.py:51
+#, python-format
+msgid "%(number)d %(type)s"
+msgstr "%(type)s: %(number)d"
+
+#: utils/timesince.py:57
+#, python-format
+msgid ", %(number)d %(type)s"
+msgstr ", %(type)s: %(number)d"
+
+#: utils/translation/trans_real.py:401
+msgid "DATE_FORMAT"
+msgstr "D, d.m.Y."
+
+#: utils/translation/trans_real.py:402
+msgid "DATETIME_FORMAT"
+msgstr "d.m.Y. H:i:s"
+
+#: utils/translation/trans_real.py:403
+msgid "TIME_FORMAT"
+msgstr "H:i:s"
+
+#: utils/translation/trans_real.py:419
+msgid "YEAR_MONTH_FORMAT"
+msgstr "m.Y."
+
+#: utils/translation/trans_real.py:420
+msgid "MONTH_DAY_FORMAT"
+msgstr "d.m."
+
+#: views/generic/create_update.py:129
+#, python-format
+msgid "The %(verbose_name)s was created successfully."
+msgstr "%(verbose_name)s uspešno kreiran."
+
+#: views/generic/create_update.py:172
+#, python-format
+msgid "The %(verbose_name)s was updated successfully."
+msgstr "%(verbose_name)s uspešno promenjen."
+
+#: views/generic/create_update.py:214
+#, python-format
+msgid "The %(verbose_name)s was deleted."
+msgstr "%(verbose_name)s je obrisan."
+
+#~ msgid "Added %s."
+#~ msgstr "Dodat %s"
+#~ msgid "Deleted %s."
+#~ msgstr "Obrisan %s."
+#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
+#~ msgstr ""
+#~ "Da li ste <a href=\"/password_reset/\">zaboravili vašu lozinku?</a>?"
+#~ msgid "Ordering"
+#~ msgstr "Redosled"
+#~ msgid "Use '[algo]$[salt]$[hexdigest]'"
+#~ msgstr "Koristite '[algo]$[salt]$[hexdigest]'"
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Odvojite višestruke ID-ove zarezima."
#~ msgid "Comment"
#~ msgstr "Komentar"
#~ msgid "Comments"
diff --git a/django/conf/locale/sr/LC_MESSAGES/djangojs.mo b/django/conf/locale/sr/LC_MESSAGES/djangojs.mo
index 5713185742..1de89774d7 100644
--- a/django/conf/locale/sr/LC_MESSAGES/djangojs.mo
+++ b/django/conf/locale/sr/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/django/conf/locale/sr/LC_MESSAGES/djangojs.po b/django/conf/locale/sr/LC_MESSAGES/djangojs.po
index 65a17757f7..c1338be4bd 100644
--- a/django/conf/locale/sr/LC_MESSAGES/djangojs.po
+++ b/django/conf/locale/sr/LC_MESSAGES/djangojs.po
@@ -7,15 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2005-12-09 11:51+0100\n"
-"PO-Revision-Date: 2007-02-20 18:51+0100\n"
-"Last-Translator: Petar Marić <petar.maric@gmail.com>\n"
-"Language-Team: Nesh <nesh@studioquatro.co.yu> & Petar <petar.maric@gmail.com> <sr@li.org>\n"
+"POT-Creation-Date: 2008-07-29 12:07+0200\n"
+"PO-Revision-Date: 2008-07-29 12:53+0100\n"
+"Last-Translator: Nebojsa Djordjevic <djnesh@gmail.com>\n"
+"Language-Team: Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail.com> <sr@li.org>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Country: YUGOSLAVIA\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Serbian\n"
+"X-Poedit-SourceCharset: utf-8\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
@@ -47,63 +49,72 @@ msgstr "Izaberite potrebno i kliknite"
msgid "Clear all"
msgstr "Obrišite sve"
-#: contrib/admin/media/js/dateparse.js:26
#: contrib/admin/media/js/calendar.js:24
+#: contrib/admin/media/js/dateparse.js:32
msgid "January February March April May June July August September October November December"
msgstr "Januar Februar Mart April Maj Jun Jul Avgust Septembar Oktobar Novembar Decembar"
-#: contrib/admin/media/js/dateparse.js:27
-msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
-msgstr "Nedelja Ponedeljak Utorak Sreda ÄŒetvrtak Petak Subota"
-
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "N P U S Č P S"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
+#: contrib/admin/media/js/dateparse.js:33
+msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
+msgstr "Nedelja Ponedeljak Utorak Sreda ÄŒetvrtak Petak Subota"
+
+#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
+#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
+msgid "Show"
+msgstr "Prikaži"
+
+#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
+msgid "Hide"
+msgstr "Sakrij"
+
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr "Sada"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr "Sat"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr "Izaberite vreme"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr "Ponoć"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr "6 sati"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr "Podne"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr "Poništi"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr "Danas"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr "Kalendar"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr "JuÄe"
-#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
+#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr "Sutra"
diff --git a/django/conf/locale/sv/LC_MESSAGES/django.mo b/django/conf/locale/sv/LC_MESSAGES/django.mo
index acb08754a5..f6cf8c22c5 100644
--- a/django/conf/locale/sv/LC_MESSAGES/django.mo
+++ b/django/conf/locale/sv/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/sv/LC_MESSAGES/django.po b/django/conf/locale/sv/LC_MESSAGES/django.po
index b6ef3c3a6d..32d04d4b14 100644
--- a/django/conf/locale/sv/LC_MESSAGES/django.po
+++ b/django/conf/locale/sv/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-05-26 10:58+0200\n"
+"POT-Creation-Date: 2008-07-27 21:27+0200\n"
"PO-Revision-Date: 2008-05-26 11:15+0200\n"
"Last-Translator: Ludvig Ericson <ludvig.ericson@gmail.com>\n"
"Language-Team: Django I18N <Django-I18N@googlegroups.com>\n"
@@ -17,191 +17,199 @@ msgstr ""
"X-Poedit-Language: Swedish\n"
"X-Poedit-Country: SWEDEN\n"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:44
msgid "Arabic"
msgstr "Arabiska"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:45
msgid "Bengali"
msgstr "Bengaliska"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:46
msgid "Bulgarian"
msgstr "Bulgariska"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:47
msgid "Catalan"
msgstr "Katalanska"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:48
msgid "Czech"
msgstr "Tjeckiska"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:49
msgid "Welsh"
msgstr "Walesiska"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:50
msgid "Danish"
msgstr "Danska"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:51
msgid "German"
msgstr "Tyska"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:52
msgid "Greek"
msgstr "Grekiska"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:53
msgid "English"
msgstr "Engelska"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:54
msgid "Spanish"
msgstr "Spanska"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:55
+msgid "Estonian"
+msgstr "Estländska"
+
+#: conf/global_settings.py:56
msgid "Argentinean Spanish"
msgstr "Argentisk Spanska"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:57
msgid "Basque"
msgstr "Baskiska"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:58
msgid "Persian"
msgstr "Persiska"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:59
msgid "Finnish"
msgstr "Finska"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:60
msgid "French"
msgstr "Franska"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:61
msgid "Irish"
msgstr "Irländska"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:62
msgid "Galician"
msgstr "Galisiska"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:63
msgid "Hungarian"
msgstr "Ungerska"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:64
msgid "Hebrew"
msgstr "Hebreiska"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:65
msgid "Croatian"
msgstr "Kroatiska"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:66
msgid "Icelandic"
msgstr "Isländska"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:67
msgid "Italian"
msgstr "Italienska"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:68
msgid "Japanese"
msgstr "Japanska"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:69
msgid "Georgian"
msgstr "Georgiska"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:70
msgid "Korean"
msgstr "Koreanska"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:71
msgid "Khmer"
msgstr "Khmer"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:72
msgid "Kannada"
msgstr "Kannada"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:73
msgid "Latvian"
msgstr "Lettiska"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:74
+msgid "Lithuanian"
+msgstr "Lettiska"
+
+#: conf/global_settings.py:75
msgid "Macedonian"
msgstr "Makedonska"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:76
msgid "Dutch"
msgstr "Holländska"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:77
msgid "Norwegian"
msgstr "Norska"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:78
msgid "Polish"
msgstr "Polska"
-#: conf/global_settings.py:76
+#: conf/global_settings.py:79
msgid "Portugese"
msgstr "Portugisiska"
-#: conf/global_settings.py:77
+#: conf/global_settings.py:80
msgid "Brazilian Portuguese"
msgstr "Brasiliensk portugisiska"
-#: conf/global_settings.py:78
+#: conf/global_settings.py:81
msgid "Romanian"
msgstr "Rumänska"
-#: conf/global_settings.py:79
+#: conf/global_settings.py:82
msgid "Russian"
msgstr "Ryska"
-#: conf/global_settings.py:80
+#: conf/global_settings.py:83
msgid "Slovak"
msgstr "Slovakiska"
-#: conf/global_settings.py:81
+#: conf/global_settings.py:84
msgid "Slovenian"
msgstr "Slovenska"
-#: conf/global_settings.py:82
+#: conf/global_settings.py:85
msgid "Serbian"
msgstr "Serbiska"
-#: conf/global_settings.py:83
+#: conf/global_settings.py:86
msgid "Swedish"
msgstr "Svenska"
-#: conf/global_settings.py:84
+#: conf/global_settings.py:87
msgid "Tamil"
msgstr "Tamilska"
-#: conf/global_settings.py:85
+#: conf/global_settings.py:88
msgid "Telugu"
msgstr "Telugu"
-#: conf/global_settings.py:86
+#: conf/global_settings.py:89
msgid "Turkish"
msgstr "Turkiska"
-#: conf/global_settings.py:87
+#: conf/global_settings.py:90
msgid "Ukrainian"
msgstr "Ukrainska"
-#: conf/global_settings.py:88
+#: conf/global_settings.py:91
msgid "Simplified Chinese"
msgstr "Förenklad Kinesiska"
-#: conf/global_settings.py:89
+#: conf/global_settings.py:92
msgid "Traditional Chinese"
msgstr "Traditionell Kinesiska"
@@ -239,49 +247,206 @@ msgstr "Denna månad"
msgid "This year"
msgstr "Detta år"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Yes"
msgstr "Ja"
-#: contrib/admin/filterspecs.py:147 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:147 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "No"
msgstr "Nej"
-#: contrib/admin/filterspecs.py:154 newforms/widgets.py:231
+#: contrib/admin/filterspecs.py:154 forms/widgets.py:379
#: oldforms/__init__.py:592
msgid "Unknown"
msgstr "Okänt"
-#: contrib/admin/models.py:18
+#: contrib/admin/models.py:19
msgid "action time"
msgstr "händelsetid"
-#: contrib/admin/models.py:21
+#: contrib/admin/models.py:22
msgid "object id"
msgstr "objektets id"
-#: contrib/admin/models.py:22
+#: contrib/admin/models.py:23
msgid "object repr"
msgstr "objektets beskrivning"
-#: contrib/admin/models.py:23
+#: contrib/admin/models.py:24
msgid "action flag"
msgstr "händelseflagga"
-#: contrib/admin/models.py:24
+#: contrib/admin/models.py:25
msgid "change message"
msgstr "ändra meddelande"
-#: contrib/admin/models.py:27
+#: contrib/admin/models.py:28
msgid "log entry"
msgstr "loggpost"
-#: contrib/admin/models.py:28
+#: contrib/admin/models.py:29
msgid "log entries"
msgstr "loggposter"
+#: contrib/admin/options.py:161 contrib/admin/options.py:180
+msgid "None"
+msgstr "Inget"
+
+#: contrib/admin/options.py:347 contrib/auth/admin.py:37
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was added successfully."
+msgstr "%(name)s \"%(obj)s\" lades till."
+
+#: contrib/admin/options.py:351 contrib/admin/options.py:419
+#: contrib/auth/admin.py:42
+msgid "You may edit it again below."
+msgstr "Du kan ändra det igen nedanför."
+
+#: contrib/admin/options.py:361 contrib/admin/options.py:428
+#, python-format
+msgid "You may add another %s below."
+msgstr "Du kan lägga till ytterligare %s nedanför."
+
+#: contrib/admin/options.py:395
+#, python-format
+msgid "Changed %s."
+msgstr "Ändrade %s."
+
+#: contrib/admin/options.py:395 contrib/admin/options.py:405
+#: core/validators.py:279 db/models/manipulators.py:305
+msgid "and"
+msgstr "och"
+
+#: contrib/admin/options.py:400
+msgid "Added %(name)s \"%(object)s\"."
+msgstr "Lade till %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:404
+#, python-format
+msgid "Changed %(list)s for %(name)s \"%(object)s\"."
+msgstr "Ändrade %(list)s på %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:409
+#, python-format
+msgid "Deleted %(name)s \"%(object)s\"."
+msgstr "Tog bort %(name)s \"%(object)s\"."
+
+#: contrib/admin/options.py:414
+msgid "No fields changed."
+msgstr "Inga fält ändrade."
+
+#: contrib/admin/options.py:417
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was changed successfully."
+msgstr "%(name)s \"%(obj)s\" ändrades."
+
+#: contrib/admin/options.py:425
+#, python-format
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr ""
+"%(name)s \"%(obj)s\" lades till. Du kan redigera objektet igen nedanför."
+
+#: contrib/admin/options.py:506
+#, python-format
+msgid "Add %s"
+msgstr "Lägg till %s"
+
+#: contrib/admin/options.py:568
+#, python-format
+msgid "Change %s"
+msgstr "Ändra %s"
+
+#: contrib/admin/options.py:598
+msgid "Database error"
+msgstr "Databasfel"
+
+#: contrib/admin/options.py:647
+#, python-format
+msgid "The %(name)s \"%(obj)s\" was deleted successfully."
+msgstr "%(name)s \"%(obj)s\" togs bort."
+
+#: contrib/admin/options.py:653
+msgid "Are you sure?"
+msgstr "Är du säker?"
+
+#: contrib/admin/options.py:680
+#, python-format
+msgid "Change history: %s"
+msgstr "Ändringshistorik: %s"
+
+#: contrib/admin/sites.py:18 contrib/admin/views/decorators.py:16
+#: contrib/auth/forms.py:70 contrib/comments/views/comments.py:56
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Var god ange ett korrekt användarnamn och lösenord. Tänk på att skilja "
+"mellan gemener och versaler."
+
+#: contrib/admin/sites.py:233 contrib/admin/views/decorators.py:68
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Du måste logga in igen eftersom din session har förfallit. Oroa dig inte: "
+"Din data har sparats."
+
+#: contrib/admin/sites.py:240 contrib/admin/views/decorators.py:75
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Det verkar som att din webläsare inte är konfigurerad att acceptera cookies. "
+"Aktivera cookies, ladda om denna sida och försök igen."
+
+#: contrib/admin/sites.py:254 contrib/admin/sites.py:260
+#: contrib/admin/views/decorators.py:92
+msgid "Usernames cannot contain the '@' character."
+msgstr "Användarnamn får inte innehålla '@'-tecknet."
+
+#: contrib/admin/sites.py:257 contrib/admin/views/decorators.py:88
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "Din e-postadress är inte ditt användarnamn. Försök med '%s' istället."
+
+#: contrib/admin/sites.py:325
+msgid "Site administration"
+msgstr "Webbplatsadministration"
+
+#: contrib/admin/sites.py:347 contrib/admin/templates/admin/login.html:27
+#: contrib/admin/views/decorators.py:30
+msgid "Log in"
+msgstr "Logga in"
+
+#: contrib/admin/util.py:126
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
+msgstr "Ett eller flera %(fieldname)s i %(name)s: %(obj)s"
+
+#: contrib/admin/util.py:131
+#, python-format
+msgid "One or more %(fieldname)s in %(name)s:"
+msgstr "Ett eller flera %(fieldname)s i %(name)s:"
+
+#: contrib/admin/widgets.py:65
+msgid "Date:"
+msgstr "Datum:"
+
+#: contrib/admin/widgets.py:65
+msgid "Time:"
+msgstr "Tid:"
+
+#: contrib/admin/widgets.py:89
+msgid "Currently:"
+msgstr "Aktuell:"
+
+#: contrib/admin/widgets.py:89
+msgid "Change:"
+msgstr "Ändra:"
+
#: contrib/admin/templates/admin/404.html:4
#: contrib/admin/templates/admin/404.html:8
msgid "Page not found"
@@ -292,17 +457,17 @@ msgid "We're sorry, but the requested page could not be found."
msgstr "Vi beklagar men den begärda sidan hittades inte."
#: contrib/admin/templates/admin/500.html:4
-#: contrib/admin/templates/admin/base.html:37
-#: contrib/admin/templates/admin/change_form.html:12
-#: contrib/admin/templates/admin/change_list.html:5
-#: contrib/admin/templates/admin/delete_confirmation.html:5
+#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/change_form.html:17
+#: contrib/admin/templates/admin/change_list.html:8
+#: contrib/admin/templates/admin/delete_confirmation.html:6
#: contrib/admin/templates/admin/invalid_setup.html:4
-#: contrib/admin/templates/admin/object_history.html:4
-#: contrib/admin/templates/admin/auth/user/change_password.html:11
+#: contrib/admin/templates/admin/object_history.html:5
+#: contrib/admin/templates/admin/auth/user/change_password.html:10
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
#: contrib/admin/templates/registration/logged_out.html:4
-#: 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: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"
@@ -328,22 +493,28 @@ msgstr ""
"Ett fel har uppstått. Administratören har meddelats via e-post och felet bör "
"vara åtgärdat inom kort. Tack för visat tålamod."
-#: contrib/admin/templates/admin/base.html:26
+#: contrib/admin/templates/admin/base.html:25
msgid "Welcome,"
msgstr "Välkommen,"
-#: contrib/admin/templates/admin/base.html:28
+#: contrib/admin/templates/admin/base.html:25
#: 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:29
-#: contrib/admin/templates/admin/auth/user/change_password.html:14
-#: contrib/admin/templates/admin/auth/user/change_password.html:45
+#: contrib/admin/templates/admin/base.html:25
+#: contrib/admin/templates/admin/auth/user/change_password.html:13
+#: 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
msgid "Change password"
msgstr "Ändra lösenord"
-#: contrib/admin/templates/admin/base.html:30
+#: contrib/admin/templates/admin/base.html:25
+#: 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 "Logga ut"
@@ -356,46 +527,43 @@ msgstr "Django webbplatsadministration"
msgid "Django administration"
msgstr "Django-administration"
-#: contrib/admin/templates/admin/change_form.html:14
-#: contrib/admin/templates/admin/index.html:28
+#: contrib/admin/templates/admin/change_form.html:19
+#: contrib/admin/templates/admin/index.html:29
msgid "Add"
msgstr "Lägg till"
-#: contrib/admin/templates/admin/change_form.html:20
-#: contrib/admin/templates/admin/object_history.html:4
+#: contrib/admin/templates/admin/change_form.html:26
+#: contrib/admin/templates/admin/object_history.html:5
msgid "History"
msgstr "Historik"
-#: contrib/admin/templates/admin/change_form.html:21
+#: contrib/admin/templates/admin/change_form.html:27
msgid "View on site"
msgstr "Visa på webbplats"
-#: contrib/admin/templates/admin/change_form.html:31
-#: contrib/admin/templates/admin/auth/user/change_password.html:23
+#: contrib/admin/templates/admin/change_form.html:37
+#: contrib/admin/templates/admin/auth/user/change_password.html:22
msgid "Please correct the error below."
msgid_plural "Please correct the errors below."
msgstr[0] "Rätta till felet nedan."
msgstr[1] "Rätta till felen nedan."
-#: contrib/admin/templates/admin/change_form.html:49
-msgid "Ordering"
-msgstr "Sortering"
-
-#: contrib/admin/templates/admin/change_form.html:52
-msgid "Order:"
-msgstr "Sortera:"
-
-#: contrib/admin/templates/admin/change_list.html:11
+#: contrib/admin/templates/admin/change_list.html:16
#, python-format
msgid "Add %(name)s"
msgstr "Lägg till %(name)s"
-#: contrib/admin/templates/admin/delete_confirmation.html:8
+#: contrib/admin/templates/admin/change_list.html:26
+msgid "Filter"
+msgstr "Filter"
+
+#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
+#: contrib/admin/templates/admin/edit_inline/tabular.html:15
msgid "Delete"
msgstr "Ta bort"
-#: contrib/admin/templates/admin/delete_confirmation.html:13
+#: contrib/admin/templates/admin/delete_confirmation.html:15
#, python-format
msgid ""
"Deleting the %(object_name)s '%(escaped_object)s' would result in deleting "
@@ -406,7 +574,7 @@ msgstr ""
"relaterade objekt togs bort, men ditt konto har inte rättigheter att ta bort "
"följande objekttyper:"
-#: contrib/admin/templates/admin/delete_confirmation.html:20
+#: contrib/admin/templates/admin/delete_confirmation.html:22
#, python-format
msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
@@ -415,7 +583,7 @@ msgstr ""
"Är du säker på att du vill ta bort %(object_name)s \"%(escaped_object)s\"? "
"Följande relaterade objekt kommer att tas bort:"
-#: contrib/admin/templates/admin/delete_confirmation.html:25
+#: contrib/admin/templates/admin/delete_confirmation.html:27
msgid "Yes, I'm sure"
msgstr "Ja, jag är säker"
@@ -424,41 +592,37 @@ msgstr "Ja, jag är säker"
msgid " By %(filter_title)s "
msgstr " Av %(filter_title)s "
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filter"
-
-#: contrib/admin/templates/admin/index.html:17
+#: contrib/admin/templates/admin/index.html:18
#, python-format
msgid "Models available in the %(name)s application."
msgstr "Modeller tillgängliga i applikationen %(name)s."
-#: contrib/admin/templates/admin/index.html:18
+#: contrib/admin/templates/admin/index.html:19
#, python-format
msgid "%(name)s"
msgstr "%(name)s"
-#: contrib/admin/templates/admin/index.html:34
+#: contrib/admin/templates/admin/index.html:35
msgid "Change"
msgstr "Ändra"
-#: contrib/admin/templates/admin/index.html:44
+#: contrib/admin/templates/admin/index.html:45
msgid "You don't have permission to edit anything."
msgstr "Du har inte rättigheter att redigera något."
-#: contrib/admin/templates/admin/index.html:52
+#: contrib/admin/templates/admin/index.html:53
msgid "Recent Actions"
msgstr "Senaste Händelser"
-#: contrib/admin/templates/admin/index.html:53
+#: contrib/admin/templates/admin/index.html:54
msgid "My Actions"
msgstr "Mina händelser"
-#: contrib/admin/templates/admin/index.html:57
+#: contrib/admin/templates/admin/index.html:58
msgid "None available"
msgstr "Inga tillgängliga"
-#: contrib/admin/templates/admin/invalid_setup.html:8
+#: contrib/admin/templates/admin/invalid_setup.html:7
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 "
@@ -467,39 +631,34 @@ msgstr ""
"Någonting är fel med din databasinstallation. Se till att de rätta "
"databastabellerna har skapats och att databasen är läsbar av rätt användare."
-#: contrib/admin/templates/admin/login.html:17
+#: contrib/admin/templates/admin/login.html:19
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
msgid "Username:"
msgstr "Användarnamn:"
-#: contrib/admin/templates/admin/login.html:20
+#: contrib/admin/templates/admin/login.html:22
#: contrib/comments/templates/comments/form.html:8
msgid "Password:"
msgstr "Lösenord:"
-#: contrib/admin/templates/admin/login.html:25
-#: contrib/admin/views/decorators.py:31
-msgid "Log in"
-msgstr "Logga in"
-
-#: contrib/admin/templates/admin/object_history.html:17
+#: contrib/admin/templates/admin/object_history.html:16
msgid "Date/time"
msgstr "Datum tid"
-#: contrib/admin/templates/admin/object_history.html:18
+#: contrib/admin/templates/admin/object_history.html:17
msgid "User"
msgstr "Användare"
-#: contrib/admin/templates/admin/object_history.html:19
+#: contrib/admin/templates/admin/object_history.html:18
msgid "Action"
msgstr "Händelse"
-#: contrib/admin/templates/admin/object_history.html:25
+#: contrib/admin/templates/admin/object_history.html:24
msgid "DATE_WITH_TIME_FULL"
msgstr "Y-m-d H:i:s"
-#: contrib/admin/templates/admin/object_history.html:35
+#: contrib/admin/templates/admin/object_history.html:32
msgid ""
"This object doesn't have a change history. It probably wasn't added via this "
"admin site."
@@ -551,26 +710,29 @@ msgstr ""
"Ange först ett användarnamn och ett lösenord. Efter det kommer du att få "
"fler användaralternativ."
-#: contrib/admin/templates/admin/auth/user/add_form.html:12
+#: contrib/admin/templates/admin/auth/user/add_form.html:13
+#: contrib/auth/forms.py:12 contrib/auth/forms.py:49
msgid "Username"
msgstr "Användarnamn"
-#: contrib/admin/templates/admin/auth/user/add_form.html:18
+#: contrib/admin/templates/admin/auth/user/add_form.html:20
#: contrib/admin/templates/admin/auth/user/change_password.html:33
+#: contrib/auth/forms.py:15 contrib/auth/forms.py:50 contrib/auth/forms.py:166
msgid "Password"
msgstr "Lösenord"
-#: contrib/admin/templates/admin/auth/user/add_form.html:23
-#: contrib/admin/templates/admin/auth/user/change_password.html:38
+#: contrib/admin/templates/admin/auth/user/add_form.html:26
+#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/auth/forms.py:167
msgid "Password (again)"
msgstr "Lösenord (igen)"
-#: contrib/admin/templates/admin/auth/user/add_form.html:24
-#: contrib/admin/templates/admin/auth/user/change_password.html:39
+#: contrib/admin/templates/admin/auth/user/add_form.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:40
msgid "Enter the same password as above, for verification."
msgstr "Fyll i samma lösenord som ovan för verifiering."
-#: contrib/admin/templates/admin/auth/user/change_password.html:27
+#: contrib/admin/templates/admin/auth/user/change_password.html:26
#, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>."
msgstr "Ange nytt lösenord för användare <strong>%(username)s</strong>."
@@ -652,23 +814,23 @@ msgstr "Tack för att du spenderade lite kvalitetstid med webbplatsen idag."
msgid "Log in again"
msgstr "Logga in igen"
-#: contrib/admin/templates/registration/password_change_done.html:3
-#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/registration/password_change_form.html:5
-#: contrib/admin/templates/registration/password_change_form.html:9
+#: 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 "Ändra lösenord"
-#: contrib/admin/templates/registration/password_change_done.html:5
-#: contrib/admin/templates/registration/password_change_done.html:9
+#: contrib/admin/templates/registration/password_change_done.html:6
+#: contrib/admin/templates/registration/password_change_done.html:10
msgid "Password change successful"
msgstr "Lösenordet ändrades"
-#: contrib/admin/templates/registration/password_change_done.html:11
+#: contrib/admin/templates/registration/password_change_done.html:12
msgid "Your password was changed."
msgstr "Ditt lösenord har ändrats."
-#: contrib/admin/templates/registration/password_change_form.html:11
+#: 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."
@@ -676,19 +838,19 @@ msgstr ""
"Var god fyll i ditt gamla lösenord för säkerhets skull och skriv sedan in "
"ditt nya lösenord två gånger så vi kan kontrollera att du skrev det rätt."
-#: contrib/admin/templates/registration/password_change_form.html:16
+#: contrib/admin/templates/registration/password_change_form.html:17
msgid "Old password:"
msgstr "Gammalt lösenord:"
-#: contrib/admin/templates/registration/password_change_form.html:18
+#: contrib/admin/templates/registration/password_change_form.html:19
msgid "New password:"
msgstr "Nytt lösenord:"
-#: contrib/admin/templates/registration/password_change_form.html:20
+#: contrib/admin/templates/registration/password_change_form.html:21
msgid "Confirm password:"
msgstr "Bekräfta lösenord:"
-#: contrib/admin/templates/registration/password_change_form.html:22
+#: contrib/admin/templates/registration/password_change_form.html:23
msgid "Change my password"
msgstr "Ändra mitt lösenord"
@@ -760,325 +922,210 @@ msgstr "E-postadress:"
msgid "Reset my password"
msgstr "Nollställ mitt lösenord"
-#: contrib/admin/templates/widget/date_time.html:3
-msgid "Date:"
-msgstr "Datum:"
-
-#: contrib/admin/templates/widget/date_time.html:4
-msgid "Time:"
-msgstr "Tid:"
-
-#: contrib/admin/templates/widget/file.html:2
-msgid "Currently:"
-msgstr "Aktuell:"
-
-#: contrib/admin/templates/widget/file.html:3
-msgid "Change:"
-msgstr "Ändra:"
-
#: contrib/admin/templatetags/admin_list.py:257
msgid "All dates"
msgstr "Alla datum"
-#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "%(name)s \"%(obj)s\" lades till."
-
-#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
-#: contrib/admin/views/main.py:356
-msgid "You may edit it again below."
-msgstr "Du kan ändra det igen nedanför."
-
-#: contrib/admin/views/auth.py:31
-msgid "Add user"
-msgstr "Lägg till användare"
-
-#: contrib/admin/views/auth.py:58
-msgid "Password changed successfully."
-msgstr "Lösenordet ändrades."
-
-#: contrib/admin/views/auth.py:65
-#, python-format
-msgid "Change password: %s"
-msgstr "Ändra lösenord: %s"
-
-#: contrib/admin/views/decorators.py:17 contrib/auth/forms.py:60
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"Var god ange ett korrekt användarnamn och lösenord. Tänk på att skilja "
-"mellan gemener och versaler."
-
-#: contrib/admin/views/decorators.py:69
-msgid ""
-"Please log in again, because your session has expired. Don't worry: Your "
-"submission has been saved."
-msgstr ""
-"Du måste logga in igen eftersom din session har förfallit. Oroa dig inte: "
-"Din data har sparats."
-
-#: contrib/admin/views/decorators.py:76
-msgid ""
-"Looks like your browser isn't configured to accept cookies. Please enable "
-"cookies, reload this page, and try again."
-msgstr ""
-"Det verkar som att din webläsare inte är konfigurerad att acceptera cookies. "
-"Aktivera cookies, ladda om denna sida och försök igen."
+msgid "Select %s"
+msgstr "Välj %s"
-#: contrib/admin/views/decorators.py:89
+#: contrib/admin/views/main.py:65
#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Din e-postadress är inte ditt användarnamn. Försök med '%s' istället."
-
-#: contrib/admin/views/decorators.py:93
-msgid "Usernames cannot contain the '@' character."
-msgstr "Användarnamn får inte innehålla '@'-tecknet."
+msgid "Select %s to change"
+msgstr "Välj %s att ändra"
-#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
-#: contrib/admin/views/doc.py:52
+#: contrib/admindocs/views.py:53 contrib/admindocs/views.py:55
+#: contrib/admindocs/views.py:57
msgid "tag:"
msgstr "tagg:"
-#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
-#: contrib/admin/views/doc.py:83
+#: contrib/admindocs/views.py:87 contrib/admindocs/views.py:89
+#: contrib/admindocs/views.py:91
msgid "filter:"
msgstr "filter:"
-#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
-#: contrib/admin/views/doc.py:141
+#: contrib/admindocs/views.py:153 contrib/admindocs/views.py:155
+#: contrib/admindocs/views.py:157
msgid "view:"
msgstr "vy:"
-#: contrib/admin/views/doc.py:166
+#: contrib/admindocs/views.py:187
#, python-format
msgid "App %r not found"
msgstr "Applikation %r hittades inte"
-#: contrib/admin/views/doc.py:173
+#: contrib/admindocs/views.py:194
#, python-format
-msgid "Model %(name)r not found in app %(label)r"
-msgstr "Modell %(name)r hittades inte i applikation %(label)r"
+msgid "Model %(model_name)r not found in app %(app_label)r"
+msgstr "Modell %(model_name)r hittades inte i applikation %(app_label)r"
-#: contrib/admin/views/doc.py:185
+#: contrib/admindocs/views.py:206
#, python-format
-msgid "the related `%(label)s.%(type)s` object"
-msgstr "det relaterade `%(label)s.%(type)s`-objektet"
+msgid "the related `%(app_label)s.%(data_type)s` object"
+msgstr "det relaterade `%(app_label)s.%(data_type)s`-objektet"
-#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
-#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:206 contrib/admindocs/views.py:228
+#: contrib/admindocs/views.py:242 contrib/admindocs/views.py:247
msgid "model:"
msgstr "modell:"
-#: contrib/admin/views/doc.py:216
+#: contrib/admindocs/views.py:237
#, python-format
-msgid "related `%(label)s.%(name)s` objects"
-msgstr "relaterade `%(label)s.%(name)s`-objekt"
+msgid "related `%(app_label)s.%(object_name)s` objects"
+msgstr "relaterade `%(app_label)s.%(object_name)s`-objekt"
-#: contrib/admin/views/doc.py:221
+#: contrib/admindocs/views.py:242
#, python-format
msgid "all %s"
msgstr "alla %s"
-#: contrib/admin/views/doc.py:226
+#: contrib/admindocs/views.py:247
#, python-format
msgid "number of %s"
msgstr "antal %s"
-#: contrib/admin/views/doc.py:231
+#: contrib/admindocs/views.py:253
#, python-format
msgid "Fields on %s objects"
msgstr "Fält på %s objekt"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
-#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
-#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
+#: contrib/admindocs/views.py:317 contrib/admindocs/views.py:328
+#: contrib/admindocs/views.py:330 contrib/admindocs/views.py:336
+#: contrib/admindocs/views.py:337 contrib/admindocs/views.py:339
msgid "Integer"
msgstr "Heltal"
-#: contrib/admin/views/doc.py:294
+#: contrib/admindocs/views.py:318
msgid "Boolean (Either True or False)"
msgstr "Boolesk (antingen True eller False)"
-#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
+#: contrib/admindocs/views.py:319 contrib/admindocs/views.py:338
#, python-format
msgid "String (up to %(max_length)s)"
msgstr "Sträng (upp till %(max_length)s)"
-#: contrib/admin/views/doc.py:296
+#: contrib/admindocs/views.py:320
msgid "Comma-separated integers"
msgstr "Komma-separerade heltal"
-#: contrib/admin/views/doc.py:297
+#: contrib/admindocs/views.py:321
msgid "Date (without time)"
msgstr "Datum (utan tid)"
-#: contrib/admin/views/doc.py:298
+#: contrib/admindocs/views.py:322
msgid "Date (with time)"
msgstr "Datum (med tid)"
-#: contrib/admin/views/doc.py:299
+#: contrib/admindocs/views.py:323
msgid "Decimal number"
msgstr "Decimaltal"
-#: contrib/admin/views/doc.py:300
+#: contrib/admindocs/views.py:324
msgid "E-mail address"
msgstr "E-postadress"
-#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
-#: contrib/admin/views/doc.py:305
+#: contrib/admindocs/views.py:325 contrib/admindocs/views.py:326
+#: contrib/admindocs/views.py:329
msgid "File path"
msgstr "Sökväg till fil"
-#: contrib/admin/views/doc.py:303
+#: contrib/admindocs/views.py:327
msgid "Floating point number"
msgstr "Flyttal"
-#: contrib/admin/views/doc.py:307 contrib/comments/models.py:89
+#: contrib/admindocs/views.py:331 contrib/comments/models.py:89
msgid "IP address"
msgstr "IP-adress"
-#: contrib/admin/views/doc.py:309
+#: contrib/admindocs/views.py:333
msgid "Boolean (Either True, False or None)"
msgstr "Boolesk (antingen True, False eller None)"
-#: contrib/admin/views/doc.py:310
+#: contrib/admindocs/views.py:334
msgid "Relation to parent model"
msgstr "Relation till förälder-modell"
-#: contrib/admin/views/doc.py:311
+#: contrib/admindocs/views.py:335
msgid "Phone number"
msgstr "Telefonnummer"
-#: contrib/admin/views/doc.py:316
+#: contrib/admindocs/views.py:340
msgid "Text"
msgstr "Text"
-#: contrib/admin/views/doc.py:317
+#: contrib/admindocs/views.py:341
msgid "Time"
msgstr "Tid"
-#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:8
+#: contrib/admindocs/views.py:342 contrib/flatpages/models.py:8
msgid "URL"
msgstr "URL"
-#: contrib/admin/views/doc.py:319
+#: contrib/admindocs/views.py:343
msgid "U.S. state (two uppercase letters)"
msgstr "Delstat i USA (två versaler)"
-#: contrib/admin/views/doc.py:320
+#: contrib/admindocs/views.py:344
msgid "XML text"
msgstr "XML-text"
-#: contrib/admin/views/doc.py:346
+#: contrib/admindocs/views.py:370
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s verkar inte vara ett urlpattern-objekt"
-#: contrib/admin/views/main.py:233
-msgid "Site administration"
-msgstr "Webbplatsadministration"
-
-#: contrib/admin/views/main.py:280 contrib/admin/views/main.py:365
-#, python-format
-msgid "You may add another %s below."
-msgstr "Du kan lägga till ytterligare %s nedanför."
-
-#: contrib/admin/views/main.py:298
-#, python-format
-msgid "Add %s"
-msgstr "Lägg till %s"
-
-#: contrib/admin/views/main.py:344
-#, python-format
-msgid "Added %s."
-msgstr "Lade till %s."
-
-#: contrib/admin/views/main.py:344 contrib/admin/views/main.py:346
-#: contrib/admin/views/main.py:348 core/validators.py:283
-#: db/models/manipulators.py:309
-msgid "and"
-msgstr "och"
+#: contrib/auth/admin.py:17
+msgid "Personal info"
+msgstr "Personlig information"
-#: contrib/admin/views/main.py:346
-#, python-format
-msgid "Changed %s."
-msgstr "Ändrade %s."
+#: contrib/auth/admin.py:18
+msgid "Permissions"
+msgstr "Rättigheter"
-#: contrib/admin/views/main.py:348
-#, python-format
-msgid "Deleted %s."
-msgstr "Tog bort %s."
+#: contrib/auth/admin.py:19
+msgid "Important dates"
+msgstr "Viktiga datum"
-#: contrib/admin/views/main.py:351
-msgid "No fields changed."
-msgstr "Inga fält ändrade."
+#: contrib/auth/admin.py:20
+msgid "Groups"
+msgstr "Grupper"
-#: contrib/admin/views/main.py:354
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "%(name)s \"%(obj)s\" ändrades."
+#: contrib/auth/admin.py:47
+msgid "Add user"
+msgstr "Lägg till användare"
-#: contrib/admin/views/main.py:362
-#, python-format
+#: contrib/auth/forms.py:13 contrib/auth/models.py:134
msgid ""
-"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
msgstr ""
-"%(name)s \"%(obj)s\" lades till. Du kan redigera objektet igen nedanför."
-
-#: contrib/admin/views/main.py:400
-#, python-format
-msgid "Change %s"
-msgstr "Ändra %s"
-
-#: contrib/admin/views/main.py:487
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
-msgstr "Ett eller flera %(fieldname)s i %(name)s: %(obj)s"
-
-#: contrib/admin/views/main.py:492
-#, python-format
-msgid "One or more %(fieldname)s in %(name)s:"
-msgstr "Ett eller flera %(fieldname)s i %(name)s:"
-
-#: contrib/admin/views/main.py:524
-#, python-format
-msgid "The %(name)s \"%(obj)s\" was deleted successfully."
-msgstr "%(name)s \"%(obj)s\" togs bort."
-
-#: contrib/admin/views/main.py:527
-msgid "Are you sure?"
-msgstr "Är du säker?"
-
-#: contrib/admin/views/main.py:549
-#, python-format
-msgid "Change history: %s"
-msgstr "Ändringshistorik: %s"
+"Obligatorisk. 30 tecken eller färre. Endast bokstäver, siffror eller "
+"understreck."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s"
-msgstr "Välj %s"
+#: contrib/auth/forms.py:14 core/validators.py:72
+msgid "This value must contain only letters, numbers and underscores."
+msgstr "Detta värde får endast innehålla bokstäver, siffror och understreck."
-#: contrib/admin/views/main.py:583
-#, python-format
-msgid "Select %s to change"
-msgstr "Välj %s att ändra"
+#: contrib/auth/forms.py:16
+msgid "Password confirmation"
+msgstr "Lösenordsbekräftelse"
-#: contrib/admin/views/main.py:765
-msgid "Database error"
-msgstr "Databasfel"
+#: contrib/auth/forms.py:28
+msgid "A user with that username already exists."
+msgstr "En användare med det användarnamnet finns redan."
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+#: contrib/auth/forms.py:34 contrib/auth/forms.py:153
+#: contrib/auth/forms.py:178
msgid "The two password fields didn't match."
msgstr "De två lösenordsfälten stämde inte överens."
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "En användare med det användarnamnet finns redan."
+#: contrib/auth/forms.py:72 contrib/comments/views/comments.py:58
+msgid "This account is inactive."
+msgstr "Detta konto är inaktivt."
-#: contrib/auth/forms.py:53
+#: contrib/auth/forms.py:77 contrib/comments/views/comments.py:49
msgid ""
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
"required for logging in."
@@ -1086,11 +1133,11 @@ msgstr ""
"Din webbläsare verkar inte tillåta cookies. Cookies behövs för att kunna "
"logga in."
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Detta konto är inaktivt."
+#: contrib/auth/forms.py:90
+msgid "E-mail"
+msgstr "E-postadress"
-#: contrib/auth/forms.py:84
+#: contrib/auth/forms.py:99
msgid ""
"That e-mail address doesn't have an associated user account. Are you sure "
"you've registered?"
@@ -1098,16 +1145,24 @@ msgstr ""
"Den e-postadressen är inte associerad med något användarkonto. Är du säker "
"på att du har registrerat dig?"
-#: contrib/auth/forms.py:107
+#: contrib/auth/forms.py:124
#, python-format
msgid "Password reset on %s"
-msgstr "Lösenord nollställt: %s"
+msgstr "Lösenord nollställt för %s"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "De två 'nytt lösenord'-fälten stämde inte överens."
+#: contrib/auth/forms.py:131
+msgid "Old password"
+msgstr "Gammalt lösenord"
-#: contrib/auth/forms.py:124
+#: contrib/auth/forms.py:132
+msgid "New password"
+msgstr "Nytt lösenord"
+
+#: contrib/auth/forms.py:133
+msgid "New password confirmation"
+msgstr "Bekräfta nytt lösenord"
+
+#: contrib/auth/forms.py:145
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "Ditt gamla lösenord var felaktigt ifyllt. Var vänlig fyll i det igen."
@@ -1131,39 +1186,31 @@ msgstr "rättigheter"
msgid "group"
msgstr "grupp"
-#: contrib/auth/models.py:98 contrib/auth/models.py:141
+#: contrib/auth/models.py:98 contrib/auth/models.py:144
msgid "groups"
msgstr "grupper"
-#: contrib/auth/models.py:131
+#: contrib/auth/models.py:134
msgid "username"
msgstr "användarnamn"
-#: contrib/auth/models.py:131
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr ""
-"Obligatorisk. 30 tecken eller färre. Endast bokstäver, siffror eller "
-"understreck."
-
-#: contrib/auth/models.py:132
+#: contrib/auth/models.py:135
msgid "first name"
msgstr "förnamn"
-#: contrib/auth/models.py:133
+#: contrib/auth/models.py:136
msgid "last name"
msgstr "efternamn"
-#: contrib/auth/models.py:134
+#: contrib/auth/models.py:137
msgid "e-mail address"
msgstr "e-postadress"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:138
msgid "password"
msgstr "lösenord"
-#: contrib/auth/models.py:135
+#: contrib/auth/models.py:138
msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
@@ -1171,31 +1218,31 @@ msgstr ""
"Använd '[algo]$[salt]$[hexdigest]' eller använd <a href=\"password/\">Ändra "
"lösenord-formuläret</a>."
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "staff status"
msgstr "personalstatus"
-#: contrib/auth/models.py:136
+#: contrib/auth/models.py:139
msgid "Designates whether the user can log into this admin site."
msgstr "Avgör om användaren kan logga in på denna adminsida."
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:140
msgid "active"
msgstr "aktiv"
-#: contrib/auth/models.py:137
+#: contrib/auth/models.py:140
msgid ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
-"Anger om användaren skall betraktas som aktiv. Avmarkera detta istället "
-"för att ta bort konton."
+"Anger om användaren skall betraktas som aktiv. Avmarkera detta istället för "
+"att ta bort konton."
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:141
msgid "superuser status"
msgstr "superanvändare"
-#: contrib/auth/models.py:138
+#: contrib/auth/models.py:141
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
@@ -1203,15 +1250,15 @@ msgstr ""
"Anger att denna användare har alla rättigheter utan att uttryckligen "
"tilldela dem."
-#: contrib/auth/models.py:139
+#: contrib/auth/models.py:142
msgid "last login"
msgstr "senaste inloggning"
-#: contrib/auth/models.py:140
+#: contrib/auth/models.py:143
msgid "date joined"
msgstr "registreringsdatum"
-#: contrib/auth/models.py:142
+#: contrib/auth/models.py:145
msgid ""
"In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in."
@@ -1219,43 +1266,36 @@ msgstr ""
"Förutom de rättigheterna som utdelas manuellt så kommer användaren dessutom "
"få samma rättigheter som de grupper där han/hon är medlem."
-#: contrib/auth/models.py:143
+#: contrib/auth/models.py:146
msgid "user permissions"
msgstr "användarättigheter"
-#: contrib/auth/models.py:147
+#: contrib/auth/models.py:150
msgid "user"
msgstr "användare"
-#: contrib/auth/models.py:148
+#: contrib/auth/models.py:151
msgid "users"
msgstr "användare"
-#: contrib/auth/models.py:154
-msgid "Personal info"
-msgstr "Personlig information"
-
-#: contrib/auth/models.py:155
-msgid "Permissions"
-msgstr "Rättigheter"
-
-#: contrib/auth/models.py:156
-msgid "Important dates"
-msgstr "Viktiga datum"
-
-#: contrib/auth/models.py:157
-msgid "Groups"
-msgstr "Grupper"
-
-#: contrib/auth/models.py:316
+#: contrib/auth/models.py:306
msgid "message"
msgstr "meddelande"
-#: contrib/auth/views.py:47
+#: contrib/auth/views.py:49
msgid "Logged out"
msgstr "Utloggad"
-#: contrib/comments/models.py:71 contrib/comments/models.py:176
+#: contrib/auth/views.py:116
+msgid "Password changed successfully."
+msgstr "Lösenordet ändrades."
+
+#: contrib/auth/views.py:122
+#, python-format
+msgid "Change password: %s"
+msgstr "Ändra lösenord: %s"
+
+#: contrib/comments/models.py:71 contrib/comments/models.py:164
msgid "object ID"
msgstr "objektets ID"
@@ -1264,7 +1304,7 @@ msgid "headline"
msgstr "rubrik"
#: contrib/comments/models.py:73 contrib/comments/models.py:95
-#: contrib/comments/models.py:177
+#: contrib/comments/models.py:165
msgid "comment"
msgstr "kommentar"
@@ -1304,11 +1344,11 @@ msgstr "betyg #8"
msgid "is valid rating"
msgstr "är ett giltigt betyg"
-#: contrib/comments/models.py:87 contrib/comments/models.py:179
+#: contrib/comments/models.py:87 contrib/comments/models.py:167
msgid "date/time submitted"
msgstr "skickat datum/tid"
-#: contrib/comments/models.py:88 contrib/comments/models.py:180
+#: contrib/comments/models.py:88 contrib/comments/models.py:168
msgid "is public"
msgstr "är offentlig"
@@ -1328,11 +1368,11 @@ msgstr ""
msgid "comments"
msgstr "kommentarer"
-#: contrib/comments/models.py:140 contrib/comments/models.py:222
+#: contrib/comments/models.py:128 contrib/comments/models.py:199
msgid "Content object"
msgstr "Innehållsobjekt"
-#: contrib/comments/models.py:168
+#: contrib/comments/models.py:156
#, python-format
msgid ""
"Posted by %(user)s at %(date)s\n"
@@ -1347,48 +1387,48 @@ msgstr ""
"\n"
"http://%(domain)s%(url)s"
-#: contrib/comments/models.py:178
+#: contrib/comments/models.py:166
msgid "person's name"
msgstr "personens namn"
-#: contrib/comments/models.py:181
+#: contrib/comments/models.py:169
msgid "ip address"
msgstr "IP-adress"
-#: contrib/comments/models.py:183
+#: contrib/comments/models.py:171
msgid "approved by staff"
msgstr "godkänd av personal"
-#: contrib/comments/models.py:187
+#: contrib/comments/models.py:175
msgid "free comment"
msgstr "fri kommentar"
-#: contrib/comments/models.py:188
+#: contrib/comments/models.py:176
msgid "free comments"
msgstr "fria kommentarer"
-#: contrib/comments/models.py:250
+#: contrib/comments/models.py:227
msgid "score"
msgstr "poäng"
-#: contrib/comments/models.py:251
+#: contrib/comments/models.py:228
msgid "score date"
msgstr "poäng tilldelad"
-#: contrib/comments/models.py:255
+#: contrib/comments/models.py:232
msgid "karma score"
msgstr "karmapoäng"
-#: contrib/comments/models.py:256
+#: contrib/comments/models.py:233
msgid "karma scores"
msgstr "karmapoäng"
-#: contrib/comments/models.py:260
+#: contrib/comments/models.py:237
#, python-format
msgid "%(score)d rating by %(user)s"
msgstr "Betyg %(score)d av %(user)s"
-#: contrib/comments/models.py:277
+#: contrib/comments/models.py:254
#, python-format
msgid ""
"This comment was flagged by %(user)s:\n"
@@ -1399,36 +1439,36 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/models.py:285
+#: contrib/comments/models.py:262
msgid "flag date"
msgstr "flaggdatum"
-#: contrib/comments/models.py:289
+#: contrib/comments/models.py:266
msgid "user flag"
msgstr "användarflagga"
-#: contrib/comments/models.py:290
+#: contrib/comments/models.py:267
msgid "user flags"
msgstr "användarflaggor"
-#: contrib/comments/models.py:294
+#: contrib/comments/models.py:271
#, python-format
msgid "Flag by %r"
msgstr "Flaggad av %r"
-#: contrib/comments/models.py:300
+#: contrib/comments/models.py:277
msgid "deletion date"
msgstr "borttagningsdatum"
-#: contrib/comments/models.py:303
+#: contrib/comments/models.py:280
msgid "moderator deletion"
msgstr "borttaget av moderator"
-#: contrib/comments/models.py:304
+#: contrib/comments/models.py:281
msgid "moderator deletions"
msgstr "borttagna av moderator"
-#: contrib/comments/models.py:308
+#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
msgstr "Borttaget av moderator %r"
@@ -1469,12 +1509,12 @@ msgstr "Förhandsgranska kommentar"
msgid "Your name:"
msgstr "Ditt namn:"
-#: contrib/comments/views/comments.py:28
+#: contrib/comments/views/comments.py:76
msgid ""
"This rating is required because you've entered at least one other rating."
msgstr "Detta betyg krävs eftersom du har fyllt i minst ett annat betyg."
-#: contrib/comments/views/comments.py:112
+#: contrib/comments/views/comments.py:160
#, python-format
msgid ""
"This comment was posted by a user who has posted fewer than %(count)s "
@@ -1497,7 +1537,7 @@ msgstr[1] ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:117
+#: contrib/comments/views/comments.py:165
#, python-format
msgid ""
"This comment was posted by a sketchy user:\n"
@@ -1508,23 +1548,23 @@ msgstr ""
"\n"
"%(text)s"
-#: contrib/comments/views/comments.py:190
-#: contrib/comments/views/comments.py:283
+#: contrib/comments/views/comments.py:238
+#: contrib/comments/views/comments.py:331
msgid "Only POSTs are allowed"
msgstr "Endast POST är tillåtet"
-#: contrib/comments/views/comments.py:194
-#: contrib/comments/views/comments.py:287
+#: contrib/comments/views/comments.py:242
+#: contrib/comments/views/comments.py:335
msgid "One or more of the required fields wasn't submitted"
msgstr "Ett eller flera av de obligatoriska fälten skickades inte"
-#: contrib/comments/views/comments.py:198
-#: contrib/comments/views/comments.py:289
+#: contrib/comments/views/comments.py:246
+#: contrib/comments/views/comments.py:337
msgid "Somebody tampered with the comment form (security violation)"
msgstr "Någon har manipulerat kommentarformuläret (säkerhetsintrång)"
-#: contrib/comments/views/comments.py:208
-#: contrib/comments/views/comments.py:295
+#: contrib/comments/views/comments.py:256
+#: contrib/comments/views/comments.py:343
msgid ""
"The comment form had an invalid 'target' parameter -- the object ID was "
"invalid"
@@ -1532,8 +1572,8 @@ msgstr ""
"Kommentarformuläret hade en ogiltig 'target'-parameter -- objektets ID var "
"ogiltigt"
-#: contrib/comments/views/comments.py:259
-#: contrib/comments/views/comments.py:324
+#: contrib/comments/views/comments.py:307
+#: contrib/comments/views/comments.py:372
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr ""
"Kommentarformuläret tillhandahöll varken 'förhandsgranska' eller 'post'"
@@ -1562,6 +1602,10 @@ msgstr "innehålls typ"
msgid "content types"
msgstr "innehålls typer"
+#: contrib/flatpages/admin.py:9
+msgid "Advanced options"
+msgstr "Avancerade inställningar"
+
#: contrib/flatpages/models.py:9
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
@@ -1608,32 +1652,27 @@ msgstr "statisk sida"
msgid "flat pages"
msgstr "statiska sidor"
-#: contrib/flatpages/models.py:27
-msgid "Advanced options"
-msgstr "Avancerade inställningar"
-
# Setting these as fuzzy because they might not make sense in Swedish. Consider
# the code's usage of them. They turn numbers such as 1 in to 1st, which isn't
# how we do it in Swedish, we do it by textualizing the number: first, första.
# For the time being, we'll leave these as fuzzy, IMO. // toxik
-
#: contrib/humanize/templatetags/humanize.py:19
-#,fuzzy
+#, fuzzy
msgid "th"
msgstr ":a"
#: contrib/humanize/templatetags/humanize.py:19
-#,fuzzy
+#, fuzzy
msgid "st"
msgstr ":a"
#: contrib/humanize/templatetags/humanize.py:19
-#,fuzzy
+#, fuzzy
msgid "nd"
msgstr ":e"
#: contrib/humanize/templatetags/humanize.py:19
-#,fuzzy
+#, fuzzy
msgid "rd"
msgstr ":e"
@@ -1728,6 +1767,58 @@ msgstr "Fyll i ett giltigt CUIT med formatet XX-XXXXXXXX-X eller XXXXXXXXXXXX."
msgid "Invalid CUIT."
msgstr "Felaktigt CUIT."
+#: contrib/localflavor/at/at_states.py:5
+#, fuzzy
+msgid "Burgenland"
+msgstr "Friesland"
+
+#: contrib/localflavor/at/at_states.py:6
+#, fuzzy
+msgid "Carinthia"
+msgstr "Kantabrien"
+
+#: contrib/localflavor/at/at_states.py:7
+#, fuzzy
+msgid "Lower Austria"
+msgstr "Lower Silesia"
+
+#: contrib/localflavor/at/at_states.py:8
+msgid "Upper Austria"
+msgstr ""
+
+#: contrib/localflavor/at/at_states.py:9
+#, fuzzy
+msgid "Salzburg"
+msgstr "Hamburg"
+
+#: contrib/localflavor/at/at_states.py:10
+#, fuzzy
+msgid "Styria"
+msgstr "Soria"
+
+#: contrib/localflavor/at/at_states.py:11
+#, fuzzy
+msgid "Tyrol"
+msgstr "Tokyo"
+
+#: contrib/localflavor/at/at_states.py:12
+msgid "Vorarlberg"
+msgstr ""
+
+#: contrib/localflavor/at/at_states.py:13
+msgid "Vienna"
+msgstr ""
+
+#: contrib/localflavor/at/forms.py:20 contrib/localflavor/ch/forms.py:16
+#: contrib/localflavor/no/forms.py:12
+msgid "Enter a zip code in the format XXXX."
+msgstr "Fyll i postnummer med formatet XXXX."
+
+#: contrib/localflavor/at/forms.py:48
+#, fuzzy
+msgid "Enter a valid Austrian Social Security Number in XXXX XXXXXX format."
+msgstr "Fyll i ett giltigt amerikanskt personnummer i formatet XXX-XX-XXXX."
+
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
msgstr "Fyll i ett fyrsiffrigt postnummer."
@@ -1878,10 +1969,6 @@ msgstr "Zug"
msgid "Zurich"
msgstr "Zürich"
-#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
-msgid "Enter a zip code in the format XXXX."
-msgstr "Fyll i postnummer med formatet XXXX."
-
#: contrib/localflavor/ch/forms.py:64
msgid ""
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
@@ -2804,6 +2891,31 @@ msgstr ""
msgid "West Pomerania"
msgstr ""
+#: contrib/localflavor/ro/forms.py:19
+#, fuzzy
+msgid "Enter a valid CIF."
+msgstr "Fyll i en giltig URL."
+
+#: contrib/localflavor/ro/forms.py:56
+#, fuzzy
+msgid "Enter a valid CNP."
+msgstr "Fyll i en giltig URL."
+
+#: contrib/localflavor/ro/forms.py:141
+#, fuzzy
+msgid "Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format"
+msgstr "Fyll i ett giltigt CUIT med formatet XX-XXXXXXXX-X eller XXXXXXXXXXXX."
+
+#: contrib/localflavor/ro/forms.py:171
+#, fuzzy
+msgid "Phone numbers must be in XXXX-XXXXXX format."
+msgstr "Telefonnummer måste vara i formatet XX-XXXX-XXXX."
+
+#: contrib/localflavor/ro/forms.py:194
+#, fuzzy
+msgid "Enter a valid postal code in the format XXXXXX"
+msgstr "Fyll i ett postnummer med formatet XXX XXX."
+
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
msgstr "Fyll i ett postnummer med formatet XXXXX eller XXX XX."
@@ -3524,23 +3636,23 @@ msgstr "omdirigera"
msgid "redirects"
msgstr "omdirigeringar"
-#: contrib/sessions/models.py:41
+#: contrib/sessions/models.py:45
msgid "session key"
msgstr "sessionsnyckel"
-#: contrib/sessions/models.py:42
+#: contrib/sessions/models.py:47
msgid "session data"
msgstr "sessionsdata"
-#: contrib/sessions/models.py:43
+#: contrib/sessions/models.py:48
msgid "expire date"
msgstr "utgångsdatum"
-#: contrib/sessions/models.py:48
+#: contrib/sessions/models.py:53
msgid "session"
msgstr "session"
-#: contrib/sessions/models.py:49
+#: contrib/sessions/models.py:54
msgid "sessions"
msgstr "sessioner"
@@ -3552,18 +3664,14 @@ msgstr "domännamn"
msgid "display name"
msgstr "visningsnamn"
-#: contrib/sites/models.py:37
+#: contrib/sites/models.py:38
msgid "site"
msgstr "webbplats"
-#: contrib/sites/models.py:38
+#: contrib/sites/models.py:39
msgid "sites"
msgstr "webbplatser"
-#: core/validators.py:72
-msgid "This value must contain only letters, numbers and underscores."
-msgstr "Detta värde får endast innehålla bokstäver, siffror och understreck."
-
#: core/validators.py:76
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
@@ -3610,7 +3718,7 @@ msgstr "Icke-numeriska tecken är inte tillåtna här."
msgid "This value can't be comprised solely of digits."
msgstr "Detta värde kan inte enbart bestå av siffror."
-#: core/validators.py:128 newforms/fields.py:152
+#: core/validators.py:128 forms/fields.py:158
msgid "Enter a whole number."
msgstr "Fyll i ett heltal."
@@ -3619,36 +3727,31 @@ msgid "Only alphabetical characters are allowed here."
msgstr "Endast bokstäver är tillåtna här."
#: core/validators.py:147
-msgid "Year must be 1900 or later."
-msgstr "Årtal måste vara 1900 eller senare."
-
-#: core/validators.py:151
#, python-format
msgid "Invalid date: %s"
msgstr "Ogiltigt datum: %s"
-#: core/validators.py:156 db/models/fields/__init__.py:548
+#: core/validators.py:152 db/models/fields/__init__.py:559
msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Fyll i ett giltigt datum med formatet Ã…Ã…Ã…Ã…-MM-DD."
-#: core/validators.py:161
+#: core/validators.py:157
msgid "Enter a valid time in HH:MM format."
msgstr "Fyll i ett giltigt klockslag med formatet TT:MM."
-#: core/validators.py:165 db/models/fields/__init__.py:625
+#: core/validators.py:161 db/models/fields/__init__.py:640
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Fyll i en giltig tidpunkt med formatet Ã…Ã…Ã…Ã…-MM-DD TT:MM."
-#: core/validators.py:170 newforms/fields.py:403
+#: core/validators.py:166 forms/fields.py:409
msgid "Enter a valid e-mail address."
msgstr "Fyll i en giltig e-postadress."
-#: core/validators.py:182 core/validators.py:474 newforms/fields.py:433
-#: oldforms/__init__.py:687
+#: core/validators.py:178 core/validators.py:470 forms/fields.py:427
msgid "No file was submitted. Check the encoding type on the form."
msgstr "Ingen fil skickades. Kontrollera kodningnstypen i formuläret."
-#: core/validators.py:193 newforms/fields.py:459
+#: core/validators.py:189 forms/fields.py:467
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
@@ -3656,28 +3759,28 @@ msgstr ""
"Ladda upp en giltig bild. Filen du laddade upp var antingen ingen bild eller "
"en korrupt bild."
-#: core/validators.py:200
+#: core/validators.py:196
#, python-format
msgid "The URL %s does not point to a valid image."
msgstr "URL:en %s pekar inte på en giltig bild."
-#: core/validators.py:204
+#: core/validators.py:200
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
"Telefonnummer måste vara angivna med formatet XXX-XXX-XXXX. \"%s\" är "
"ogiltigt."
-#: core/validators.py:212
+#: core/validators.py:208
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "URL:en %s pekar inte på en giltig QuickTime-video."
-#: core/validators.py:216
+#: core/validators.py:212
msgid "A valid URL is required."
msgstr "En giltig URL krävs."
-#: core/validators.py:230
+#: core/validators.py:226
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -3686,84 +3789,84 @@ msgstr ""
"Giltig HTML krävs. Specifika fel är:\n"
"%s"
-#: core/validators.py:237
+#: core/validators.py:233
#, python-format
msgid "Badly formed XML: %s"
msgstr "Felaktigt formaterad XML: %s"
-#: core/validators.py:254
+#: core/validators.py:250
#, python-format
msgid "Invalid URL: %s"
msgstr "Felaktig URL: %s"
-#: core/validators.py:259 core/validators.py:261
+#: core/validators.py:255 core/validators.py:257
#, python-format
msgid "The URL %s is a broken link."
msgstr "URL:en %s är en trasig länk."
-#: core/validators.py:267
+#: core/validators.py:263
msgid "Enter a valid U.S. state abbreviation."
msgstr "Fyll i en giltig förkortning för en amerikansk delstat."
-#: core/validators.py:281
+#: core/validators.py:277
#, 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] "Akta din tunga! Ordet %s är inte tillåtet här."
msgstr[1] "Akta din tunga! Orden %s är inte tillåtna här."
-#: core/validators.py:288
+#: core/validators.py:284
#, python-format
msgid "This field must match the '%s' field."
msgstr "Detta fält måste matcha fältet '%s'."
-#: core/validators.py:307
+#: core/validators.py:303
msgid "Please enter something for at least one field."
msgstr "Var god fyll i minst ett fält."
-#: core/validators.py:316 core/validators.py:327
+#: core/validators.py:312 core/validators.py:323
msgid "Please enter both fields or leave them both empty."
msgstr "Fyll antingen i båda fälten eller lämna båda tomma."
-#: core/validators.py:335
+#: core/validators.py:331
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "Detta fält måste anges om %(field)s är %(value)s"
-#: core/validators.py:348
+#: core/validators.py:344
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr "Detta fält måste anges om %(field)s inte är %(value)s"
-#: core/validators.py:367
+#: core/validators.py:363
msgid "Duplicate values are not allowed."
msgstr "Dubbletter är inte tillåtna."
-#: core/validators.py:382
+#: core/validators.py:378
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
msgstr "Detta värde måste vara mellan %(lower)s och %(upper)s."
-#: core/validators.py:384
+#: core/validators.py:380
#, python-format
msgid "This value must be at least %s."
msgstr "Detta värde måste vara minst %s."
-#: core/validators.py:386
+#: core/validators.py:382
#, python-format
msgid "This value must be no more than %s."
msgstr "Detta värde får inte vara mer än %s."
-#: core/validators.py:427
+#: core/validators.py:423
#, python-format
msgid "This value must be a power of %s."
msgstr "Detta värde måste vara en potens av %s."
-#: core/validators.py:437
+#: core/validators.py:433
msgid "Please enter a valid decimal number."
msgstr "Fyll i ett giltigt decimaltal."
-#: core/validators.py:444
+#: core/validators.py:440
#, python-format
msgid "Please enter a valid decimal number with at most %s total digit."
msgid_plural ""
@@ -3771,7 +3874,7 @@ msgid_plural ""
msgstr[0] "Fyll i ett giltigt decimaltal med som mest %s siffra totalt."
msgstr[1] "Fyll i ett giltigt decimaltal med som mest %s siffror totalt."
-#: core/validators.py:447
+#: core/validators.py:443
#, python-format
msgid ""
"Please enter a valid decimal number with a whole part of at most %s digit."
@@ -3782,7 +3885,7 @@ msgstr[0] ""
msgstr[1] ""
"Fyll i ett giltigt decimaltal med en heltalsdel med som mest %s siffror."
-#: core/validators.py:450
+#: core/validators.py:446
#, python-format
msgid "Please enter a valid decimal number with at most %s decimal place."
msgid_plural ""
@@ -3790,34 +3893,34 @@ msgid_plural ""
msgstr[0] "Fyll i ett giltigt decimaltal med som mest %s decimal."
msgstr[1] "Fyll i ett giltigt decimaltal med som mest %s decimaler."
-#: core/validators.py:458
+#: core/validators.py:454
msgid "Please enter a valid floating point number."
msgstr "Fyll i ett giltigt flyttal."
-#: core/validators.py:467
+#: core/validators.py:463
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "Se till att filen du laddade upp är minst %s byte stor."
-#: core/validators.py:468
+#: core/validators.py:464
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "Se till att filen du laddade upp är som mest %s byte stor."
-#: core/validators.py:485
+#: core/validators.py:481
msgid "The format for this field is wrong."
msgstr "Formatet för detta fält är fel."
-#: core/validators.py:500
+#: core/validators.py:496
msgid "This field is invalid."
msgstr "Detta fält är ogiltigt."
-#: core/validators.py:536
+#: core/validators.py:532
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Kunde inte hämta något från %s."
-#: core/validators.py:539
+#: core/validators.py:535
#, python-format
msgid ""
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
@@ -3825,7 +3928,7 @@ msgstr ""
"URL:en %(url)s returnerade den ogiltiga Content-Type headern '%(contenttype)"
"s'."
-#: core/validators.py:572
+#: core/validators.py:568
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
@@ -3834,7 +3937,7 @@ msgstr ""
"Var god avsluta den oavslutade taggen %(tag)s på rad %(line)s. (Raden börjar "
"med \"%(start)s\".)"
-#: core/validators.py:576
+#: core/validators.py:572
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
@@ -3843,7 +3946,7 @@ msgstr ""
"En del text som börjar på rad %(line)s är inte tillåten i det sammanhanget. "
"(Raden börjar med \"%(start)s\".)"
-#: core/validators.py:581
+#: core/validators.py:577
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
@@ -3852,7 +3955,7 @@ msgstr ""
"\"%(attr)s\" på rad %(line)s är ett ogiltigt attribut. (Raden börjar med \"%"
"(start)s\".)"
-#: core/validators.py:586
+#: core/validators.py:582
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
@@ -3861,7 +3964,7 @@ msgstr ""
"\"<%(tag)s>\" på rad %(line)s är en ogiltig tagg. (Raden börjar med \"%"
"(start)s\".)"
-#: core/validators.py:590
+#: core/validators.py:586
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
@@ -3870,7 +3973,7 @@ msgstr ""
"En tagg på rad %(line)s saknar en eller flera obligatoriska attribut. (Raden "
"börjar med \"%(start)s\".)"
-#: core/validators.py:595
+#: core/validators.py:591
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
@@ -3879,62 +3982,58 @@ msgstr ""
"Attributet \"%(attr)s\" på rad %(line)s har ett ogiltigt värde. (Raden "
"börjar med \"%(start)s\".)"
-#: db/models/manipulators.py:308
+#: db/models/manipulators.py:304
#, python-format
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "%(object)s med typen %(type)s finns redan för %(field)s."
-#: db/models/fields/__init__.py:54
+#: db/models/fields/__init__.py:47
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "%(optname)s med detta %(fieldname)s finns redan."
-#: db/models/fields/__init__.py:179 db/models/fields/__init__.py:348
-#: db/models/fields/__init__.py:780 db/models/fields/__init__.py:791
-#: newforms/fields.py:46 oldforms/__init__.py:374
+#: db/models/fields/__init__.py:175 db/models/fields/__init__.py:343
+#: db/models/fields/__init__.py:802 db/models/fields/__init__.py:813
+#: forms/fields.py:52 oldforms/__init__.py:374
msgid "This field is required."
msgstr "Detta fält måste fyllas i."
-#: db/models/fields/__init__.py:448
+#: db/models/fields/__init__.py:457
msgid "This value must be an integer."
msgstr "Detta värde måste vara ett heltal."
-#: db/models/fields/__init__.py:487
+#: db/models/fields/__init__.py:498
msgid "This value must be either True or False."
msgstr "Detta värde måste vara antingen True eller False."
-#: db/models/fields/__init__.py:511
+#: db/models/fields/__init__.py:522
msgid "This field cannot be null."
msgstr "Detta fält får inte vara null."
-#: db/models/fields/__init__.py:689
+#: db/models/fields/__init__.py:709
msgid "This value must be a decimal number."
msgstr "Detta värde måste vara ett decimaltal."
-#: db/models/fields/__init__.py:800
+#: db/models/fields/__init__.py:822
msgid "Enter a valid filename."
msgstr "Fyll i ett giltigt filnamn."
-#: db/models/fields/__init__.py:981
+#: db/models/fields/__init__.py:1013
msgid "This value must be either None, True or False."
msgstr "Detta värde måste vara antingen None, True eller False."
-#: db/models/fields/related.py:94
+#: db/models/fields/related.py:93
#, python-format
msgid "Please enter a valid %s."
msgstr "Var god fyll i giltig %s."
-#: db/models/fields/related.py:721
-msgid "Separate multiple IDs with commas."
-msgstr "Separera flera ID-nummer med kommatecken."
-
-#: db/models/fields/related.py:723
+#: db/models/fields/related.py:729
msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr ""
"Håll ner \"Control\" eller \"Command\" på en Mac för att välja fler än en."
-#: db/models/fields/related.py:770
+#: db/models/fields/related.py:773
#, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural ""
@@ -3944,101 +4043,101 @@ msgstr[0] ""
msgstr[1] ""
"Var god och fyll giltiga %(self)s ID-nummer. Värdena %(value)r är ogiltiga."
-#: newforms/fields.py:47
+#: forms/fields.py:53
msgid "Enter a valid value."
msgstr "Fyll i ett giltigt värde."
-#: newforms/fields.py:124
+#: forms/fields.py:130
#, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr ""
"Kontrollera att detta värde har högst %(max)d tecken (det har %(length)d)."
-#: newforms/fields.py:125
+#: forms/fields.py:131
#, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr ""
"Kontrollera att detta värde har minst %(min)d tecken (det har %(length)d)."
-#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211
+#: forms/fields.py:159 forms/fields.py:188 forms/fields.py:217
#, python-format
msgid "Ensure this value is less than or equal to %s."
msgstr "Kontrollera att detta värde är mindre eller lika med %s."
-#: newforms/fields.py:154 newforms/fields.py:183 newforms/fields.py:212
+#: forms/fields.py:160 forms/fields.py:189 forms/fields.py:218
#, python-format
msgid "Ensure this value is greater than or equal to %s."
msgstr "Kontrollera att detta värde är mer eller lika med %s."
-#: newforms/fields.py:181 newforms/fields.py:210
+#: forms/fields.py:187 forms/fields.py:216
msgid "Enter a number."
msgstr "Fyll i ett tal."
-#: newforms/fields.py:213
+#: forms/fields.py:219
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr "Kontrollera att det inte finns mer än totalt %s siffror."
-#: newforms/fields.py:214
+#: forms/fields.py:220
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr "Kontrollera att det inte finns mer än %s decimaler."
-#: newforms/fields.py:215
+#: forms/fields.py:221
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Kontrollera att det inte finns mer än %s siffror före decimaltecknet."
-#: newforms/fields.py:263 newforms/fields.py:751
+#: forms/fields.py:269 forms/fields.py:799
msgid "Enter a valid date."
msgstr "Fyll i ett giltigt datum."
-#: newforms/fields.py:296 newforms/fields.py:752
+#: forms/fields.py:302 forms/fields.py:800
msgid "Enter a valid time."
msgstr "Fyll i en giltig tid."
-#: newforms/fields.py:335
+#: forms/fields.py:341
msgid "Enter a valid date/time."
msgstr "Fyll i ett giltigt datum/tid."
-#: newforms/fields.py:434
+#: forms/fields.py:428
msgid "No file was submitted."
msgstr "Ingen fil skickades."
-#: newforms/fields.py:435 oldforms/__init__.py:689
+#: forms/fields.py:429 oldforms/__init__.py:693
msgid "The submitted file is empty."
msgstr "Den skickade filen är tom."
-#: newforms/fields.py:497
+#: forms/fields.py:528
msgid "Enter a valid URL."
msgstr "Fyll i en giltig URL."
-#: newforms/fields.py:498
+#: forms/fields.py:529
msgid "This URL appears to be a broken link."
msgstr "Denna URL verkar vara en trasig länk."
-#: newforms/fields.py:560 newforms/models.py:299
-msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr ""
-"Välj ett giltigt alternativ. Det valet finns inte bland tillgängliga "
-"alternativ."
-
-#: newforms/fields.py:599
+#: forms/fields.py:597 forms/fields.py:648
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr ""
"Välj ett giltigt alternativ. %(value)s finns inte bland tillgängliga "
"alternativ."
-#: newforms/fields.py:600 newforms/fields.py:662 newforms/models.py:371
+#: forms/fields.py:649 forms/fields.py:710 forms/models.py:581
msgid "Enter a list of values."
msgstr "Fyll i en lista med värden."
-#: newforms/fields.py:780
+#: forms/fields.py:828
msgid "Enter a valid IPv4 address."
msgstr "Fyll i en giltig IPv4 adress."
-#: newforms/models.py:372
+#: forms/models.py:514
+msgid "Select a valid choice. That choice is not one of the available choices."
+msgstr ""
+"Välj ett giltigt alternativ. Det valet finns inte bland tillgängliga "
+"alternativ."
+
+#: forms/models.py:582
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr ""
@@ -4060,15 +4159,15 @@ msgstr "Radbrytningar är inte tillåtna här."
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Välj ett giltigt alternativ; '%(data)s' finns inte bland %(choices)s."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Fyll i ett heltal mellan -32768 och 32767."
-#: oldforms/__init__.py:755
+#: oldforms/__init__.py:764
msgid "Enter a positive number."
msgstr "Fyll i ett positivt tal."
-#: oldforms/__init__.py:765
+#: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767."
msgstr "Fyll i ett heltal mellan 0 och 32767."
@@ -4302,7 +4401,7 @@ msgstr "Nov."
msgid "Dec."
msgstr "Dec."
-#: utils/text.py:127
+#: utils/text.py:128
msgid "or"
msgstr "eller"
@@ -4356,41 +4455,62 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s"
-#: utils/translation/trans_real.py:403
+#: utils/translation/trans_real.py:401
msgid "DATE_FORMAT"
msgstr "Y-m-d"
-#: utils/translation/trans_real.py:404
+#: utils/translation/trans_real.py:402
msgid "DATETIME_FORMAT"
msgstr "Y-m-d H:i"
-#: utils/translation/trans_real.py:405
+#: utils/translation/trans_real.py:403
msgid "TIME_FORMAT"
msgstr "H:i"
-#: utils/translation/trans_real.py:421
+#: utils/translation/trans_real.py:419
msgid "YEAR_MONTH_FORMAT"
msgstr "F Y"
-#: utils/translation/trans_real.py:422
+#: utils/translation/trans_real.py:420
msgid "MONTH_DAY_FORMAT"
msgstr "j F"
-#: views/generic/create_update.py:43
+#: views/generic/create_update.py:129
#, python-format
msgid "The %(verbose_name)s was created successfully."
msgstr "%(verbose_name)s skapades."
-#: views/generic/create_update.py:117
+#: views/generic/create_update.py:172
#, python-format
msgid "The %(verbose_name)s was updated successfully."
msgstr "%(verbose_name)s uppdaterades."
-#: views/generic/create_update.py:184
+#: views/generic/create_update.py:214
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s togs bort."
+#~ msgid "Ordering"
+#~ msgstr "Sortering"
+
+#~ msgid "Order:"
+#~ msgstr "Sortera:"
+
+#~ msgid "Added %s."
+#~ msgstr "Lade till %s."
+
+#~ msgid "Deleted %s."
+#~ msgstr "Tog bort %s."
+
+#~ msgid "The two 'new password' fields didn't match."
+#~ msgstr "De två 'nytt lösenord'-fälten stämde inte överens."
+
+#~ msgid "Year must be 1900 or later."
+#~ msgstr "Årtal måste vara 1900 eller senare."
+
+#~ msgid "Separate multiple IDs with commas."
+#~ msgstr "Separera flera ID-nummer med kommatecken."
+
#~ msgid "Brazilian"
#~ msgstr "Brasilianska"
diff --git a/django/conf/project_template/urls.py b/django/conf/project_template/urls.py
index 98335a151c..7b56d73c9e 100644
--- a/django/conf/project_template/urls.py
+++ b/django/conf/project_template/urls.py
@@ -1,15 +1,16 @@
from django.conf.urls.defaults import *
-# Uncomment this for admin:
-#from django.contrib import admin
+# Uncomment the next two lines to enable the admin:
+# from django.contrib import admin
+# admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
- # Uncomment this for admin docs:
- #(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+ # Uncomment the next line to enable admin documentation:
+ # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
- # Uncomment this for admin:
- #('^admin/(.*)', admin.site.root),
+ # Uncomment the next line for to enable the admin:
+ # (r'^admin/(.*)', admin.site.root),
)
diff --git a/django/contrib/admin/__init__.py b/django/contrib/admin/__init__.py
index 56b64faacb..704dc58ee4 100644
--- a/django/contrib/admin/__init__.py
+++ b/django/contrib/admin/__init__.py
@@ -8,9 +8,12 @@ def autodiscover():
not present. This forces an import on them to register any admin bits they
may want.
"""
+ import imp
from django.conf import settings
for app in settings.INSTALLED_APPS:
try:
- __import__("%s.admin" % app)
+ imp.find_module("admin", __import__(app, {}, {}, [app.split(".")[-1]]).__path__)
except ImportError:
- pass
+ # there is no app admin.py, skip it
+ continue
+ __import__("%s.admin" % app)
diff --git a/django/contrib/admin/media/css/rtl.css b/django/contrib/admin/media/css/rtl.css
index 1974e7c2ec..54175a7f9a 100644
--- a/django/contrib/admin/media/css/rtl.css
+++ b/django/contrib/admin/media/css/rtl.css
@@ -44,3 +44,6 @@ div.breadcrumbs { text-align:right; }
.selector { float: right;}
.selector .selector-filter { text-align: right;}
+
+/* x unsorted */
+.inline-related h2 { text-align:right }
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 501014a0d5..d161c58e64 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -1,5 +1,4 @@
-from django import oldforms, template
-from django import forms
+from django import forms, template
from django.forms.formsets import all_valid
from django.forms.models import modelform_factory, inlineformset_factory
from django.forms.models import BaseInlineFormset
@@ -15,7 +14,10 @@ from django.utils.safestring import mark_safe
from django.utils.text import capfirst, get_text_list
from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode
-import sets
+try:
+ set
+except NameError:
+ from sets import Set as set # Python 2.3 fallback
HORIZONTAL, VERTICAL = 1, 2
# returns the <ul> class for a given radio_admin field
@@ -90,7 +92,7 @@ class Fieldline(object):
yield AdminField(self.form, field, is_first=(i == 0))
def errors(self):
- return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]))
+ return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]).strip('\n'))
class AdminField(object):
def __init__(self, form, field, is_first):
@@ -130,6 +132,23 @@ class BaseModelAdmin(object):
If kwargs are given, they're passed to the form Field's constructor.
"""
+
+ # If the field specifies choices, we don't need to look for special
+ # admin widgets - we just need to use a select widget of some kind.
+ if db_field.choices:
+ if db_field.name in self.radio_fields:
+ # If the field is named as a radio_field, use a RadioSelect
+ kwargs['widget'] = widgets.AdminRadioSelect(
+ choices=db_field.get_choices(include_blank=db_field.blank,
+ blank_choice=[('', _('None'))]),
+ attrs={
+ 'class': get_ul_class(self.radio_fields[db_field.name]),
+ }
+ )
+ else:
+ # Otherwise, use the default select widget.
+ return db_field.formfield(**kwargs)
+
# For DateTimeFields, use a special field and widget.
if isinstance(db_field, models.DateTimeField):
kwargs['form_class'] = forms.SplitDateTimeField
@@ -162,10 +181,13 @@ class BaseModelAdmin(object):
kwargs['empty_label'] = db_field.blank and _('None') or None
else:
if isinstance(db_field, models.ManyToManyField):
- if db_field.name in self.raw_id_fields:
+ # If it uses an intermediary model, don't show field in admin.
+ if db_field.rel.through is not None:
+ return None
+ elif db_field.name in self.raw_id_fields:
kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
kwargs['help_text'] = ''
- elif db_field.name in (self.filter_vertical + self.filter_horizontal):
+ elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
# Wrap the widget's render() method with a method that adds
# extra HTML to the end of the rendered output.
@@ -174,15 +196,6 @@ class BaseModelAdmin(object):
if not db_field.name in self.raw_id_fields:
formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)
return formfield
-
- if db_field.choices and db_field.name in self.radio_fields:
- kwargs['widget'] = widgets.AdminRadioSelect(
- choices=db_field.get_choices(include_blank=db_field.blank,
- blank_choice=[('', _('None'))]),
- attrs={
- 'class': get_ul_class(self.radio_fields[db_field.name]),
- }
- )
# For any other type of field, just call its formfield() method.
return db_field.formfield(**kwargs)
@@ -210,7 +223,7 @@ class ModelAdmin(BaseModelAdmin):
save_on_top = False
ordering = None
inlines = []
-
+
# Custom templates (designed to be over-ridden in subclasses)
change_form_template = None
change_list_template = None
@@ -261,7 +274,7 @@ class ModelAdmin(BaseModelAdmin):
js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
if self.filter_vertical or self.filter_horizontal:
js.extend(['js/SelectBox.js' , 'js/SelectFilter2.js'])
-
+
return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
media = property(_media)
@@ -345,7 +358,7 @@ class ModelAdmin(BaseModelAdmin):
pk_value = new_object._get_pk_val()
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION)
- msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+ msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
# Here, we distinguish between different save types by checking for
# the presence of keys in request.POST.
if request.POST.has_key("_continue"):
@@ -359,7 +372,7 @@ class ModelAdmin(BaseModelAdmin):
# escape() calls force_unicode.
(escape(pk_value), escape(new_object)))
elif request.POST.has_key("_addanother"):
- request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+ request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
return HttpResponseRedirect(request.path)
else:
request.user.message_set.create(message=msg)
@@ -378,7 +391,7 @@ class ModelAdmin(BaseModelAdmin):
Saves the object in the "change" stage and returns an HttpResponseRedirect.
`form` is a bound Form instance that's verified to be valid.
-
+
`formsets` is a sequence of InlineFormSet instances that are verified to be valid.
"""
from django.contrib.admin.models import LogEntry, CHANGE
@@ -394,20 +407,20 @@ class ModelAdmin(BaseModelAdmin):
change_message = []
if form.changed_data:
change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
-
+
if formsets:
for formset in formsets:
for added_object in formset.new_objects:
- change_message.append(_('Added %(name)s "%(object)s".')
+ change_message.append(_('Added %(name)s "%(object)s".')
% {'name': added_object._meta.verbose_name,
'object': added_object})
for changed_object, changed_fields in formset.changed_objects:
- change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
- % {'list': get_text_list(changed_fields, _('and')),
- 'name': changed_object._meta.verbose_name,
+ change_message.append(_('Changed %(list)s for %(name)s "%(object)s".')
+ % {'list': get_text_list(changed_fields, _('and')),
+ 'name': changed_object._meta.verbose_name,
'object': changed_object})
for deleted_object in formset.deleted_objects:
- change_message.append(_('Deleted %(name)s "%(object)s".')
+ change_message.append(_('Deleted %(name)s "%(object)s".')
% {'name': deleted_object._meta.verbose_name,
'object': deleted_object})
change_message = ' '.join(change_message)
@@ -415,7 +428,7 @@ class ModelAdmin(BaseModelAdmin):
change_message = _('No fields changed.')
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
- msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+ msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object}
if request.POST.has_key("_continue"):
request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
if request.REQUEST.has_key('_popup'):
@@ -423,10 +436,10 @@ class ModelAdmin(BaseModelAdmin):
else:
return HttpResponseRedirect(request.path)
elif request.POST.has_key("_saveasnew"):
- request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
+ request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': new_object})
return HttpResponseRedirect("../%s/" % pk_value)
elif request.POST.has_key("_addanother"):
- request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+ request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
return HttpResponseRedirect("../add/")
else:
request.user.message_set.create(message=msg)
@@ -504,7 +517,7 @@ class ModelAdmin(BaseModelAdmin):
inline_admin_formsets.append(inline_admin_formset)
context = {
- 'title': _('Add %s') % opts.verbose_name,
+ 'title': _('Add %s') % force_unicode(opts.verbose_name),
'adminform': adminForm,
'is_popup': request.REQUEST.has_key('_popup'),
'show_delete': False,
@@ -534,7 +547,7 @@ class ModelAdmin(BaseModelAdmin):
raise PermissionDenied
if obj is None:
- raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
+ raise Http404('%s object with primary key %r does not exist.' % (force_unicode(opts.verbose_name), escape(object_id)))
if request.POST and request.POST.has_key("_saveasnew"):
return self.add_view(request, form_url='../../add/')
@@ -557,17 +570,16 @@ class ModelAdmin(BaseModelAdmin):
adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
media = self.media + adminForm.media
- for fs in inline_formsets:
- media = media + fs.media
inline_admin_formsets = []
for inline, formset in zip(self.inline_instances, inline_formsets):
fieldsets = list(inline.get_fieldsets(request, obj))
inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
inline_admin_formsets.append(inline_admin_formset)
+ media = media + inline_admin_formset.media
context = {
- 'title': _('Change %s') % opts.verbose_name,
+ 'title': _('Change %s') % force_unicode(opts.verbose_name),
'adminform': adminForm,
'object_id': object_id,
'original': obj,
@@ -599,7 +611,7 @@ class ModelAdmin(BaseModelAdmin):
if ERROR_FLAG in request.GET.keys():
return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
-
+
context = {
'title': cl.title,
'is_popup': cl.is_popup,
@@ -632,12 +644,12 @@ class ModelAdmin(BaseModelAdmin):
raise PermissionDenied
if obj is None:
- raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
+ raise Http404('%s object with primary key %r does not exist.' % (force_unicode(opts.verbose_name), escape(object_id)))
# Populate deleted_objects, a data structure of all related objects that
# will also be deleted.
deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), quote(object_id), escape(obj))), []]
- perms_needed = sets.Set()
+ perms_needed = set()
get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site)
if request.POST: # The user has already confirmed the deletion.
@@ -650,10 +662,10 @@ class ModelAdmin(BaseModelAdmin):
if not self.has_change_permission(request, None):
return HttpResponseRedirect("../../../../")
return HttpResponseRedirect("../../")
-
+
context = {
"title": _("Are you sure?"),
- "object_name": opts.verbose_name,
+ "object_name": force_unicode(opts.verbose_name),
"object": obj,
"deleted_objects": deleted_objects,
"perms_lacking": perms_needed,
@@ -681,7 +693,7 @@ class ModelAdmin(BaseModelAdmin):
context = {
'title': _('Change history: %s') % force_unicode(obj),
'action_list': action_list,
- 'module_name': capfirst(opts.verbose_name_plural),
+ 'module_name': capfirst(force_unicode(opts.verbose_name_plural)),
'object': obj,
'root_path': self.admin_site.root_path,
}
@@ -761,6 +773,13 @@ class InlineAdminFormSet(object):
for field_name in flatten_fieldsets(self.fieldsets):
yield self.formset.form.base_fields[field_name]
+ def _media(self):
+ media = self.formset.media
+ for fs in self:
+ media = media + fs.media
+ return media
+ media = property(_media)
+
class InlineAdminForm(AdminForm):
"""
A wrapper around an inline form for use in the admin system.
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index bb4dc58ece..26e935e7fb 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -1,3 +1,7 @@
+import base64
+import cPickle as pickle
+import re
+
from django import http, template
from django.contrib.admin import ModelAdmin
from django.contrib.auth import authenticate, login
@@ -8,11 +12,7 @@ from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _
from django.views.decorators.cache import never_cache
from django.conf import settings
-import base64
-import cPickle as pickle
-import datetime
-import md5
-import re
+from django.utils.hashcompat import md5_constructor
ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
LOGIN_FORM_KEY = 'this_is_the_login_form'
@@ -26,16 +26,14 @@ class NotRegistered(Exception):
pass
def _encode_post_data(post_data):
- from django.conf import settings
pickled = pickle.dumps(post_data)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def _decode_post_data(encoded_data):
- from django.conf import settings
encoded_data = base64.decodestring(encoded_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation, "User may have tampered with session cookie."
return pickle.loads(pickled)
@@ -47,10 +45,10 @@ class AdminSite(object):
register() method, and the root() method can then be used as a Django view function
that presents a full admin interface for the collection of registered models.
"""
-
+
index_template = None
login_template = None
-
+
def __init__(self):
self._registry = {} # model_class class -> admin_class instance
@@ -66,19 +64,33 @@ class AdminSite(object):
If a model is already registered, this will raise AlreadyRegistered.
"""
- do_validate = admin_class and settings.DEBUG
- if do_validate:
- # don't import the humongous validation code unless required
+ # Don't import the humongous validation code unless required
+ if admin_class and settings.DEBUG:
from django.contrib.admin.validation import validate
- admin_class = admin_class or ModelAdmin
- # TODO: Handle options
+ else:
+ validate = lambda model, adminclass: None
+
+ if not admin_class:
+ admin_class = ModelAdmin
if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable:
if model in self._registry:
raise AlreadyRegistered('The model %s is already registered' % model.__name__)
- if do_validate:
- validate(admin_class, model)
+
+ # If we got **options then dynamically construct a subclass of
+ # admin_class with those **options.
+ if options:
+ # For reasons I don't quite understand, without a __module__
+ # the created class appears to "live" in the wrong place,
+ # which causes issues later on.
+ options['__module__'] = __name__
+ admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
+
+ # Validate (which might be a no-op)
+ validate(admin_class, model)
+
+ # Instantiate the admin class to save in the registry
self._registry[model] = admin_class(model, self)
def unregister(self, model_or_iterable):
@@ -102,23 +114,23 @@ class AdminSite(object):
return request.user.is_authenticated() and request.user.is_staff
def root(self, request, url):
- """
+ """
Handles main URL routing for the admin app.
`url` is the remainder of the URL -- e.g. 'comments/comment/'.
"""
if request.method == 'GET' and not request.path.endswith('/'):
return http.HttpResponseRedirect(request.path + '/')
-
+
# Figure out the admin base URL path and stash it for later use
self.root_path = re.sub(re.escape(url) + '$', '', request.path)
-
+
url = url.rstrip('/') # Trim trailing slash, if it exists.
# The 'logout' view doesn't require that the person is logged in.
if url == 'logout':
return self.logout(request)
-
+
# Check permission to continue or display login form.
if not self.has_permission(request):
return self.login(request)
@@ -139,7 +151,7 @@ class AdminSite(object):
match = USER_CHANGE_PASSWORD_URL_RE.match(url)
if match:
return self.user_change_password(request, match.group(1))
-
+
if '/' in url:
return self.model_page(request, *url.split('/', 2))
@@ -189,7 +201,6 @@ class AdminSite(object):
This takes into account the USE_I18N setting. If it's set to False, the
generated JavaScript will be leaner and faster.
"""
- from django.conf import settings
if settings.USE_I18N:
from django.views.i18n import javascript_catalog
else:
@@ -249,9 +260,6 @@ class AdminSite(object):
else:
if user.is_active and user.is_staff:
login(request, user)
- # TODO: set last_login with an event.
- user.last_login = datetime.datetime.now()
- user.save()
if request.POST.has_key('post_data'):
post_data = _decode_post_data(request.POST['post_data'])
if post_data and not post_data.has_key(LOGIN_FORM_KEY):
@@ -308,14 +316,14 @@ class AdminSite(object):
# Sort the models alphabetically within each app.
for app in app_list:
app['models'].sort(lambda x, y: cmp(x['name'], y['name']))
-
+
context = {
'title': _('Site administration'),
'app_list': app_list,
'root_path': self.root_path,
}
context.update(extra_context or {})
- return render_to_response(self.index_template or 'admin/index.html', context,
+ return render_to_response(self.index_template or 'admin/index.html', context,
context_instance=template.RequestContext(request)
)
index = never_cache(index)
@@ -330,7 +338,7 @@ class AdminSite(object):
post_data = _encode_post_data(request.POST)
else:
post_data = _encode_post_data({})
-
+
context = {
'title': _('Log in'),
'app_path': request.path,
diff --git a/django/contrib/admin/templates/admin/includes/fieldset.html b/django/contrib/admin/templates/admin/includes/fieldset.html
index a61795cfe4..27e54c75d3 100644
--- a/django/contrib/admin/templates/admin/includes/fieldset.html
+++ b/django/contrib/admin/templates/admin/includes/fieldset.html
@@ -1,6 +1,6 @@
<fieldset class="module aligned {{ fieldset.classes }}">
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
- {% if fieldset.description %}<div class="description">{{ fieldset.description }}</div>{% endif %}
+ {% if fieldset.description %}<div class="description">{{ fieldset.description|safe }}</div>{% endif %}
{% for line in fieldset %}
<div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} ">
{{ line.errors }}
@@ -14,4 +14,4 @@
{% endfor %}
</div>
{% endfor %}
-</fieldset> \ No newline at end of file
+</fieldset>
diff --git a/django/contrib/admin/templates/admin_doc/model_detail.html b/django/contrib/admin/templates/admin_doc/model_detail.html
index 81bf87db15..414397f23a 100644
--- a/django/contrib/admin/templates/admin_doc/model_detail.html
+++ b/django/contrib/admin/templates/admin_doc/model_detail.html
@@ -34,7 +34,7 @@
<tr>
<td>{{ field.name }}</td>
<td>{{ field.data_type }}</td>
- <td>{% if field.verbose %}{{ field.verbose }}{% endif %}{% if field.help_text %} - {{ field.help_text }}{% endif %}</td>
+ <td>{% if field.verbose %}{{ field.verbose }}{% endif %}{% if field.help_text %} - {{ field.help_text|safe }}{% endif %}</td>
</tr>
{% endfor %}
</tbody>
diff --git a/django/contrib/admin/templates/registration/password_reset_complete.html b/django/contrib/admin/templates/registration/password_reset_complete.html
new file mode 100644
index 0000000000..fceb167a88
--- /dev/null
+++ b/django/contrib/admin/templates/registration/password_reset_complete.html
@@ -0,0 +1,16 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password reset complete' %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans 'Password reset complete' %}</h1>
+
+<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
+
+<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
+
+{% endblock %}
diff --git a/django/contrib/admin/templates/registration/password_reset_confirm.html b/django/contrib/admin/templates/registration/password_reset_confirm.html
new file mode 100644
index 0000000000..9ba0e5af27
--- /dev/null
+++ b/django/contrib/admin/templates/registration/password_reset_confirm.html
@@ -0,0 +1,32 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}</div>{% endblock %}
+
+{% block title %}{% trans 'Password reset' %}{% endblock %}
+
+{% block content %}
+
+{% if validlink %}
+
+<h1>{% trans 'Enter new password' %}</h1>
+
+<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">
+{% if form.new_password1.errors %}{{ form.new_password1.errors }}{% endif %}
+<p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
+{% if form.new_password2.errors %}{{ form.new_password2.errors }}{% endif %}
+<p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
+<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
+</form>
+
+{% else %}
+
+<h1>{% trans 'Password reset unsuccessful' %}</h1>
+
+<p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}
+
+{% endif %}
+
+{% endblock %}
diff --git a/django/contrib/admin/templates/registration/password_reset_done.html b/django/contrib/admin/templates/registration/password_reset_done.html
index f97b5688c2..e223bdb9de 100644
--- a/django/contrib/admin/templates/registration/password_reset_done.html
+++ b/django/contrib/admin/templates/registration/password_reset_done.html
@@ -9,6 +9,6 @@
<h1>{% trans 'Password reset successful' %}</h1>
-<p>{% trans "We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
+<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
{% endblock %}
diff --git a/django/contrib/admin/templates/registration/password_reset_email.html b/django/contrib/admin/templates/registration/password_reset_email.html
index f765dd0670..3b2d5b0f34 100644
--- a/django/contrib/admin/templates/registration/password_reset_email.html
+++ b/django/contrib/admin/templates/registration/password_reset_email.html
@@ -1,15 +1,15 @@
-{% load i18n %}
+{% load i18n %}{% autoescape off %}
{% trans "You're receiving this e-mail because you requested a password reset" %}
{% blocktrans %}for your user account at {{ site_name }}{% endblocktrans %}.
-{% blocktrans %}Your new password is: {{ new_password }}{% endblocktrans %}
-
-{% trans "Feel free to change this password by going to this page:" %}
-
-http://{{ domain }}/password_change/
-
+{% trans "Please go to the following page and choose a new password:" %}
+{% block reset_link %}
+{{ protocol }}://{{ domain }}/reset/{{ uid }}-{{ token }}/
+{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
+
+{% endautoescape %}
diff --git a/django/contrib/admin/templates/registration/password_reset_form.html b/django/contrib/admin/templates/registration/password_reset_form.html
index d8c7d03f93..4ecebc77a1 100644
--- a/django/contrib/admin/templates/registration/password_reset_form.html
+++ b/django/contrib/admin/templates/registration/password_reset_form.html
@@ -9,7 +9,7 @@
<h1>{% trans "Password reset" %}</h1>
-<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you." %}</p>
+<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
<form action="" method="post">
{% if form.email.errors %}{{ form.email.errors }}{% endif %}
diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
index 2c9cb8554d..a42f2eb985 100644
--- a/django/contrib/admin/validation.py
+++ b/django/contrib/admin/validation.py
@@ -1,3 +1,7 @@
+try:
+ set
+except NameError:
+ from sets import Set as set # Python 2.3 fallback
from django.core.exceptions import ImproperlyConfigured
from django.db import models
@@ -165,6 +169,8 @@ def _validate_base(cls, model):
_check_form_field_existsw('fields', field)
if cls.fieldsets:
raise ImproperlyConfigured('Both fieldsets and fields are specified in %s.' % cls.__name__)
+ if len(cls.fields) > len(set(cls.fields)):
+ raise ImproperlyConfigured('There are duplicate field(s) in %s.fields' % cls.__name__)
# fieldsets
if cls.fieldsets: # default value is None
@@ -179,7 +185,10 @@ def _validate_base(cls, model):
raise ImproperlyConfigured("`fields` key is required in "
"%s.fieldsets[%d][1] field options dict."
% (cls.__name__, idx))
- for field in flatten_fieldsets(cls.fieldsets):
+ flattened_fieldsets = flatten_fieldsets(cls.fieldsets)
+ if len(flattened_fieldsets) > len(set(flattened_fieldsets)):
+ raise ImproperlyConfigured('There are duplicate field(s) in %s.fieldsets' % cls.__name__)
+ for field in flattened_fieldsets:
_check_form_field_existsw("fieldsets[%d][1]['fields']" % idx, field)
# form
diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py
index 57517cc821..cf0cd704c2 100644
--- a/django/contrib/admin/views/decorators.py
+++ b/django/contrib/admin/views/decorators.py
@@ -1,5 +1,4 @@
import base64
-import md5
import cPickle as pickle
try:
from functools import wraps
@@ -12,6 +11,7 @@ from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from django.shortcuts import render_to_response
from django.utils.translation import ugettext_lazy, ugettext as _
+from django.utils.hashcompat import md5_constructor
ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
LOGIN_FORM_KEY = 'this_is_the_login_form'
@@ -35,13 +35,13 @@ def _display_login_form(request, error_message=''):
def _encode_post_data(post_data):
pickled = pickle.dumps(post_data)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def _decode_post_data(encoded_data):
encoded_data = base64.decodestring(encoded_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation, "User may have tampered with session cookie."
return pickle.loads(pickled)
@@ -87,7 +87,7 @@ def staff_member_required(view_func):
if len(users) == 1:
message = _("Your e-mail address is not your username. Try '%s' instead.") % users[0].username
else:
- # Either we cannot find the user, or if more than 1
+ # Either we cannot find the user, or if more than 1
# we cannot guess which user is the correct one.
message = _("Usernames cannot contain the '@' character.")
return _display_login_form(request, message)
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 926270cc68..116d9d49f1 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -6,7 +6,6 @@ from django.db import models
from django.db.models.query import QuerySet
from django.utils.encoding import force_unicode, smart_str
from django.utils.translation import ugettext
-from django.utils.safestring import mark_safe
from django.utils.http import urlencode
import operator
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index 1139f8af60..1737920312 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -7,8 +7,7 @@ import copy
from django import forms
from django.forms.widgets import RadioFieldRenderer
from django.forms.util import flatatt
-from django.utils.datastructures import MultiValueDict
-from django.utils.text import capfirst, truncate_words
+from django.utils.text import truncate_words
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py
index e81293adcb..d6d263c851 100644
--- a/django/contrib/admindocs/views.py
+++ b/django/contrib/admindocs/views.py
@@ -5,7 +5,7 @@ from django.contrib.admin.views.decorators import staff_member_required
from django.db import models
from django.shortcuts import render_to_response
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
-from django.http import Http404, get_host
+from django.http import Http404
from django.core import urlresolvers
from django.contrib.admindocs import utils
from django.contrib.sites.models import Site
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py
index 998692a6cb..f97935d599 100644
--- a/django/contrib/auth/admin.py
+++ b/django/contrib/auth/admin.py
@@ -1,6 +1,6 @@
from django.contrib.auth.models import User, Group
from django.core.exceptions import PermissionDenied
-from django import oldforms, template
+from django import template
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext, ugettext_lazy as _
diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py
index 25bc20780e..1371c62eea 100644
--- a/django/contrib/auth/decorators.py
+++ b/django/contrib/auth/decorators.py
@@ -1,7 +1,7 @@
try:
- from functools import wraps, update_wrapper
+ from functools import update_wrapper
except ImportError:
- from django.utils.functional import wraps, update_wrapper # Python 2.3, 2.4 fallback.
+ from django.utils.functional import update_wrapper # Python 2.3, 2.4 fallback.
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponseRedirect
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index 13ddcd3841..13647865d4 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -1,10 +1,11 @@
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
+from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.models import Site
from django.template import Context, loader
-from django.core import validators
from django import forms
from django.utils.translation import ugettext_lazy as _
+from django.utils.http import int_to_base36
class UserCreationForm(forms.ModelForm):
"""
@@ -13,13 +14,13 @@ class UserCreationForm(forms.ModelForm):
username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^\w+$',
help_text = _("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."),
error_message = _("This value must contain only letters, numbers and underscores."))
- password1 = forms.CharField(label=_("Password"), max_length=60, widget=forms.PasswordInput)
- password2 = forms.CharField(label=_("Password confirmation"), max_length=60, widget=forms.PasswordInput)
-
+ password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
+ password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput)
+
class Meta:
model = User
fields = ("username",)
-
+
def clean_username(self):
username = self.cleaned_data["username"]
try:
@@ -27,14 +28,14 @@ class UserCreationForm(forms.ModelForm):
except User.DoesNotExist:
return username
raise forms.ValidationError(_("A user with that username already exists."))
-
+
def clean_password2(self):
password1 = self.cleaned_data["password1"]
password2 = self.cleaned_data["password2"]
if password1 != password2:
raise forms.ValidationError(_("The two password fields didn't match."))
return password2
-
+
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
@@ -48,8 +49,8 @@ class AuthenticationForm(forms.Form):
username/password logins.
"""
username = forms.CharField(label=_("Username"), max_length=30)
- password = forms.CharField(label=_("Password"), max_length=30, widget=forms.PasswordInput)
-
+ password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
+
def __init__(self, request=None, *args, **kwargs):
"""
If request is passed in, the form will validate that cookies are
@@ -60,36 +61,36 @@ class AuthenticationForm(forms.Form):
self.request = request
self.user_cache = None
super(AuthenticationForm, self).__init__(*args, **kwargs)
-
+
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
-
+
if username and password:
self.user_cache = authenticate(username=username, password=password)
if self.user_cache is None:
raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive."))
elif not self.user_cache.is_active:
raise forms.ValidationError(_("This account is inactive."))
-
+
# TODO: determine whether this should move to its own method.
if self.request:
if not self.request.session.test_cookie_worked():
raise forms.ValidationError(_("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in."))
-
+
return self.cleaned_data
-
+
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
-
+
def get_user(self):
return self.user_cache
class PasswordResetForm(forms.Form):
- email = forms.EmailField(label=_("E-mail"), max_length=40)
-
+ email = forms.EmailField(label=_("E-mail"), max_length=75)
+
def clean_email(self):
"""
Validates that a user exists with the given e-mail address.
@@ -98,16 +99,14 @@ class PasswordResetForm(forms.Form):
self.users_cache = User.objects.filter(email__iexact=email)
if len(self.users_cache) == 0:
raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?"))
-
- def save(self, domain_override=None, email_template_name='registration/password_reset_email.html'):
+
+ def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
+ use_https=False, token_generator=default_token_generator):
"""
- Calculates a new password randomly and sends it to the user.
+ Generates a one-use only link for resetting password and sends to the user
"""
from django.core.mail import send_mail
for user in self.users_cache:
- new_pass = User.objects.make_random_password()
- user.set_password(new_pass)
- user.save()
if not domain_override:
current_site = Site.objects.get_current()
site_name = current_site.name
@@ -116,36 +115,29 @@ class PasswordResetForm(forms.Form):
site_name = domain = domain_override
t = loader.get_template(email_template_name)
c = {
- 'new_password': new_pass,
'email': user.email,
'domain': domain,
'site_name': site_name,
+ 'uid': int_to_base36(user.id),
'user': user,
+ 'token': token_generator.make_token(user),
+ 'protocol': use_https and 'https' or 'http',
}
send_mail(_("Password reset on %s") % site_name,
t.render(Context(c)), None, [user.email])
-class PasswordChangeForm(forms.Form):
+class SetPasswordForm(forms.Form):
"""
- A form that lets a user change his/her password.
+ A form that lets a user change set his/her password without
+ entering the old password
"""
- old_password = forms.CharField(label=_("Old password"), max_length=30, widget=forms.PasswordInput)
- new_password1 = forms.CharField(label=_("New password"), max_length=30, widget=forms.PasswordInput)
- new_password2 = forms.CharField(label=_("New password confirmation"), max_length=30, widget=forms.PasswordInput)
-
+ new_password1 = forms.CharField(label=_("New password"), widget=forms.PasswordInput)
+ new_password2 = forms.CharField(label=_("New password confirmation"), widget=forms.PasswordInput)
+
def __init__(self, user, *args, **kwargs):
self.user = user
- super(PasswordChangeForm, self).__init__(*args, **kwargs)
-
- def clean_old_password(self):
- """
- Validates that the old_password field is correct.
- """
- old_password = self.cleaned_data["old_password"]
- if not self.user.check_password(old_password):
- raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again."))
- return old_password
-
+ super(SetPasswordForm, self).__init__(*args, **kwargs)
+
def clean_new_password2(self):
password1 = self.cleaned_data.get('new_password1')
password2 = self.cleaned_data.get('new_password2')
@@ -153,24 +145,41 @@ class PasswordChangeForm(forms.Form):
if password1 != password2:
raise forms.ValidationError(_("The two password fields didn't match."))
return password2
-
+
def save(self, commit=True):
self.user.set_password(self.cleaned_data['new_password1'])
if commit:
self.user.save()
return self.user
+class PasswordChangeForm(SetPasswordForm):
+ """
+ A form that lets a user change his/her password by entering
+ their old password.
+ """
+ old_password = forms.CharField(label=_("Old password"), widget=forms.PasswordInput)
+
+ def clean_old_password(self):
+ """
+ Validates that the old_password field is correct.
+ """
+ old_password = self.cleaned_data["old_password"]
+ if not self.user.check_password(old_password):
+ raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again."))
+ return old_password
+PasswordChangeForm.base_fields.keyOrder = ['old_password', 'new_password1', 'new_password2']
+
class AdminPasswordChangeForm(forms.Form):
"""
A form used to change the password of a user in the admin interface.
"""
- password1 = forms.CharField(label=_("Password"), max_length=60, widget=forms.PasswordInput)
- password2 = forms.CharField(label=_("Password (again)"), max_length=60, widget=forms.PasswordInput)
-
+ password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
+ password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput)
+
def __init__(self, user, *args, **kwargs):
self.user = user
super(AdminPasswordChangeForm, self).__init__(*args, **kwargs)
-
+
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
@@ -178,7 +187,7 @@ class AdminPasswordChangeForm(forms.Form):
if password1 != password2:
raise forms.ValidationError(_("The two password fields didn't match."))
return password2
-
+
def save(self, commit=True):
"""
Saves the new password.
diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py
index 4299762c74..91e39f7235 100644
--- a/django/contrib/auth/management/commands/createsuperuser.py
+++ b/django/contrib/auth/management/commands/createsuperuser.py
@@ -7,7 +7,7 @@ import os
import re
import sys
from optparse import make_option
-from django.contrib.auth.models import User, UNUSABLE_PASSWORD
+from django.contrib.auth.models import User
from django.core import validators
from django.core.management.base import BaseCommand, CommandError
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index a0ed4f366f..3ea184a7f8 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -358,6 +358,9 @@ class AnonymousUser(object):
def has_perm(self, perm):
return False
+ def has_perms(self, perm_list):
+ return False
+
def has_module_perms(self, module):
return False
diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py
index 6242303f46..2458800b22 100644
--- a/django/contrib/auth/tests/__init__.py
+++ b/django/contrib/auth/tests/__init__.py
@@ -1,8 +1,11 @@
-from django.contrib.auth.tests.basic import BASIC_TESTS, PasswordResetTest
+from django.contrib.auth.tests.basic import BASIC_TESTS
+from django.contrib.auth.tests.views import PasswordResetTest
from django.contrib.auth.tests.forms import FORM_TESTS
+from django.contrib.auth.tests.tokens import TOKEN_GENERATOR_TESTS
__test__ = {
'BASIC_TESTS': BASIC_TESTS,
'PASSWORDRESET_TESTS': PasswordResetTest,
'FORM_TESTS': FORM_TESTS,
+ 'TOKEN_GENERATOR_TESTS': TOKEN_GENERATOR_TESTS
}
diff --git a/django/contrib/auth/tests/basic.py b/django/contrib/auth/tests/basic.py
index 76dbdc9cb9..2071710279 100644
--- a/django/contrib/auth/tests/basic.py
+++ b/django/contrib/auth/tests/basic.py
@@ -54,24 +54,3 @@ u'joe@somewhere.org'
>>> u.password
u'!'
"""
-
-from django.test import TestCase
-from django.core import mail
-
-class PasswordResetTest(TestCase):
- fixtures = ['authtestdata.json']
- urls = 'django.contrib.auth.urls'
-
- def test_email_not_found(self):
- "Error is raised if the provided email address isn't currently registered"
- response = self.client.get('/password_reset/')
- self.assertEquals(response.status_code, 200)
- response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'})
- self.assertContains(response, "That e-mail address doesn't have an associated user account")
- self.assertEquals(len(mail.outbox), 0)
-
- def test_email_found(self):
- "Email is sent if a valid email address is provided for password reset"
- response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
- self.assertEquals(response.status_code, 302)
- self.assertEquals(len(mail.outbox), 1)
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
index 1e1e0a95d4..01f4995bb7 100644
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -2,7 +2,7 @@
FORM_TESTS = """
>>> from django.contrib.auth.models import User
>>> from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
->>> from django.contrib.auth.forms import PasswordChangeForm
+>>> from django.contrib.auth.forms import PasswordChangeForm, SetPasswordForm
The user already exists.
@@ -95,6 +95,32 @@ True
>>> form.non_field_errors()
[]
+SetPasswordForm:
+
+The two new passwords do not match.
+
+>>> data = {
+... 'new_password1': 'abc123',
+... 'new_password2': 'abc',
+... }
+>>> form = SetPasswordForm(user, data)
+>>> form.is_valid()
+False
+>>> form["new_password2"].errors
+[u"The two password fields didn't match."]
+
+The success case.
+
+>>> data = {
+... 'new_password1': 'abc123',
+... 'new_password2': 'abc123',
+... }
+>>> form = SetPasswordForm(user, data)
+>>> form.is_valid()
+True
+
+PasswordChangeForm:
+
The old password is incorrect.
>>> data = {
@@ -132,4 +158,9 @@ The success case.
>>> form.is_valid()
True
+Regression test - check the order of fields:
+
+>>> PasswordChangeForm(user, {}).fields.keys()
+['old_password', 'new_password1', 'new_password2']
+
"""
diff --git a/django/contrib/auth/tests/tokens.py b/django/contrib/auth/tests/tokens.py
new file mode 100644
index 0000000000..6d3a964fe7
--- /dev/null
+++ b/django/contrib/auth/tests/tokens.py
@@ -0,0 +1,29 @@
+TOKEN_GENERATOR_TESTS = """
+>>> from django.contrib.auth.models import User, AnonymousUser
+>>> from django.contrib.auth.tokens import PasswordResetTokenGenerator
+>>> from django.conf import settings
+>>> u = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
+>>> p0 = PasswordResetTokenGenerator()
+>>> tk1 = p0.make_token(u)
+>>> p0.check_token(u, tk1)
+True
+
+Tests to ensure we can use the token after n days, but no greater.
+Use a mocked version of PasswordResetTokenGenerator so we can change
+the value of 'today'
+
+>>> class Mocked(PasswordResetTokenGenerator):
+... def __init__(self, today):
+... self._today_val = today
+... def _today(self):
+... return self._today_val
+
+>>> from datetime import date, timedelta
+>>> p1 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS))
+>>> p1.check_token(u, tk1)
+True
+>>> p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
+>>> p2.check_token(u, tk1)
+False
+
+"""
diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py
new file mode 100644
index 0000000000..9abdc3baaf
--- /dev/null
+++ b/django/contrib/auth/tests/views.py
@@ -0,0 +1,88 @@
+
+import re
+from django.contrib.auth.models import User
+from django.test import TestCase
+from django.core import mail
+
+class PasswordResetTest(TestCase):
+ fixtures = ['authtestdata.json']
+ urls = 'django.contrib.auth.urls'
+
+ def test_email_not_found(self):
+ "Error is raised if the provided email address isn't currently registered"
+ response = self.client.get('/password_reset/')
+ self.assertEquals(response.status_code, 200)
+ response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'})
+ self.assertContains(response, "That e-mail address doesn't have an associated user account")
+ self.assertEquals(len(mail.outbox), 0)
+
+ def test_email_found(self):
+ "Email is sent if a valid email address is provided for password reset"
+ response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
+ self.assertEquals(response.status_code, 302)
+ self.assertEquals(len(mail.outbox), 1)
+ self.assert_("http://" in mail.outbox[0].body)
+
+ def _test_confirm_start(self):
+ # Start by creating the email
+ response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})
+ self.assertEquals(response.status_code, 302)
+ self.assertEquals(len(mail.outbox), 1)
+ return self._read_signup_email(mail.outbox[0])
+
+ def _read_signup_email(self, email):
+ urlmatch = re.search(r"https?://[^/]*(/.*reset/\S*)", email.body)
+ self.assert_(urlmatch is not None, "No URL found in sent email")
+ return urlmatch.group(), urlmatch.groups()[0]
+
+ def test_confirm_valid(self):
+ url, path = self._test_confirm_start()
+ response = self.client.get(path)
+ # redirect to a 'complete' page:
+ self.assertEquals(response.status_code, 200)
+ self.assert_("Please enter your new password" in response.content)
+
+ def test_confirm_invalid(self):
+ url, path = self._test_confirm_start()
+ # Lets munge the token in the path, but keep the same length,
+ # in case the URL conf will reject a different length
+ path = path[:-5] + ("0"*4) + path[-1]
+
+ response = self.client.get(path)
+ self.assertEquals(response.status_code, 200)
+ self.assert_("The password reset link was invalid" in response.content)
+
+ def test_confirm_invalid_post(self):
+ # Same as test_confirm_invalid, but trying
+ # to do a POST instead.
+ url, path = self._test_confirm_start()
+ path = path[:-5] + ("0"*4) + path[-1]
+
+ response = self.client.post(path, {'new_password1': 'anewpassword',
+ 'new_password2':' anewpassword'})
+ # Check the password has not been changed
+ u = User.objects.get(email='staffmember@example.com')
+ self.assert_(not u.check_password("anewpassword"))
+
+ def test_confirm_complete(self):
+ url, path = self._test_confirm_start()
+ response = self.client.post(path, {'new_password1': 'anewpassword',
+ 'new_password2': 'anewpassword'})
+ # It redirects us to a 'complete' page:
+ self.assertEquals(response.status_code, 302)
+ # Check the password has been changed
+ u = User.objects.get(email='staffmember@example.com')
+ self.assert_(u.check_password("anewpassword"))
+
+ # Check we can't use the link again
+ response = self.client.get(path)
+ self.assertEquals(response.status_code, 200)
+ self.assert_("The password reset link was invalid" in response.content)
+
+ def test_confirm_different_passwords(self):
+ url, path = self._test_confirm_start()
+ response = self.client.post(path, {'new_password1': 'anewpassword',
+ 'new_password2':' x'})
+ self.assertEquals(response.status_code, 200)
+ self.assert_("The two password fields didn't match" in response.content)
+
diff --git a/django/contrib/auth/tokens.py b/django/contrib/auth/tokens.py
new file mode 100644
index 0000000000..c9b353583c
--- /dev/null
+++ b/django/contrib/auth/tokens.py
@@ -0,0 +1,66 @@
+from datetime import date
+from django.conf import settings
+from django.utils.http import int_to_base36, base36_to_int
+
+class PasswordResetTokenGenerator(object):
+ """
+ Stratgy object used to generate and check tokens for the password
+ reset mechanism.
+ """
+ def make_token(self, user):
+ """
+ Returns a token that can be used once to do a password reset
+ for the given user.
+ """
+ return self._make_token_with_timestamp(user, self._num_days(self._today()))
+
+ def check_token(self, user, token):
+ """
+ Check that a password reset token is correct for a given user.
+ """
+ # Parse the tokem
+ try:
+ ts_b36, hash = token.split("-")
+ except ValueError:
+ return False
+
+ try:
+ ts = base36_to_int(ts_b36)
+ except ValueError:
+ return False
+
+ # Check that the timestamp/uid has not been tampered with
+ if self._make_token_with_timestamp(user, ts) != token:
+ return False
+
+ # Check the timestamp is within limit
+ if (self._num_days(self._today()) - ts) > settings.PASSWORD_RESET_TIMEOUT_DAYS:
+ return False
+
+ return True
+
+ def _make_token_with_timestamp(self, user, timestamp):
+ # timestamp is number of days since 2001-1-1. Converted to
+ # base 36, this gives us a 3 digit string until about 2121
+ ts_b36 = int_to_base36(timestamp)
+
+ # By hashing on the internal state of the user and using state
+ # that is sure to change (the password salt will change as soon as
+ # the password is set, at least for current Django auth, and
+ # last_login will also change), we produce a hash that will be
+ # invalid as soon as it is used.
+ # We limit the hash to 20 chars to keep URL short
+ from django.utils.hashcompat import sha_constructor
+ hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
+ user.password + unicode(user.last_login) +
+ unicode(timestamp)).hexdigest()[::2]
+ return "%s-%s" % (ts_b36, hash)
+
+ def _num_days(self, dt):
+ return (dt - date(2001,1,1)).days
+
+ def _today(self):
+ # Used for mocking in tests
+ return date.today()
+
+default_token_generator = PasswordResetTokenGenerator()
diff --git a/django/contrib/auth/urls.py b/django/contrib/auth/urls.py
index 5ddfcf15e8..72052c3795 100644
--- a/django/contrib/auth/urls.py
+++ b/django/contrib/auth/urls.py
@@ -5,9 +5,12 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('',
- ('^logout/$', 'django.contrib.auth.views.logout'),
- ('^password_change/$', 'django.contrib.auth.views.password_change'),
- ('^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
- ('^password_reset/$', 'django.contrib.auth.views.password_reset')
+ (r'^logout/$', 'django.contrib.auth.views.logout'),
+ (r'^password_change/$', 'django.contrib.auth.views.password_change'),
+ (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
+ (r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
+ (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
+ (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
+ (r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
)
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index 0a52240631..e503f87caa 100644
--- a/django/contrib/auth/views.py
+++ b/django/contrib/auth/views.py
@@ -1,13 +1,15 @@
+from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
-from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm, AdminPasswordChangeForm
+from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm, AdminPasswordChangeForm
+from django.contrib.auth.tokens import default_token_generator
from django.core.exceptions import PermissionDenied
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import Site, RequestSite
-from django.http import HttpResponseRedirect
+from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
-from django.utils.http import urlquote
+from django.utils.http import urlquote, base36_to_int
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
@@ -65,19 +67,29 @@ def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_N
login_url = settings.LOGIN_URL
return HttpResponseRedirect('%s?%s=%s' % (login_url, urlquote(redirect_field_name), urlquote(next)))
+# 4 views for password reset:
+# - password_reset sends the mail
+# - password_reset_done shows a success message for the above
+# - password_reset_confirm checks the link the user clicked and
+# prompts for a new password
+# - password_reset_complete shows a success message for the above
+
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
- password_reset_form=PasswordResetForm):
+ password_reset_form=PasswordResetForm, token_generator=default_token_generator):
if request.method == "POST":
form = password_reset_form(request.POST)
if form.is_valid():
+ opts = {}
+ opts['use_https'] = request.is_secure()
+ opts['token_generator'] = token_generator
if is_admin_site:
- form.save(domain_override=request.META['HTTP_HOST'])
+ opts['domain_override'] = request.META['HTTP_HOST']
else:
- if Site._meta.installed:
- form.save(email_template_name=email_template_name)
- else:
- form.save(domain_override=RequestSite(request).domain, email_template_name=email_template_name)
+ opts['email_template_name'] = email_template_name
+ if not Site._meta.installed:
+ opts['domain_override'] = RequestSite(request).domain
+ form.save(**opts)
return HttpResponseRedirect('%sdone/' % request.path)
else:
form = password_reset_form()
@@ -88,6 +100,40 @@ def password_reset(request, is_admin_site=False, template_name='registration/pas
def password_reset_done(request, template_name='registration/password_reset_done.html'):
return render_to_response(template_name, context_instance=RequestContext(request))
+def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
+ token_generator=default_token_generator, set_password_form=SetPasswordForm):
+ """
+ View that checks the hash in a password reset link and presents a
+ form for entering a new password.
+ """
+ assert uidb36 is not None and token is not None # checked by URLconf
+ try:
+ uid_int = base36_to_int(uidb36)
+ except ValueError:
+ raise Http404
+
+ user = get_object_or_404(User, id=uid_int)
+ context_instance = RequestContext(request)
+
+ if token_generator.check_token(user, token):
+ context_instance['validlink'] = True
+ if request.method == 'POST':
+ form = set_password_form(user, request.POST)
+ if form.is_valid():
+ form.save()
+ return HttpResponseRedirect("../done/")
+ else:
+ form = set_password_form(None)
+ else:
+ context_instance['validlink'] = False
+ form = None
+ context_instance['form'] = form
+ return render_to_response(template_name, context_instance=context_instance)
+
+def password_reset_complete(request, template_name='registration/password_reset_complete.html'):
+ return render_to_response(template_name, context_instance=RequestContext(request,
+ {'login_url': settings.LOGIN_URL}))
+
def password_change(request, template_name='registration/password_change_form.html'):
if request.method == "POST":
form = PasswordChangeForm(request.user, request.POST)
diff --git a/django/contrib/comments/models.py b/django/contrib/comments/models.py
index a13fec9e6e..fdf34c8997 100644
--- a/django/contrib/comments/models.py
+++ b/django/contrib/comments/models.py
@@ -29,8 +29,8 @@ class CommentManager(models.Manager):
'pa,ra') and target (something like 'lcom.eventtimes:5157'). Used to
validate that submitted form options have not been tampered-with.
"""
- import md5
- return md5.new(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest()
+ from django.utils.hashcompat import md5_constructor
+ return md5_constructor(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest()
def get_rating_options(self, rating_string):
"""
diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py
index e91be70d1b..2d38936265 100644
--- a/django/contrib/contenttypes/generic.py
+++ b/django/contrib/contenttypes/generic.py
@@ -95,7 +95,7 @@ class GenericForeignKey(object):
setattr(instance, self.cache_attr, value)
class GenericRelation(RelatedField, Field):
- """Provides an accessor to generic related objects (i.e. comments)"""
+ """Provides an accessor to generic related objects (e.g. comments)"""
def __init__(self, to, **kwargs):
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
@@ -104,6 +104,9 @@ class GenericRelation(RelatedField, Field):
limit_choices_to=kwargs.pop('limit_choices_to', None),
symmetrical=kwargs.pop('symmetrical', True))
+ # By its very nature, a GenericRelation doesn't create a table.
+ self.creates_table = False
+
# Override content-type/object-id field names on the related class
self.object_id_field_name = kwargs.pop("object_id_field", "object_id")
self.content_type_field_name = kwargs.pop("content_type_field", "content_type")
diff --git a/django/contrib/csrf/middleware.py b/django/contrib/csrf/middleware.py
index 1a75a5d6ab..24c1511c91 100644
--- a/django/contrib/csrf/middleware.py
+++ b/django/contrib/csrf/middleware.py
@@ -2,44 +2,45 @@
Cross Site Request Forgery Middleware.
This module provides a middleware that implements protection
-against request forgeries from other sites.
-
+against request forgeries from other sites.
"""
+
+import re
+import itertools
+
from django.conf import settings
from django.http import HttpResponseForbidden
+from django.utils.hashcompat import md5_constructor
from django.utils.safestring import mark_safe
-import md5
-import re
-import itertools
_ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>')
_POST_FORM_RE = \
re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
-
-_HTML_TYPES = ('text/html', 'application/xhtml+xml')
+
+_HTML_TYPES = ('text/html', 'application/xhtml+xml')
def _make_token(session_id):
- return md5.new(settings.SECRET_KEY + session_id).hexdigest()
+ return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
class CsrfMiddleware(object):
"""Django middleware that adds protection against Cross Site
- Request Forgeries by adding hidden form fields to POST forms and
- checking requests for the correct value.
-
- In the list of middlewares, SessionMiddleware is required, and must come
- after this middleware. CsrfMiddleWare must come after compression
+ Request Forgeries by adding hidden form fields to POST forms and
+ checking requests for the correct value.
+
+ In the list of middlewares, SessionMiddleware is required, and must come
+ after this middleware. CsrfMiddleWare must come after compression
middleware.
-
- If a session ID cookie is present, it is hashed with the SECRET_KEY
- setting to create an authentication token. This token is added to all
- outgoing POST forms and is expected on all incoming POST requests that
+
+ If a session ID cookie is present, it is hashed with the SECRET_KEY
+ setting to create an authentication token. This token is added to all
+ outgoing POST forms and is expected on all incoming POST requests that
have a session ID cookie.
-
- If you are setting cookies directly, instead of using Django's session
+
+ If you are setting cookies directly, instead of using Django's session
framework, this middleware will not work.
"""
-
+
def process_request(self, request):
if request.method == 'POST':
try:
@@ -54,10 +55,10 @@ class CsrfMiddleware(object):
request_csrf_token = request.POST['csrfmiddlewaretoken']
except KeyError:
return HttpResponseForbidden(_ERROR_MSG)
-
+
if request_csrf_token != csrf_token:
return HttpResponseForbidden(_ERROR_MSG)
-
+
return None
def process_response(self, request, response):
@@ -66,7 +67,7 @@ class CsrfMiddleware(object):
cookie = response.cookies[settings.SESSION_COOKIE_NAME]
csrf_token = _make_token(cookie.value)
except KeyError:
- # No outgoing cookie to set session, but
+ # No outgoing cookie to set session, but
# a session might already exist.
try:
session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
@@ -74,12 +75,12 @@ class CsrfMiddleware(object):
except KeyError:
# no incoming or outgoing cookie
pass
-
+
if csrf_token is not None and \
response['Content-Type'].split(';')[0] in _HTML_TYPES:
-
+
# ensure we don't add the 'id' attribute twice (HTML validity)
- idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
+ idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
itertools.repeat(''))
def add_csrf_field(match):
"""Returns the matched <form> tag plus the added <input> element"""
diff --git a/django/contrib/databrowse/plugins/calendars.py b/django/contrib/databrowse/plugins/calendars.py
index a4524e20dd..ac2f522148 100644
--- a/django/contrib/databrowse/plugins/calendars.py
+++ b/django/contrib/databrowse/plugins/calendars.py
@@ -4,7 +4,6 @@ from django.contrib.databrowse.datastructures import EasyModel
from django.contrib.databrowse.sites import DatabrowsePlugin
from django.shortcuts import render_to_response
from django.utils.text import capfirst
-from django.utils.translation import get_date_formats
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
from django.views.generic import date_based
diff --git a/django/contrib/databrowse/plugins/fieldchoices.py b/django/contrib/databrowse/plugins/fieldchoices.py
index 0a58e7a6ab..8f77792579 100644
--- a/django/contrib/databrowse/plugins/fieldchoices.py
+++ b/django/contrib/databrowse/plugins/fieldchoices.py
@@ -6,7 +6,6 @@ from django.shortcuts import render_to_response
from django.utils.text import capfirst
from django.utils.encoding import smart_str, force_unicode
from django.utils.safestring import mark_safe
-from django.views.generic import date_based
import urllib
class FieldChoicePlugin(DatabrowsePlugin):
diff --git a/django/contrib/databrowse/sites.py b/django/contrib/databrowse/sites.py
index 5d8c1c8b49..9ef35dbc1c 100644
--- a/django/contrib/databrowse/sites.py
+++ b/django/contrib/databrowse/sites.py
@@ -1,6 +1,6 @@
from django import http
from django.db import models
-from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
+from django.contrib.databrowse.datastructures import EasyModel
from django.shortcuts import render_to_response
from django.utils.safestring import mark_safe
diff --git a/django/contrib/databrowse/views.py b/django/contrib/databrowse/views.py
index c17aad5d85..4543e95780 100644
--- a/django/contrib/databrowse/views.py
+++ b/django/contrib/databrowse/views.py
@@ -1,7 +1,5 @@
-from django.db.models import FieldDoesNotExist, DateTimeField
from django.http import Http404
from django.shortcuts import render_to_response
-from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
###########
# CHOICES #
diff --git a/django/contrib/formtools/preview.py b/django/contrib/formtools/preview.py
index db5d58e971..c56fdff628 100644
--- a/django/contrib/formtools/preview.py
+++ b/django/contrib/formtools/preview.py
@@ -2,12 +2,13 @@
Formtools Preview application.
"""
+import cPickle as pickle
+
from django.conf import settings
from django.http import Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
-import cPickle as pickle
-import md5
+from django.utils.hashcompat import md5_constructor
AUTO_ID = 'formtools_%s' # Each form here uses this as its auto_id parameter.
@@ -109,7 +110,7 @@ class FormPreview(object):
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- return md5.new(pickled).hexdigest()
+ return md5_constructor(pickled).hexdigest()
def failed_hash(self, request):
"Returns an HttpResponse in the case of an invalid security hash."
diff --git a/django/contrib/formtools/tests.py b/django/contrib/formtools/tests.py
index 99fe80bbb3..2ea0cc90a4 100644
--- a/django/contrib/formtools/tests.py
+++ b/django/contrib/formtools/tests.py
@@ -1,7 +1,6 @@
from django import forms
from django.contrib.formtools import preview
from django import http
-from django.conf import settings
from django.test import TestCase
success_string = "Done was called!"
diff --git a/django/contrib/formtools/wizard.py b/django/contrib/formtools/wizard.py
index 7b96d91187..984b6e487e 100644
--- a/django/contrib/formtools/wizard.py
+++ b/django/contrib/formtools/wizard.py
@@ -4,13 +4,14 @@ step and storing the form's state as HTML hidden fields so that no state is
stored on the server side.
"""
+import cPickle as pickle
+
from django import forms
from django.conf import settings
from django.http import Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
-import cPickle as pickle
-import md5
+from django.utils.hashcompat import md5_constructor
class FormWizard(object):
# Dictionary of extra template context variables.
@@ -150,7 +151,7 @@ class FormWizard(object):
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- return md5.new(pickled).hexdigest()
+ return md5_constructor(pickled).hexdigest()
def determine_step(self, request, *args, **kwargs):
"""
diff --git a/django/contrib/gis/db/backend/oracle/field.py b/django/contrib/gis/db/backend/oracle/field.py
index 829d5a5b02..22625f5e10 100644
--- a/django/contrib/gis/db/backend/oracle/field.py
+++ b/django/contrib/gis/db/backend/oracle/field.py
@@ -70,7 +70,7 @@ class OracleSpatialField(Field):
style.SQL_TABLE('MDSYS.SPATIAL_INDEX') + ';'
return sql
- def _post_create_sql(self, style, db_table):
+ def post_create_sql(self, style, db_table):
"""
Returns SQL that will be executed after the model has been
created.
diff --git a/django/contrib/gis/db/backend/postgis/field.py b/django/contrib/gis/db/backend/postgis/field.py
index 1e055ff60b..9d6c0fad24 100644
--- a/django/contrib/gis/db/backend/postgis/field.py
+++ b/django/contrib/gis/db/backend/postgis/field.py
@@ -50,7 +50,7 @@ class PostGISField(Field):
style.SQL_KEYWORD(index_opts) + ' );'
return sql
- def _post_create_sql(self, style, db_table):
+ def post_create_sql(self, style, db_table):
"""
Returns SQL that will be executed after the model has been
created. Geometry columns must be added after creation with the
diff --git a/django/contrib/gis/db/models/manager.py b/django/contrib/gis/db/models/manager.py
index 4b010ac20c..602d11251a 100644
--- a/django/contrib/gis/db/models/manager.py
+++ b/django/contrib/gis/db/models/manager.py
@@ -4,6 +4,11 @@ from django.contrib.gis.db.models.query import GeoQuerySet
class GeoManager(Manager):
"Overrides Manager to return Geographic QuerySets."
+ # This manager should be used for queries on related fields
+ # so that geometry columns on Oracle and MySQL are selected
+ # properly.
+ use_for_related_fields = True
+
def get_query_set(self):
return GeoQuerySet(model=self.model)
diff --git a/tests/regressiontests/maxlength/__init__.py b/django/contrib/localflavor/at/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/maxlength/__init__.py
+++ b/django/contrib/localflavor/at/__init__.py
diff --git a/django/contrib/localflavor/at/at_states.py b/django/contrib/localflavor/at/at_states.py
new file mode 100644
index 0000000000..d4b4d8aa53
--- /dev/null
+++ b/django/contrib/localflavor/at/at_states.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*
+from django.utils.translation import ugettext_lazy as _
+
+STATE_CHOICES = (
+ ('BL', _('Burgenland')),
+ ('KA', _('Carinthia')),
+ ('NO', _('Lower Austria')),
+ ('OO', _('Upper Austria')),
+ ('SA', _('Salzburg')),
+ ('ST', _('Styria')),
+ ('TI', _('Tyrol')),
+ ('VO', _('Vorarlberg')),
+ ('WI', _('Vienna')),
+) \ No newline at end of file
diff --git a/django/contrib/localflavor/at/forms.py b/django/contrib/localflavor/at/forms.py
new file mode 100644
index 0000000000..e428fdaa17
--- /dev/null
+++ b/django/contrib/localflavor/at/forms.py
@@ -0,0 +1,65 @@
+"""
+AT-specific Form helpers
+"""
+
+import re
+
+from django.utils.translation import ugettext_lazy as _
+from django.forms.fields import Field, RegexField, Select
+from django.forms import ValidationError
+
+re_ssn = re.compile(r'^\d{4} \d{6}')
+
+class ATZipCodeField(RegexField):
+ """
+ A form field that validates its input is an Austrian postcode.
+
+ Accepts 4 digits.
+ """
+ default_error_messages = {
+ 'invalid': _('Enter a zip code in the format XXXX.'),
+ }
+ def __init__(self, *args, **kwargs):
+ super(ATZipCodeField, self).__init__(r'^\d{4}$',
+ max_length=None, min_length=None, *args, **kwargs)
+
+class ATStateSelect(Select):
+ """
+ A Select widget that uses a list of AT states as its choices.
+ """
+ def __init__(self, attrs=None):
+ from django.contrib.localflavor.at.at_states import STATE_CHOICES
+ super(ATStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
+
+class ATSocialSecurityNumberField(Field):
+ """
+ Austrian Social Security numbers are composed of a 4 digits and 6 digits
+ field. The latter represents in most cases the person's birthdate while
+ the first 4 digits represent a 3-digits counter and a one-digit checksum.
+
+ The 6-digits field can also differ from the person's birthdate if the
+ 3-digits counter suffered an overflow.
+
+ This code is based on information available on
+ http://de.wikipedia.org/wiki/Sozialversicherungsnummer#.C3.96sterreich
+ """
+
+ default_error_messages = {
+ 'invalid': _(u'Enter a valid Austrian Social Security Number in XXXX XXXXXX format.'),
+ }
+
+ def clean(self, value):
+ if not re_ssn.search(value):
+ raise ValidationError(self.error_messages['invalid'])
+ sqnr, date = value.split(" ")
+ sqnr, check = (sqnr[:3], (sqnr[3]))
+ if int(sqnr) < 100:
+ raise ValidationError(self.error_messages['invalid'])
+ res = int(sqnr[0])*3 + int(sqnr[1])*7 + int(sqnr[2])*9 \
+ + int(date[0])*5 + int(date[1])*8 + int(date[2])*4 \
+ + int(date[3])*2 + int(date[4])*1 + int(date[5])*6
+ res = res % 11
+ if res != int(check):
+ raise ValidationError(self.error_messages['invalid'])
+ return u'%s%s %s'%(sqnr, check, date,)
+
diff --git a/tests/regressiontests/maxlength/models.py b/django/contrib/localflavor/ro/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/maxlength/models.py
+++ b/django/contrib/localflavor/ro/__init__.py
diff --git a/django/contrib/localflavor/ro/forms.py b/django/contrib/localflavor/ro/forms.py
new file mode 100644
index 0000000000..ca51d91839
--- /dev/null
+++ b/django/contrib/localflavor/ro/forms.py
@@ -0,0 +1,200 @@
+# -*- coding: utf-8 -*-
+"""
+Romanian specific form helpers.
+"""
+
+import re
+
+from django.forms import ValidationError, Field, RegexField, Select
+from django.forms.fields import EMPTY_VALUES
+from django.utils.translation import ugettext_lazy as _
+
+class ROCIFField(RegexField):
+ """
+ A Romanian fiscal identity code (CIF) field
+
+ For CIF validation algorithm see http://www.validari.ro/cui.html
+ """
+ default_error_messages = {
+ 'invalid': _("Enter a valid CIF."),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ROCIFField, self).__init__(r'^[0-9]{2,10}', max_length=10,
+ min_length=2, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ CIF validation
+ """
+ value = super(ROCIFField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ # strip RO part
+ if value[0:2] == 'RO':
+ value = value[2:]
+ key = '753217532'[::-1]
+ value = value[::-1]
+ key_iter = iter(key)
+ checksum = 0
+ for digit in value[1:]:
+ checksum += int(digit) * int(key_iter.next())
+ checksum = checksum * 10 % 11
+ if checksum == 10:
+ checksum = 0
+ if checksum != int(value[0]):
+ raise ValidationError(self.error_messages['invalid'])
+ return value[::-1]
+
+class ROCNPField(RegexField):
+ """
+ A Romanian personal identity code (CNP) field
+
+ For CNP validation algorithm see http://www.validari.ro/cnp.html
+ """
+ default_error_messages = {
+ 'invalid': _("Enter a valid CNP."),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ROCNPField, self).__init__(r'^[1-9][0-9]{12}', max_length=13,
+ min_length=13, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ CNP validations
+ """
+ value = super(ROCNPField, self).clean(value)
+ # check birthdate digits
+ import datetime
+ try:
+ datetime.date(int(value[1:3]),int(value[3:5]),int(value[5:7]))
+ except:
+ raise ValidationError(self.error_messages['invalid'])
+ # checksum
+ key = '279146358279'
+ checksum = 0
+ value_iter = iter(value)
+ for digit in key:
+ checksum += int(digit) * int(value_iter.next())
+ checksum %= 11
+ if checksum == 10:
+ checksum = 1
+ if checksum != int(value[12]):
+ raise ValidationError(self.error_messages['invalid'])
+ return value
+
+class ROCountyField(Field):
+ """
+ A form field that validates its input is a Romanian county name or
+ abbreviation. It normalizes the input to the standard vehicle registration
+ abbreviation for the given county
+
+ WARNING: This field will only accept names written with diacritics; consider
+ using ROCountySelect if this behavior is unnaceptable for you
+ Example:
+ ArgeÅŸ => valid
+ Arges => invalid
+ """
+ default_error_messages = {
+ 'invalid': u'Enter a Romanian county code or name.',
+ }
+
+ def clean(self, value):
+ from ro_counties import COUNTIES_CHOICES
+ super(ROCountyField, self).clean(value)
+ if value in EMPTY_VALUES:
+ return u''
+ try:
+ value = value.strip().upper()
+ except AttributeError:
+ pass
+ # search for county code
+ for entry in COUNTIES_CHOICES:
+ if value in entry:
+ return value
+ # search for county name
+ normalized_CC = []
+ for entry in COUNTIES_CHOICES:
+ normalized_CC.append((entry[0],entry[1].upper()))
+ for entry in normalized_CC:
+ if entry[1] == value:
+ return entry[0]
+ raise ValidationError(self.error_messages['invalid'])
+
+class ROCountySelect(Select):
+ """
+ A Select widget that uses a list of Romanian counties (judete) as its
+ choices.
+ """
+ def __init__(self, attrs=None):
+ from ro_counties import COUNTIES_CHOICES
+ super(ROCountySelect, self).__init__(attrs, choices=COUNTIES_CHOICES)
+
+class ROIBANField(RegexField):
+ """
+ Romanian International Bank Account Number (IBAN) field
+
+ For Romanian IBAN validation algorithm see http://validari.ro/iban.html
+ """
+ default_error_messages = {
+ 'invalid': _('Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format'),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ROIBANField, self).__init__(r'^[0-9A-Za-z\-\s]{24,40}$',
+ max_length=40, min_length=24, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ Strips - and spaces, performs country code and checksum validation
+ """
+ value = super(ROIBANField, self).clean(value)
+ value = value.replace('-','')
+ value = value.replace(' ','')
+ value = value.upper()
+ if value[0:2] != 'RO':
+ raise ValidationError(self.error_messages['invalid'])
+ numeric_format = ''
+ for char in value[4:] + value[0:4]:
+ if char.isalpha():
+ numeric_format += str(ord(char) - 55)
+ else:
+ numeric_format += char
+ if int(numeric_format) % 97 != 1:
+ raise ValidationError(self.error_messages['invalid'])
+ return value
+
+class ROPhoneNumberField(RegexField):
+ """Romanian phone number field"""
+ default_error_messages = {
+ 'invalid': _('Phone numbers must be in XXXX-XXXXXX format.'),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ROPhoneNumberField, self).__init__(r'^[0-9\-\(\)\s]{10,20}$',
+ max_length=20, min_length=10, *args, **kwargs)
+
+ def clean(self, value):
+ """
+ Strips -, (, ) and spaces. Checks the final length.
+ """
+ value = super(ROPhoneNumberField, self).clean(value)
+ value = value.replace('-','')
+ value = value.replace('(','')
+ value = value.replace(')','')
+ value = value.replace(' ','')
+ if len(value) != 10:
+ raise ValidationError(self.error_messages['invalid'])
+ return value
+
+class ROPostalCodeField(RegexField):
+ """Romanian postal code field."""
+ default_error_messages = {
+ 'invalid': _('Enter a valid postal code in the format XXXXXX'),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ROPostalCodeField, self).__init__(r'^[0-9][0-8][0-9]{4}$',
+ max_length=6, min_length=6, *args, **kwargs)
+
diff --git a/django/contrib/localflavor/ro/ro_counties.py b/django/contrib/localflavor/ro/ro_counties.py
new file mode 100644
index 0000000000..40423ddc87
--- /dev/null
+++ b/django/contrib/localflavor/ro/ro_counties.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+"""
+A list of Romanian counties as `choices` in a formfield.
+
+This exists as a standalone file so that it's only imported into memory when
+explicitly needed.
+"""
+
+COUNTIES_CHOICES = (
+ ('AB', u'Alba'),
+ ('AR', u'Arad'),
+ ('AG', u'ArgeÅŸ'),
+ ('BC', u'Bacău'),
+ ('BH', u'Bihor'),
+ ('BN', u'Bistriţa-Năsăud'),
+ ('BT', u'BotoÅŸani'),
+ ('BV', u'BraÅŸov'),
+ ('BR', u'Brăila'),
+ ('B', u'BucureÅŸti'),
+ ('BZ', u'Buzău'),
+ ('CS', u'CaraÅŸ-Severin'),
+ ('CL', u'Călăraşi'),
+ ('CJ', u'Cluj'),
+ ('CT', u'Constanţa'),
+ ('CV', u'Covasna'),
+ ('DB', u'Dâmboviţa'),
+ ('DJ', u'Dolj'),
+ ('GL', u'Galaţi'),
+ ('GR', u'Giurgiu'),
+ ('GJ', u'Gorj'),
+ ('HR', u'Harghita'),
+ ('HD', u'Hunedoara'),
+ ('IL', u'Ialomiţa'),
+ ('IS', u'IaÅŸi'),
+ ('IF', u'Ilfov'),
+ ('MM', u'MaramureÅŸ'),
+ ('MH', u'Mehedinţi'),
+ ('MS', u'MureÅŸ'),
+ ('NT', u'Neamţ'),
+ ('OT', u'Olt'),
+ ('PH', u'Prahova'),
+ ('SM', u'Satu Mare'),
+ ('SJ', u'Sălaj'),
+ ('SB', u'Sibiu'),
+ ('SV', u'Suceava'),
+ ('TR', u'Teleorman'),
+ ('TM', u'TimiÅŸ'),
+ ('TL', u'Tulcea'),
+ ('VS', u'Vaslui'),
+ ('VL', u'Vâlcea'),
+ ('VN', u'Vrancea'),
+)
diff --git a/django/contrib/redirects/admin.py b/django/contrib/redirects/admin.py
new file mode 100644
index 0000000000..a9b2a3228f
--- /dev/null
+++ b/django/contrib/redirects/admin.py
@@ -0,0 +1,11 @@
+
+from django.contrib import admin
+from django.contrib.redirects.models import Redirect
+
+class RedirectAdmin(admin.ModelAdmin):
+ list_display = ('old_path', 'new_path')
+ list_filter = ('site',)
+ search_fields = ('old_path', 'new_path')
+ radio_fields = {'site': admin.VERTICAL}
+
+admin.site.register(Redirect, RedirectAdmin) \ No newline at end of file
diff --git a/django/contrib/redirects/models.py b/django/contrib/redirects/models.py
index 991423268d..4233d55793 100644
--- a/django/contrib/redirects/models.py
+++ b/django/contrib/redirects/models.py
@@ -18,18 +18,3 @@ class Redirect(models.Model):
def __unicode__(self):
return "%s ---> %s" % (self.old_path, self.new_path)
-
-# Register the admin options for these models.
-# TODO: Maybe this should live in a separate module admin.py, but how would we
-# ensure that module was loaded?
-
-from django.contrib import admin
-
-class RedirectAdmin(admin.ModelAdmin):
- list_display = ('old_path', 'new_path')
- list_filter = ('site',)
- search_fields = ('old_path', 'new_path')
- radio_fields = {'site': admin.VERTICAL}
-
-admin.site.register(Redirect, RedirectAdmin)
-
diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
index b40fba6e6e..7153b8a267 100644
--- a/django/contrib/sessions/backends/base.py
+++ b/django/contrib/sessions/backends/base.py
@@ -1,5 +1,4 @@
import base64
-import md5
import os
import random
import sys
@@ -12,6 +11,7 @@ except ImportError:
from django.conf import settings
from django.core.exceptions import SuspiciousOperation
+from django.utils.hashcompat import md5_constructor
class SessionBase(object):
@@ -73,13 +73,13 @@ class SessionBase(object):
def encode(self, session_dict):
"Returns the given session dictionary pickled and encoded as a string."
pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def decode(self, session_data):
encoded_data = base64.decodestring(session_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
raise SuspiciousOperation("User tampered with session cookie.")
try:
return pickle.loads(pickled)
@@ -117,8 +117,8 @@ class SessionBase(object):
# No getpid() in Jython, for example
pid = 1
while 1:
- session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1),
- pid, time.time(), settings.SECRET_KEY)).hexdigest()
+ session_key = md5_constructor("%s%s%s%s" % (random.randint(0, sys.maxint - 1),
+ pid, time.time(), settings.SECRET_KEY)).hexdigest()
if not self.exists(session_key):
break
return session_key
diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py
index 7e171e8309..5ffb5a136b 100644
--- a/django/contrib/sessions/backends/cache.py
+++ b/django/contrib/sessions/backends/cache.py
@@ -1,8 +1,6 @@
-from django.conf import settings
from django.contrib.sessions.backends.base import SessionBase
from django.core.cache import cache
-
class SessionStore(SessionBase):
"""
A cache-based session store.
diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py
index 67132c7560..add3d70074 100644
--- a/django/contrib/sessions/backends/db.py
+++ b/django/contrib/sessions/backends/db.py
@@ -1,11 +1,8 @@
import datetime
-
-from django.conf import settings
from django.contrib.sessions.models import Session
from django.contrib.sessions.backends.base import SessionBase
from django.core.exceptions import SuspiciousOperation
-
class SessionStore(SessionBase):
"""
Implements database session store.
diff --git a/django/contrib/sessions/middleware.py b/django/contrib/sessions/middleware.py
index 238d6095e5..ce6e678ebc 100644
--- a/django/contrib/sessions/middleware.py
+++ b/django/contrib/sessions/middleware.py
@@ -4,12 +4,7 @@ from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
-TEST_COOKIE_NAME = 'testcookie'
-TEST_COOKIE_VALUE = 'worked'
-
-
class SessionMiddleware(object):
-
def process_request(self, request):
engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
diff --git a/django/contrib/sessions/models.py b/django/contrib/sessions/models.py
index 70fce3b226..cf2865fcc8 100644
--- a/django/contrib/sessions/models.py
+++ b/django/contrib/sessions/models.py
@@ -1,10 +1,10 @@
import base64
-import md5
import cPickle as pickle
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
+from django.utils.hashcompat import md5_constructor
class SessionManager(models.Manager):
@@ -13,7 +13,7 @@ class SessionManager(models.Manager):
Returns the given session dictionary pickled and encoded as a string.
"""
pickled = pickle.dumps(session_dict)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def save(self, session_key, session_dict, expire_date):
@@ -56,7 +56,7 @@ class Session(models.Model):
def get_decoded(self):
encoded_data = base64.decodestring(self.session_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation, "User tampered with session cookie."
try:
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 30949837e4..13e667e142 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -1,4 +1,4 @@
-from django.core import urlresolvers
+from django.core import urlresolvers, paginator
import urllib
PING_URL = "http://www.google.com/webmasters/tools/ping"
@@ -34,6 +34,10 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
urllib.urlopen("%s?%s" % (ping_url, params))
class Sitemap:
+ # This limit is defined by Google. See the index documentation at
+ # http://sitemaps.org/protocol.php#index.
+ limit = 50000
+
def __get(self, name, obj, default=None):
try:
attr = getattr(self, name)
@@ -49,11 +53,17 @@ class Sitemap:
def location(self, obj):
return obj.get_absolute_url()
- def get_urls(self):
+ def _get_paginator(self):
+ if not hasattr(self, "paginator"):
+ self.paginator = paginator.Paginator(self.items(), self.limit)
+ return self.paginator
+ paginator = property(_get_paginator)
+
+ def get_urls(self, page=1):
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
urls = []
- for item in self.items():
+ for item in self.paginator.page(page).object_list:
loc = "http://%s%s" % (current_site.domain, self.__get('location', item))
url_info = {
'location': loc,
diff --git a/django/contrib/sitemaps/management/__init__.py b/django/contrib/sitemaps/management/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/django/contrib/sitemaps/management/__init__.py
diff --git a/django/contrib/sitemaps/management/commands/__init__.py b/django/contrib/sitemaps/management/commands/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/django/contrib/sitemaps/management/commands/__init__.py
diff --git a/django/contrib/sitemaps/views.py b/django/contrib/sitemaps/views.py
index 86ef1e3526..7a5fe38a08 100644
--- a/django/contrib/sitemaps/views.py
+++ b/django/contrib/sitemaps/views.py
@@ -3,14 +3,22 @@ from django.template import loader
from django.contrib.sites.models import Site
from django.core import urlresolvers
from django.utils.encoding import smart_str
+from django.core.paginator import EmptyPage, PageNotAnInteger
def index(request, sitemaps):
current_site = Site.objects.get_current()
sites = []
protocol = request.is_secure() and 'https' or 'http'
- for section in sitemaps.keys():
+ for section, site in sitemaps.items():
+ if callable(site):
+ pages = site().paginator.num_pages
+ else:
+ pages = site.paginator.num_pages
sitemap_url = urlresolvers.reverse('django.contrib.sitemaps.views.sitemap', kwargs={'section': section})
sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url))
+ if pages > 1:
+ for page in range(2, pages+1):
+ sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page))
xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites})
return HttpResponse(xml, mimetype='application/xml')
@@ -22,10 +30,16 @@ def sitemap(request, sitemaps, section=None):
maps.append(sitemaps[section])
else:
maps = sitemaps.values()
+ page = request.GET.get("p", 1)
for site in maps:
- if callable(site):
- urls.extend(site().get_urls())
- else:
- urls.extend(site.get_urls())
+ try:
+ if callable(site):
+ urls.extend(site().get_urls(page))
+ else:
+ urls.extend(site.get_urls(page))
+ except EmptyPage:
+ raise Http404("Page %s empty" % page)
+ except PageNotAnInteger:
+ raise Http404("No page '%s'" % page)
xml = smart_str(loader.render_to_string('sitemap.xml', {'urlset': urls}))
return HttpResponse(xml, mimetype='application/xml')
diff --git a/django/contrib/sites/tests.py b/django/contrib/sites/tests.py
index 5c38ee1b6d..f39f7a2c82 100644
--- a/django/contrib/sites/tests.py
+++ b/django/contrib/sites/tests.py
@@ -1,6 +1,9 @@
"""
->>> # Make sure that get_current() does not return a deleted Site object.
>>> from django.contrib.sites.models import Site
+>>> from django.conf import settings
+>>> Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
+
+>>> # Make sure that get_current() does not return a deleted Site object.
>>> s = Site.objects.get_current()
>>> isinstance(s, Site)
True
diff --git a/django/contrib/syndication/feeds.py b/django/contrib/syndication/feeds.py
index 85af79cc27..63d2431883 100644
--- a/django/contrib/syndication/feeds.py
+++ b/django/contrib/syndication/feeds.py
@@ -1,5 +1,5 @@
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
-from django.template import Context, loader, Template, TemplateDoesNotExist
+from django.template import loader, Template, TemplateDoesNotExist
from django.contrib.sites.models import Site, RequestSite
from django.utils import feedgenerator
from django.utils.encoding import smart_unicode, iri_to_uri
diff --git a/django/core/cache/__init__.py b/django/core/cache/__init__.py
index 495cc92822..c136ce4f4d 100644
--- a/django/core/cache/__init__.py
+++ b/django/core/cache/__init__.py
@@ -19,8 +19,10 @@ from cgi import parse_qsl
from django.conf import settings
from django.core.cache.backends.base import InvalidCacheBackendError
+# Name for use in settings file --> name of module in "backends" directory.
+# Any backend scheme that is not in this dictionary is treated as a Python
+# import path to a custom backend.
BACKENDS = {
- # name for use in settings file --> name of module in "backends" directory
'memcached': 'memcached',
'locmem': 'locmem',
'file': 'filebased',
@@ -28,24 +30,12 @@ BACKENDS = {
'dummy': 'dummy',
}
-DEPRECATED_BACKENDS = {
- # deprecated backend --> replacement module
- 'simple': 'locmem',
-}
-
def get_cache(backend_uri):
if backend_uri.find(':') == -1:
raise InvalidCacheBackendError, "Backend URI must start with scheme://"
scheme, rest = backend_uri.split(':', 1)
if not rest.startswith('//'):
raise InvalidCacheBackendError, "Backend URI must start with scheme://"
- if scheme in DEPRECATED_BACKENDS:
- import warnings
- warnings.warn("'%s' backend is deprecated. Use '%s' instead." %
- (scheme, DEPRECATED_BACKENDS[scheme]), DeprecationWarning)
- scheme = DEPRECATED_BACKENDS[scheme]
- if scheme not in BACKENDS:
- raise InvalidCacheBackendError, "%r is not a valid cache backend" % scheme
host = rest[2:]
qpos = rest.find('?')
@@ -57,7 +47,10 @@ def get_cache(backend_uri):
if host.endswith('/'):
host = host[:-1]
- cache_class = getattr(__import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, ['']), 'CacheClass')
- return cache_class(host, params)
+ if scheme in BACKENDS:
+ module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, [''])
+ else:
+ module = __import__(scheme, {}, {}, [''])
+ return getattr(module, 'CacheClass')(host, params)
cache = get_cache(settings.CACHE_BACKEND)
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index ff4223bf86..58e166d655 100644
--- a/django/core/cache/backends/base.py
+++ b/django/core/cache/backends/base.py
@@ -63,4 +63,11 @@ class BaseCache(object):
"""
return self.get(key) is not None
- __contains__ = has_key
+ def __contains__(self, key):
+ """
+ Returns True if the key is in the cache and has not expired.
+ """
+ # This is a separate method, rather than just a copy of has_key(),
+ # so that it always has the same functionality as has_key(), even
+ # if a subclass overrides it.
+ return self.has_key(key)
diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
index c1277bf20c..0ad586d477 100644
--- a/django/core/cache/backends/filebased.py
+++ b/django/core/cache/backends/filebased.py
@@ -1,29 +1,31 @@
"File-based cache backend"
-import md5
-import os, time
+import os
+import time
try:
import cPickle as pickle
except ImportError:
import pickle
+
from django.core.cache.backends.base import BaseCache
+from django.utils.hashcompat import md5_constructor
class CacheClass(BaseCache):
def __init__(self, dir, params):
BaseCache.__init__(self, params)
-
+
max_entries = params.get('max_entries', 300)
try:
self._max_entries = int(max_entries)
except (ValueError, TypeError):
self._max_entries = 300
-
+
cull_frequency = params.get('cull_frequency', 3)
try:
self._cull_frequency = int(cull_frequency)
except (ValueError, TypeError):
self._cull_frequency = 3
-
+
self._dir = dir
if not os.path.exists(self._dir):
self._createdir()
@@ -31,7 +33,7 @@ class CacheClass(BaseCache):
def add(self, key, value, timeout=None):
if self.has_key(key):
return None
-
+
self.set(key, value, timeout)
def get(self, key, default=None):
@@ -52,12 +54,12 @@ class CacheClass(BaseCache):
def set(self, key, value, timeout=None):
fname = self._key_to_file(key)
dirname = os.path.dirname(fname)
-
+
if timeout is None:
timeout = self.default_timeout
-
+
self._cull()
-
+
try:
if not os.path.exists(dirname):
os.makedirs(dirname)
@@ -103,12 +105,12 @@ class CacheClass(BaseCache):
def _cull(self):
if int(self._num_entries) < self._max_entries:
return
-
+
try:
filelist = os.listdir(self._dir)
except (IOError, OSError):
return
-
+
if self._cull_frequency == 0:
doomed = filelist
else:
@@ -133,11 +135,11 @@ class CacheClass(BaseCache):
Convert the filename into an md5 string. We'll turn the first couple
bits of the path into directory prefixes to be nice to filesystems
that have problems with large numbers of files in a directory.
-
+
Thus, a cache key of "foo" gets turnned into a file named
``{cache-dir}ac/bd/18db4cc2f85cedef654fccc4a4d8``.
"""
- path = md5.new(key.encode('utf-8')).hexdigest()
+ path = md5_constructor(key.encode('utf-8')).hexdigest()
path = os.path.join(path[:2], path[2:4], path[4:])
return os.path.join(self._dir, path)
@@ -147,4 +149,3 @@ class CacheClass(BaseCache):
count += len(files)
return count
_num_entries = property(_get_num_entries)
-
diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py
index e8e1e0d450..053e0735f7 100644
--- a/django/core/cache/backends/locmem.py
+++ b/django/core/cache/backends/locmem.py
@@ -107,7 +107,7 @@ class CacheClass(BaseCache):
else:
doomed = [k for (i, k) in enumerate(self._cache) if i % self._cull_frequency == 0]
for k in doomed:
- self.delete(k)
+ self._delete(k)
def _delete(self, key):
try:
diff --git a/django/core/files/temp.py b/django/core/files/temp.py
new file mode 100644
index 0000000000..298fcbf0a5
--- /dev/null
+++ b/django/core/files/temp.py
@@ -0,0 +1,58 @@
+"""
+The temp module provides a NamedTemporaryFile that can be re-opened on any
+platform. Most platforms use the standard Python tempfile.TemporaryFile class,
+but MS Windows users are given a custom class.
+
+This is needed because in Windows NT, the default implementation of
+NamedTemporaryFile uses the O_TEMPORARY flag, and thus cannot be reopened [1].
+
+1: http://mail.python.org/pipermail/python-list/2005-December/359474.html
+"""
+
+import os
+import tempfile
+
+__all__ = ('NamedTemporaryFile', 'gettempdir',)
+
+if os.name == 'nt':
+ class TemporaryFile(object):
+ """
+ Temporary file object constructor that works in Windows and supports
+ reopening of the temporary file in windows.
+ """
+ def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='',
+ dir=None):
+ fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix,
+ dir=dir)
+ self.name = name
+ self._file = os.fdopen(fd, mode, bufsize)
+
+ def __del__(self):
+ try:
+ self._file.close()
+ except (OSError, IOError):
+ pass
+ try:
+ os.unlink(self.name)
+ except (OSError):
+ pass
+
+ try:
+ super(TemporaryFile, self).__del__()
+ except AttributeError:
+ pass
+
+
+ def read(self, *args): return self._file.read(*args)
+ def seek(self, offset): return self._file.seek(offset)
+ def write(self, s): return self._file.write(s)
+ def close(self): return self._file.close()
+ def __iter__(self): return iter(self._file)
+ def readlines(self, size=None): return self._file.readlines(size)
+ def xreadlines(self): return self._file.xreadlines()
+
+ NamedTemporaryFile = TemporaryFile
+else:
+ NamedTemporaryFile = tempfile.NamedTemporaryFile
+
+gettempdir = tempfile.gettempdir
diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py
index 7f515f94d4..c498561c18 100644
--- a/django/core/files/uploadedfile.py
+++ b/django/core/files/uploadedfile.py
@@ -3,7 +3,6 @@ Classes representing uploaded files.
"""
import os
-import tempfile
import warnings
try:
from cStringIO import StringIO
@@ -12,6 +11,8 @@ except ImportError:
from django.conf import settings
+from django.core.files import temp as tempfile
+
__all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile')
# Because we fooled around with it a bunch, UploadedFile has a bunch
diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py
index 008a05a148..fa4d2df804 100644
--- a/django/core/files/uploadhandler.py
+++ b/django/core/files/uploadhandler.py
@@ -1,8 +1,7 @@
"""
Base file upload handler classes, and the built-in concrete subclasses
"""
-import os
-import tempfile
+
try:
from cStringIO import StringIO
except ImportError:
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 29835d7ce5..214032e318 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -3,6 +3,7 @@ import sys
from django import http
from django.core import signals
from django.dispatch import dispatcher
+from django.utils.encoding import force_unicode
class BaseHandler(object):
# Changes that are always applied to a response (in this order).
@@ -73,7 +74,8 @@ class BaseHandler(object):
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
try:
- callback, callback_args, callback_kwargs = resolver.resolve(request.path)
+ callback, callback_args, callback_kwargs = resolver.resolve(
+ request.path_info)
# Apply view middleware
for middleware_method in self._view_middleware:
@@ -107,8 +109,11 @@ class BaseHandler(object):
from django.views import debug
return debug.technical_404_response(request, e)
else:
- callback, param_dict = resolver.resolve404()
- return callback(request, **param_dict)
+ try:
+ callback, param_dict = resolver.resolve404()
+ return callback(request, **param_dict)
+ except:
+ return self.handle_uncaught_exception(request, resolver, sys.exc_info())
except exceptions.PermissionDenied:
return http.HttpResponseForbidden('<h1>Permission denied</h1>')
except SystemExit:
@@ -118,9 +123,6 @@ class BaseHandler(object):
# Get the exception info now, in case another exception is thrown later.
exc_info = sys.exc_info()
receivers = dispatcher.send(signal=signals.got_request_exception, request=request)
-
- if settings.DEBUG_PROPAGATE_EXCEPTIONS:
- raise
return self.handle_uncaught_exception(request, resolver, exc_info)
def handle_uncaught_exception(self, request, resolver, exc_info):
@@ -136,6 +138,9 @@ class BaseHandler(object):
from django.conf import settings
from django.core.mail import mail_admins
+ if settings.DEBUG_PROPAGATE_EXCEPTIONS:
+ raise
+
if settings.DEBUG:
from django.views import debug
return debug.technical_500_response(request, *exc_info)
@@ -167,3 +172,27 @@ class BaseHandler(object):
response = func(request, response)
return response
+def get_script_name(environ):
+ """
+ Returns the equivalent of the HTTP request's SCRIPT_NAME environment
+ variable. If Apache mod_rewrite has been used, returns what would have been
+ the script name prior to any rewriting (so it's the script name as seen
+ from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to
+ anything).
+ """
+ from django.conf import settings
+ if settings.FORCE_SCRIPT_NAME is not None:
+ return force_unicode(settings.FORCE_SCRIPT_NAME)
+
+ # If Apache's mod_rewrite had a whack at the URL, Apache set either
+ # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
+ # rewrites. Unfortunately not every webserver (lighttpd!) passes this
+ # information through all the time, so FORCE_SCRIPT_NAME, above, is still
+ # needed.
+ script_url = environ.get('SCRIPT_URL', u'')
+ if not script_url:
+ script_url = environ.get('REDIRECT_URL', u'')
+ if script_url:
+ return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
+ return force_unicode(environ.get('SCRIPT_NAME', u''))
+
diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py
index 332df6f54c..58699816fd 100644
--- a/django/core/handlers/modpython.py
+++ b/django/core/handlers/modpython.py
@@ -4,6 +4,7 @@ from pprint import pformat
from django import http
from django.core import signals
from django.core.handlers.base import BaseHandler
+from django.core.urlresolvers import set_script_prefix
from django.dispatch import dispatcher
from django.utils import datastructures
from django.utils.encoding import force_unicode, smart_str
@@ -15,7 +16,26 @@ from django.utils.encoding import force_unicode, smart_str
class ModPythonRequest(http.HttpRequest):
def __init__(self, req):
self._req = req
+ # FIXME: This isn't ideal. The request URI may be encoded (it's
+ # non-normalized) slightly differently to the "real" SCRIPT_NAME
+ # and PATH_INFO values. This causes problems when we compute path_info,
+ # below. For now, don't use script names that will be subject to
+ # encoding/decoding.
self.path = force_unicode(req.uri)
+ root = req.get_options().get('django.root', '')
+ self.django_root = root
+ # req.path_info isn't necessarily computed correctly in all
+ # circumstances (it's out of mod_python's control a bit), so we use
+ # req.uri and some string manipulations to get the right value.
+ if root and req.uri.startswith(root):
+ self.path_info = force_unicode(req.uri[len(root):])
+ else:
+ self.path_info = self.path
+ if not self.path_info:
+ # Django prefers empty paths to be '/', rather than '', to give us
+ # a common start character for URL patterns. So this is a little
+ # naughty, but also pretty harmless.
+ self.path_info = u'/'
def __repr__(self):
# Since this is called as part of error handling, we need to be very
@@ -100,7 +120,7 @@ class ModPythonRequest(http.HttpRequest):
'CONTENT_LENGTH': self._req.clength, # This may be wrong
'CONTENT_TYPE': self._req.content_type, # This may be wrong
'GATEWAY_INTERFACE': 'CGI/1.1',
- 'PATH_INFO': self._req.path_info,
+ 'PATH_INFO': self.path_info,
'PATH_TRANSLATED': None, # Not supported
'QUERY_STRING': self._req.args,
'REMOTE_ADDR': self._req.connection.remote_ip,
@@ -108,7 +128,7 @@ class ModPythonRequest(http.HttpRequest):
'REMOTE_IDENT': self._req.connection.remote_logname,
'REMOTE_USER': self._req.user,
'REQUEST_METHOD': self._req.method,
- 'SCRIPT_NAME': None, # Not supported
+ 'SCRIPT_NAME': self.django_root,
'SERVER_NAME': self._req.server.server_hostname,
'SERVER_PORT': self._req.server.port,
'SERVER_PROTOCOL': self._req.protocol,
@@ -153,6 +173,7 @@ class ModPythonHandler(BaseHandler):
if self._request_middleware is None:
self.load_middleware()
+ set_script_prefix(req.get_options().get('django.root', ''))
dispatcher.send(signal=signals.request_started)
try:
try:
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 795f139042..a1324936cd 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -7,7 +7,8 @@ except ImportError:
from django import http
from django.core import signals
-from django.core.handlers.base import BaseHandler
+from django.core.handlers import base
+from django.core.urlresolvers import set_script_prefix
from django.dispatch import dispatcher
from django.utils import datastructures
from django.utils.encoding import force_unicode
@@ -74,9 +75,20 @@ def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
class WSGIRequest(http.HttpRequest):
def __init__(self, environ):
+ script_name = base.get_script_name(environ)
+ path_info = force_unicode(environ.get('PATH_INFO', u'/'))
+ if not path_info:
+ # Sometimes PATH_INFO exists, but is empty (e.g. accessing
+ # the SCRIPT_NAME URL without a trailing slash). We really need to
+ # operate as if they'd requested '/'. Not amazingly nice to force
+ # the path like this, but should be harmless.
+ path_info = u'/'
self.environ = environ
- self.path = force_unicode(environ['PATH_INFO'])
+ self.path_info = path_info
+ self.path = '%s%s' % (script_name, path_info)
self.META = environ
+ self.META['PATH_INFO'] = path_info
+ self.META['SCRIPT_NAME'] = script_name
self.method = environ['REQUEST_METHOD'].upper()
def __repr__(self):
@@ -178,7 +190,7 @@ class WSGIRequest(http.HttpRequest):
REQUEST = property(_get_request)
raw_post_data = property(_get_raw_post_data)
-class WSGIHandler(BaseHandler):
+class WSGIHandler(base.BaseHandler):
initLock = Lock()
request_class = WSGIRequest
@@ -194,6 +206,7 @@ class WSGIHandler(BaseHandler):
self.load_middleware()
self.initLock.release()
+ set_script_prefix(base.get_script_name(environ))
dispatcher.send(signal=signals.request_started)
try:
try:
diff --git a/django/core/mail.py b/django/core/mail.py
index b60757366f..d6c6eea190 100644
--- a/django/core/mail.py
+++ b/django/core/mail.py
@@ -71,10 +71,11 @@ class BadHeaderError(ValueError):
def forbid_multi_line_headers(name, val):
"""Forbids multi-line headers, to prevent header injection."""
+ val = force_unicode(val)
if '\n' in val or '\r' in val:
raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
try:
- val = force_unicode(val).encode('ascii')
+ val = val.encode('ascii')
except UnicodeEncodeError:
if name.lower() in ('to', 'from', 'cc'):
result = []
@@ -84,7 +85,7 @@ def forbid_multi_line_headers(name, val):
result.append(formataddr((nm, str(addr))))
val = ', '.join(result)
else:
- val = Header(force_unicode(val), settings.DEFAULT_CHARSET)
+ val = Header(val, settings.DEFAULT_CHARSET)
return name, val
class SafeMIMEText(MIMEText):
@@ -174,7 +175,7 @@ class SMTPConnection(object):
def _send(self, email_message):
"""A helper method that does the actual sending."""
- if not email_message.to:
+ if not email_message.recipients():
return False
try:
self.connection.sendmail(email_message.from_email,
diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py
index 7a189a426a..f0975ca6c1 100644
--- a/django/core/management/commands/compilemessages.py
+++ b/django/core/management/commands/compilemessages.py
@@ -1,8 +1,7 @@
import os
import sys
from optparse import make_option
-from django.core.management.base import BaseCommand
-from django.core.management.color import no_style
+from django.core.management.base import BaseCommand, CommandError
try:
set
diff --git a/django/core/management/commands/test.py b/django/core/management/commands/test.py
index f0e13a2069..ef7b197b00 100644
--- a/django/core/management/commands/test.py
+++ b/django/core/management/commands/test.py
@@ -17,7 +17,6 @@ class Command(BaseCommand):
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)
diff --git a/django/core/management/commands/testserver.py b/django/core/management/commands/testserver.py
index 9b169d3d9b..b409bc91d1 100644
--- a/django/core/management/commands/testserver.py
+++ b/django/core/management/commands/testserver.py
@@ -17,7 +17,6 @@ class Command(BaseCommand):
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
diff --git a/django/core/management/sql.py b/django/core/management/sql.py
index 0b01edcfc9..7c17807130 100644
--- a/django/core/management/sql.py
+++ b/django/core/management/sql.py
@@ -181,7 +181,7 @@ def sql_delete(app, style):
for model in app_models:
opts = model._meta
for f in opts.local_many_to_many:
- if isinstance(f.rel, generic.GenericRel):
+ if not f.creates_table:
continue
if cursor and table_name_converter(f.m2m_db_table()) in table_names:
output.append("%s %s;" % (style.SQL_KEYWORD('DROP TABLE'),
@@ -353,7 +353,7 @@ def many_to_many_sql_for_model(model, style):
qn = connection.ops.quote_name
inline_references = connection.features.inline_fk_references
for f in opts.local_many_to_many:
- if not isinstance(f.rel, generic.GenericRel):
+ if f.creates_table:
tablespace = f.db_tablespace or opts.db_tablespace
if tablespace and connection.features.supports_tablespaces:
tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace, inline=True)
@@ -435,12 +435,12 @@ def custom_sql_for_model(model, style):
output = []
# Post-creation SQL should come before any initial SQL data is loaded.
- # However, this should not be done for fields that are part of a
- # a parent model (via model inheritance).
+ # However, this should not be done for fields that are part of a a parent
+ # model (via model inheritance).
nm = opts.init_name_map()
- post_sql_fields = [f for f in opts.fields if nm[f.name][1] is None and hasattr(f, '_post_create_sql')]
+ post_sql_fields = [f for f in opts.local_fields if hasattr(f, 'post_create_sql')]
for f in post_sql_fields:
- output.extend(f._post_create_sql(style, model._meta.db_table))
+ output.extend(f.post_create_sql(style, model._meta.db_table))
# Some backends can't execute more than one SQL statement at a time,
# so split into separate statements.
diff --git a/django/core/management/validation.py b/django/core/management/validation.py
index e17409ae5d..e9d7b53027 100644
--- a/django/core/management/validation.py
+++ b/django/core/management/validation.py
@@ -102,6 +102,7 @@ def get_validation_errors(outfile, app=None):
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))
+ seen_intermediary_signatures = []
for i, f in enumerate(opts.local_many_to_many):
# Check to see if the related m2m field will clash with any
# existing fields, m2m fields, m2m related objects or related
@@ -112,7 +113,49 @@ def get_validation_errors(outfile, app=None):
# so skip the next section
if isinstance(f.rel.to, (str, unicode)):
continue
-
+ if getattr(f.rel, 'through', None) is not None:
+ if hasattr(f.rel, 'through_model'):
+ from_model, to_model = cls, f.rel.to
+ if from_model == to_model and f.rel.symmetrical:
+ e.add(opts, "Many-to-many fields with intermediate tables cannot be symmetrical.")
+ seen_from, seen_to, seen_self = False, False, 0
+ for inter_field in f.rel.through_model._meta.fields:
+ rel_to = getattr(inter_field.rel, 'to', None)
+ if from_model == to_model: # relation to self
+ if rel_to == from_model:
+ seen_self += 1
+ if seen_self > 2:
+ e.add(opts, "Intermediary model %s has more than two foreign keys to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, from_model._meta.object_name))
+ else:
+ if rel_to == from_model:
+ if seen_from:
+ e.add(opts, "Intermediary model %s has more than one foreign key to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, rel_from._meta.object_name))
+ else:
+ seen_from = True
+ elif rel_to == to_model:
+ if seen_to:
+ e.add(opts, "Intermediary model %s has more than one foreign key to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, rel_to._meta.object_name))
+ else:
+ seen_to = True
+ if f.rel.through_model not in models.get_models():
+ e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed." % (f.name, f.rel.through))
+ signature = (f.rel.to, cls, f.rel.through_model)
+ if signature in seen_intermediary_signatures:
+ e.add(opts, "The model %s has two manually-defined m2m relations through the model %s, which is not permitted. Please consider using an extra field on your intermediary model instead." % (cls._meta.object_name, f.rel.through_model._meta.object_name))
+ else:
+ seen_intermediary_signatures.append(signature)
+ seen_related_fk, seen_this_fk = False, False
+ for field in f.rel.through_model._meta.fields:
+ if field.rel:
+ if not seen_related_fk and field.rel.to == f.rel.to:
+ seen_related_fk = True
+ elif field.rel.to == cls:
+ seen_this_fk = True
+ if not seen_related_fk or not seen_this_fk:
+ e.add(opts, "'%s' has a manually-defined m2m relation through model %s, which does not have foreign keys to %s and %s" % (f.name, f.rel.through, f.rel.to._meta.object_name, cls._meta.object_name))
+ else:
+ e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed" % (f.name, f.rel.through))
+
rel_opts = f.rel.to._meta
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()
rel_query_name = f.related_query_name()
diff --git a/django/core/paginator.py b/django/core/paginator.py
index 439b0bc717..495cdf2d76 100644
--- a/django/core/paginator.py
+++ b/django/core/paginator.py
@@ -1,3 +1,5 @@
+from math import ceil
+
class InvalidPage(Exception):
pass
@@ -42,10 +44,12 @@ class Paginator(object):
def _get_count(self):
"Returns the total number of objects, across all pages."
if self._count is None:
- from django.db.models.query import QuerySet
- if isinstance(self.object_list, QuerySet):
+ try:
self._count = self.object_list.count()
- else:
+ except (AttributeError, TypeError):
+ # AttributeError if object_list has no count() method.
+ # TypeError if object_list.count() requires arguments
+ # (i.e. is of type list).
self._count = len(self.object_list)
return self._count
count = property(_get_count)
@@ -53,13 +57,11 @@ class Paginator(object):
def _get_num_pages(self):
"Returns the total number of pages."
if self._num_pages is None:
- hits = self.count - 1 - self.orphans
- if hits < 1:
- hits = 0
- if hits == 0 and not self.allow_empty_first_page:
+ if self.count == 0 and not self.allow_empty_first_page:
self._num_pages = 0
else:
- self._num_pages = hits // self.per_page + 1
+ hits = max(1, self.count - self.orphans)
+ self._num_pages = int(ceil(hits / float(self.per_page)))
return self._num_pages
num_pages = property(_get_num_pages)
@@ -102,6 +104,9 @@ class Page(object):
Returns the 1-based index of the first object on this page,
relative to total objects in the paginator.
"""
+ # Special case, return zero if no items.
+ if self.paginator.count == 0:
+ return 0
return (self.paginator.per_page * (self.number - 1)) + 1
def end_index(self):
@@ -109,82 +114,7 @@ class Page(object):
Returns the 1-based index of the last object on this page,
relative to total objects found (hits).
"""
+ # Special case for the last page because there can be orphans.
if self.number == self.paginator.num_pages:
return self.paginator.count
return self.number * self.paginator.per_page
-
-class ObjectPaginator(Paginator):
- """
- Legacy ObjectPaginator class, for backwards compatibility.
-
- Note that each method on this class that takes page_number expects a
- zero-based page number, whereas the new API (Paginator/Page) uses one-based
- page numbers.
- """
- def __init__(self, query_set, num_per_page, orphans=0):
- Paginator.__init__(self, query_set, num_per_page, orphans)
- import warnings
- warnings.warn("The ObjectPaginator is deprecated. Use django.core.paginator.Paginator instead.", DeprecationWarning)
-
- # Keep these attributes around for backwards compatibility.
- self.query_set = query_set
- self.num_per_page = num_per_page
- self._hits = self._pages = None
-
- def validate_page_number(self, page_number):
- try:
- page_number = int(page_number) + 1
- except ValueError:
- raise PageNotAnInteger
- return self.validate_number(page_number)
-
- def get_page(self, page_number):
- try:
- page_number = int(page_number) + 1
- except ValueError:
- raise PageNotAnInteger
- return self.page(page_number).object_list
-
- def has_next_page(self, page_number):
- return page_number < self.pages - 1
-
- def has_previous_page(self, page_number):
- return page_number > 0
-
- def first_on_page(self, page_number):
- """
- Returns the 1-based index of the first object on the given page,
- relative to total objects found (hits).
- """
- page_number = self.validate_page_number(page_number)
- return (self.num_per_page * (page_number - 1)) + 1
-
- def last_on_page(self, page_number):
- """
- Returns the 1-based index of the last object on the given page,
- relative to total objects found (hits).
- """
- page_number = self.validate_page_number(page_number)
- if page_number == self.num_pages:
- return self.count
- return page_number * self.num_per_page
-
- def _get_count(self):
- # The old API allowed for self.object_list to be either a QuerySet or a
- # list. Here, we handle both.
- if self._count is None:
- try:
- self._count = self.object_list.count()
- except (AttributeError, TypeError):
- # AttributeError if object_list has no count() method.
- # TypeError if object_list.count() requires arguments
- # (i.e. is of type list).
- self._count = len(self.object_list)
- return self._count
- count = property(_get_count)
-
- # The old API called it "hits" instead of "count".
- hits = count
-
- # The old API called it "pages" instead of "num_pages".
- pages = Paginator.num_pages
diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
index f6943e543e..bfd785a6fe 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -2,10 +2,8 @@
Module for abstract serializer/unserializer base classes.
"""
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
+from StringIO import StringIO
+
from django.db import models
from django.utils.encoding import smart_str, smart_unicode
from django.utils import datetime_safe
diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py
index a84206a0fe..97e5bc9b26 100644
--- a/django/core/serializers/json.py
+++ b/django/core/serializers/json.py
@@ -3,14 +3,13 @@ Serialize data to/from JSON
"""
import datetime
-from django.utils import simplejson
+from StringIO import StringIO
+
from django.core.serializers.python import Serializer as PythonSerializer
from django.core.serializers.python import Deserializer as PythonDeserializer
from django.utils import datetime_safe
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
+from django.utils import simplejson
+
try:
import decimal
except ImportError:
diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py
index 58cf59bed9..ac77166a2f 100644
--- a/django/core/serializers/pyyaml.py
+++ b/django/core/serializers/pyyaml.py
@@ -4,14 +4,12 @@ YAML serializer.
Requires PyYaml (http://pyyaml.org/), but that's checked for in __init__.
"""
+from StringIO import StringIO
+import yaml
+
from django.db import models
from django.core.serializers.python import Serializer as PythonSerializer
from django.core.serializers.python import Deserializer as PythonDeserializer
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-import yaml
class Serializer(PythonSerializer):
"""
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index ff0bcbcfea..4ec725cb38 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -7,11 +7,13 @@ a string) and returns a tuple in this format:
(view_function, function_args, function_kwargs)
"""
+import re
+
from django.http import Http404
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
from django.utils.encoding import iri_to_uri, force_unicode, smart_str
from django.utils.functional import memoize
-import re
+from django.utils.thread_support import currentThread
try:
reversed
@@ -21,6 +23,11 @@ except NameError:
_resolver_cache = {} # Maps urlconf modules to RegexURLResolver instances.
_callable_cache = {} # Maps view and url pattern names to their view functions.
+# SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for
+# the current thread (which is the only one we ever access), it is assumed to
+# be empty.
+_prefixes = {}
+
class Resolver404(Http404):
pass
@@ -291,13 +298,33 @@ class RegexURLResolver(object):
def resolve(path, urlconf=None):
return get_resolver(urlconf).resolve(path)
-def reverse(viewname, urlconf=None, args=None, kwargs=None):
+def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None):
args = args or []
kwargs = kwargs or {}
- return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs))
+ if prefix is None:
+ prefix = get_script_prefix()
+ return iri_to_uri(u'%s%s' % (prefix, get_resolver(urlconf).reverse(viewname,
+ *args, **kwargs)))
def clear_url_caches():
global _resolver_cache
global _callable_cache
_resolver_cache.clear()
_callable_cache.clear()
+
+def set_script_prefix(prefix):
+ """
+ Sets the script prefix for the current thread.
+ """
+ if not prefix.endswith('/'):
+ prefix += '/'
+ _prefixes[currentThread()] = prefix
+
+def get_script_prefix():
+ """
+ Returns the currently active script prefix. Useful for client code that
+ wishes to construct their own URLs manually (although accessing the request
+ instance is normally going to be a lot cleaner).
+ """
+ return _prefixes.get(currentThread(), u'/')
+
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 899a779673..d65eacd042 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -5,6 +5,9 @@ except ImportError:
# Import copy of _thread_local.py from Python 2.4
from django.utils._threading_local import local
+from django.db.backends import util
+from django.utils import datetime_safe
+
class BaseDatabaseWrapper(local):
"""
Represents a database connection.
@@ -36,12 +39,13 @@ class BaseDatabaseWrapper(local):
return cursor
def make_debug_cursor(self, cursor):
- from django.db.backends import util
return util.CursorDebugWrapper(cursor, self)
class BaseDatabaseFeatures(object):
allows_group_by_ordinal = True
inline_fk_references = True
+ # True if django.db.backend.utils.typecast_timestamp is used on values
+ # returned from dates() calls.
needs_datetime_string_cast = True
supports_constraints = True
supports_tablespaces = False
@@ -49,10 +53,7 @@ class BaseDatabaseFeatures(object):
uses_custom_query_class = False
empty_fetchmany_value = []
update_can_self_select = True
- supports_usecs = True
- time_field_needs_date = False
interprets_empty_strings_as_nulls = False
- date_field_supports_time_value = True
can_use_chunked_reads = True
class BaseDatabaseOperations(object):
@@ -263,3 +264,64 @@ class BaseDatabaseOperations(object):
"""Prepares a value for use in a LIKE query."""
from django.utils.encoding import smart_unicode
return smart_unicode(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
+
+ def value_to_db_date(self, value):
+ """
+ Transform a date value to an object compatible with what is expected
+ by the backend driver for date columns.
+ """
+ if value is None:
+ return None
+ return datetime_safe.new_date(value).strftime('%Y-%m-%d')
+
+ def value_to_db_datetime(self, value):
+ """
+ Transform a datetime value to an object compatible with what is expected
+ by the backend driver for datetime columns.
+ """
+ if value is None:
+ return None
+ return unicode(value)
+
+ def value_to_db_time(self, value):
+ """
+ Transform a datetime value to an object compatible with what is expected
+ by the backend driver for time columns.
+ """
+ if value is None:
+ return None
+ return unicode(value)
+
+ def value_to_db_decimal(self, value, max_digits, decimal_places):
+ """
+ Transform a decimal.Decimal value to an object compatible with what is
+ expected by the backend driver for decimal (numeric) columns.
+ """
+ if value is None:
+ return None
+ return util.format_number(value, max_digits, decimal_places)
+
+ def year_lookup_bounds(self, value):
+ """
+ Returns a two-elements list with the lower and upper bound to be used
+ with a BETWEEN operator to query a field value using a year lookup
+
+ `value` is an int, containing the looked-up year.
+ """
+ first = '%s-01-01 00:00:00'
+ second = '%s-12-31 23:59:59.999999'
+ return [first % value, second % value]
+
+ def year_lookup_bounds_for_date_field(self, value):
+ """
+ Returns a two-elements list with the lower and upper bound to be used
+ with a BETWEEN operator to query a DateField value using a year lookup
+
+ `value` is an int, containing the looked-up year.
+
+ By default, it just calls `self.year_lookup_bounds`. Some backends need
+ this hook because on their DB date fields can't be compared to values
+ which include a time part.
+ """
+ return self.year_lookup_bounds(value)
+
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 74138a7b11..3b8d897925 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -63,7 +63,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
inline_fk_references = False
empty_fetchmany_value = ()
update_can_self_select = False
- supports_usecs = False
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
@@ -124,6 +123,24 @@ class DatabaseOperations(BaseDatabaseOperations):
else:
return []
+ def value_to_db_datetime(self, value):
+ # MySQL doesn't support microseconds
+ if value is None:
+ return None
+ return unicode(value.replace(microsecond=0))
+
+ def value_to_db_time(self, value):
+ # MySQL doesn't support microseconds
+ if value is None:
+ return None
+ return unicode(value.replace(microsecond=0))
+
+ def year_lookup_bounds(self, value):
+ # Again, no microseconds
+ first = '%s-01-01 00:00:00'
+ second = '%s-12-31 23:59:59.99'
+ return [first % value, second % value]
+
class DatabaseWrapper(BaseDatabaseWrapper):
features = DatabaseFeatures()
ops = DatabaseOperations()
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index a41084bca3..bdb73b1864 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -5,10 +5,11 @@ Requires cx_Oracle: http://www.python.net/crew/atuining/cx_Oracle/
"""
import os
+import datetime
+import time
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util
from django.db.backends.oracle import query
-from django.utils.datastructures import SortedDict
from django.utils.encoding import smart_str, force_unicode
# Oracle takes client-side character set encoding from the environment.
@@ -29,9 +30,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_tablespaces = True
uses_case_insensitive_names = True
uses_custom_query_class = True
- time_field_needs_date = True
interprets_empty_strings_as_nulls = True
- date_field_supports_time_value = False
class DatabaseOperations(BaseDatabaseOperations):
def autoinc_sql(self, table, column):
@@ -181,6 +180,21 @@ class DatabaseOperations(BaseDatabaseOperations):
def tablespace_sql(self, tablespace, inline=False):
return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), self.quote_name(tablespace))
+ def value_to_db_time(self, value):
+ if value is None:
+ return None
+ if isinstance(value, basestring):
+ return datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6]))
+ return datetime.datetime(1900, 1, 1, value.hour, value.minute,
+ value.second, value.microsecond)
+
+ def year_lookup_bounds_for_date_field(self, value):
+ first = '%s-01-01'
+ second = '%s-12-31'
+ return [first % value, second % value]
+
+
+
class DatabaseWrapper(BaseDatabaseWrapper):
features = DatabaseFeatures()
ops = DatabaseOperations()
@@ -245,10 +259,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
class OracleParam(object):
"""
- Wrapper object for formatting parameters for Oracle. If the string
- representation of the value is large enough (greater than 4000 characters)
+ Wrapper object for formatting parameters for Oracle. If the string
+ representation of the value is large enough (greater than 4000 characters)
the input size needs to be set as NCLOB. Alternatively, if the parameter has
- an `input_size` attribute, then the value of the `input_size` attribute will
+ an `input_size` attribute, then the value of the `input_size` attribute will
be used instead. Otherwise, no input size will be set for the parameter when
executing the query.
"""
@@ -282,7 +296,7 @@ class FormatStylePlaceholderCursor(Database.Cursor):
return result
else:
return tuple([OracleParam(p, self.charset, True) for p in params])
-
+
def _guess_input_sizes(self, params_list):
if isinstance(params_list[0], dict):
sizes = {}
@@ -303,7 +317,7 @@ class FormatStylePlaceholderCursor(Database.Cursor):
return dict([(k, p.smart_str) for k, p in params.iteritems()])
else:
return [p.smart_str for p in params]
-
+
def execute(self, query, params=None):
if params is None:
params = []
diff --git a/django/db/backends/oracle/query.py b/django/db/backends/oracle/query.py
index 7e50c7b5db..49e1c4131c 100644
--- a/django/db/backends/oracle/query.py
+++ b/django/db/backends/oracle/query.py
@@ -87,9 +87,11 @@ def query_class(QueryClass, Database):
If 'with_limits' is False, any limit/offset information is not
included in the query.
"""
+
# The `do_offset` flag indicates whether we need to construct
# the SQL needed to use limit/offset w/Oracle.
- do_offset = with_limits and (self.high_mark or self.low_mark)
+ do_offset = with_limits and (self.high_mark is not None
+ or self.low_mark)
# If no offsets, just return the result of the base class
# `as_sql`.
@@ -117,7 +119,7 @@ def query_class(QueryClass, Database):
# Getting the selection SQL and the params, which has the `rn`
# extra selection SQL.
self.extra_select['rn'] = 'ROW_NUMBER() OVER (ORDER BY %s )' % rn_orderby
- sql, params= super(OracleQuery, self).as_sql(with_limits=False,
+ sql, params = super(OracleQuery, self).as_sql(with_limits=False,
with_col_aliases=True)
# Constructing the result SQL, using the initial select SQL
@@ -126,7 +128,7 @@ def query_class(QueryClass, Database):
# Place WHERE condition on `rn` for the desired range.
result.append('WHERE rn > %d' % self.low_mark)
- if self.high_mark:
+ if self.high_mark is not None:
result.append('AND rn <= %d' % self.high_mark)
# Returning the SQL w/params.
@@ -148,4 +150,3 @@ def query_class(QueryClass, Database):
_classes[QueryClass] = OracleQuery
return OracleQuery
-
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 48d9ad4c4b..71be86f00b 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -84,6 +84,12 @@ class DatabaseOperations(BaseDatabaseOperations):
# sql_flush() implementations). Just return SQL at this point
return sql
+ def year_lookup_bounds(self, value):
+ first = '%s-01-01'
+ second = '%s-12-31 23:59:59.999999'
+ return [first % value, second % value]
+
+
class DatabaseWrapper(BaseDatabaseWrapper):
features = DatabaseFeatures()
ops = DatabaseOperations()
@@ -159,7 +165,7 @@ def _sqlite_extract(lookup_type, dt):
dt = util.typecast_timestamp(dt)
except (ValueError, TypeError):
return None
- return str(getattr(dt, lookup_type))
+ return getattr(dt, lookup_type)
def _sqlite_date_trunc(lookup_type, dt):
try:
diff --git a/django/db/backends/util.py b/django/db/backends/util.py
index 367072879e..7228b4046b 100644
--- a/django/db/backends/util.py
+++ b/django/db/backends/util.py
@@ -1,7 +1,8 @@
import datetime
-import md5
from time import time
+from django.utils.hashcompat import md5_constructor
+
try:
import decimal
except ImportError:
@@ -114,6 +115,13 @@ def truncate_name(name, length=None):
if length is None or len(name) <= length:
return name
- hash = md5.md5(name).hexdigest()[:4]
+ hash = md5_constructor(name).hexdigest()[:4]
return '%s%s' % (name[:length-4], hash)
+
+def format_number(value, max_digits, decimal_places):
+ """
+ Formats a number into a string with the requisite number of digits and
+ decimal places.
+ """
+ return u"%.*f" % (decimal_places, value)
diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py
index bd6cc3542d..18c47e86f3 100644
--- a/django/db/models/__init__.py
+++ b/django/db/models/__init__.py
@@ -10,8 +10,6 @@ from django.db.models.fields import *
from django.db.models.fields.subclassing import SubfieldBase
from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED
from django.db.models import signals
-from django.utils.functional import curry
-from django.utils.text import capfirst
# Admin stages.
ADD, CHANGE, BOTH = 1, 2, 3
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 080e0af588..7d7def3bad 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -12,7 +12,7 @@ import django.db.models.manipulators # Imported to register signal handler.
import django.db.models.manager # Ditto.
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
-from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
+from django.db.models.fields import AutoField, ImageField
from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
from django.db.models.query import delete_objects, Q, CollectedObjects
from django.db.models.options import Options
@@ -20,7 +20,6 @@ from django.db import connection, transaction
from django.db.models import signals
from django.db.models.loading import register_models, get_model
from django.dispatch import dispatcher
-from django.utils.datastructures import SortedDict
from django.utils.functional import curry
from django.utils.encoding import smart_str, force_unicode, smart_unicode
from django.core.files.move import file_move_safe
@@ -201,6 +200,7 @@ class Model(object):
# keywords, or default.
for field in fields_iter:
+ rel_obj = None
if kwargs:
if isinstance(field.rel, ManyToOneRel):
try:
@@ -217,17 +217,18 @@ class Model(object):
# pass in "None" for related objects if it's allowed.
if rel_obj is None and field.null:
val = None
- else:
- try:
- val = getattr(rel_obj, field.rel.get_related_field().attname)
- except AttributeError:
- raise TypeError("Invalid value: %r should be a %s instance, not a %s" %
- (field.name, field.rel.to, type(rel_obj)))
else:
val = kwargs.pop(field.attname, field.get_default())
else:
val = field.get_default()
- setattr(self, field.attname, val)
+ # If we got passed a related instance, set it using the field.name
+ # instead of field.attname (e.g. "user" instead of "user_id") so
+ # that the object gets properly cached (and type checked) by the
+ # RelatedObjectDescriptor.
+ if rel_obj:
+ setattr(self, field.name, rel_obj)
+ else:
+ setattr(self, field.attname, val)
if kwargs:
for prop in kwargs.keys():
@@ -299,6 +300,12 @@ class Model(object):
# attributes we have been given to the class we have been given.
if not raw:
for parent, field in meta.parents.items():
+ # At this point, parent's primary key field may be unknown
+ # (for example, from administration form which doesn't fill
+ # this field). If so, fill it.
+ if getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None:
+ setattr(self, parent._meta.pk.attname, getattr(self, field.attname))
+
self.save_base(raw, parent)
setattr(self, field.attname, self._get_pk_val(parent._meta))
@@ -472,11 +479,12 @@ class Model(object):
return os.path.getsize(self._get_FIELD_filename(field))
def _save_FIELD_file(self, field, filename, raw_field, save=True):
- directory = field.get_directory_name()
- try: # Create the date-based directory if it doesn't exist.
- os.makedirs(os.path.join(settings.MEDIA_ROOT, directory))
- except OSError: # Directory probably already exists.
- pass
+ # Create the upload directory if it doesn't already exist
+ directory = os.path.join(settings.MEDIA_ROOT, field.get_directory_name())
+ if not os.path.exists(directory):
+ os.makedirs(directory)
+ elif not os.path.isdir(directory):
+ raise IOError('%s exists and is not a directory' % directory)
# Check for old-style usage (files-as-dictionaries). Warn here first
# since there are multiple locations where we need to support both new
@@ -494,7 +502,7 @@ class Model(object):
elif isinstance(raw_field, basestring):
import warnings
warnings.warn(
- message = "Representing uploaded files as dictionaries is deprecated. Use django.core.files.uploadedfile.SimpleUploadedFile instead.",
+ message = "Representing uploaded files as strings is deprecated. Use django.core.files.uploadedfile.SimpleUploadedFile instead.",
category = DeprecationWarning,
stacklevel = 2
)
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 78f75aea35..494c42cc54 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -22,7 +22,6 @@ from django.utils.itercompat import tee
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.encoding import smart_unicode, force_unicode, smart_str
-from django.utils.maxlength import LegacyMaxlength
from django.utils import datetime_safe
class NOT_PROVIDED:
@@ -62,10 +61,6 @@ def manipulator_validator_unique(f, opts, self, field_data, all_data):
# getattr(obj, opts.pk.attname)
class Field(object):
- # Provide backwards compatibility for the maxlength attribute and
- # argument for this class and all subclasses.
- __metaclass__ = LegacyMaxlength
-
# Designates whether empty strings fundamentally are allowed at the
# database level.
empty_strings_allowed = True
@@ -191,7 +186,8 @@ class Field(object):
def set_attributes_from_name(self, name):
self.name = name
self.attname, self.column = self.get_attname_column()
- self.verbose_name = self.verbose_name or (name and name.replace('_', ' '))
+ if self.verbose_name is None and name:
+ self.verbose_name = name.replace('_', ' ')
def contribute_to_class(self, cls, name):
self.set_attributes_from_name(name)
@@ -217,19 +213,30 @@ class Field(object):
"Returns field's value just before saving."
return getattr(model_instance, self.attname)
+ def get_db_prep_value(self, value):
+ """Returns field's value prepared for interacting with the database
+ backend.
+
+ Used by the default implementations of ``get_db_prep_save``and
+ `get_db_prep_lookup```
+ """
+ return value
+
def get_db_prep_save(self, value):
"Returns field's value prepared for saving into a database."
- return value
+ return self.get_db_prep_value(value)
def get_db_prep_lookup(self, lookup_type, value):
"Returns field's value prepared for database lookup."
if hasattr(value, 'as_sql'):
sql, params = value.as_sql()
return QueryWrapper(('(%s)' % sql), params)
- if lookup_type in ('exact', 'regex', 'iregex', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search'):
+ if lookup_type in ('regex', 'iregex', 'month', 'day', 'search'):
return [value]
+ elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte'):
+ return [self.get_db_prep_value(value)]
elif lookup_type in ('range', 'in'):
- return value
+ return [self.get_db_prep_value(v) for v in value]
elif lookup_type in ('contains', 'icontains'):
return ["%%%s%%" % connection.ops.prep_for_like_query(value)]
elif lookup_type == 'iexact':
@@ -245,19 +252,12 @@ class Field(object):
value = int(value)
except ValueError:
raise ValueError("The __year lookup type requires an integer argument")
- if settings.DATABASE_ENGINE == 'sqlite3':
- first = '%s-01-01'
- second = '%s-12-31 23:59:59.999999'
- elif not connection.features.date_field_supports_time_value and self.get_internal_type() == 'DateField':
- first = '%s-01-01'
- second = '%s-12-31'
- elif not connection.features.supports_usecs:
- first = '%s-01-01 00:00:00'
- second = '%s-12-31 23:59:59.99'
+
+ if self.get_internal_type() == 'DateField':
+ return connection.ops.year_lookup_bounds_for_date_field(value)
else:
- first = '%s-01-01 00:00:00'
- second = '%s-12-31 23:59:59.999999'
- return [first % value, second % value]
+ return connection.ops.year_lookup_bounds(value)
+
raise TypeError("Field has invalid lookup: %s" % lookup_type)
def has_default(self):
@@ -288,7 +288,7 @@ class Field(object):
if self.choices:
field_objs = [oldforms.SelectField]
- params['choices'] = self.flatchoices
+ params['choices'] = self.get_flatchoices()
else:
field_objs = self.get_manipulator_field_objs()
return (field_objs, params)
@@ -362,7 +362,8 @@ class Field(object):
return val
def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
- "Returns a list of tuples used as SelectField choices for this field."
+ """Returns choices with a default blank choices included, for use
+ as SelectField choices for this field."""
first_choice = include_blank and blank_choice or []
if self.choices:
return first_choice + list(self.choices)
@@ -376,6 +377,11 @@ class Field(object):
def get_choices_default(self):
return self.get_choices()
+ def get_flatchoices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
+ "Returns flattened choices with a default blank choice included."
+ first_choice = include_blank and blank_choice or []
+ return first_choice + list(self.flatchoices)
+
def _get_val_from_obj(self, obj):
if obj:
return getattr(obj, self.attname)
@@ -408,15 +414,16 @@ class Field(object):
choices = property(_get_choices)
def _get_flatchoices(self):
+ """Flattened version of choices tuple."""
flat = []
- for choice, value in self.get_choices_default():
+ for choice, value in self.choices:
if type(value) in (list, tuple):
flat.extend(value)
else:
flat.append((choice,value))
return flat
flatchoices = property(_get_flatchoices)
-
+
def save_form_data(self, instance, data):
setattr(instance, self.name, data)
@@ -449,6 +456,11 @@ class AutoField(Field):
except (TypeError, ValueError):
raise validators.ValidationError, _("This value must be an integer.")
+ def get_db_prep_value(self, value):
+ if value is None:
+ return None
+ return int(value)
+
def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
if not rel:
return [] # Don't add a FormField unless it's in a related context.
@@ -477,6 +489,8 @@ class AutoField(Field):
class BooleanField(Field):
def __init__(self, *args, **kwargs):
kwargs['blank'] = True
+ if 'default' not in kwargs and not kwargs.get('null'):
+ kwargs['default'] = False
Field.__init__(self, *args, **kwargs)
def get_internal_type(self):
@@ -488,6 +502,11 @@ class BooleanField(Field):
if value in ('f', 'False', '0'): return False
raise validators.ValidationError, _("This value must be either True or False.")
+ def get_db_prep_value(self, value):
+ if value is None:
+ return None
+ return bool(value)
+
def get_manipulator_field_objs(self):
return [oldforms.CheckboxField]
@@ -549,15 +568,6 @@ class DateField(Field):
except ValueError:
raise validators.ValidationError, _('Enter a valid date in YYYY-MM-DD format.')
- def get_db_prep_lookup(self, lookup_type, value):
- if lookup_type in ('range', 'in'):
- value = [smart_unicode(v) for v in value]
- elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'):
- value = datetime_safe.new_date(value).strftime('%Y-%m-%d')
- else:
- value = smart_unicode(value)
- return Field.get_db_prep_lookup(self, lookup_type, value)
-
def pre_save(self, model_instance, add):
if self.auto_now or (self.auto_now_add and add):
value = datetime.datetime.now()
@@ -581,16 +591,9 @@ class DateField(Field):
else:
return self.editable or self.auto_now or self.auto_now_add
- def get_db_prep_save(self, value):
- # Casts dates into string format for entry into database.
- if value is not None:
- try:
- value = datetime_safe.new_date(value).strftime('%Y-%m-%d')
- except AttributeError:
- # If value is already a string it won't have a strftime method,
- # so we'll just let it pass through.
- pass
- return Field.get_db_prep_save(self, value)
+ def get_db_prep_value(self, value):
+ # Casts dates into the format expected by the backend
+ return connection.ops.value_to_db_date(self.to_python(value))
def get_manipulator_field_objs(self):
return [oldforms.DateField]
@@ -619,33 +622,37 @@ class DateTimeField(DateField):
return value
if isinstance(value, datetime.date):
return datetime.datetime(value.year, value.month, value.day)
+
+ # Attempt to parse a datetime:
+ value = smart_str(value)
+ # split usecs, because they are not recognized by strptime.
+ if '.' in value:
+ try:
+ value, usecs = value.split('.')
+ usecs = int(usecs)
+ except ValueError:
+ raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format.')
+ else:
+ usecs = 0
+ kwargs = {'microsecond': usecs}
try: # Seconds are optional, so try converting seconds first.
- return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6])
+ return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6],
+ **kwargs)
+
except ValueError:
try: # Try without seconds.
- return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5])
+ return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5],
+ **kwargs)
except ValueError: # Try without hour/minutes/seconds.
try:
- return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3])
+ return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3],
+ **kwargs)
except ValueError:
- raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM format.')
+ raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[ss[.uuuuuu]] format.')
- def get_db_prep_save(self, value):
- # Casts dates into string format for entry into database.
- if value is not None:
- # MySQL will throw a warning if microseconds are given, because it
- # doesn't support microseconds.
- if not connection.features.supports_usecs and hasattr(value, 'microsecond'):
- value = value.replace(microsecond=0)
- value = smart_unicode(value)
- return Field.get_db_prep_save(self, value)
-
- def get_db_prep_lookup(self, lookup_type, value):
- if lookup_type in ('range', 'in'):
- value = [smart_unicode(v) for v in value]
- else:
- value = smart_unicode(value)
- return Field.get_db_prep_lookup(self, lookup_type, value)
+ def get_db_prep_value(self, value):
+ # Casts dates into the format expected by the backend
+ return connection.ops.value_to_db_datetime(self.to_python(value))
def get_manipulator_field_objs(self):
return [oldforms.DateField, oldforms.TimeField]
@@ -710,26 +717,18 @@ class DecimalField(Field):
Formats a number into a string with the requisite number of digits and
decimal places.
"""
- num_chars = self.max_digits
- # Allow for a decimal point
- if self.decimal_places > 0:
- num_chars += 1
- # Allow for a minus sign
- if value < 0:
- num_chars += 1
-
- return u"%.*f" % (self.decimal_places, value)
-
- def get_db_prep_save(self, value):
- value = self._format(value)
- return super(DecimalField, self).get_db_prep_save(value)
+ # Method moved to django.db.backends.util.
+ #
+ # It is preserved because it is used by the oracle backend
+ # (django.db.backends.oracle.query), and also for
+ # backwards-compatibility with any external code which may have used
+ # this method.
+ from django.db.backends import util
+ return util.format_number(value, self.max_digits, self.decimal_places)
- def get_db_prep_lookup(self, lookup_type, value):
- if lookup_type in ('range', 'in'):
- value = [self._format(v) for v in value]
- else:
- value = self._format(value)
- return super(DecimalField, self).get_db_prep_lookup(lookup_type, value)
+ def get_db_prep_value(self, value):
+ return connection.ops.value_to_db_decimal(self.to_python(value),
+ self.max_digits, self.decimal_places)
def get_manipulator_field_objs(self):
return [curry(oldforms.DecimalField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
@@ -768,7 +767,7 @@ class FileField(Field):
def get_internal_type(self):
return "FileField"
- def get_db_prep_save(self, value):
+ def get_db_prep_value(self, value):
"Returns field's value prepared for saving into a database."
# Need to convert UploadedFile objects provided via a form to unicode for database insertion
if hasattr(value, 'name'):
@@ -909,6 +908,11 @@ class FilePathField(Field):
class FloatField(Field):
empty_strings_allowed = False
+ def get_db_prep_value(self, value):
+ if value is None:
+ return None
+ return float(value)
+
def get_manipulator_field_objs(self):
return [oldforms.FloatField]
@@ -956,6 +960,11 @@ class ImageField(FileField):
class IntegerField(Field):
empty_strings_allowed = False
+ def get_db_prep_value(self, value):
+ if value is None:
+ return None
+ return int(value)
+
def get_manipulator_field_objs(self):
return [oldforms.IntegerField]
@@ -1003,6 +1012,11 @@ class NullBooleanField(Field):
if value in ('f', 'False', '0'): return False
raise validators.ValidationError, _("This value must be either None, True or False.")
+ def get_db_prep_value(self, value):
+ if value is None:
+ return None
+ return bool(value)
+
def get_manipulator_field_objs(self):
return [oldforms.NullBooleanField]
@@ -1015,7 +1029,7 @@ class NullBooleanField(Field):
defaults.update(kwargs)
return super(NullBooleanField, self).formfield(**defaults)
-class PhoneNumberField(IntegerField):
+class PhoneNumberField(Field):
def get_manipulator_field_objs(self):
return [oldforms.PhoneNumberField]
@@ -1097,20 +1111,34 @@ class TimeField(Field):
def get_internal_type(self):
return "TimeField"
- def get_db_prep_lookup(self, lookup_type, value):
- if connection.features.time_field_needs_date:
- # Oracle requires a date in order to parse.
- def prep(value):
- if isinstance(value, datetime.time):
- value = datetime.datetime.combine(datetime.date(1900, 1, 1), value)
- return smart_unicode(value)
- else:
- prep = smart_unicode
- if lookup_type in ('range', 'in'):
- value = [prep(v) for v in value]
+ def to_python(self, value):
+ if value is None:
+ return None
+ if isinstance(value, datetime.time):
+ return value
+
+ # Attempt to parse a datetime:
+ value = smart_str(value)
+ # split usecs, because they are not recognized by strptime.
+ if '.' in value:
+ try:
+ value, usecs = value.split('.')
+ usecs = int(usecs)
+ except ValueError:
+ raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.')
else:
- value = prep(value)
- return Field.get_db_prep_lookup(self, lookup_type, value)
+ usecs = 0
+ kwargs = {'microsecond': usecs}
+
+ try: # Seconds are optional, so try converting seconds first.
+ return datetime.time(*time.strptime(value, '%H:%M:%S')[3:6],
+ **kwargs)
+ except ValueError:
+ try: # Try without seconds.
+ return datetime.time(*time.strptime(value, '%H:%M')[3:5],
+ **kwargs)
+ except ValueError:
+ raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.')
def pre_save(self, model_instance, add):
if self.auto_now or (self.auto_now_add and add):
@@ -1120,23 +1148,9 @@ class TimeField(Field):
else:
return super(TimeField, self).pre_save(model_instance, add)
- def get_db_prep_save(self, value):
- # Casts dates into string format for entry into database.
- if value is not None:
- # MySQL will throw a warning if microseconds are given, because it
- # doesn't support microseconds.
- if not connection.features.supports_usecs and hasattr(value, 'microsecond'):
- value = value.replace(microsecond=0)
- if connection.features.time_field_needs_date:
- # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
- if isinstance(value, datetime.time):
- value = datetime.datetime(1900, 1, 1, value.hour, value.minute,
- value.second, value.microsecond)
- elif isinstance(value, basestring):
- value = datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6]))
- else:
- value = smart_unicode(value)
- return Field.get_db_prep_save(self, value)
+ def get_db_prep_value(self, value):
+ # Casts times into the format expected by the backend
+ return connection.ops.value_to_db_time(self.to_python(value))
def get_manipulator_field_objs(self):
return [oldforms.TimeField]
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 735dda4969..ab2b9a6c5e 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -2,11 +2,10 @@ from django.db import connection, transaction
from django.db.models import signals, get_model
from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, FieldDoesNotExist
from django.db.models.related import RelatedObject
+from django.db.models.query import QuerySet
from django.db.models.query_utils import QueryWrapper
-from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _
from django.utils.functional import curry
-from django.utils.encoding import smart_unicode
from django.core import validators
from django import oldforms
from django import forms
@@ -24,7 +23,7 @@ RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
pending_lookups = {}
-def add_lazy_relation(cls, field, relation):
+def add_lazy_relation(cls, field, relation, operation):
"""
Adds a lookup on ``cls`` when a related field is defined using a string,
i.e.::
@@ -46,6 +45,8 @@ def add_lazy_relation(cls, field, relation):
If the other model hasn't yet been loaded -- almost a given if you're using
lazy relationships -- then the relation won't be set up until the
class_prepared signal fires at the end of model initialization.
+
+ operation is the work that must be performed once the relation can be resolved.
"""
# Check for recursive relations
if relation == RECURSIVE_RELATIONSHIP_CONSTANT:
@@ -67,11 +68,10 @@ def add_lazy_relation(cls, field, relation):
# is prepared.
model = get_model(app_label, model_name, False)
if model:
- field.rel.to = model
- field.do_related_class(model, cls)
+ operation(field, model, cls)
else:
key = (app_label, model_name)
- value = (cls, field)
+ value = (cls, field, operation)
pending_lookups.setdefault(key, []).append(value)
def do_pending_lookups(sender):
@@ -79,9 +79,8 @@ def do_pending_lookups(sender):
Handle any pending relations to the sending model. Sent from class_prepared.
"""
key = (sender._meta.app_label, sender.__name__)
- for cls, field in pending_lookups.pop(key, []):
- field.rel.to = sender
- field.do_related_class(sender, cls)
+ for cls, field, operation in pending_lookups.pop(key, []):
+ operation(field, sender, cls)
dispatcher.connect(do_pending_lookups, signal=signals.class_prepared)
@@ -109,13 +108,17 @@ class RelatedField(object):
other = self.rel.to
if isinstance(other, basestring):
- add_lazy_relation(cls, self, other)
+ def resolve_related_class(field, model, cls):
+ field.rel.to = model
+ field.do_related_class(model, cls)
+ add_lazy_relation(cls, self, other, resolve_related_class)
else:
self.do_related_class(other, cls)
def set_attributes_from_rel(self):
self.name = self.name or (self.rel.to._meta.object_name.lower() + '_' + self.rel.to._meta.pk.name)
- self.verbose_name = self.verbose_name or self.rel.to._meta.verbose_name
+ if self.verbose_name is None:
+ self.verbose_name = self.rel.to._meta.verbose_name
self.rel.field_name = self.rel.field_name or self.rel.to._meta.pk.name
def do_related_class(self, other, cls):
@@ -236,7 +239,14 @@ class ReverseSingleRelatedObjectDescriptor(object):
params = {'%s__pk' % self.field.rel.field_name: val}
else:
params = {'%s__exact' % self.field.rel.field_name: val}
- rel_obj = self.field.rel.to._default_manager.get(**params)
+
+ # If the related manager indicates that it should be used for
+ # related fields, respect that.
+ rel_mgr = self.field.rel.to._default_manager
+ if getattr(rel_mgr, 'use_for_related_fields', False):
+ rel_obj = rel_mgr.get(**params)
+ else:
+ rel_obj = QuerySet(self.field.rel.to).get(**params)
setattr(instance, cache_name, rel_obj)
return rel_obj
@@ -340,7 +350,7 @@ class ForeignRelatedObjectsDescriptor(object):
manager.clear()
manager.add(*value)
-def create_many_related_manager(superclass):
+def create_many_related_manager(superclass, through=False):
"""Creates a manager that subclasses 'superclass' (which is a Manager)
and adds behavior for many-to-many related objects."""
class ManyRelatedManager(superclass):
@@ -354,6 +364,7 @@ def create_many_related_manager(superclass):
self.join_table = join_table
self.source_col_name = source_col_name
self.target_col_name = target_col_name
+ self.through = through
self._pk_val = self.instance._get_pk_val()
if self._pk_val is None:
raise ValueError("%r instance needs to have a primary key value before a many-to-many relationship can be used." % instance.__class__.__name__)
@@ -361,21 +372,24 @@ def create_many_related_manager(superclass):
def get_query_set(self):
return superclass.get_query_set(self).filter(**(self.core_filters))
- def add(self, *objs):
- self._add_items(self.source_col_name, self.target_col_name, *objs)
+ # If the ManyToMany relation has an intermediary model,
+ # the add and remove methods do not exist.
+ if through is None:
+ def add(self, *objs):
+ self._add_items(self.source_col_name, self.target_col_name, *objs)
- # If this is a symmetrical m2m relation to self, add the mirror entry in the m2m table
- if self.symmetrical:
- self._add_items(self.target_col_name, self.source_col_name, *objs)
- add.alters_data = True
+ # If this is a symmetrical m2m relation to self, add the mirror entry in the m2m table
+ if self.symmetrical:
+ self._add_items(self.target_col_name, self.source_col_name, *objs)
+ add.alters_data = True
- def remove(self, *objs):
- self._remove_items(self.source_col_name, self.target_col_name, *objs)
+ def remove(self, *objs):
+ self._remove_items(self.source_col_name, self.target_col_name, *objs)
- # If this is a symmetrical m2m relation to self, remove the mirror entry in the m2m table
- if self.symmetrical:
- self._remove_items(self.target_col_name, self.source_col_name, *objs)
- remove.alters_data = True
+ # If this is a symmetrical m2m relation to self, remove the mirror entry in the m2m table
+ if self.symmetrical:
+ self._remove_items(self.target_col_name, self.source_col_name, *objs)
+ remove.alters_data = True
def clear(self):
self._clear_items(self.source_col_name)
@@ -386,6 +400,10 @@ def create_many_related_manager(superclass):
clear.alters_data = True
def create(self, **kwargs):
+ # This check needs to be done here, since we can't later remove this
+ # from the method lookup table, as we do with add and remove.
+ if through is not None:
+ raise AttributeError, "Cannot use create() on a ManyToManyField which specifies an intermediary model. Use %s's Manager instead." % through
new_obj = self.model(**kwargs)
new_obj.save()
self.add(new_obj)
@@ -473,7 +491,7 @@ class ManyRelatedObjectsDescriptor(object):
# model's default manager.
rel_model = self.related.model
superclass = rel_model._default_manager.__class__
- RelatedManager = create_many_related_manager(superclass)
+ RelatedManager = create_many_related_manager(superclass, self.related.field.rel.through)
qn = connection.ops.quote_name
manager = RelatedManager(
@@ -492,6 +510,10 @@ class ManyRelatedObjectsDescriptor(object):
if instance is None:
raise AttributeError, "Manager must be accessed via instance"
+ through = getattr(self.related.field.rel, 'through', None)
+ if through is not None:
+ raise AttributeError, "Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s's Manager instead." % through
+
manager = self.__get__(instance)
manager.clear()
manager.add(*value)
@@ -514,7 +536,7 @@ class ReverseManyRelatedObjectsDescriptor(object):
# model's default manager.
rel_model=self.field.rel.to
superclass = rel_model._default_manager.__class__
- RelatedManager = create_many_related_manager(superclass)
+ RelatedManager = create_many_related_manager(superclass, self.field.rel.through)
qn = connection.ops.quote_name
manager = RelatedManager(
@@ -533,6 +555,10 @@ class ReverseManyRelatedObjectsDescriptor(object):
if instance is None:
raise AttributeError, "Manager must be accessed via instance"
+ through = getattr(self.field.rel, 'through', None)
+ if through is not None:
+ raise AttributeError, "Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s's Manager instead." % through
+
manager = self.__get__(instance)
manager.clear()
manager.add(*value)
@@ -584,7 +610,7 @@ class OneToOneRel(ManyToOneRel):
class ManyToManyRel(object):
def __init__(self, to, num_in_admin=0, related_name=None,
- limit_choices_to=None, symmetrical=True):
+ limit_choices_to=None, symmetrical=True, through=None):
self.to = to
self.num_in_admin = num_in_admin
self.related_name = related_name
@@ -594,6 +620,7 @@ class ManyToManyRel(object):
self.edit_inline = False
self.symmetrical = symmetrical
self.multiple = True
+ self.through = through
class ForeignKey(RelatedField, Field):
empty_strings_allowed = False
@@ -604,12 +631,7 @@ class ForeignKey(RelatedField, Field):
assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT)
else:
to_field = to_field or to._meta.pk.name
- kwargs['verbose_name'] = kwargs.get('verbose_name', '')
-
- if 'edit_inline_type' in kwargs:
- import warnings
- warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.", DeprecationWarning)
- kwargs['edit_inline'] = kwargs.pop('edit_inline_type')
+ kwargs['verbose_name'] = kwargs.get('verbose_name', None)
kwargs['rel'] = rel_class(to, to_field,
num_in_admin=kwargs.pop('num_in_admin', 3),
@@ -705,6 +727,7 @@ class OneToOneField(ForeignKey):
"""
def __init__(self, to, to_field=None, **kwargs):
kwargs['unique'] = True
+ kwargs['editable'] = False
if 'num_in_admin' not in kwargs:
kwargs['num_in_admin'] = 0
super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs)
@@ -722,8 +745,16 @@ class ManyToManyField(RelatedField, Field):
num_in_admin=kwargs.pop('num_in_admin', 0),
related_name=kwargs.pop('related_name', None),
limit_choices_to=kwargs.pop('limit_choices_to', None),
- symmetrical=kwargs.pop('symmetrical', True))
+ symmetrical=kwargs.pop('symmetrical', True),
+ through=kwargs.pop('through', None))
+
self.db_table = kwargs.pop('db_table', None)
+ if kwargs['rel'].through is not None:
+ self.creates_table = False
+ assert self.db_table is None, "Cannot specify a db_table if an intermediary model is used."
+ else:
+ self.creates_table = True
+
Field.__init__(self, **kwargs)
msg = ugettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.')
@@ -738,26 +769,62 @@ class ManyToManyField(RelatedField, Field):
def _get_m2m_db_table(self, opts):
"Function that can be curried to provide the m2m table name for this relation"
- if self.db_table:
+ if self.rel.through is not None:
+ return self.rel.through_model._meta.db_table
+ elif self.db_table:
return self.db_table
else:
return '%s_%s' % (opts.db_table, self.name)
def _get_m2m_column_name(self, related):
"Function that can be curried to provide the source column name for the m2m table"
- # If this is an m2m relation to self, avoid the inevitable name clash
- if related.model == related.parent_model:
- return 'from_' + related.model._meta.object_name.lower() + '_id'
- else:
- return related.model._meta.object_name.lower() + '_id'
+ try:
+ return self._m2m_column_name_cache
+ except:
+ if self.rel.through is not None:
+ for f in self.rel.through_model._meta.fields:
+ if hasattr(f,'rel') and f.rel and f.rel.to == related.model:
+ self._m2m_column_name_cache = f.column
+ break
+ # If this is an m2m relation to self, avoid the inevitable name clash
+ elif related.model == related.parent_model:
+ self._m2m_column_name_cache = 'from_' + related.model._meta.object_name.lower() + '_id'
+ else:
+ self._m2m_column_name_cache = related.model._meta.object_name.lower() + '_id'
+
+ # Return the newly cached value
+ return self._m2m_column_name_cache
def _get_m2m_reverse_name(self, related):
"Function that can be curried to provide the related column name for the m2m table"
- # If this is an m2m relation to self, avoid the inevitable name clash
- if related.model == related.parent_model:
- return 'to_' + related.parent_model._meta.object_name.lower() + '_id'
- else:
- return related.parent_model._meta.object_name.lower() + '_id'
+ try:
+ return self._m2m_reverse_name_cache
+ except:
+ if self.rel.through is not None:
+ found = False
+ for f in self.rel.through_model._meta.fields:
+ if hasattr(f,'rel') and f.rel and f.rel.to == related.parent_model:
+ if related.model == related.parent_model:
+ # If this is an m2m-intermediate to self,
+ # the first foreign key you find will be
+ # the source column. Keep searching for
+ # the second foreign key.
+ if found:
+ self._m2m_reverse_name_cache = f.column
+ break
+ else:
+ found = True
+ else:
+ self._m2m_reverse_name_cache = f.column
+ break
+ # If this is an m2m relation to self, avoid the inevitable name clash
+ elif related.model == related.parent_model:
+ self._m2m_reverse_name_cache = 'to_' + related.parent_model._meta.object_name.lower() + '_id'
+ else:
+ self._m2m_reverse_name_cache = related.parent_model._meta.object_name.lower() + '_id'
+
+ # Return the newly cached value
+ return self._m2m_reverse_name_cache
def isValidIDList(self, field_data, all_data):
"Validates that the value is a valid list of foreign keys"
@@ -791,13 +858,23 @@ class ManyToManyField(RelatedField, Field):
return new_data
def contribute_to_class(self, cls, name):
- super(ManyToManyField, self).contribute_to_class(cls, name)
+ super(ManyToManyField, self).contribute_to_class(cls, name)
# Add the descriptor for the m2m relation
setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self))
# Set up the accessor for the m2m table name for the relation
self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta)
-
+
+ # Populate some necessary rel arguments so that cross-app relations
+ # work correctly.
+ if isinstance(self.rel.through, basestring):
+ def resolve_through_model(field, model, cls):
+ field.rel.through_model = model
+ add_lazy_relation(cls, self, self.rel.through, resolve_through_model)
+ elif self.rel.through:
+ self.rel.through_model = self.rel.through
+ self.rel.through = self.rel.through._meta.object_name
+
if isinstance(self.rel.to, basestring):
target = self.rel.to
else:
diff --git a/django/db/models/fields/subclassing.py b/django/db/models/fields/subclassing.py
index 36f7e4d934..10add10739 100644
--- a/django/db/models/fields/subclassing.py
+++ b/django/db/models/fields/subclassing.py
@@ -5,9 +5,7 @@ Add SubfieldBase as the __metaclass__ for your Field subclass, implement
to_python() and the other necessary methods and everything will work seamlessly.
"""
-from django.utils.maxlength import LegacyMaxlength
-
-class SubfieldBase(LegacyMaxlength):
+class SubfieldBase(type):
"""
A metaclass for custom Field subclasses. This ensures the model's attribute
has the descriptor protocol attached to it.
@@ -50,4 +48,3 @@ def make_contrib(func=None):
setattr(cls, self.name, Creator(self))
return contribute_to_class
-
diff --git a/django/db/models/query.py b/django/db/models/query.py
index f0a0cf8218..5b24195a7d 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -1,4 +1,3 @@
-import warnings
try:
set
except NameError:
@@ -757,22 +756,6 @@ class EmptyQuerySet(QuerySet):
yield iter([]).next()
-# QOperator, QNot, QAnd and QOr are temporarily retained for backwards
-# compatibility. All the old functionality is now part of the 'Q' class.
-class QOperator(Q):
- def __init__(self, *args, **kwargs):
- warnings.warn('Use Q instead of QOr, QAnd or QOperation.',
- DeprecationWarning, stacklevel=2)
- super(QOperator, self).__init__(*args, **kwargs)
-
-QOr = QAnd = QOperator
-
-
-def QNot(q):
- warnings.warn('Use ~q instead of QNot(q)', DeprecationWarning, stacklevel=2)
- return ~q
-
-
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
requested=None):
"""
@@ -785,7 +768,11 @@ def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
restricted = requested is not None
index_end = index_start + len(klass._meta.fields)
- obj = klass(*row[index_start:index_end])
+ fields = row[index_start:index_end]
+ if not [x for x in fields if x is not None]:
+ # If we only have a list of Nones, there was not related object.
+ return None, index_end
+ obj = klass(*fields)
for f in klass._meta.fields:
if not select_related_descend(f, restricted, requested):
continue
@@ -831,9 +818,15 @@ def delete_objects(seen_objs):
del_query.delete_batch_related(pk_list)
update_query = sql.UpdateQuery(cls, connection)
- for field in cls._meta.fields:
- if field.rel and field.null and field.rel.to in seen_objs:
- update_query.clear_related(field, pk_list)
+ for field, model in cls._meta.get_fields_with_model():
+ if (field.rel and field.null and field.rel.to in seen_objs and
+ filter(lambda f: f.column == field.column,
+ field.rel.to._meta.fields)):
+ if model:
+ sql.UpdateQuery(model, connection).clear_related(field,
+ pk_list)
+ else:
+ update_query.clear_related(field, pk_list)
# Now delete the actual data.
for cls in ordered_classes:
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ef69d7657f..18dd8cc3f2 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -7,7 +7,6 @@ databases). The abstraction barrier only works one way: this module has to know
all about the internals of models in order to get the information it needs.
"""
-import datetime
from copy import deepcopy
from django.utils.tree import Node
@@ -107,6 +106,8 @@ class Query(object):
Pickling support.
"""
obj_dict = self.__dict__.copy()
+ obj_dict['related_select_fields'] = []
+ obj_dict['related_select_cols'] = []
del obj_dict['connection']
return obj_dict
@@ -196,14 +197,18 @@ class Query(object):
Returns an iterator over the results from executing this query.
"""
resolve_columns = hasattr(self, 'resolve_columns')
- if resolve_columns:
- if self.select_fields:
- fields = self.select_fields + self.related_select_fields
- else:
- fields = self.model._meta.fields
+ fields = None
for rows in self.execute_sql(MULTI):
for row in rows:
if resolve_columns:
+ if fields is None:
+ # We only set this up here because
+ # related_select_fields isn't populated until
+ # execute_sql() has been called.
+ if self.select_fields:
+ fields = self.select_fields + self.related_select_fields
+ else:
+ fields = self.model._meta.fields
row = self.resolve_columns(row, fields)
yield row
@@ -1088,20 +1093,23 @@ class Query(object):
join_it = iter(join_list)
table_it = iter(self.tables)
join_it.next(), table_it.next()
+ table_promote = False
for join in join_it:
table = table_it.next()
if join == table and self.alias_refcount[join] > 1:
continue
- self.promote_alias(join)
+ join_promote = self.promote_alias(join)
if table != join:
- self.promote_alias(table)
+ table_promote = self.promote_alias(table)
break
for join in join_it:
- self.promote_alias(join)
+ if self.promote_alias(join, join_promote):
+ join_promote = True
for table in table_it:
# Some of these will have been promoted from the join_list, but
# that's harmless.
- self.promote_alias(table)
+ if self.promote_alias(table, table_promote):
+ table_promote = True
self.where.add((alias, col, field, lookup_type, value), connector)
@@ -1214,7 +1222,6 @@ class Query(object):
raise MultiJoin(pos + 1)
if model:
# The field lives on a base class of the current model.
- alias_list = []
for int_model in opts.get_base_chain(model):
lhs_col = opts.parents[int_model].column
dedupe = lhs_col in opts.duplicate_targets
@@ -1618,8 +1625,9 @@ class Query(object):
if self.ordering_aliases:
result = order_modified_iter(cursor, len(self.ordering_aliases),
self.connection.features.empty_fetchmany_value)
- result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
- self.connection.features.empty_fetchmany_value)
+ else:
+ result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
+ self.connection.features.empty_fetchmany_value)
if not self.connection.features.can_use_chunked_reads:
# If we are using non-chunked reads, we return the same data
# structure as normally, but ensure it is all read into memory
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 18e4bf2f7e..662d99a4a2 100644
--- a/django/db/models/sql/where.py
+++ b/django/db/models/sql/where.py
@@ -35,20 +35,30 @@ class WhereNode(tree.Node):
storing any reference to field objects). Otherwise, the 'data' is
stored unchanged and can be anything with an 'as_sql()' method.
"""
+ # Because of circular imports, we need to import this here.
+ from django.db.models.base import ObjectDoesNotExist
+
if not isinstance(data, (list, tuple)):
super(WhereNode, self).add(data, connector)
return
alias, col, field, lookup_type, value = data
- if field:
- params = field.get_db_prep_lookup(lookup_type, value)
- db_type = field.db_type()
- else:
- # This is possible when we add a comparison to NULL sometimes (we
- # don't really need to waste time looking up the associated field
- # object).
- params = Field().get_db_prep_lookup(lookup_type, value)
- db_type = None
+ try:
+ if field:
+ params = field.get_db_prep_lookup(lookup_type, value)
+ db_type = field.db_type()
+ else:
+ # This is possible when we add a comparison to NULL sometimes
+ # (we don't really need to waste time looking up the associated
+ # field object).
+ params = Field().get_db_prep_lookup(lookup_type, value)
+ db_type = None
+ except ObjectDoesNotExist:
+ # This can happen when trying to insert a reference to a null pk.
+ # We break out of the normal path and indicate there's nothing to
+ # match.
+ super(WhereNode, self).add(NothingNode(), connector)
+ return
if isinstance(value, datetime.datetime):
annotation = datetime.datetime
else:
@@ -190,3 +200,14 @@ class EverythingNode(object):
def relabel_aliases(self, change_map, node=None):
return
+
+class NothingNode(object):
+ """
+ A node that matches nothing.
+ """
+ def as_sql(self, qn=None):
+ raise EmptyResultSet
+
+ def relabel_aliases(self, change_map, node=None):
+ return
+
diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py
index 029c59fd3f..725544446e 100644
--- a/django/dispatch/dispatcher.py
+++ b/django/dispatch/dispatcher.py
@@ -25,7 +25,7 @@ Internal attributes:
deletion, (considerably speeds up the cleanup process
vs. the original code.)
"""
-import types, weakref
+import weakref
from django.dispatch import saferef, robustapply, errors
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
@@ -129,7 +129,7 @@ def connect(receiver, signal=Any, sender=Any, weak=True):
"""
if signal is None:
raise errors.DispatcherTypeError(
- 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender)
+ 'Signal cannot be None (receiver=%r sender=%r)' % (receiver, sender)
)
if weak:
receiver = saferef.safeRef(receiver, onDelete=_removeReceiver)
@@ -159,7 +159,7 @@ def connect(receiver, signal=Any, sender=Any, weak=True):
else:
receivers = signals[signal] = []
try:
- current = sendersBack.get( receiverID )
+ current = sendersBack.get(receiverID)
if current is None:
sendersBack[ receiverID ] = current = []
if senderkey not in current:
@@ -199,7 +199,7 @@ def disconnect(receiver, signal=Any, sender=Any, weak=True):
"""
if signal is None:
raise errors.DispatcherTypeError(
- 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender)
+ 'Signal cannot be None (receiver=%r sender=%r)' % (receiver, sender)
)
if weak: receiver = saferef.safeRef(receiver)
senderkey = id(sender)
@@ -226,7 +226,7 @@ def disconnect(receiver, signal=Any, sender=Any, weak=True):
)
_cleanupConnections(senderkey, signal)
-def getReceivers( sender = Any, signal = Any ):
+def getReceivers(sender=Any, signal=Any):
"""Get list of receivers from global tables
This utility function allows you to retrieve the
@@ -240,7 +240,7 @@ def getReceivers( sender = Any, signal = Any ):
rather than, for instance a list to which you
might append new records.
- Normally you would use liveReceivers( getReceivers( ...))
+ Normally you would use liveReceivers(getReceivers(...))
to retrieve the actual receiver objects as an iterable
object.
"""
@@ -258,7 +258,7 @@ def liveReceivers(receivers):
receivers.
"""
for receiver in receivers:
- if isinstance( receiver, WEAKREF_TYPES):
+ if isinstance(receiver, WEAKREF_TYPES):
# Dereference the weak reference.
receiver = receiver()
if receiver is not None:
@@ -268,7 +268,7 @@ def liveReceivers(receivers):
-def getAllReceivers( sender = Any, signal = Any ):
+def getAllReceivers(sender=Any, signal=Any):
"""Get list of all receivers from global tables
This gets all dereferenced receivers which should receive
@@ -363,7 +363,7 @@ def send(signal=Any, sender=Anonymous, *arguments, **named):
return responses
-def sendExact( signal=Any, sender=Anonymous, *arguments, **named ):
+def sendExact(signal=Any, sender=Anonymous, *arguments, **named ):
"""Send signal only to those receivers registered for exact message
sendExact allows for avoiding Any/Anonymous registered
@@ -403,7 +403,7 @@ def _removeReceiver(receiver):
pass
else:
try:
- receivers.remove( receiver )
+ receivers.remove(receiver)
except Exception, err:
pass
_cleanupConnections(senderkey, signal)
@@ -439,11 +439,11 @@ def _removeSender(senderkey):
senders.pop(senderkey, None)
-def _removeBackrefs( senderkey):
+def _removeBackrefs(senderkey):
"""Remove all back-references to this senderkey"""
for receiver_list in connections.pop(senderkey, {}).values():
for receiver in receiver_list:
- _killBackref( receiver, senderkey )
+ _killBackref(receiver, senderkey)
def _removeOldBackRefs(senderkey, signal, receiver, receivers):
@@ -473,18 +473,18 @@ def _removeOldBackRefs(senderkey, signal, receiver, receivers):
found = 1
break
if not found:
- _killBackref( oldReceiver, senderkey )
+ _killBackref(oldReceiver, senderkey)
return True
return False
-def _killBackref( receiver, senderkey ):
+def _killBackref(receiver, senderkey):
"""Do the actual removal of back reference from receiver to senderkey"""
receiverkey = id(receiver)
- receivers_list = sendersBack.get( receiverkey, () )
+ receivers_list = sendersBack.get(receiverkey, ())
while senderkey in receivers_list:
try:
- receivers_list.remove( senderkey )
+ receivers_list.remove(senderkey)
except:
break
if not receivers_list:
diff --git a/django/dispatch/saferef.py b/django/dispatch/saferef.py
index c0d2eeb788..2abe3300da 100644
--- a/django/dispatch/saferef.py
+++ b/django/dispatch/saferef.py
@@ -1,6 +1,5 @@
"""Refactored "safe reference" from dispatcher.py"""
import weakref, traceback
-from django.utils.functional import curry
def safeRef(target, onDelete = None):
"""Return a *safe* weak reference to a callable target
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 9df8955392..47ae5e11b2 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -7,6 +7,7 @@ import datetime
import os
import re
import time
+import urlparse
try:
from cStringIO import StringIO
except ImportError:
@@ -23,7 +24,7 @@ except NameError:
from sets import Set as set
from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import StrAndUnicode, smart_unicode, smart_str
+from django.utils.encoding import smart_unicode, smart_str
from util import ErrorList, ValidationError
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
@@ -73,7 +74,10 @@ class Field(object):
if label is not None:
label = smart_unicode(label)
self.required, self.label, self.initial = required, label, initial
- self.help_text = smart_unicode(help_text or '')
+ if help_text is None:
+ self.help_text = u''
+ else:
+ self.help_text = smart_unicode(help_text)
widget = widget or self.widget
if isinstance(widget, type):
widget = widget()
@@ -503,6 +507,11 @@ class ImageField(FileField):
# but it must be called immediately after the constructor
trial_image = Image.open(file)
trial_image.verify()
+ except ImportError:
+ # Under PyPy, it is possible to import PIL. However, the underlying
+ # _imaging C module isn't available, so an ImportError will be
+ # raised. Catch and re-raise.
+ raise
except Exception: # Python Imaging Library doesn't recognize it as an image
raise ValidationError(self.error_messages['invalid_image'])
if hasattr(f, 'seek') and callable(f.seek):
@@ -534,6 +543,9 @@ class URLField(RegexField):
# If no URL scheme given, assume http://
if value and '://' not in value:
value = u'http://%s' % value
+ # If no URL path given, assume /
+ if value and not urlparse.urlsplit(value)[2]:
+ value += '/'
value = super(URLField, self).clean(value)
if value == u'':
return value
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 1ae27bf58c..2f13bf5fed 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -2,7 +2,7 @@ from forms import Form
from django.utils.encoding import StrAndUnicode
from django.utils.safestring import mark_safe
from fields import IntegerField, BooleanField
-from widgets import Media, HiddenInput, TextInput
+from widgets import Media, HiddenInput
from util import ErrorList, ValidationError
__all__ = ('BaseFormSet', 'all_valid')
@@ -10,7 +10,6 @@ __all__ = ('BaseFormSet', 'all_valid')
# special field names
TOTAL_FORM_COUNT = 'TOTAL_FORMS'
INITIAL_FORM_COUNT = 'INITIAL_FORMS'
-MAX_FORM_COUNT = 'MAX_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'
@@ -23,7 +22,6 @@ class ManagementForm(Form):
def __init__(self, *args, **kwargs):
self.base_fields[TOTAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
self.base_fields[INITIAL_FORM_COUNT] = IntegerField(widget=HiddenInput)
- self.base_fields[MAX_FORM_COUNT] = IntegerField(widget=HiddenInput)
super(ManagementForm, self).__init__(*args, **kwargs)
class BaseFormSet(StrAndUnicode):
@@ -47,23 +45,21 @@ class BaseFormSet(StrAndUnicode):
if self.management_form.is_valid():
self._total_form_count = self.management_form.cleaned_data[TOTAL_FORM_COUNT]
self._initial_form_count = self.management_form.cleaned_data[INITIAL_FORM_COUNT]
- self._max_form_count = self.management_form.cleaned_data[MAX_FORM_COUNT]
else:
raise ValidationError('ManagementForm data is missing or has been tampered with')
else:
if initial:
self._initial_form_count = len(initial)
- if self._initial_form_count > self._max_form_count and self._max_form_count > 0:
- self._initial_form_count = self._max_form_count
+ if self._initial_form_count > self.max_num and self.max_num > 0:
+ self._initial_form_count = self.max_num
self._total_form_count = self._initial_form_count + self.extra
else:
self._initial_form_count = 0
self._total_form_count = self.extra
- if self._total_form_count > self._max_form_count and self._max_form_count > 0:
- self._total_form_count = self._max_form_count
+ if self._total_form_count > self.max_num and self.max_num > 0:
+ self._total_form_count = self.max_num
initial = {TOTAL_FORM_COUNT: self._total_form_count,
- INITIAL_FORM_COUNT: self._initial_form_count,
- MAX_FORM_COUNT: self._max_form_count}
+ INITIAL_FORM_COUNT: self._initial_form_count}
self.management_form = ManagementForm(initial=initial, auto_id=self.auto_id, prefix=self.prefix)
# construct the forms in the formset
@@ -280,7 +276,7 @@ def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
"""Return a FormSet for the given form class."""
attrs = {'form': form, 'extra': extra,
'can_order': can_order, 'can_delete': can_delete,
- '_max_form_count': max_num}
+ 'max_num': max_num}
return type(form.__name__ + 'FormSet', (formset,), attrs)
def all_valid(formsets):
diff --git a/django/forms/models.py b/django/forms/models.py
index 43e2978ba8..1f807f2b42 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -8,7 +8,6 @@ from warnings import warn
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode
from django.utils.datastructures import SortedDict
-from django.core.exceptions import ImproperlyConfigured
from util import ValidationError, ErrorList
from forms import BaseForm, get_declared_fields
@@ -260,8 +259,8 @@ class BaseModelForm(BaseForm):
# if initial was provided, it should override the values from instance
if initial is not None:
object_data.update(initial)
- BaseForm.__init__(self, data, files, auto_id, prefix, object_data,
- error_class, label_suffix, empty_permitted)
+ super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data,
+ error_class, label_suffix, empty_permitted)
def save(self, commit=True):
"""
@@ -306,8 +305,8 @@ class BaseModelFormSet(BaseFormSet):
queryset=None, **kwargs):
self.queryset = queryset
defaults = {'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix}
- if self._max_form_count > 0:
- qs = self.get_queryset()[:self._max_form_count]
+ if self.max_num > 0:
+ qs = self.get_queryset()[:self.max_num]
else:
qs = self.get_queryset()
defaults['initial'] = [model_to_dict(obj) for obj in qs]
@@ -379,8 +378,9 @@ class BaseModelFormSet(BaseFormSet):
def add_fields(self, form, index):
"""Add a hidden field for the object's primary key."""
- self._pk_field_name = self.model._meta.pk.attname
- form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
+ if self.model._meta.has_auto_field:
+ self._pk_field_name = self.model._meta.pk.attname
+ form.fields[self._pk_field_name] = IntegerField(required=False, widget=HiddenInput)
super(BaseModelFormSet, self).add_fields(form, index)
def modelformset_factory(model, form=ModelForm, formfield_callback=lambda f: f.formfield(),
@@ -402,13 +402,14 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=lambda f: f.f
class BaseInlineFormset(BaseModelFormSet):
"""A formset for child objects related to a parent."""
- def __init__(self, data=None, files=None, instance=None, save_as_new=False):
+ def __init__(self, data=None, files=None, instance=None,
+ save_as_new=False, prefix=None):
from django.db.models.fields.related import RelatedObject
self.instance = instance
self.save_as_new = save_as_new
# is there a better way to get the object descriptor?
self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
- super(BaseInlineFormset, self).__init__(data, files, prefix=self.rel_name)
+ super(BaseInlineFormset, self).__init__(data, files, prefix=prefix or self.rel_name)
def _construct_forms(self):
if self.save_as_new:
@@ -441,13 +442,20 @@ def _get_foreign_key(parent_model, model, fk_name=None):
fks_to_parent = [f for f in opts.fields if f.name == fk_name]
if len(fks_to_parent) == 1:
fk = fks_to_parent[0]
- if not isinstance(fk, ForeignKey) or fk.rel.to != parent_model:
+ if not isinstance(fk, ForeignKey) or \
+ (fk.rel.to != parent_model and
+ fk.rel.to not in parent_model._meta.parents.keys()):
raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model))
elif len(fks_to_parent) == 0:
raise Exception("%s has no field named '%s'" % (model, fk_name))
else:
# Try to discover what the ForeignKey from model to parent_model is
- fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model]
+ fks_to_parent = [
+ f for f in opts.fields
+ if isinstance(f, ForeignKey)
+ and (f.rel.to == parent_model
+ or f.rel.to in parent_model._meta.parents.keys())
+ ]
if len(fks_to_parent) == 1:
fk = fks_to_parent[0]
elif len(fks_to_parent) == 0:
diff --git a/django/forms/util.py b/django/forms/util.py
index b3edf41adf..3d80ad219f 100644
--- a/django/forms/util.py
+++ b/django/forms/util.py
@@ -1,6 +1,5 @@
from django.utils.html import escape
from django.utils.encoding import smart_unicode, StrAndUnicode, force_unicode
-from django.utils.functional import Promise
from django.utils.safestring import mark_safe
def flatatt(attrs):
diff --git a/django/http/__init__.py b/django/http/__init__.py
index ef15479983..0124022478 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -31,6 +31,7 @@ class HttpRequest(object):
def __init__(self):
self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
self.path = ''
+ self.path_info = ''
self.method = None
def __repr__(self):
@@ -38,17 +39,6 @@ class HttpRequest(object):
(pformat(self.GET), pformat(self.POST), pformat(self.COOKIES),
pformat(self.META))
- def __getitem__(self, key):
- for d in (self.POST, self.GET):
- if key in d:
- return d[key]
- raise KeyError, "%s not found in either POST or GET" % key
-
- def has_key(self, key):
- return key in self.GET or key in self.POST
-
- __contains__ = has_key
-
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.
@@ -442,3 +432,4 @@ def str_to_unicode(s, encoding):
return unicode(s, encoding, 'replace')
else:
return s
+
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index fa1ae11968..2049289a0b 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -4,6 +4,7 @@ Multi-part parsing for file uploads.
Exposes one class, ``MultiPartParser``, which feeds chunks of uploaded data to
file upload handlers for processing.
"""
+
import cgi
from django.conf import settings
from django.core.exceptions import SuspiciousOperation
@@ -12,7 +13,7 @@ from django.utils.encoding import force_unicode
from django.utils.text import unescape_entities
from django.core.files.uploadhandler import StopUpload, SkipFile, StopFutureHandlers
-__all__ = ('MultiPartParser','MultiPartParserError','InputStreamExhausted')
+__all__ = ('MultiPartParser', 'MultiPartParserError', 'InputStreamExhausted')
class MultiPartParserError(Exception):
pass
@@ -162,7 +163,6 @@ class MultiPartParser(object):
force_unicode(data, encoding, errors='replace'))
elif item_type == FILE:
# This is a file, use the handler...
- file_successful = True
file_name = disposition.get('filename')
if not file_name:
continue
@@ -209,7 +209,6 @@ class MultiPartParser(object):
break
except SkipFile, e:
- file_successful = False
# Just use up the rest of this file...
exhaust(field_stream)
else:
@@ -515,21 +514,11 @@ class BoundaryIter(object):
else:
end = index
next = index + len(self._boundary)
- data_len = len(data) - 1
# backup over CRLF
if data[max(0,end-1)] == '\n':
end -= 1
if data[max(0,end-1)] == '\r':
end -= 1
- # skip over --CRLF
- #if data[min(data_len,next)] == '-':
- # next += 1
- #if data[min(data_len,next)] == '-':
- # next += 1
- #if data[min(data_len,next)] == '\r':
- # next += 1
- #if data[min(data_len,next)] == '\n':
- # next += 1
return end, next
def exhaust(stream_or_iterable):
diff --git a/django/middleware/common.py b/django/middleware/common.py
index 5cb7ca1bd3..a564017ed6 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -1,4 +1,3 @@
-import md5
import re
from django.conf import settings
@@ -6,6 +5,7 @@ from django import http
from django.core.mail import mail_managers
from django.utils.http import urlquote
from django.core import urlresolvers
+from django.utils.hashcompat import md5_constructor
class CommonMiddleware(object):
"""
@@ -21,7 +21,7 @@ class CommonMiddleware(object):
slash, and it is not found in urlpatterns, a new URL is formed by
appending a slash at the end. If this new URL is found in
urlpatterns, then an HTTP-redirect is returned to this new URL;
- otherwise the initial URL is processed as usual.
+ otherwise the initial URL is processed as usual.
- ETags: If the USE_ETAGS setting is set, ETags will be calculated from
the entire page content and Not Modified responses will be returned
@@ -108,7 +108,7 @@ class CommonMiddleware(object):
if response.has_header('ETag'):
etag = response['ETag']
else:
- etag = '"%s"' % md5.new(response.content).hexdigest()
+ etag = '"%s"' % md5_constructor(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()
diff --git a/django/oldforms/__init__.py b/django/oldforms/__init__.py
index 2a300df0bd..b5698ab807 100644
--- a/django/oldforms/__init__.py
+++ b/django/oldforms/__init__.py
@@ -5,7 +5,6 @@ from django.utils.safestring import mark_safe
from django.conf import settings
from django.utils.translation import ugettext, ungettext
from django.utils.encoding import smart_unicode, force_unicode
-from django.utils.maxlength import LegacyMaxlength
FORM_FIELD_ID_PREFIX = 'id_'
@@ -304,9 +303,6 @@ class FormField(object):
Subclasses should also implement a render(data) method, which is responsible
for rending the form field in XHTML.
"""
- # Provide backwards compatibility for the maxlength attribute and
- # argument for this class and all subclasses.
- __metaclass__ = LegacyMaxlength
def __str__(self):
return unicode(self).encode('utf-8')
diff --git a/django/template/context.py b/django/template/context.py
index 6ba53f340b..8f16a95021 100644
--- a/django/template/context.py
+++ b/django/template/context.py
@@ -62,6 +62,8 @@ class Context(object):
def update(self, other_dict):
"Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
+ if not hasattr(other_dict, '__getitem__'):
+ raise TypeError('other_dict must be a mapping (dictionary-like) object.')
self.dicts = [other_dict] + self.dicts
return other_dict
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 01c43ee86f..489faa243e 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -157,8 +157,8 @@ class ForNode(Node):
return nodelist.render(context)
class IfChangedNode(Node):
- def __init__(self, nodelist, *varlist):
- self.nodelist = nodelist
+ def __init__(self, nodelist_true, nodelist_false, *varlist):
+ self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
self._last_seen = None
self._varlist = map(Variable, varlist)
self._id = str(id(self))
@@ -173,20 +173,21 @@ class IfChangedNode(Node):
# like an OR evaluation of the multiple variables.
compare_to = [var.resolve(context) for var in self._varlist]
else:
- compare_to = self.nodelist.render(context)
+ compare_to = self.nodelist_true.render(context)
except VariableDoesNotExist:
compare_to = None
- if compare_to != self._last_seen:
+ if compare_to != self._last_seen:
firstloop = (self._last_seen == None)
self._last_seen = compare_to
context.push()
context['ifchanged'] = {'firstloop': firstloop}
- content = self.nodelist.render(context)
+ content = self.nodelist_true.render(context)
context.pop()
return content
- else:
- return ''
+ elif self.nodelist_false:
+ return self.nodelist_false.render(context)
+ return ''
class IfEqualNode(Node):
def __init__(self, var1, var2, nodelist_true, nodelist_false, negate):
@@ -363,12 +364,9 @@ class URLNode(Node):
try:
return reverse(self.view_name, args=args, kwargs=kwargs)
except NoReverseMatch:
- try:
- project_name = settings.SETTINGS_MODULE.split('.')[0]
- return reverse(project_name + '.' + self.view_name,
- args=args, kwargs=kwargs)
- except NoReverseMatch:
- return ''
+ project_name = settings.SETTINGS_MODULE.split('.')[0]
+ return reverse(project_name + '.' + self.view_name,
+ args=args, kwargs=kwargs)
class WidthRatioNode(Node):
def __init__(self, val_expr, max_expr, max_width):
@@ -803,9 +801,14 @@ def ifchanged(parser, token):
{% endfor %}
"""
bits = token.contents.split()
- nodelist = parser.parse(('endifchanged',))
- parser.delete_first_token()
- return IfChangedNode(nodelist, *bits[1:])
+ nodelist_true = parser.parse(('else', 'endifchanged'))
+ token = parser.next_token()
+ if token.contents == 'else':
+ nodelist_false = parser.parse(('endifchanged',))
+ parser.delete_first_token()
+ else:
+ nodelist_false = NodeList()
+ return IfChangedNode(nodelist_true, nodelist_false, *bits[1:])
ifchanged = register.tag(ifchanged)
#@register.tag
diff --git a/django/test/client.py b/django/test/client.py
index 47c12a4ca1..7d621449ea 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -190,7 +190,7 @@ class Client:
'PATH_INFO': '/',
'QUERY_STRING': '',
'REQUEST_METHOD': 'GET',
- 'SCRIPT_NAME': None,
+ 'SCRIPT_NAME': '',
'SERVER_NAME': 'testserver',
'SERVER_PORT': 80,
'SERVER_PROTOCOL': 'HTTP/1.1',
diff --git a/django/test/testcases.py b/django/test/testcases.py
index 3bad3995bb..dcab078553 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -1,15 +1,17 @@
import re
import unittest
from urlparse import urlsplit, urlunsplit
+from xml.dom.minidom import parseString, Node
-from django.http import QueryDict
-from django.db import transaction
from django.conf import settings
from django.core import mail
from django.core.management import call_command
+from django.core.urlresolvers import clear_url_caches
+from django.db import transaction
+from django.http import QueryDict
from django.test import _doctest as doctest
from django.test.client import Client
-from django.core.urlresolvers import clear_url_caches
+from django.utils import simplejson
normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
@@ -27,15 +29,133 @@ def to_list(value):
class OutputChecker(doctest.OutputChecker):
def check_output(self, want, got, optionflags):
- ok = doctest.OutputChecker.check_output(self, want, got, optionflags)
-
- # Doctest does an exact string comparison of output, which means long
- # integers aren't equal to normal integers ("22L" vs. "22"). The
- # following code normalizes long integers so that they equal normal
- # integers.
- if not ok:
- return normalize_long_ints(want) == normalize_long_ints(got)
- return ok
+ "The entry method for doctest output checking. Defers to a sequence of child checkers"
+ checks = (self.check_output_default,
+ self.check_output_long,
+ self.check_output_xml,
+ self.check_output_json)
+ for check in checks:
+ if check(want, got, optionflags):
+ return True
+ return False
+
+ def check_output_default(self, want, got, optionflags):
+ "The default comparator provided by doctest - not perfect, but good for most purposes"
+ return doctest.OutputChecker.check_output(self, want, got, optionflags)
+
+ def check_output_long(self, want, got, optionflags):
+ """Doctest does an exact string comparison of output, which means long
+ integers aren't equal to normal integers ("22L" vs. "22"). The
+ following code normalizes long integers so that they equal normal
+ integers.
+ """
+ return normalize_long_ints(want) == normalize_long_ints(got)
+
+ def check_output_xml(self, want, got, optionsflags):
+ """Tries to do a 'xml-comparision' of want and got. Plain string
+ comparision doesn't always work because, for example, attribute
+ ordering should not be important.
+
+ Based on http://codespeak.net/svn/lxml/trunk/src/lxml/doctestcompare.py
+ """
+ _norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+')
+ def norm_whitespace(v):
+ return _norm_whitespace_re.sub(' ', v)
+
+ def child_text(element):
+ return ''.join([c.data for c in element.childNodes
+ if c.nodeType == Node.TEXT_NODE])
+
+ def children(element):
+ return [c for c in element.childNodes
+ if c.nodeType == Node.ELEMENT_NODE]
+
+ def norm_child_text(element):
+ return norm_whitespace(child_text(element))
+
+ def attrs_dict(element):
+ return dict(element.attributes.items())
+
+ def check_element(want_element, got_element):
+ if want_element.tagName != got_element.tagName:
+ return False
+ if norm_child_text(want_element) != norm_child_text(got_element):
+ return False
+ if attrs_dict(want_element) != attrs_dict(got_element):
+ return False
+ want_children = children(want_element)
+ got_children = children(got_element)
+ if len(want_children) != len(got_children):
+ return False
+ for want, got in zip(want_children, got_children):
+ if not check_element(want, got):
+ return False
+ return True
+
+ want, got = self._strip_quotes(want, got)
+ want = want.replace('\\n','\n')
+ got = got.replace('\\n','\n')
+
+ # If the string is not a complete xml document, we may need to add a
+ # root element. This allow us to compare fragments, like "<foo/><bar/>"
+ if not want.startswith('<?xml'):
+ wrapper = '<root>%s</root>'
+ want = wrapper % want
+ got = wrapper % got
+
+ # Parse the want and got strings, and compare the parsings.
+ try:
+ want_root = parseString(want).firstChild
+ got_root = parseString(got).firstChild
+ except:
+ return False
+ return check_element(want_root, got_root)
+
+ def check_output_json(self, want, got, optionsflags):
+ "Tries to compare want and got as if they were JSON-encoded data"
+ want, got = self._strip_quotes(want, got)
+ try:
+ want_json = simplejson.loads(want)
+ got_json = simplejson.loads(got)
+ except:
+ return False
+ return want_json == got_json
+
+ def _strip_quotes(self, want, got):
+ """
+ Strip quotes of doctests output values:
+
+ >>> o = OutputChecker()
+ >>> o._strip_quotes("'foo'")
+ "foo"
+ >>> o._strip_quotes('"foo"')
+ "foo"
+ >>> o._strip_quotes("u'foo'")
+ "foo"
+ >>> o._strip_quotes('u"foo"')
+ "foo"
+ """
+ def is_quoted_string(s):
+ s = s.strip()
+ return (len(s) >= 2
+ and s[0] == s[-1]
+ and s[0] in ('"', "'"))
+
+ def is_quoted_unicode(s):
+ s = s.strip()
+ return (len(s) >= 3
+ and s[0] == 'u'
+ and s[1] == s[-1]
+ and s[1] in ('"', "'"))
+
+ if is_quoted_string(want) and is_quoted_string(got):
+ want = want.strip()[1:-1]
+ got = got.strip()[1:-1]
+ elif is_quoted_unicode(want) and is_quoted_unicode(got):
+ want = want.strip()[2:-1]
+ got = got.strip()[2:-1]
+ return want, got
+
class DocTestRunner(doctest.DocTestRunner):
def __init__(self, *args, **kwargs):
diff --git a/django/utils/cache.py b/django/utils/cache.py
index 603199cc7e..78063c6b11 100644
--- a/django/utils/cache.py
+++ b/django/utils/cache.py
@@ -17,7 +17,6 @@ An example: i18n middleware would need to distinguish caches by the
"Accept-language" header.
"""
-import md5
import re
import time
try:
@@ -29,6 +28,7 @@ from django.conf import settings
from django.core.cache import cache
from django.utils.encoding import smart_str, iri_to_uri
from django.utils.http import http_date
+from django.utils.hashcompat import md5_constructor
cc_delim_re = re.compile(r'\s*,\s*')
@@ -104,7 +104,7 @@ def patch_response_headers(response, cache_timeout=None):
if cache_timeout < 0:
cache_timeout = 0 # Can't have max-age negative
if not response.has_header('ETag'):
- response['ETag'] = '"%s"' % md5.new(response.content).hexdigest()
+ response['ETag'] = '"%s"' % md5_constructor(response.content).hexdigest()
if not response.has_header('Last-Modified'):
response['Last-Modified'] = http_date()
if not response.has_header('Expires'):
@@ -138,7 +138,7 @@ def patch_vary_headers(response, newheaders):
def _generate_cache_key(request, headerlist, key_prefix):
"""Returns a cache key from the headers given in the header list."""
- ctx = md5.new()
+ ctx = md5_constructor()
for header in headerlist:
value = request.META.get(header, None)
if value is not None:
diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
index bfca46b3d5..8da9385f6c 100644
--- a/django/utils/dateformat.py
+++ b/django/utils/dateformat.py
@@ -13,7 +13,7 @@ Usage:
from django.utils.dates import MONTHS, MONTHS_3, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR
from django.utils.tzinfo import LocalTimezone
-from django.utils.translation import string_concat, ugettext as _
+from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode
from calendar import isleap, monthrange
import re, time
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index 33bb37b0ea..c54e67610f 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -1,9 +1,7 @@
import types
import urllib
import datetime
-
from django.utils.functional import Promise
-from django.utils.safestring import SafeData, mark_safe
class DjangoUnicodeDecodeError(UnicodeDecodeError):
def __init__(self, obj, *args):
diff --git a/django/utils/functional.py b/django/utils/functional.py
index 3de693e18c..9a12eda5a1 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -148,42 +148,54 @@ def lazy(func, *resultclasses):
function is evaluated on every access.
"""
class __proxy__(Promise):
- # This inner class encapsulates the code that should be evaluated
- # lazily. On calling of one of the magic methods it will force
- # the evaluation and store the result. Afterwards, the result
- # is delivered directly. So the result is memoized.
+ """
+ Encapsulate a function call and act as a proxy for methods that are
+ called on the result of that function. The function is not evaluated
+ until one of the methods on the result is called.
+ """
+ __dispatch = None
+
def __init__(self, args, kw):
self.__func = func
self.__args = args
self.__kw = kw
- self.__dispatch = {}
+ if self.__dispatch is None:
+ self.__prepare_class__()
+
+ def __prepare_class__(cls):
+ cls.__dispatch = {}
for resultclass in resultclasses:
- self.__dispatch[resultclass] = {}
+ cls.__dispatch[resultclass] = {}
for (k, v) in resultclass.__dict__.items():
- setattr(self, k, self.__promise__(resultclass, k, v))
- self._delegate_str = str in resultclasses
- self._delegate_unicode = unicode in resultclasses
- assert not (self._delegate_str and self._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
- if self._delegate_unicode:
- # Each call to lazy() makes a new __proxy__ object, so this
- # doesn't interfere with any other lazy() results.
- __proxy__.__unicode__ = __proxy__.__unicode_cast
- elif self._delegate_str:
- __proxy__.__str__ = __proxy__.__str_cast
-
- def __promise__(self, klass, funcname, func):
+ if hasattr(cls, k):
+ continue
+ setattr(cls, k, cls.__promise__(resultclass, k, v))
+ cls._delegate_str = str in resultclasses
+ cls._delegate_unicode = unicode in resultclasses
+ assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
+ if cls._delegate_unicode:
+ cls.__unicode__ = cls.__unicode_cast
+ elif cls._delegate_str:
+ cls.__str__ = cls.__str_cast
+ __prepare_class__ = classmethod(__prepare_class__)
+
+ def __promise__(cls, klass, funcname, func):
# Builds a wrapper around some magic method and registers that magic
# method for the given type and method name.
- def __wrapper__(*args, **kw):
+ def __wrapper__(self, *args, **kw):
# Automatically triggers the evaluation of a lazy value and
# applies the given magic method of the result type.
res = self.__func(*self.__args, **self.__kw)
- return self.__dispatch[type(res)][funcname](res, *args, **kw)
-
- if klass not in self.__dispatch:
- self.__dispatch[klass] = {}
- self.__dispatch[klass][funcname] = func
+ for t in type(res).mro():
+ if t in self.__dispatch:
+ return self.__dispatch[t][funcname](res, *args, **kw)
+ raise TypeError("Lazy object returned unexpected type.")
+
+ if klass not in cls.__dispatch:
+ cls.__dispatch[klass] = {}
+ cls.__dispatch[klass][funcname] = func
return __wrapper__
+ __promise__ = classmethod(__promise__)
def __unicode_cast(self):
return self.__func(*self.__args, **self.__kw)
diff --git a/django/utils/hashcompat.py b/django/utils/hashcompat.py
new file mode 100644
index 0000000000..8880d92646
--- /dev/null
+++ b/django/utils/hashcompat.py
@@ -0,0 +1,16 @@
+"""
+The md5 and sha modules are deprecated since Python 2.5, replaced by the
+hashlib module containing both hash algorithms. Here, we provide a common
+interface to the md5 and sha constructors, preferring the hashlib module when
+available.
+"""
+
+try:
+ import hashlib
+ md5_constructor = hashlib.md5
+ sha_constructor = hashlib.sha1
+except ImportError:
+ import md5
+ md5_constructor = md5.new
+ import sha
+ sha_constructor = sha.new
diff --git a/django/utils/html.py b/django/utils/html.py
index 747af52879..9b3fad8b03 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -94,7 +94,9 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
words = word_split_re.split(force_unicode(text))
nofollow_attr = nofollow and ' rel="nofollow"' or ''
for i, word in enumerate(words):
- match = punctuation_re.match(word)
+ match = None
+ if '.' in word or '@' in word or ':' in word:
+ match = punctuation_re.match(word)
if match:
lead, middle, trail = match.groups()
# Make URL we want to point to.
@@ -102,7 +104,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
if middle.startswith('http://') or middle.startswith('https://'):
url = urlquote(middle, safe='/&=:;#?+*')
elif middle.startswith('www.') or ('@' not in middle and \
- len(middle) > 0 and middle[0] in string.ascii_letters + string.digits and \
+ middle and middle[0] in string.ascii_letters + string.digits and \
(middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))):
url = urlquote('http://%s' % middle, safe='/&=:;#?+*')
elif '@' in middle and not ':' in middle and simple_email_re.match(middle):
diff --git a/django/utils/http.py b/django/utils/http.py
index 5ec6e92d28..7d2af95c47 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -65,3 +65,32 @@ def http_date(epoch_seconds=None):
"""
rfcdate = formatdate(epoch_seconds)
return '%s GMT' % rfcdate[:25]
+
+# Base 36 functions: useful for generating compact URLs
+
+def base36_to_int(s):
+ """
+ Convertd a base 36 string to an integer
+ """
+ return int(s, 36)
+
+def int_to_base36(i):
+ """
+ Converts an integer to a base36 string
+ """
+ digits = "0123456789abcdefghijklmnopqrstuvwxyz"
+ factor = 0
+ # Find starting factor
+ while True:
+ factor += 1
+ if i < 36 ** factor:
+ factor -= 1
+ break
+ base36 = []
+ # Construct base36 representation
+ while factor >= 0:
+ j = 36 ** factor
+ base36.append(digits[i / j])
+ i = i % j
+ factor -= 1
+ return ''.join(base36)
diff --git a/django/utils/maxlength.py b/django/utils/maxlength.py
deleted file mode 100644
index a616541f85..0000000000
--- a/django/utils/maxlength.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
-Utilities for providing backwards compatibility for the maxlength argument,
-which has been replaced by max_length. See ticket #2101.
-"""
-
-from warnings import warn
-
-def get_maxlength(self):
- return self.max_length
-
-def set_maxlength(self, value):
- self.max_length = value
-
-def legacy_maxlength(max_length, maxlength):
- """
- Consolidates max_length and maxlength, providing backwards compatibilty
- for the legacy "maxlength" argument.
-
- If one of max_length or maxlength is given, then that value is returned.
- If both are given, a TypeError is raised. If maxlength is used at all, a
- deprecation warning is issued.
- """
- if maxlength is not None:
- warn("maxlength is deprecated. Use max_length instead.", DeprecationWarning, stacklevel=3)
- if max_length is not None:
- raise TypeError("Field cannot take both the max_length argument and the legacy maxlength argument.")
- max_length = maxlength
- return max_length
-
-def remove_maxlength(func):
- """
- A decorator to be used on a class's __init__ that provides backwards
- compatibilty for the legacy "maxlength" keyword argument, i.e.
- name = models.CharField(maxlength=20)
-
- It does this by changing the passed "maxlength" keyword argument
- (if it exists) into a "max_length" keyword argument.
- """
- def inner(self, *args, **kwargs):
- max_length = kwargs.get('max_length', None)
- # pop maxlength because we don't want this going to __init__.
- maxlength = kwargs.pop('maxlength', None)
- max_length = legacy_maxlength(max_length, maxlength)
- # Only set the max_length keyword argument if we got a value back.
- if max_length is not None:
- kwargs['max_length'] = max_length
- func(self, *args, **kwargs)
- return inner
-
-# This metaclass is used in two places, and should be removed when legacy
-# support for maxlength is dropped.
-# * oldforms.FormField
-# * db.models.fields.Field
-
-class LegacyMaxlength(type):
- """
- Metaclass for providing backwards compatibility support for the
- "maxlength" keyword argument.
- """
- def __init__(cls, name, bases, attrs):
- super(LegacyMaxlength, cls).__init__(name, bases, attrs)
- # Decorate the class's __init__ to remove any maxlength keyword.
- cls.__init__ = remove_maxlength(cls.__init__)
- # Support accessing and setting to the legacy maxlength attribute.
- cls.maxlength = property(get_maxlength, set_maxlength)
diff --git a/django/utils/simplejson/LICENSE.txt b/django/utils/simplejson/LICENSE.txt
index 1fa4fd5ba2..ad95f29c17 100644
--- a/django/utils/simplejson/LICENSE.txt
+++ b/django/utils/simplejson/LICENSE.txt
@@ -1,4 +1,3 @@
-simplejson 1.5
Copyright (c) 2006 Bob Ippolito
Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/django/utils/simplejson/__init__.py b/django/utils/simplejson/__init__.py
index 15b7173976..130940f358 100644
--- a/django/utils/simplejson/__init__.py
+++ b/django/utils/simplejson/__init__.py
@@ -65,6 +65,9 @@ Specializing JSON object decoding::
>>> simplejson.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
+ >>> import decimal
+ >>> simplejson.loads('1.1', parse_float=decimal.Decimal)
+ Decimal("1.1")
Extending JSONEncoder::
@@ -83,20 +86,48 @@ Extending JSONEncoder::
['[', '2.0', ', ', '1.0', ']']
+Using simplejson from the shell to validate and
+pretty-print::
+
+ $ echo '{"json":"obj"}' | python -msimplejson.tool
+ {
+ "json": "obj"
+ }
+ $ echo '{ 1.2:3.4}' | python -msimplejson.tool
+ Expecting property name: line 1 column 2 (char 2)
+
Note that the JSON produced by this module's default settings
is a subset of YAML, so it may be used as a serializer for that as well.
"""
-__version__ = '1.5'
+__version__ = '1.9.2'
__all__ = [
'dump', 'dumps', 'load', 'loads',
'JSONDecoder', 'JSONEncoder',
]
-from django.utils.simplejson.decoder import JSONDecoder
-from django.utils.simplejson.encoder import JSONEncoder
+if __name__ == '__main__':
+ import warnings
+ warnings.warn('python -msimplejson is deprecated, use python -msiplejson.tool', DeprecationWarning)
+ from django.utils.simplejson.decoder import JSONDecoder
+ from django.utils.simplejson.encoder import JSONEncoder
+else:
+ from decoder import JSONDecoder
+ from encoder import JSONEncoder
+
+_default_encoder = JSONEncoder(
+ skipkeys=False,
+ ensure_ascii=True,
+ check_circular=True,
+ allow_nan=True,
+ indent=None,
+ separators=None,
+ encoding='utf-8',
+ default=None,
+)
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
- allow_nan=True, cls=None, indent=None, **kw):
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, **kw):
"""
Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
``.write()``-supporting file-like object).
@@ -107,7 +138,7 @@ def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
If ``ensure_ascii`` is ``False``, then the some chunks written to ``fp``
may be ``unicode`` instances, subject to normal Python ``str`` to
- ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
+ ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
to cause an error.
@@ -121,25 +152,44 @@ def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and object
- members will be pretty-printed with that indent level. An indent level
- of 0 will only insert newlines. ``None`` is the most compact representation.
+ members will be pretty-printed with that indent level. An indent level
+ of 0 will only insert newlines. ``None`` is the most compact representation.
+
+ If ``separators`` is an ``(item_separator, dict_separator)`` tuple
+ then it will be used instead of the default ``(', ', ': ')`` separators.
+ ``(',', ':')`` is the most compact JSON representation.
+
+ ``encoding`` is the character encoding for str instances, default is UTF-8.
+
+ ``default(obj)`` is a function that should return a serializable version
+ of obj or raise TypeError. The default simply raises TypeError.
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg.
"""
- if cls is None:
- cls = JSONEncoder
- iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
- check_circular=check_circular, allow_nan=allow_nan, indent=indent,
- **kw).iterencode(obj)
+ # cached encoder
+ if (skipkeys is False and ensure_ascii is True and
+ check_circular is True and allow_nan is True and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and not kw):
+ iterable = _default_encoder.iterencode(obj)
+ else:
+ if cls is None:
+ cls = JSONEncoder
+ iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+ check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+ separators=separators, encoding=encoding,
+ default=default, **kw).iterencode(obj)
# could accelerate with writelines in some versions of Python, at
# a debuggability cost
for chunk in iterable:
fp.write(chunk)
+
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
- allow_nan=True, cls=None, indent=None, separators=None, **kw):
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, **kw):
"""
Serialize ``obj`` to a JSON formatted ``str``.
@@ -161,88 +211,159 @@ def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and
- object members will be pretty-printed with that indent level. An indent
- level of 0 will only insert newlines. ``None`` is the most compact
+ object members will be pretty-printed with that indent level. An indent
+ level of 0 will only insert newlines. ``None`` is the most compact
representation.
If ``separators`` is an ``(item_separator, dict_separator)`` tuple
then it will be used instead of the default ``(', ', ': ')`` separators.
``(',', ':')`` is the most compact JSON representation.
+ ``encoding`` is the character encoding for str instances, default is UTF-8.
+
+ ``default(obj)`` is a function that should return a serializable version
+ of obj or raise TypeError. The default simply raises TypeError.
+
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg.
"""
+ # cached encoder
+ if (skipkeys is False and ensure_ascii is True and
+ check_circular is True and allow_nan is True and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and not kw):
+ return _default_encoder.encode(obj)
if cls is None:
cls = JSONEncoder
return cls(
skipkeys=skipkeys, ensure_ascii=ensure_ascii,
check_circular=check_circular, allow_nan=allow_nan, indent=indent,
- separators=separators,
+ separators=separators, encoding=encoding, default=default,
**kw).encode(obj)
-def load(fp, encoding=None, cls=None, object_hook=None, **kw):
+
+_default_decoder = JSONDecoder(encoding=None, object_hook=None)
+
+
+def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, **kw):
"""
Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object.
If the contents of ``fp`` is encoded with an ASCII based encoding other
than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must
- be specified. Encodings that are not ASCII based (such as UCS-2) are
+ be specified. Encodings that are not ASCII based (such as UCS-2) are
not allowed, and should be wrapped with
``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode``
object and passed to ``loads()``
``object_hook`` is an optional function that will be called with the
- result of any object literal decode (a ``dict``). The return value of
- ``object_hook`` will be used instead of the ``dict``. This feature
+ result of any object literal decode (a ``dict``). The return value of
+ ``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg.
"""
- if cls is None:
- cls = JSONDecoder
- if object_hook is not None:
- kw['object_hook'] = object_hook
- return cls(encoding=encoding, **kw).decode(fp.read())
+ return loads(fp.read(),
+ encoding=encoding, cls=cls, object_hook=object_hook,
+ parse_float=parse_float, parse_int=parse_int,
+ parse_constant=parse_constant, **kw)
+
-def loads(s, encoding=None, cls=None, object_hook=None, **kw):
+def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, **kw):
"""
Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
document) to a Python object.
If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
- must be specified. Encodings that are not ASCII based (such as UCS-2)
+ must be specified. Encodings that are not ASCII based (such as UCS-2)
are not allowed and should be decoded to ``unicode`` first.
``object_hook`` is an optional function that will be called with the
- result of any object literal decode (a ``dict``). The return value of
- ``object_hook`` will be used instead of the ``dict``. This feature
+ result of any object literal decode (a ``dict``). The return value of
+ ``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
+ ``parse_float``, if specified, will be called with the string
+ of every JSON float to be decoded. By default this is equivalent to
+ float(num_str). This can be used to use another datatype or parser
+ for JSON floats (e.g. decimal.Decimal).
+
+ ``parse_int``, if specified, will be called with the string
+ of every JSON int to be decoded. By default this is equivalent to
+ int(num_str). This can be used to use another datatype or parser
+ for JSON integers (e.g. float).
+
+ ``parse_constant``, if specified, will be called with one of the
+ following strings: -Infinity, Infinity, NaN, null, true, false.
+ This can be used to raise an exception if invalid JSON numbers
+ are encountered.
+
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg.
"""
+ if (cls is None and encoding is None and object_hook is None and
+ parse_int is None and parse_float is None and
+ parse_constant is None and not kw):
+ return _default_decoder.decode(s)
if cls is None:
cls = JSONDecoder
if object_hook is not None:
kw['object_hook'] = object_hook
+ if parse_float is not None:
+ kw['parse_float'] = parse_float
+ if parse_int is not None:
+ kw['parse_int'] = parse_int
+ if parse_constant is not None:
+ kw['parse_constant'] = parse_constant
return cls(encoding=encoding, **kw).decode(s)
+
+#
+# Compatibility cruft from other libraries
+#
+
+
+def decode(s):
+ """
+ demjson, python-cjson API compatibility hook. Use loads(s) instead.
+ """
+ import warnings
+ warnings.warn("simplejson.loads(s) should be used instead of decode(s)",
+ DeprecationWarning)
+ return loads(s)
+
+
+def encode(obj):
+ """
+ demjson, python-cjson compatibility hook. Use dumps(s) instead.
+ """
+ import warnings
+ warnings.warn("simplejson.dumps(s) should be used instead of encode(s)",
+ DeprecationWarning)
+ return dumps(obj)
+
+
def read(s):
"""
- json-py API compatibility hook. Use loads(s) instead.
+ jsonlib, JsonUtils, python-json, json-py API compatibility hook.
+ Use loads(s) instead.
"""
import warnings
warnings.warn("simplejson.loads(s) should be used instead of read(s)",
DeprecationWarning)
return loads(s)
+
def write(obj):
"""
- json-py API compatibility hook. Use dumps(s) instead.
+ jsonlib, JsonUtils, python-json, json-py API compatibility hook.
+ Use dumps(s) instead.
"""
import warnings
warnings.warn("simplejson.dumps(s) should be used instead of write(s)",
@@ -250,3 +371,6 @@ def write(obj):
return dumps(obj)
+if __name__ == '__main__':
+ import simplejson.tool
+ simplejson.tool.main()
diff --git a/django/utils/simplejson/decoder.py b/django/utils/simplejson/decoder.py
index 66f68a200b..cef9fc002b 100644
--- a/django/utils/simplejson/decoder.py
+++ b/django/utils/simplejson/decoder.py
@@ -2,8 +2,13 @@
Implementation of JSONDecoder
"""
import re
+import sys
from django.utils.simplejson.scanner import Scanner, pattern
+try:
+ from django.utils.simplejson._speedups import scanstring as c_scanstring
+except ImportError:
+ pass
FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
@@ -18,6 +23,7 @@ def _floatconstants():
NaN, PosInf, NegInf = _floatconstants()
+
def linecol(doc, pos):
lineno = doc.count('\n', 0, pos) + 1
if lineno == 1:
@@ -26,6 +32,7 @@ def linecol(doc, pos):
colno = pos - doc.rindex('\n', 0, pos)
return lineno, colno
+
def errmsg(msg, doc, pos, end=None):
lineno, colno = linecol(doc, pos)
if end is None:
@@ -34,6 +41,7 @@ def errmsg(msg, doc, pos, end=None):
return '%s: line %d column %d - line %d column %d (char %d - %d)' % (
msg, lineno, colno, endlineno, endcolno, pos, end)
+
_CONSTANTS = {
'-Infinity': NegInf,
'Infinity': PosInf,
@@ -44,20 +52,30 @@ _CONSTANTS = {
}
def JSONConstant(match, context, c=_CONSTANTS):
- return c[match.group(0)], None
+ s = match.group(0)
+ fn = getattr(context, 'parse_constant', None)
+ if fn is None:
+ rval = c[s]
+ else:
+ rval = fn(s)
+ return rval, None
pattern('(-?Infinity|NaN|true|false|null)')(JSONConstant)
+
def JSONNumber(match, context):
match = JSONNumber.regex.match(match.string, *match.span())
integer, frac, exp = match.groups()
if frac or exp:
- res = float(integer + (frac or '') + (exp or ''))
+ fn = getattr(context, 'parse_float', None) or float
+ res = fn(integer + (frac or '') + (exp or ''))
else:
- res = int(integer)
+ fn = getattr(context, 'parse_int', None) or int
+ res = fn(integer)
return res, None
pattern(r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?')(JSONNumber)
-STRINGCHUNK = re.compile(r'(.*?)(["\\])', FLAGS)
+
+STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
BACKSLASH = {
'"': u'"', '\\': u'\\', '/': u'/',
'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
@@ -65,7 +83,7 @@ BACKSLASH = {
DEFAULT_ENCODING = "utf-8"
-def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match):
+def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match):
if encoding is None:
encoding = DEFAULT_ENCODING
chunks = []
@@ -84,6 +102,12 @@ def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match):
_append(content)
if terminator == '"':
break
+ elif terminator != '\\':
+ if strict:
+ raise ValueError(errmsg("Invalid control character %r at", s, end))
+ else:
+ _append(terminator)
+ continue
try:
esc = s[end]
except IndexError:
@@ -98,21 +122,43 @@ def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match):
end += 1
else:
esc = s[end + 1:end + 5]
+ next_end = end + 5
+ msg = "Invalid \\uXXXX escape"
try:
- m = unichr(int(esc, 16))
- if len(esc) != 4 or not esc.isalnum():
+ if len(esc) != 4:
raise ValueError
+ uni = int(esc, 16)
+ if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535:
+ msg = "Invalid \\uXXXX\\uXXXX surrogate pair"
+ if not s[end + 5:end + 7] == '\\u':
+ raise ValueError
+ esc2 = s[end + 7:end + 11]
+ if len(esc2) != 4:
+ raise ValueError
+ uni2 = int(esc2, 16)
+ uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
+ next_end += 6
+ m = unichr(uni)
except ValueError:
- raise ValueError(errmsg("Invalid \\uXXXX escape", s, end))
- end += 5
+ raise ValueError(errmsg(msg, s, end))
+ end = next_end
_append(m)
return u''.join(chunks), end
+
+# Use speedup
+try:
+ scanstring = c_scanstring
+except NameError:
+ scanstring = py_scanstring
+
def JSONString(match, context):
encoding = getattr(context, 'encoding', None)
- return scanstring(match.string, match.end(), encoding)
+ strict = getattr(context, 'strict', True)
+ return scanstring(match.string, match.end(), encoding, strict)
pattern(r'"')(JSONString)
+
WHITESPACE = re.compile(r'\s*', FLAGS)
def JSONObject(match, context, _w=WHITESPACE.match):
@@ -120,16 +166,17 @@ def JSONObject(match, context, _w=WHITESPACE.match):
s = match.string
end = _w(s, match.end()).end()
nextchar = s[end:end + 1]
- # trivial empty object
+ # Trivial empty object
if nextchar == '}':
return pairs, end + 1
if nextchar != '"':
raise ValueError(errmsg("Expecting property name", s, end))
end += 1
encoding = getattr(context, 'encoding', None)
+ strict = getattr(context, 'strict', True)
iterscan = JSONScanner.iterscan
while True:
- key, end = scanstring(s, end, encoding)
+ key, end = scanstring(s, end, encoding, strict)
end = _w(s, end).end()
if s[end:end + 1] != ':':
raise ValueError(errmsg("Expecting : delimiter", s, end))
@@ -156,12 +203,13 @@ def JSONObject(match, context, _w=WHITESPACE.match):
pairs = object_hook(pairs)
return pairs, end
pattern(r'{')(JSONObject)
-
+
+
def JSONArray(match, context, _w=WHITESPACE.match):
values = []
s = match.string
end = _w(s, match.end()).end()
- # look-ahead for trivial empty array
+ # Look-ahead for trivial empty array
nextchar = s[end:end + 1]
if nextchar == ']':
return values, end + 1
@@ -182,7 +230,8 @@ def JSONArray(match, context, _w=WHITESPACE.match):
end = _w(s, end).end()
return values, end
pattern(r'\[')(JSONArray)
-
+
+
ANYTHING = [
JSONObject,
JSONArray,
@@ -193,11 +242,12 @@ ANYTHING = [
JSONScanner = Scanner(ANYTHING)
+
class JSONDecoder(object):
"""
Simple JSON <http://json.org> decoder
- Performs the following translations in decoding:
+ Performs the following translations in decoding by default:
+---------------+-------------------+
| JSON | Python |
@@ -226,7 +276,8 @@ class JSONDecoder(object):
_scanner = Scanner(ANYTHING)
__all__ = ['__init__', 'decode', 'raw_decode']
- def __init__(self, encoding=None, object_hook=None):
+ def __init__(self, encoding=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, strict=True):
"""
``encoding`` determines the encoding used to interpret any ``str``
objects decoded by this instance (utf-8 by default). It has no
@@ -239,9 +290,28 @@ class JSONDecoder(object):
of every JSON object decoded and its return value will be used in
place of the given ``dict``. This can be used to provide custom
deserializations (e.g. to support JSON-RPC class hinting).
+
+ ``parse_float``, if specified, will be called with the string
+ of every JSON float to be decoded. By default this is equivalent to
+ float(num_str). This can be used to use another datatype or parser
+ for JSON floats (e.g. decimal.Decimal).
+
+ ``parse_int``, if specified, will be called with the string
+ of every JSON int to be decoded. By default this is equivalent to
+ int(num_str). This can be used to use another datatype or parser
+ for JSON integers (e.g. float).
+
+ ``parse_constant``, if specified, will be called with one of the
+ following strings: -Infinity, Infinity, NaN, null, true, false.
+ This can be used to raise an exception if invalid JSON numbers
+ are encountered.
"""
self.encoding = encoding
self.object_hook = object_hook
+ self.parse_float = parse_float
+ self.parse_int = parse_int
+ self.parse_constant = parse_constant
+ self.strict = strict
def decode(self, s, _w=WHITESPACE.match):
"""
diff --git a/django/utils/simplejson/encoder.py b/django/utils/simplejson/encoder.py
index c83c6873eb..e6c01f6138 100644
--- a/django/utils/simplejson/encoder.py
+++ b/django/utils/simplejson/encoder.py
@@ -3,11 +3,15 @@ Implementation of JSONEncoder
"""
import re
-ESCAPE = re.compile(r'[\x00-\x19\\"\b\f\n\r\t]')
-ESCAPE_ASCII = re.compile(r'([\\"/]|[^\ -~])')
+try:
+ from django.utils.simplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii
+except ImportError:
+ pass
+
+ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
+ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
+HAS_UTF8 = re.compile(r'[\x80-\xff]')
ESCAPE_DCT = {
- # escape all forward slashes to prevent </script> attack
- '/': '\\/',
'\\': '\\\\',
'"': '\\"',
'\b': '\\b',
@@ -19,8 +23,9 @@ ESCAPE_DCT = {
for i in range(0x20):
ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
-# assume this produces an infinity on all machines (probably not guaranteed)
+# Assume this produces an infinity on all machines (probably not guaranteed)
INFINITY = float('1e66666')
+FLOAT_REPR = repr
def floatstr(o, allow_nan=True):
# Check for specials. Note that this type of test is processor- and/or
@@ -33,7 +38,7 @@ def floatstr(o, allow_nan=True):
elif o == -INFINITY:
text = '-Infinity'
else:
- return str(o)
+ return FLOAT_REPR(o)
if not allow_nan:
raise ValueError("Out of range float values are not JSON compliant: %r"
@@ -50,15 +55,32 @@ def encode_basestring(s):
return ESCAPE_DCT[match.group(0)]
return '"' + ESCAPE.sub(replace, s) + '"'
-def encode_basestring_ascii(s):
+
+def py_encode_basestring_ascii(s):
+ if isinstance(s, str) and HAS_UTF8.search(s) is not None:
+ s = s.decode('utf-8')
def replace(match):
s = match.group(0)
try:
return ESCAPE_DCT[s]
except KeyError:
- return '\\u%04x' % (ord(s),)
+ n = ord(s)
+ if n < 0x10000:
+ return '\\u%04x' % (n,)
+ else:
+ # surrogate pair
+ n -= 0x10000
+ s1 = 0xd800 | ((n >> 10) & 0x3ff)
+ s2 = 0xdc00 | (n & 0x3ff)
+ return '\\u%04x\\u%04x' % (s1, s2)
return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
-
+
+
+try:
+ encode_basestring_ascii = c_encode_basestring_ascii
+except NameError:
+ encode_basestring_ascii = py_encode_basestring_ascii
+
class JSONEncoder(object):
"""
@@ -94,7 +116,7 @@ class JSONEncoder(object):
key_separator = ': '
def __init__(self, skipkeys=False, ensure_ascii=True,
check_circular=True, allow_nan=True, sort_keys=False,
- indent=None, separators=None):
+ indent=None, separators=None, encoding='utf-8', default=None):
"""
Constructor for JSONEncoder, with sensible defaults.
@@ -126,8 +148,16 @@ class JSONEncoder(object):
None is the most compact representation.
If specified, separators should be a (item_separator, key_separator)
- tuple. The default is (', ', ': '). To get the most compact JSON
+ tuple. The default is (', ', ': '). To get the most compact JSON
representation you should specify (',', ':') to eliminate whitespace.
+
+ If specified, default is a function that gets called for objects
+ that can't otherwise be serialized. It should return a JSON encodable
+ version of the object or raise a ``TypeError``.
+
+ If encoding is not None, then all input strings will be
+ transformed into unicode using that encoding prior to JSON-encoding.
+ The default is UTF-8.
"""
self.skipkeys = skipkeys
@@ -139,6 +169,9 @@ class JSONEncoder(object):
self.current_indent_level = 0
if separators is not None:
self.item_separator, self.key_separator = separators
+ if default is not None:
+ self.default = default
+ self.encoding = encoding
def _newline_indent(self):
return '\n' + (' ' * (self.indent * self.current_indent_level))
@@ -207,8 +240,14 @@ class JSONEncoder(object):
items = [(k, dct[k]) for k in keys]
else:
items = dct.iteritems()
+ _encoding = self.encoding
+ _do_decode = (_encoding is not None
+ and not (_encoding == 'utf-8'))
for key, value in items:
- if isinstance(key, basestring):
+ if isinstance(key, str):
+ if _do_decode:
+ key = key.decode(_encoding)
+ elif isinstance(key, basestring):
pass
# JavaScript is weakly typed for these, so it makes sense to
# also allow them. Many encoders seem to do something like this.
@@ -247,6 +286,10 @@ class JSONEncoder(object):
encoder = encode_basestring_ascii
else:
encoder = encode_basestring
+ _encoding = self.encoding
+ if (_encoding is not None and isinstance(o, str)
+ and not (_encoding == 'utf-8')):
+ o = o.decode(_encoding)
yield encoder(o)
elif o is None:
yield 'null'
@@ -304,11 +347,22 @@ class JSONEncoder(object):
Return a JSON string representation of a Python data structure.
>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
- '{"foo":["bar", "baz"]}'
+ '{"foo": ["bar", "baz"]}'
"""
- # This doesn't pass the iterator directly to ''.join() because it
- # sucks at reporting exceptions. It's going to do this internally
- # anyway because it uses PySequence_Fast or similar.
+ # This is for extremely simple cases and benchmarks.
+ if isinstance(o, basestring):
+ if isinstance(o, str):
+ _encoding = self.encoding
+ if (_encoding is not None
+ and not (_encoding == 'utf-8')):
+ o = o.decode(_encoding)
+ if self.ensure_ascii:
+ return encode_basestring_ascii(o)
+ else:
+ return encode_basestring(o)
+ # This doesn't pass the iterator directly to ''.join() because the
+ # exceptions aren't as detailed. The list call should be roughly
+ # equivalent to the PySequence_Fast that ''.join() would do.
chunks = list(self.iterencode(o))
return ''.join(chunks)
diff --git a/django/utils/simplejson/jsonfilter.py b/django/utils/simplejson/jsonfilter.py
deleted file mode 100644
index d02ae2033a..0000000000
--- a/django/utils/simplejson/jsonfilter.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from django.utils import simplejson
-import cgi
-
-class JSONFilter(object):
- def __init__(self, app, mime_type='text/x-json'):
- self.app = app
- self.mime_type = mime_type
-
- def __call__(self, environ, start_response):
- # Read JSON POST input to jsonfilter.json if matching mime type
- response = {'status': '200 OK', 'headers': []}
- def json_start_response(status, headers):
- response['status'] = status
- response['headers'].extend(headers)
- environ['jsonfilter.mime_type'] = self.mime_type
- if environ.get('REQUEST_METHOD', '') == 'POST':
- if environ.get('CONTENT_TYPE', '') == self.mime_type:
- args = [_ for _ in [environ.get('CONTENT_LENGTH')] if _]
- data = environ['wsgi.input'].read(*map(int, args))
- environ['jsonfilter.json'] = simplejson.loads(data)
- res = simplejson.dumps(self.app(environ, json_start_response))
- jsonp = cgi.parse_qs(environ.get('QUERY_STRING', '')).get('jsonp')
- if jsonp:
- content_type = 'text/javascript'
- res = ''.join(jsonp + ['(', res, ')'])
- elif 'Opera' in environ.get('HTTP_USER_AGENT', ''):
- # Opera has bunk XMLHttpRequest support for most mime types
- content_type = 'text/plain'
- else:
- content_type = self.mime_type
- headers = [
- ('Content-type', content_type),
- ('Content-length', len(res)),
- ]
- headers.extend(response['headers'])
- start_response(response['status'], headers)
- return [res]
-
-def factory(app, global_conf, **kw):
- return JSONFilter(app, **kw)
diff --git a/django/utils/simplejson/scanner.py b/django/utils/simplejson/scanner.py
index 64f4999fb5..2a18390d0d 100644
--- a/django/utils/simplejson/scanner.py
+++ b/django/utils/simplejson/scanner.py
@@ -1,18 +1,21 @@
"""
Iterator based sre token scanner
"""
-import sre_parse, sre_compile, sre_constants
-from sre_constants import BRANCH, SUBPATTERN
-from re import VERBOSE, MULTILINE, DOTALL
import re
+from re import VERBOSE, MULTILINE, DOTALL
+import sre_parse
+import sre_compile
+import sre_constants
+from sre_constants import BRANCH, SUBPATTERN
__all__ = ['Scanner', 'pattern']
FLAGS = (VERBOSE | MULTILINE | DOTALL)
+
class Scanner(object):
def __init__(self, lexicon, flags=FLAGS):
self.actions = [None]
- # combine phrases into a compound pattern
+ # Combine phrases into a compound pattern
s = sre_parse.Pattern()
s.flags = flags
p = []
@@ -26,10 +29,10 @@ class Scanner(object):
p.append(subpattern)
self.actions.append(token)
+ s.groups = len(p) + 1 # NOTE(guido): Added to make SRE validation work
p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])
self.scanner = sre_compile.compile(p)
-
def iterscan(self, string, idx=0, context=None):
"""
Yield match, end_idx for each match
@@ -54,10 +57,11 @@ class Scanner(object):
match = self.scanner.scanner(string, matchend).match
yield rval, matchend
lastend = matchend
-
+
+
def pattern(pattern, flags=FLAGS):
def decorator(fn):
fn.pattern = pattern
fn.regex = re.compile(pattern, flags)
return fn
- return decorator
+ return decorator \ No newline at end of file
diff --git a/django/utils/simplejson/tool.py b/django/utils/simplejson/tool.py
new file mode 100644
index 0000000000..d0eb8ad9ee
--- /dev/null
+++ b/django/utils/simplejson/tool.py
@@ -0,0 +1,44 @@
+r"""
+Using simplejson from the shell to validate and
+pretty-print::
+
+ $ echo '{"json":"obj"}' | python -msimplejson
+ {
+ "json": "obj"
+ }
+ $ echo '{ 1.2:3.4}' | python -msimplejson
+ Expecting property name: line 1 column 2 (char 2)
+
+Note that the JSON produced by this module's default settings
+is a subset of YAML, so it may be used as a serializer for that as well.
+"""
+import django.utils.simplejson
+
+#
+# Pretty printer:
+# curl http://mochikit.com/examples/ajax_tables/domains.json | python -msimplejson.tool
+#
+
+def main():
+ import sys
+ if len(sys.argv) == 1:
+ infile = sys.stdin
+ outfile = sys.stdout
+ elif len(sys.argv) == 2:
+ infile = open(sys.argv[1], 'rb')
+ outfile = sys.stdout
+ elif len(sys.argv) == 3:
+ infile = open(sys.argv[1], 'rb')
+ outfile = open(sys.argv[2], 'wb')
+ else:
+ raise SystemExit("%s [infile [outfile]]" % (sys.argv[0],))
+ try:
+ obj = simplejson.load(infile)
+ except ValueError, e:
+ raise SystemExit(e)
+ simplejson.dump(obj, outfile, sort_keys=True, indent=4)
+ outfile.write('\n')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/django/utils/thread_support.py b/django/utils/thread_support.py
new file mode 100644
index 0000000000..2b97d165ca
--- /dev/null
+++ b/django/utils/thread_support.py
@@ -0,0 +1,12 @@
+"""
+Code used in a couple of places to work with the current thread's environment.
+Current users include i18n and request prefix handling.
+"""
+
+try:
+ import threading
+ currentThread = threading.currentThread
+except ImportError:
+ def currentThread():
+ return "no threading"
+
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 451420c7d8..93bb3c9bf9 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -8,18 +8,7 @@ import gettext as gettext_module
from cStringIO import StringIO
from django.utils.safestring import mark_safe, SafeData
-
-try:
- import threading
- hasThreads = True
-except ImportError:
- hasThreads = False
-
-if hasThreads:
- currentThread = threading.currentThread
-else:
- def currentThread():
- return 'no threading'
+from django.utils.thread_support import currentThread
# Translations are cached in a dictionary for every language+app tuple.
# The active translations are stored by threadid to make them thread local.
diff --git a/django/views/debug.py b/django/views/debug.py
index 380aa8bf06..adc1ae936e 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -145,8 +145,6 @@ class ExceptionReporter:
'line': line,
'name': origin.name,
}
- if hasattr(self.exc_value, 'exc_info') and self.exc_value.exc_info:
- exc_type, exc_value, tb = self.exc_value.exc_info
def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, module_name=None):
"""
diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py
index 4fe639f321..aaa0bdc4b6 100644
--- a/django/views/generic/create_update.py
+++ b/django/views/generic/create_update.py
@@ -15,11 +15,11 @@ def deprecate_follow(follow):
needed for newforms-based forms.
"""
if follow is not None:
- import warning
+ import warnings
msg = ("Generic views have been changed to use newforms, and the"
- "'follow' argument is no longer used. Please update your code"
- "to not use the 'follow' argument.")
- warning.warn(msg, DeprecationWarning, stacklevel=3)
+ " 'follow' argument is no longer used. Please update your code"
+ " to not use the 'follow' argument.")
+ warnings.warn(msg, DeprecationWarning, stacklevel=3)
def apply_extra_context(extra_context, context):
"""
diff --git a/django/views/generic/simple.py b/django/views/generic/simple.py
index 9d7efdc6c4..0a68b82a10 100644
--- a/django/views/generic/simple.py
+++ b/django/views/generic/simple.py
@@ -1,4 +1,3 @@
-from django.shortcuts import render_to_response
from django.template import loader, RequestContext
from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseGone
diff --git a/docs/add_ons.txt b/docs/add_ons.txt
index 029e314f12..2b2de76cba 100644
--- a/docs/add_ons.txt
+++ b/docs/add_ons.txt
@@ -23,9 +23,10 @@ admin
=====
The automatic Django administrative interface. For more information, see
-`Tutorial 2`_.
+`Tutorial 2`_ and the `admin documentation`_.
.. _Tutorial 2: ../tutorial02/
+.. _admin documentation: ../admin/
Requires the auth_ and contenttypes_ contrib packages to be installed.
@@ -76,7 +77,7 @@ Requires the sites_ contrib package to be installed as well.
formtools
=========
-A set of high-level abstractions for Django forms (django.newforms).
+A set of high-level abstractions for Django forms (django.forms).
django.contrib.formtools.preview
--------------------------------
diff --git a/docs/admin.txt b/docs/admin.txt
index fbdd19bc90..82d85a6f5f 100644
--- a/docs/admin.txt
+++ b/docs/admin.txt
@@ -18,19 +18,21 @@ Django's admin interface.
Overview
========
-There are four steps in activating the Django admin site:
+There are five steps in activating the Django admin site:
- 1. Determine which of your application's models should be editable in the
+ 1. Add ``django.contrib.admin`` to your ``INSTALLED_APPS`` setting.
+
+ 2. Determine which of your application's models should be editable in the
admin interface.
- 2. For each of those models, optionally create a ``ModelAdmin`` class that
+ 3. For each of those models, optionally create a ``ModelAdmin`` class that
encapsulates the customized admin functionality and options for that
particular model.
- 3. Instantiate an ``AdminSite`` and tell it about each of your models and
+ 4. Instantiate an ``AdminSite`` and tell it about each of your models and
``ModelAdmin`` classes.
- 4. Hook the ``AdminSite`` instance into your URLconf.
+ 5. Hook the ``AdminSite`` instance into your URLconf.
``ModelAdmin`` objects
======================
@@ -41,7 +43,7 @@ Let's take a look at a very simple example the ``ModelAdmin``::
from django.contrib import admin
from myproject.myapp.models import Author
-
+
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
@@ -67,6 +69,13 @@ Example::
date_hierarchy = 'pub_date'
+``form``
+~~~~~~~~
+
+The default ``forms.ModelForm`` class used to generate the form on the
+add/change pages for models. You can easily change this to your own
+``ModelForm`` to override the default form behavior of the add/change pages.
+
``fieldsets``
~~~~~~~~~~~~~
@@ -82,7 +91,7 @@ dictionary of information about the fieldset, including a list of fields to be
displayed in it.
A full example, taken from the ``django.contrib.flatpages.FlatPage`` model::
-
+
class FlatPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
@@ -106,9 +115,9 @@ The ``field_options`` dictionary can have the following keys:
``fields``
A tuple of field names to display in this fieldset. This key is required.
-
+
Example::
-
+
{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
}
@@ -116,26 +125,20 @@ The ``field_options`` dictionary can have the following keys:
To display multiple fields on the same line, wrap those fields in their own
tuple. In this example, the ``first_name`` and ``last_name`` fields will
display on the same line::
-
+
{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}
``classes``
- A string containing extra CSS classes to apply to the fieldset.
-
+ A list containing extra CSS classes to apply to the fieldset.
+
Example::
-
- {
- 'classes': 'wide',
- }
- Apply multiple classes by separating them with spaces. Example::
-
{
- 'classes': 'wide extrapretty',
+ 'classes': ['wide', 'extrapretty'],
}
-
+
Two useful classes defined by the default admin-site stylesheet are
``collapse`` and ``wide``. Fieldsets with the ``collapse`` style will be
initially collapsed in the admin and replaced with a small "click to expand"
@@ -143,13 +146,38 @@ The ``field_options`` dictionary can have the following keys:
``description``
A string of optional extra text to be displayed at the top of each fieldset,
- under the heading of the fieldset. It's used verbatim, so you can use any HTML
- and you must escape any special HTML characters (such as ampersands) yourself.
+ under the heading of the fieldset.
+
+ Note that this value is *not* HTML-escaped when it's displayed in
+ the admin interface. This lets you include HTML if you so desire.
+ Alternatively you can use plain text and
+ ``django.utils.html.escape()`` to escape any HTML special
+ characters.
+
+``fields``
+~~~~~~~~~~
+
+Use this option as an alternative to ``fieldsets`` if the layout does not
+matter and if you want to only show a subset of the available fields in the
+form. For example, you could define a simpler version of the admin form for
+the ``django.contrib.flatpages.FlatPage`` model as follows::
+
+ class FlatPageAdmin(admin.ModelAdmin):
+ fields = ('url', 'title', 'content')
+
+In the above example, only the fields 'url', 'title' and 'content' will be
+displayed, sequencially, in the form.
+
+.. admonition:: Note
+
+ This ``fields`` option should not be confused with the ``fields``
+ dictionary key that is within the ``fieldsets`` option, as described in
+ the previous section.
``filter_horizontal``
~~~~~~~~~~~~~~~~~~~~~
-Use a nifty unobtrusive Javascript "filter" interface instead of the
+Use a nifty unobtrusive JavaScript "filter" interface instead of the
usability-challenged ``<select multiple>`` in the admin form. The value is a
list of fields that should be displayed as a horizontal filter interface. See
``filter_vertical`` to use a vertical interface.
@@ -192,7 +220,7 @@ A few special cases to note about ``list_display``:
function attribute, for use as the header for the field.
Here's a full example model::
-
+
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
@@ -200,7 +228,7 @@ A few special cases to note about ``list_display``:
def decade_born_in(self):
return self.birthday.strftime('%Y')[:3] + "0's"
decade_born_in.short_description = 'Birth decade'
-
+
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')
@@ -218,7 +246,7 @@ A few special cases to note about ``list_display``:
def colored_name(self):
return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
colored_name.allow_tags = True
-
+
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
@@ -235,7 +263,7 @@ A few special cases to note about ``list_display``:
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == 5
born_in_fifties.boolean = True
-
+
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'born_in_fifties')
@@ -264,7 +292,7 @@ A few special cases to note about ``list_display``:
return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
colored_first_name.allow_tags = True
colored_first_name.admin_order_field = 'first_name'
-
+
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'colored_first_name')
@@ -355,6 +383,11 @@ ordered. This should be a list or tuple in the same format as a model's
If this isn't provided, the Django admin will use the model's default ordering.
+.. admonition:: Note
+
+ Django will only honor the first element in the list/tuple; any others
+ will be ignored.
+
``prepopulated_fields``
~~~~~~~~~~~~~~~~~~~~~~~
@@ -364,11 +397,15 @@ it should prepopulate from::
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
-When set the given fields will use a bit of Javascript to populate from the
-fields assigned.
+When set, the given fields will use a bit of JavaScript to populate from the
+fields assigned. The main use for this functionality is to automatically
+generate the value for ``SlugField`` fields from one or more other fields. The
+generated value is produced by concatenating the values of the source fields,
+and then by transforming that result into a valid slug (e.g. substituting
+dashes for spaces).
-``prepopulated_fields`` doesn't accept DateTimeFields, ForeignKeys nor
-ManyToManyFields.
+``prepopulated_fields`` doesn't accept ``DateTimeField``, ``ForeignKey``, nor
+``ManyToManyField`` fields.
``radio_fields``
~~~~~~~~~~~~~~~~
@@ -396,7 +433,10 @@ overhead of having to select all the related instances to display in the
drop-down.
``raw_id_fields`` is a list of fields you would like to change
-into a ``Input`` widget for the primary key.
+into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
+
+ class ArticleAdmin(admin.ModelAdmin):
+ raw_id_fields = ("newspaper",)
``save_as``
~~~~~~~~~~~
@@ -484,7 +524,7 @@ with an operator:
``ModelAdmin`` media definitions
--------------------------------
-There are times where you would like add a bit of CSS and/or Javascript to
+There are times where you would like add a bit of CSS and/or JavaScript to
the add/change views. This can be accomplished by using a Media inner class
on your ``ModelAdmin``::
@@ -498,24 +538,49 @@ on your ``ModelAdmin``::
Keep in mind that this will be prepended with ``MEDIA_URL``. The same rules
apply as `regular media definitions on forms`_.
-.. _regular media definitions on forms: ../newforms/#media
+.. _regular media definitions on forms: ../forms/#media
+
+Adding custom validation to the admin
+-------------------------------------
+
+Adding custom validation of data in the admin is quite easy. The automatic
+admin interfaces reuses the Django `forms`_ module. The ``ModelAdmin`` class
+gives you the ability define your own form::
+
+ class ArticleAdmin(admin.ModelAdmin):
+ form = MyArticleAdminForm
+
+``MyArticleAdminForm`` can be defined anywhere as long as you import where
+needed. Now within your form you can add your own custom validation for
+any field::
+
+ class MyArticleAdminForm(forms.ModelForm):
+ def clean_name(self):
+ # do something that validates your data
+ return self.cleaned_data["name"]
+
+It is important you use a ``ModelForm`` here otherwise things can break. See
+the `forms`_ documentation on `custom validation`_ for more information.
+
+.. _forms: ../forms/
+.. _custom validation: ../forms/#custom-form-and-field-validation
``InlineModelAdmin`` objects
============================
The admin interface has the ability to edit models on the same page as a
-parent model. These are called inlines. You can add them a model being
-specifing them in a ``ModelAdmin.inlines`` attribute::
+parent model. These are called inlines. You can add them to a model by
+specifying them in a ``ModelAdmin.inlines`` attribute::
class BookInline(admin.TabularInline):
model = Book
-
+
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
-Django provides two subclasses of ``InlineModelAdmin`` and they are::
+Django provides two subclasses of ``InlineModelAdmin`` and they are:
* ``TabularInline``
* ``StackedInline``
@@ -562,7 +627,7 @@ inline.
This controls the number of extra forms the formset will display in addition
to the initial forms. See the `formsets documentation`_ for more information.
-.. _formsets documentation: ../newforms/#formsets
+.. _formsets documentation: ../forms/#formsets
``max_num``
~~~~~~~~~~~
@@ -573,6 +638,21 @@ enough. See `max_num in formsets`_ for more information.
.. _max_num in formsets: ../modelforms/#limiting-the-number-of-objects-editable
+``raw_id_fields``
+~~~~~~~~~~~~~~~~~
+
+By default, Django's admin uses a select-box interface (<select>) for
+fields that are ``ForeignKey``. Sometimes you don't want to incur the
+overhead of having to select all the related instances to display in the
+drop-down.
+
+``raw_id_fields`` is a list of fields you would like to change
+into a ``Input`` widget for either a ``ForeignKey`` or ``ManyToManyField``::
+
+ class BookInline(admin.TabularInline):
+ model = Book
+ raw_id_fields = ("pages",)
+
``template``
~~~~~~~~~~~~
@@ -598,7 +678,7 @@ Take this model for instance::
class Friendship(models.Model):
to_person = models.ForeignKey(Person, related_name="friends")
from_person = models.ForeignKey(Person, related_name="from_friends")
-
+
If you wanted to display an inline on the ``Person`` admin add/change pages
you need to explicitly define the foreign key since it is unable to do so
automatically::
@@ -606,12 +686,67 @@ automatically::
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
-
+
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
+Working with Many-to-Many Intermediary Models
+----------------------------------------------
+
+By default, admin widgets for many-to-many relations will be displayed inline
+on whichever model contains the actual reference to the ``ManyToManyField``.
+However, when you specify an intermediary model using the ``through``
+argument to a ``ManyToManyField``, the admin will not display a widget by
+default. This is because each instance of that intermediary model requires
+more information than could be displayed in a single widget, and the layout
+required for multiple widgets will vary depending on the intermediate model.
+
+However, we still want to be able to edit that information inline. Fortunately,
+this is easy to do with inline admin models. Suppose we have the following
+models::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ class Group(models.Model):
+ name = models.CharField(max_length=128)
+ members = models.ManyToManyField(Person, through='Membership')
+
+ class Membership(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ date_joined = models.DateField()
+ invite_reason = models.CharField(max_length=64)
+
+The first step in displaying this intermediate model in the admin is to
+define an inline class for the ``Membership`` model::
+
+ class MembershipInline(admin.TabularInline):
+ model = Membership
+ extra = 1
+
+This simple example uses the default ``InlineModelAdmin`` values for the
+``Membership`` model, and limits the extra add forms to one. This could be
+customized using any of the options available to ``InlineModelAdmin`` classes.
+
+Now create admin views for the ``Person`` and ``Group`` models::
+
+ class PersonAdmin(admin.ModelAdmin):
+ inlines = (MembershipInline,)
+
+ class GroupAdmin(admin.ModelAdmin):
+ inlines = (MembershipInline,)
+
+Finally, register your ``Person`` and ``Group`` models with the admin site::
+
+ admin.site.register(Person, PersonAdmin)
+ admin.site.register(Group, GroupAdmin)
+
+Now your admin site is set up to edit ``Membership`` objects inline from
+either the ``Person`` or the ``Group`` detail pages.
+
``AdminSite`` objects
=====================
@@ -628,7 +763,7 @@ In this example, we register the default ``AdminSite`` instance
# urls.py
from django.conf.urls.defaults import *
from django.contrib import admin
-
+
admin.autodiscover()
urlpatterns = patterns('',
diff --git a/docs/api_stability.txt b/docs/api_stability.txt
index 769359b75e..f56872ca51 100644
--- a/docs/api_stability.txt
+++ b/docs/api_stability.txt
@@ -59,7 +59,7 @@ These APIs are stable:
- `Request/response objects`_.
- - `Sending email`_.
+ - `Sending e-mail`_.
- `Sessions`_.
@@ -108,13 +108,12 @@ change:
.. _mod_python integration: ../modpython/
.. _redirects: ../redirects/
.. _request/response objects: ../request_response/
-.. _sending email: ../email/
+.. _sending e-mail: ../email/
.. _sessions: ../sessions/
.. _settings: ../settings/
.. _syndication: ../syndication_feeds/
.. _template language: ../templates/
.. _transactions: ../transactions/
.. _url dispatch: ../url_dispatch/
-.. _forms and validation: ../forms/
.. _serialization: ../serialization/
.. _authentication: ../authentication/
diff --git a/docs/authentication.txt b/docs/authentication.txt
index cd76731bc4..acd378fcab 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -517,7 +517,7 @@ It's your responsibility to provide the login form in a template called
template context variables:
* ``form``: A ``Form`` object representing the login form. See the
- `newforms documentation`_ for more on ``Form`` objects.
+ `forms documentation`_ for more on ``FormWrapper`` objects.
* ``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
@@ -557,7 +557,7 @@ block::
{% endblock %}
-.. _newforms documentation: ../newforms/
+.. _forms documentation: ../forms/
.. _site framework docs: ../sites/
Other built-in views
@@ -631,7 +631,7 @@ The page shown after a user has changed their password.
**Description:**
Allows a user to reset their password, and sends them the new password
-in an email.
+in an e-mail.
**Optional arguments:**
@@ -640,7 +640,7 @@ in an email.
``registration/password_reset_form.html`` if not supplied.
* ``email_template_name``: The full name of a template to use for
- generating the email with the new password. This will default to
+ generating the e-mail with the new password. This will default to
``registration/password_reset_email.html`` if not supplied.
**Template context:**
@@ -696,7 +696,7 @@ system provides several built-in forms:
user to change their password.
* ``django.contrib.auth.forms.PasswordResetForm``: A form for resetting a
- user's password and emailing the new password to them.
+ user's password and e-mailing the new password to them.
* ``django.contrib.auth.forms.UserCreationForm``: A form for creating a
new user.
diff --git a/docs/cache.txt b/docs/cache.txt
index 3318b2ad4a..d22dd91994 100644
--- a/docs/cache.txt
+++ b/docs/cache.txt
@@ -6,8 +6,8 @@ A fundamental tradeoff in dynamic Web sites is, well, they're dynamic. Each
time a user requests a page, the Web server makes all sorts of calculations --
from database queries to template rendering to business logic -- to create the
page that your site's visitor sees. This is a lot more expensive, from a
-processing-overhead perspective, than your standard read-a-file-off-the-filesystem
-server arrangement.
+processing-overhead perspective, than your standard
+read-a-file-off-the-filesystem server arrangement.
For most Web applications, this overhead isn't a big deal. Most Web
applications aren't washingtonpost.com or slashdot.org; they're simply small-
@@ -159,19 +159,6 @@ cache is multi-process and thread-safe. To use it, set ``CACHE_BACKEND`` to
CACHE_BACKEND = 'locmem:///'
-Simple caching (for development)
---------------------------------
-
-A simple, single-process memory cache is available as ``"simple:///"``. This
-merely saves cached data in-process, which means it should only be used in
-development or testing environments. For example::
-
- CACHE_BACKEND = 'simple:///'
-
-**New in Django development version:** This cache backend is deprecated and
-will be removed in a future release. New code should use the ``locmem`` backend
-instead.
-
Dummy caching (for development)
-------------------------------
@@ -186,6 +173,27 @@ production environment still will. To activate dummy caching, set
CACHE_BACKEND = 'dummy:///'
+Using a custom cache backend
+----------------------------
+
+**New in Django development version**
+
+While Django includes support for a number of cache backends out-of-the-box,
+sometimes you will want to use a customised verison or your own backend. To
+use an external cache backend with Django, use a Python import path as the
+scheme portion (the part before the initial colon) of the ``CACHE_BACKEND``
+URI, like so::
+
+ CACHE_BACKEND = 'path.to.backend://'
+
+If you're building your own backend, you can use the standard cache backends
+as reference implementations. You'll find the code in the
+``django/core/cache/backends/`` directory of the Django source.
+
+Note: Without a really compelling reason, like a host that doesn't support the
+them, you should stick to the cache backends included with Django. They've
+been really well-tested and are quite easy to use.
+
CACHE_BACKEND arguments
-----------------------
diff --git a/docs/contenttypes.txt b/docs/contenttypes.txt
index 96e3b0939c..a4fc045714 100644
--- a/docs/contenttypes.txt
+++ b/docs/contenttypes.txt
@@ -205,10 +205,10 @@ model. There are three parts to setting up a ``GenericForeignKey``:
models you'll be relating to. (For most models, this means an
``IntegerField`` or ``PositiveIntegerField``.)
- This field must be of the same type as the primary key of the models
- that will be involved in the generic relation. For example, if you use
- ``IntegerField``, you won't be able to form a generic relation with a
- model that uses a ``CharField`` as a primary key.
+ This field must be of the same type as the primary key of the models
+ that will be involved in the generic relation. For example, if you use
+ ``IntegerField``, you won't be able to form a generic relation with a
+ model that uses a ``CharField`` as a primary key.
3. Give your model a ``GenericForeignKey``, and pass it the names of
the two fields described above. If these fields are named
diff --git a/docs/contributing.txt b/docs/contributing.txt
index f3bee14069..d0d56a0e39 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -525,7 +525,6 @@ Model style
* All database fields
* ``class Meta``
- * ``class Admin``
* ``def __unicode__()``
* ``def __str__()``
* ``def save()``
diff --git a/docs/csrf.txt b/docs/csrf.txt
index 7d79e39502..ba04fa67cd 100644
--- a/docs/csrf.txt
+++ b/docs/csrf.txt
@@ -4,8 +4,8 @@ Cross Site Request Forgery protection
The CsrfMiddleware class provides easy-to-use protection against
`Cross Site Request Forgeries`_. This type of attack occurs when a malicious
-web site creates a link or form button that is intended to perform some action
-on your web site, using the credentials of a logged-in user who is tricked
+Web site creates a link or form button that is intended to perform some action
+on your Web site, using the credentials of a logged-in user who is tricked
into clicking on the link in their browser.
The first defense against CSRF attacks is to ensure that GET requests
@@ -38,7 +38,7 @@ CsrfMiddleware does two things:
checks that the 'csrfmiddlewaretoken' is present and correct. If it
isn't, the user will get a 403 error.
-This ensures that only forms that have originated from your web site
+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
@@ -47,7 +47,7 @@ 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
+but they do not need to be protected, since the 'attacking' Web site
could make these kind of requests anyway.
The Content-Type is checked before modifying the response, and only
@@ -64,8 +64,8 @@ a custom authentication system that manually sets cookies and the like,
it won't help you.
If your app creates HTML pages and forms in some unusual way, (e.g.
-it sends fragments of HTML in javascript document.write statements)
+it sends fragments of HTML in JavaScript document.write statements)
you might bypass the filter that adds the hidden field to the form,
in which case form submission will always fail. It may still be possible
to use the middleware, provided you can find some way to get the
-CSRF token and ensure that is included when your form is submitted. \ No newline at end of file
+CSRF token and ensure that is included when your form is submitted.
diff --git a/docs/custom_model_fields.txt b/docs/custom_model_fields.txt
index cbaac873e3..6b8f3c3ac6 100644
--- a/docs/custom_model_fields.txt
+++ b/docs/custom_model_fields.txt
@@ -111,7 +111,7 @@ into the precise details of what ``Field`` can do later on; for now, suffice it
to say that everything descends from ``Field`` and then customizes key pieces
of the class behavior.
-.. _form fields: ../newforms/#fields
+.. _form fields: ../forms/#fields
It's important to realize that a Django field class is not what is stored in
your model attributes. The model attributes contain normal Python objects. The
@@ -385,8 +385,8 @@ Python object type we want to store in the model's attribute.
called when it is created, you should be using `The SubfieldBase metaclass`_
mentioned earlier. Otherwise ``to_python()`` won't be called automatically.
-``get_db_prep_save(self, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``get_db_prep_value(self, value)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the reverse of ``to_python()`` when working with the database backends
(as opposed to serialization). The ``value`` parameter is the current value of
@@ -399,10 +399,20 @@ For example::
class HandField(models.Field):
# ...
- def get_db_prep_save(self, value):
+ def get_db_prep_value(self, value):
return ''.join([''.join(l) for l in (value.north,
value.east, value.south, value.west)])
+``get_db_prep_save(self, value)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Same as the above, but called when the Field value must be *saved* to the
+database. As the default implementation just calls ``get_db_prep_value``, you
+shouldn't need to implement this method unless your custom field need a special
+conversion when being saved that is not the same as the used for normal query
+parameters (which is implemented by ``get_db_prep_value``).
+
+
``pre_save(self, model_instance, add)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -440,14 +450,21 @@ by with handling the lookup types that need special handling for your field
and pass the rest of the ``get_db_prep_lookup()`` method of the parent class.
If you needed to implement ``get_db_prep_save()``, you will usually need to
-implement ``get_db_prep_lookup()``. The usual reason is because of the
-``range`` and ``in`` lookups. In these case, you will passed a list of
-objects (presumably of the right type) and will need to convert them to a list
-of things of the right type for passing to the database. Sometimes you can
-reuse ``get_db_prep_save()``, or at least factor out some common pieces from
-both methods into a help function.
+implement ``get_db_prep_lookup()``. If you don't, ``get_db_prep_value`` will be
+called by the default implementation, to manage ``exact``, ``gt``, ``gte``,
+``lt``, ``lte``, ``in`` and ``range`` lookups.
-For example::
+You may also want to implement this method to limit the lookup types that could
+be used with your custom field type.
+
+Note that, for ``range`` and ``in`` lookups, ``get_db_prep_lookup`` will receive
+a list of objects (presumably of the right type) and will need to convert them
+to a list of things of the right type for passing to the database. Most of the
+time, you can reuse ``get_db_prep_value()``, or at least factor out some common
+pieces.
+
+For example, the following code implements ``get_db_prep_lookup`` to limit the
+accepted lookup types to ``exact`` and ``in``::
class HandField(models.Field):
# ...
@@ -455,9 +472,9 @@ For example::
def get_db_prep_lookup(self, lookup_type, value):
# We only handle 'exact' and 'in'. All others are errors.
if lookup_type == 'exact':
- return self.get_db_prep_save(value)
+ return self.get_db_prep_value(value)
elif lookup_type == 'in':
- return [self.get_db_prep_save(v) for v in value]
+ return [self.get_db_prep_value(v) for v in value]
else:
raise TypeError('Lookup type %r not supported.' % lookup_type)
@@ -493,8 +510,8 @@ This assumes we're imported a ``MyFormField`` field class (which has its own
default widget). This document doesn't cover the details of writing custom form
fields.
-.. _helper functions: ../newforms/#generating-forms-for-models
-.. _forms documentation: ../newforms/
+.. _helper functions: ../forms/#generating-forms-for-models
+.. _forms documentation: ../forms/
``get_internal_type(self)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -538,11 +555,11 @@ serializer output in some other place, outside of Django.
Although implementing this method is necessary to allow field
serialization, the API might change in the future.
-Returns a dictionary, mapping the field's attribute name to a flattened string
-version of the data. This method has some internal uses that aren't of
-interest to use here (mostly having to do with manipulators). For our
-purposes, it's sufficient to return a one item dictionary that maps the
-attribute name to a string.
+Returns a dictionary, mapping the field's attribute name to a
+flattened string version of the data. This method has some internal
+uses that aren't of interest to use here (mostly having to do with
+forms). For our purposes, it's sufficient to return a one item
+dictionary that maps the attribute name to a string.
This method is used by the serializers to convert the field into a string for
output. You can ignore the input parameters for serialization purposes,
@@ -557,7 +574,7 @@ we can reuse some existing conversion code::
def flatten_data(self, follow, obj=None):
value = self._get_val_from_obj(obj)
- return {self.attname: self.get_db_prep_save(value)}
+ return {self.attname: self.get_db_prep_value(value)}
Some general advice
--------------------
diff --git a/docs/databases.txt b/docs/databases.txt
index 6832c2b361..0fb6381c5c 100644
--- a/docs/databases.txt
+++ b/docs/databases.txt
@@ -192,8 +192,8 @@ database user must have privileges to run the following commands:
To run Django's test suite, the user needs these *additional* privileges:
- * CREATE DATABASE
- * DROP DATABASE
+ * CREATE USER
+ * DROP USER
* CREATE TABLESPACE
* DROP TABLESPACE
diff --git a/docs/db-api.txt b/docs/db-api.txt
index 5fdcd946bd..f62d5c6d57 100644
--- a/docs/db-api.txt
+++ b/docs/db-api.txt
@@ -463,7 +463,7 @@ Be careful, if you are using ``extra()`` to add custom handling to your
may or may not make sense. If you are using custom SQL fragments in your
``extra()`` calls, Django will not inspect these fragments to see if they need
to be rewritten because of changes in the merged query. So test the effects
-carefully. Also realise that if you are combining two ``QuerySets`` with
+carefully. Also realize that if you are combining two ``QuerySets`` with
``|``, you cannot use ``extra(select=...)`` or ``extra(where=...)`` on *both*
``QuerySets``. You can only use those calls on one or the other (Django will
raise a ``ValueError`` if you try to use this incorrectly).
@@ -1676,6 +1676,28 @@ whose ``headline`` contains ``'Lennon'``::
Blog.objects.filter(entry__headline__contains='Lennon')
+If you are filtering across multiple relationships and one of the intermediate
+models doesn't have a value that meets the filter condition, Django will treat
+it as if there is an empty (all values are ``NULL``), but valid, object there.
+All this means is that no error will be raised. For example, in this filter::
+
+ Blog.objects.filter(entry__author__name='Lennon')
+
+(if there was a related ``Author`` model), if there was no ``author``
+associated with an entry, it would be treated as if there was also no ``name``
+attached, rather than raising an error because of the missing ``author``.
+Usually this is exactly what you want to have happen. The only case where it
+might be confusing is if you are using ``isnull``. Thus::
+
+ Blog.objects.filter(entry__author__name__isnull=True)
+
+will return ``Blog`` objects that have an empty ``name`` on the ``author`` and
+also those which have an empty ``author`` on the ``entry``. If you don't want
+those latter objects, you could write::
+
+ Blog.objetcs.filter(entry__author__isnull=False,
+ entry__author__name__isnull=True)
+
Spanning multi-valued relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2218,7 +2240,7 @@ statement. It is a bulk operation for direct updates. It doesn't run any
signals (which are a consequence of calling ``save()``). If you want to save
every item in a ``QuerySet`` and make sure that the ``save()`` method is
called on each instance, you don't need any special function to handle that.
-Just loop over them and call ``save()``:
+Just loop over them and call ``save()``::
for item in my_queryset:
item.save()
@@ -2280,6 +2302,11 @@ For every ``FileField``, the object will have a ``get_FOO_filename()`` method,
where ``FOO`` is the name of the field. This returns the full filesystem path
to the file, according to your ``MEDIA_ROOT`` setting.
+.. note::
+ It is only valid to call this method **after** saving the model when the
+ field has been set. Prior to saving, the value returned will not contain
+ the upload directory (the `upload_to` parameter) in the path.
+
Note that ``ImageField`` is technically a subclass of ``FileField``, so every
model with an ``ImageField`` will also get this method.
@@ -2291,6 +2318,11 @@ where ``FOO`` is the name of the field. This returns the full URL to the file,
according to your ``MEDIA_URL`` setting. If the value is blank, this method
returns an empty string.
+.. note::
+ As with ``get_FOO_filename()``, it is only valid to call this method
+ **after** saving the model, otherwise an incorrect result will be
+ returned.
+
get_FOO_size()
--------------
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index f5cc02ee52..71c4cf545a 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -395,7 +395,7 @@ makemessages
Runs over the entire source tree of the current directory and pulls out all
strings marked for translation. It creates (or updates) a message file in the
-conf/locale (in the django tree) or locale (for project and application)
+conf/locale (in the Django tree) or locale (for project and application)
directory. After making changes to the messages files you need to compile them
with ``compilemessages`` for use with the builtin gettext support. See the
`i18n documentation`_ for details.
diff --git a/docs/email.txt b/docs/email.txt
index 7f2eef6fc7..e54620c818 100644
--- a/docs/email.txt
+++ b/docs/email.txt
@@ -179,7 +179,7 @@ from the request's POST data, sends that to admin@example.com and redirects to
return HttpResponse('Invalid header found.')
return HttpResponseRedirect('/contact/thanks/')
else:
- # In reality we'd use a manipulator
+ # In reality we'd use a form class
# to get proper validation errors.
return HttpResponse('Make sure all fields are entered and valid.')
diff --git a/docs/faq.txt b/docs/faq.txt
index 6d12a95cba..2c1ffa72db 100644
--- a/docs/faq.txt
+++ b/docs/faq.txt
@@ -224,19 +224,10 @@ means!).
When will you release Django 1.0?
---------------------------------
-Short answer: When we're comfortable with Django's APIs, have added all
-features that we feel are necessary to earn a "1.0" status, and are ready to
-begin maintaining backwards compatibility.
+See our `version one roadmap`_ for the detailed timeline. We're aiming for
+September 2, 2008.
-The merging of Django's `Queryset Refactor branch`_ went a long way toward Django
-1.0. Merging the `Newforms Admin branch` will be another important step.
-
-Of course, you should note that `quite a few production sites`_ use Django in
-its current status. Don't let the lack of a 1.0 turn you off.
-
-.. _Queryset Refactor branch: http://code.djangoproject.com/wiki/QuerysetRefactorBranch
-.. _Newforms Admin branch: http://code.djangoproject.com/wiki/NewformsAdminBranch
-.. _quite a few production sites: http://code.djangoproject.com/wiki/DjangoPoweredSites
+.. _version one roadmap: http://code.djangoproject.com/wiki/VersionOneRoadmap
How can I download the Django documentation to read it offline?
---------------------------------------------------------------
@@ -434,7 +425,7 @@ Using a ``FileField`` or an ``ImageField`` in a model takes a few steps:
of ``MEDIA_ROOT`` it should upload files.
#. All that will be stored in your database is a path to the file
- (relative to ``MEDIA_ROOT``). You'll must likely want to use the
+ (relative to ``MEDIA_ROOT``). You'll most likely want to use the
convenience ``get_<fieldname>_url`` function provided by Django. For
example, if your ``ImageField`` is called ``mug_shot``, you can get the
absolute URL to your image in a template with
diff --git a/docs/fastcgi.txt b/docs/fastcgi.txt
index 78ee9d408c..edd4c8a83d 100644
--- a/docs/fastcgi.txt
+++ b/docs/fastcgi.txt
@@ -79,9 +79,9 @@ your ``manage.py`` is), and then run ``manage.py`` with the ``runfcgi`` option::
If you specify ``help`` as the only option after ``runfcgi``, it'll display a
list of all the available options.
-You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and ``port``.
-Then, when you set up your Web server, you'll just need to point it at the host/port
-or socket you specified when starting the FastCGI server.
+You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and
+``port``. Then, when you set up your Web server, you'll just need to point it
+at the host/port or socket you specified when starting the FastCGI server.
Protocols
---------
@@ -209,6 +209,9 @@ This is probably the most common case, if you're using Django's admin site::
.. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
+Django will automatically use the pre-rewrite version of the URL when
+constructing URLs with the ``{% url %}`` template tag (and similar methods).
+
lighttpd setup
==============
@@ -336,3 +339,30 @@ detailed above.
.. _modpython: ../modpython/#serving-the-admin-files
+Forcing the URL prefix to a particular value
+============================================
+
+Because many of these fastcgi-based solutions require rewriting the URL at
+some point inside the webserver, the path information that Django sees may not
+resemble the original URL that was passed in. This is a problem if the Django
+application is being served from under a particular prefix and you want your
+URLs from the ``{% url %}`` tag to look like the prefix, rather than the
+rewritten version, which might contain, for example, ``mysite.fcgi``.
+
+Django makes a good attempt to work out what the real script name prefix
+should be. In particular, if the webserver sets the ``SCRIPT_URL`` (specific
+to Apache's mod_rewrite), or ``REDIRECT_URL`` (set by a few servers, including
+Apache + mod_rewrite in some situations), Django will work out the original
+prefix automatically.
+
+In the cases where Django cannot work out the prefix correctly and where you
+want the original value to be used in URLs, you can set the
+``FORCE_SCRIPT_NAME`` setting in your main ``settings`` file. This sets the
+script name uniformly for every URL served via that settings file. Thus you'll
+need to use different settings files if you want different sets of URLs to
+have different script names in this case, but that is a rare situation.
+
+As an example of how to use it, if your Django configuration is serving all of
+the URLs under ``'/'`` and you wanted to use this setting, you would set
+``FORCE_SCRIPT_NAME = ''`` in your settings file.
+
diff --git a/docs/form_for_model.txt b/docs/form_for_model.txt
index ddca9aae18..a394cd2c54 100644
--- a/docs/form_for_model.txt
+++ b/docs/form_for_model.txt
@@ -20,13 +20,13 @@ For this reason, Django provides a few helper functions that let you create a
``form_for_model()``
--------------------
-The method ``django.newforms.form_for_model()`` creates a form based on the
+The method ``django.forms.form_for_model()`` creates a form based on the
definition of a specific model. Pass it the model class, and it will return a
``Form`` class that contains a form field for each model field.
For example::
- >>> from django.newforms import form_for_model
+ >>> from django.forms import form_for_model
# Create the form class.
>>> ArticleForm = form_for_model(Article)
@@ -93,11 +93,11 @@ the full list of conversions:
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
types are special cases:
- * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``,
+ * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
* ``ManyToManyField`` is represented by
- ``django.newforms.ModelMultipleChoiceField``, which is a
+ ``django.forms.ModelMultipleChoiceField``, which is a
``MultipleChoiceField`` whose choices are a model ``QuerySet``.
In addition, each generated form field has attributes set as follows:
@@ -228,7 +228,7 @@ Using an alternate base class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want to add custom methods to the form generated by
-``form_for_model()``, write a class that extends ``django.newforms.BaseForm``
+``form_for_model()``, write a class that extends ``django.forms.BaseForm``
and contains your custom methods. Then, use the ``form`` argument to
``form_for_model()`` to tell it to use your custom form as its base class.
For example::
@@ -412,8 +412,8 @@ note is that the form display in the ``GET`` branch of the function
will use the values from the ``message`` instance as initial values for the
form field.
-.. _contact form: ../newforms/#simple-view-example
-.. _`simple example view`: ../newforms/#simple-view-example
+.. _contact form: ../forms/#simple-view-example
+.. _`simple example view`: ../forms/#simple-view-example
When should you use ``form_for_model()`` and ``form_for_instance()``?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/form_preview.txt b/docs/form_preview.txt
index e03de36187..171174704c 100644
--- a/docs/form_preview.txt
+++ b/docs/form_preview.txt
@@ -13,7 +13,7 @@ Python class.
Overview
=========
-Given a ``django.newforms.Form`` subclass that you define, this application
+Given a ``django.forms.Form`` subclass that you define, this application
takes care of the following workflow:
1. Displays the form as HTML on a Web page.
@@ -65,7 +65,7 @@ How to use ``FormPreview``
from myapp.preview import SomeModelFormPreview
from myapp.models import SomeModel
- from django import newforms as forms
+ from django import forms
...and add the following line to the appropriate model in your URLconf::
diff --git a/docs/form_wizard.txt b/docs/form_wizard.txt
index cd9e58ded1..661127e5b0 100644
--- a/docs/form_wizard.txt
+++ b/docs/form_wizard.txt
@@ -17,7 +17,7 @@ etc.
The term "wizard," in this context, is `explained on Wikipedia`_.
.. _explained on Wikipedia: http://en.wikipedia.org/wiki/Wizard_%28software%29
-.. _forms: ../newforms/
+.. _forms: ../forms/
How it works
============
@@ -41,7 +41,7 @@ Usage
This application handles as much machinery for you as possible. Generally, you
just have to do these things:
- 1. Define a number of ``django.newforms`` ``Form`` classes -- one per wizard
+ 1. Define a number of ``django.forms`` ``Form`` classes -- one per wizard
page.
2. Create a ``FormWizard`` class that specifies what to do once all of your
forms have been submitted and validated. This also lets you override some
@@ -55,8 +55,8 @@ Defining ``Form`` classes
=========================
The first step in creating a form wizard is to create the ``Form`` classes.
-These should be standard ``django.newforms`` ``Form`` classes, covered in the
-`newforms documentation`_.
+These should be standard ``django.forms`` ``Form`` classes, covered in the
+`forms documentation`_.
These classes can live anywhere in your codebase, but convention is to put them
in a file called ``forms.py`` in your application.
@@ -65,7 +65,7 @@ For example, let's write a "contact form" wizard, where the first page's form
collects the sender's e-mail address and subject, and the second page collects
the message itself. Here's what the ``forms.py`` might look like::
- from django import newforms as forms
+ from django import forms
class ContactForm1(forms.Form):
subject = forms.CharField(max_length=100)
@@ -78,7 +78,7 @@ the message itself. Here's what the ``forms.py`` might look like::
data between pages, you may not include a ``FileField`` in any form except the
last one.
-.. _newforms documentation: ../newforms/
+.. _forms documentation: ../forms/
Creating a ``FormWizard`` class
===============================
@@ -94,7 +94,7 @@ which specifies what should happen when the data for *every* form is submitted
and validated. This method is passed two arguments:
* ``request`` -- an HttpRequest_ object
- * ``form_list`` -- a list of ``django.newforms`` ``Form`` classes
+ * ``form_list`` -- a list of ``django.forms`` ``Form`` classes
In this simplistic example, rather than perform any database operation, the
method simply renders a template of the validated data::
@@ -209,7 +209,7 @@ Default implementation::
def prefix_for_step(self, step):
return str(step)
-.. _form prefix documentation: ../newforms/#prefixes-for-forms
+.. _form prefix documentation: ../forms/#prefixes-for-forms
``render_hash_failure``
~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/forms.txt b/docs/forms.txt
index 18d322a8eb..547323d103 100644
--- a/docs/forms.txt
+++ b/docs/forms.txt
@@ -1,700 +1,2472 @@
-===============================
-Forms, fields, and manipulators
-===============================
+=================
+The forms library
+=================
-Forwards-compatibility note
-===========================
-
-The legacy forms/manipulators system described in this document is going to be
-replaced in the next Django release. If you're starting from scratch, we
-strongly encourage you not to waste your time learning this. Instead, learn and
-use the django.newforms system, which we have begun to document in the
-`newforms documentation`_.
-
-If you have legacy form/manipulator code, read the "Migration plan" section in
-that document to understand how we're making the switch.
-
-.. _newforms documentation: ../newforms/
-
-Introduction
-============
-
-Once you've got a chance to play with Django's admin interface, you'll probably
-wonder if the fantastic form validation framework it uses is available to user
-code. It is, and this document explains how the framework works.
-
-We'll take a top-down approach to examining Django's form validation framework,
-because much of the time you won't need to use the lower-level APIs. Throughout
-this document, we'll be working with the following model, a "place" object::
-
- from django.db import models
-
- PLACE_TYPES = (
- (1, 'Bar'),
- (2, 'Restaurant'),
- (3, 'Movie Theater'),
- (4, 'Secret Hideout'),
- )
-
- class Place(models.Model):
- name = models.CharField(max_length=100)
- address = models.CharField(max_length=100, blank=True)
- city = models.CharField(max_length=50, blank=True)
- state = models.USStateField()
- zip_code = models.CharField(max_length=5, blank=True)
- place_type = models.IntegerField(choices=PLACE_TYPES)
-
- class Admin:
- pass
-
- def __unicode__(self):
- return self.name
-
-Defining the above class is enough to create an admin interface to a ``Place``,
-but what if you want to allow public users to submit places?
-
-Automatic Manipulators
-======================
-
-The highest-level interface for object creation and modification is the
-**automatic Manipulator** framework. An automatic manipulator is a utility
-class tied to a given model that "knows" how to create or modify instances of
-that model and how to validate data for the object. Automatic Manipulators come
-in two flavors: ``AddManipulators`` and ``ChangeManipulators``. Functionally
-they are quite similar, but the former knows how to create new instances of the
-model, while the latter modifies existing instances. Both types of classes are
-automatically created when you define a new class::
-
- >>> from mysite.myapp.models import Place
- >>> Place.AddManipulator
- <class 'django.models.manipulators.AddManipulator'>
- >>> Place.ChangeManipulator
- <class 'django.models.manipulators.ChangeManipulator'>
-
-Using the ``AddManipulator``
-----------------------------
-
-We'll start with the ``AddManipulator``. Here's a very simple view that takes
-POSTed data from the browser and creates a new ``Place`` object::
-
- from django.shortcuts import render_to_response
- from django.http import Http404, HttpResponse, HttpResponseRedirect
- from django import forms
- from mysite.myapp.models import Place
-
- def naive_create_place(request):
- """A naive approach to creating places; don't actually use this!"""
- # Create the AddManipulator.
- manipulator = Place.AddManipulator()
-
- # Make a copy of the POSTed data so that do_html2python can
- # modify it in place (request.POST is immutable).
- new_data = request.POST.copy()
-
- # Convert the request data (which will all be strings) into the
- # appropriate Python types for those fields.
- manipulator.do_html2python(new_data)
+``django.forms`` is Django's form-handling library.
- # Save the new object.
- new_place = manipulator.save(new_data)
+.. admonition:: Looking for oldforms?
- # It worked!
- return HttpResponse("Place created: %s" % new_place)
+ ``django.forms`` was once called ``newforms`` since it replaced Django's
+ original form/manipulator/validation framework. The old form handling
+ library is still available as `django.oldforms`_, but will be removed
+ in a future version of Django.
-The ``naive_create_place`` example works, but as you probably can tell, this
-view has a number of problems:
+.. _django.oldforms: ../oldforms/
- * No validation of any sort is performed. If, for example, the ``name`` field
- isn't given in ``request.POST``, the save step will cause a database error
- because that field is required. Ugly.
+Overview
+========
- * Even if you *do* perform validation, there's still no way to give that
- information to the user in any sort of useful way.
+``django.forms`` is intended to handle HTML form display, data processing
+(validation) and redisplay. It's what you use if you want to perform
+server-side validation for an HTML form.
- * You'll have to separately create a form (and view) that submits to this
- page, which is a pain and is redundant.
+For example, if your Web site has a contact form that visitors can use to
+send you e-mail, you'd use this library to implement the display of the HTML
+form fields, along with the form validation. Any time you need to use an HTML
+``<form>``, you can use this library.
-Let's dodge these problems momentarily to take a look at how you could create a
-view with a form that submits to this flawed creation view::
+The library deals with these concepts:
- def naive_create_place_form(request):
- """Simplistic place form view; don't actually use anything like this!"""
- # Create a FormWrapper object that the template can use. Ignore
- # the last two arguments to FormWrapper for now.
- form = forms.FormWrapper(Place.AddManipulator(), {}, {})
- return render_to_response('places/naive_create_form.html', {'form': form})
+ * **Widget** -- A class that corresponds to an HTML form widget, e.g.
+ ``<input type="text">`` or ``<textarea>``. This handles rendering of the
+ widget as HTML.
-(This view, as well as all the following ones, has the same imports as in the
-first example above.)
+ * **Field** -- A class that is responsible for doing validation, e.g.
+ an ``EmailField`` that makes sure its data is a valid e-mail address.
-The ``forms.FormWrapper`` object is a wrapper that templates can
-easily deal with to create forms. Here's the ``naive_create_form.html``
-template::
+ * **Form** -- A collection of fields that knows how to validate itself and
+ display itself as HTML.
- {% extends "base.html" %}
+ * **Media** -- A definition of the CSS and JavaScript resources that are
+ required to render a form.
- {% block content %}
- <h1>Create a place:</h1>
+The library is decoupled from the other Django components, such as the database
+layer, views and templates. It relies only on Django settings, a couple of
+``django.utils`` helper functions and Django's internationalization hooks (but
+you're not required to be using internationalization features to use this
+library).
- <form method="post" action="../do_new/">
- <p><label for="id_name">Name:</label> {{ form.name }}</p>
- <p><label for="id_address">Address:</label> {{ form.address }}</p>
- <p><label for="id_city">City:</label> {{ form.city }}</p>
- <p><label for="id_state">State:</label> {{ form.state }}</p>
- <p><label for="id_zip_code">Zip:</label> {{ form.zip_code }}</p>
- <p><label for="id_place_type">Place type:</label> {{ form.place_type }}</p>
- <input type="submit" />
- </form>
- {% endblock %}
+Form objects
+============
-Before we get back to the problems with these naive set of views, let's go over
-some salient points of the above template:
+The primary way of using the ``forms`` library is to create a form object.
+Do this by subclassing ``django.forms.Form`` and specifying the form's
+fields, in a declarative style that you'll be familiar with if you've used
+Django database models. In this section, we'll iteratively develop a form
+object that you might use to implement "contact me" functionality on your
+personal Web site.
- * Field "widgets" are handled for you: ``{{ form.field }}`` automatically
- creates the "right" type of widget for the form, as you can see with the
- ``place_type`` field above.
+Start with this basic ``Form`` subclass, which we'll call ``ContactForm``::
- * There isn't a way just to spit out the form. You'll still need to define
- how the form gets laid out. This is a feature: Every form should be
- designed differently. Django doesn't force you into any type of mold.
- If you must use tables, use tables. If you're a semantic purist, you can
- probably find better HTML than in the above template.
+ from django import forms
- * To avoid name conflicts, the ``id`` values of form elements take the
- form "id_*fieldname*".
+ class ContactForm(forms.Form):
+ subject = forms.CharField(max_length=100)
+ message = forms.CharField()
+ sender = forms.EmailField()
+ cc_myself = forms.BooleanField(required=False)
-By creating a creation form we've solved problem number 3 above, but we still
-don't have any validation. Let's revise the validation issue by writing a new
-creation view that takes validation into account::
+A form is composed of ``Field`` objects. In this case, our form has four
+fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. We'll explain
+the different types of fields -- e.g., ``CharField`` and ``EmailField`` --
+shortly.
- def create_place_with_validation(request):
- manipulator = Place.AddManipulator()
- new_data = request.POST.copy()
+Creating ``Form`` instances
+---------------------------
- # Check for validation errors
- errors = manipulator.get_validation_errors(new_data)
- manipulator.do_html2python(new_data)
- if errors:
- return render_to_response('places/errors.html', {'errors': errors})
- else:
- new_place = manipulator.save(new_data)
- return HttpResponse("Place created: %s" % new_place)
+A ``Form`` instance is either **bound** to a set of data, or **unbound**.
-In this new version, errors will be found -- ``manipulator.get_validation_errors``
-handles all the validation for you -- and those errors can be nicely presented
-on an error page (templated, of course)::
+ * If it's **bound** to a set of data, it's capable of validating that data
+ and rendering the form as HTML with the data displayed in the HTML.
- {% extends "base.html" %}
+ * If it's **unbound**, it cannot do validation (because there's no data to
+ validate!), but it can still render the blank form as HTML.
- {% block content %}
+To create an unbound ``Form`` instance, simply instantiate the class::
- <h1>Please go back and correct the following error{{ errors|pluralize }}:</h1>
- <ul>
- {% for e in errors.items %}
- <li>Field "{{ e.0 }}": {{ e.1|join:", " }}</li>
- {% endfor %}
- </ul>
+ >>> f = ContactForm()
- {% endblock %}
+To bind data to a form, pass the data as a dictionary as the first parameter to
+your ``Form`` class constructor::
-Still, this has its own problems:
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
- * There's still the issue of creating a separate (redundant) view for the
- submission form.
+In this dictionary, the keys are the field names, which correspond to the
+attributes in your ``Form`` class. The values are the data you're trying
+to validate. These will usually be strings, but there's no requirement that
+they be strings; the type of data you pass depends on the ``Field``, as we'll
+see in a moment.
- * Errors, though nicely presented, are on a separate page, so the user will
- have to use the "back" button to fix errors. That's ridiculous and unusable.
+If you need to distinguish between bound and unbound form instances at runtime,
+check the value of the form's ``is_bound`` attribute::
-The best way to deal with these issues is to collapse the two views -- the form
-and the submission -- into a single view. This view will be responsible for
-creating the form, validating POSTed data, and creating the new object (if the
-data is valid). An added bonus of this approach is that errors and the form will
-both be available on the same page, so errors with fields can be presented in
-context.
+ >>> f = ContactForm()
+ >>> f.is_bound
+ False
+ >>> f = ContactForm({'subject': 'hello'})
+ >>> f.is_bound
+ True
-.. admonition:: Philosophy:
+Note that passing an empty dictionary creates a *bound* form with empty data::
- Finally, for the HTTP purists in the audience (and the authorship), this
- nicely matches the "true" meanings of HTTP GET and HTTP POST: GET fetches
- the form, and POST creates the new object.
+ >>> f = ContactForm({})
+ >>> f.is_bound
+ True
-Below is the finished view::
+If you have a bound ``Form`` instance and want to change the data somehow, or
+if you want to bind an unbound ``Form`` instance to some data, create another
+``Form`` instance. There is no way to change data in a ``Form`` instance. Once
+a ``Form`` instance has been created, you should consider its data immutable,
+whether it has data or not.
- def create_place(request):
- manipulator = Place.AddManipulator()
+Using forms to validate data
+----------------------------
+The primary task of a ``Form`` object is to validate data. With a bound
+``Form`` instance, call the ``is_valid()`` method to run validation and return
+a boolean designating whether the data was valid::
+
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
+ >>> f.is_valid()
+ True
+
+Let's try with some invalid data. In this case, ``subject`` is blank (an error,
+because all fields are required by default) and ``sender`` is not a valid
+e-mail address::
+
+ >>> data = {'subject': '',
+ ... 'message': 'Hi there',
+ ... 'sender': 'invalid e-mail address',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
+ >>> f.is_valid()
+ False
+
+Access the ``errors`` attribute to get a dictionary of error messages::
+
+ >>> f.errors
+ {'sender': [u'Enter a valid e-mail address.'], 'subject': [u'This field is required.']}
+
+In this dictionary, the keys are the field names, and the values are lists of
+Unicode strings representing the error messages. The error messages are stored
+in lists because a field can have multiple error messages.
+
+You can access ``errors`` without having to call ``is_valid()`` first. The
+form's data will be validated the first time either you call ``is_valid()`` or
+access ``errors``.
+
+The validation routines will only get called once, regardless of how many times
+you access ``errors`` or call ``is_valid()``. This means that if validation has
+side effects, those side effects will only be triggered once.
+
+Behavior of unbound forms
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's meaningless to validate a form with no data, but, for the record, here's
+what happens with unbound forms::
+
+ >>> f = ContactForm()
+ >>> f.is_valid()
+ False
+ >>> f.errors
+ {}
+
+Accessing "clean" data
+----------------------
+
+Each ``Field`` in a ``Form`` class is responsible not only for validating data,
+but also for "cleaning" it -- normalizing it to a consistent format. This is a
+nice feature, because it allows data for a particular field to be input in
+a variety of ways, always resulting in consistent output.
+
+For example, ``DateField`` normalizes input into a Python ``datetime.date``
+object. Regardless of whether you pass it a string in the format
+``'1994-07-15'``, a ``datetime.date`` object or a number of other formats,
+``DateField`` will always normalize it to a ``datetime.date`` object as long as
+it's valid.
+
+Once you've created a ``Form`` instance with a set of data and validated it,
+you can access the clean data via the ``cleaned_data`` attribute of the ``Form``
+object::
+
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
+ >>> f.is_valid()
+ True
+ >>> f.cleaned_data
+ {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
+
+.. note::
+ **New in Django development version** The ``cleaned_data`` attribute was
+ called ``clean_data`` in earlier releases.
+
+Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
+always cleans the input into a Unicode string. We'll cover the encoding
+implications later in this document.
+
+If your data does *not* validate, your ``Form`` instance will not have a
+``cleaned_data`` attribute::
+
+ >>> data = {'subject': '',
+ ... 'message': 'Hi there',
+ ... 'sender': 'invalid e-mail address',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
+ >>> f.is_valid()
+ False
+ >>> f.cleaned_data
+ Traceback (most recent call last):
+ ...
+ AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
+
+``cleaned_data`` will always *only* contain a key for fields defined in the
+``Form``, even if you pass extra data when you define the ``Form``. In this
+example, we pass a bunch of extra fields to the ``ContactForm`` constructor,
+but ``cleaned_data`` contains only the form's fields::
+
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True,
+ ... 'extra_field_1': 'foo',
+ ... 'extra_field_2': 'bar',
+ ... 'extra_field_3': 'baz'}
+ >>> f = ContactForm(data)
+ >>> f.is_valid()
+ True
+ >>> f.cleaned_data # Doesn't contain extra_field_1, etc.
+ {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
+
+``cleaned_data`` will include a key and value for *all* fields defined in the
+``Form``, even if the data didn't include a value for fields that are not
+required. In this example, the data dictionary doesn't include a value for the
+``nick_name`` field, but ``cleaned_data`` includes it, with an empty value::
+
+ >>> class OptionalPersonForm(Form):
+ ... first_name = CharField()
+ ... last_name = CharField()
+ ... nick_name = CharField(required=False)
+ >>> data = {'first_name': u'John', 'last_name': u'Lennon'}
+ >>> f = OptionalPersonForm(data)
+ >>> f.is_valid()
+ True
+ >>> f.cleaned_data
+ {'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
+
+In this above example, the ``cleaned_data`` value for ``nick_name`` is set to an
+empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
+empty values as an empty string. Each field type knows what its "blank" value
+is -- e.g., for ``DateField``, it's ``None`` instead of the empty string. For
+full details on each field's behavior in this case, see the "Empty value" note
+for each field in the "Built-in ``Field`` classes" section below.
+
+You can write code to perform validation for particular form fields (based on
+their name) or for the form as a whole (considering combinations of various
+fields). More information about this is in the `Custom form and field
+validation`_ section, below.
+
+Behavior of unbound forms
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's meaningless to request "cleaned" data in a form with no data, but, for the
+record, here's what happens with unbound forms::
+
+ >>> f = ContactForm()
+ >>> f.cleaned_data
+ Traceback (most recent call last):
+ ...
+ AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
+
+Outputting forms as HTML
+------------------------
+
+The second task of a ``Form`` object is to render itself as HTML. To do so,
+simply ``print`` it::
+
+ >>> f = ContactForm()
+ >>> print f
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+
+If the form is bound to data, the HTML output will include that data
+appropriately. For example, if a field is represented by an
+``<input type="text">``, the data will be in the ``value`` attribute. If a
+field is represented by an ``<input type="checkbox">``, then that HTML will
+include ``checked="checked"`` if appropriate::
+
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data)
+ >>> print f
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" value="foo@example.com" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
+
+This default output is a two-column HTML table, with a ``<tr>`` for each field.
+Notice the following:
+
+ * For flexibility, the output does *not* include the ``<table>`` and
+ ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
+ tags or an ``<input type="submit">`` tag. It's your job to do that.
+
+ * Each field type has a default HTML representation. ``CharField`` and
+ ``EmailField`` are represented by an ``<input type="text">``.
+ ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
+ these are merely sensible defaults; you can specify which HTML to use for
+ a given field by using widgets, which we'll explain shortly.
+
+ * The HTML ``name`` for each tag is taken directly from its attribute name
+ in the ``ContactForm`` class.
+
+ * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
+ ``'Cc myself:'`` is generated from the field name by converting all
+ underscores to spaces and upper-casing the first letter. Again, note
+ these are merely sensible defaults; you can also specify labels manually.
+
+ * Each text label is surrounded in an HTML ``<label>`` tag, which points
+ to the appropriate form field via its ``id``. Its ``id``, in turn, is
+ generated by prepending ``'id_'`` to the field name. The ``id``
+ attributes and ``<label>`` tags are included in the output by default, to
+ follow best practices, but you can change that behavior.
+
+Although ``<table>`` output is the default output style when you ``print`` a
+form, other output styles are available. Each style is available as a method on
+a form object, and each rendering method returns a Unicode object.
+
+``as_p()``
+~~~~~~~~~~
+
+``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
+containing one field::
+
+ >>> f = ContactForm()
+ >>> f.as_p()
+ u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
+ >>> print f.as_p()
+ <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
+ <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
+ <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
+
+``as_ul()``
+~~~~~~~~~~~
+
+``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
+``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
+so that you can specify any HTML attributes on the ``<ul>`` for flexibility::
+
+ >>> f = ContactForm()
+ >>> f.as_ul()
+ u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
+ >>> print f.as_ul()
+ <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
+ <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
+ <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
+
+``as_table()``
+~~~~~~~~~~~~~~
+
+Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
+exactly the same as ``print``. In fact, when you ``print`` a form object, it
+calls its ``as_table()`` method behind the scenes::
+
+ >>> f = ContactForm()
+ >>> f.as_table()
+ u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
+ >>> print f.as_table()
+ <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+ <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+ <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+
+Configuring HTML ``<label>`` tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An HTML ``<label>`` tag designates which label text is associated with which
+form element. This small enhancement makes forms more usable and more accessible
+to assistive devices. It's always a good idea to use ``<label>`` tags.
+
+By default, the form rendering methods include HTML ``id`` attributes on the
+form elements and corresponding ``<label>`` tags around the labels. The ``id``
+attribute values are generated by prepending ``id_`` to the form field names.
+This behavior is configurable, though, if you want to change the ``id``
+convention or remove HTML ``id`` attributes and ``<label>`` tags entirely.
+
+Use the ``auto_id`` argument to the ``Form`` constructor to control the label
+and ``id`` behavior. This argument must be ``True``, ``False`` or a string.
+
+If ``auto_id`` is ``False``, then the form output will not include ``<label>``
+tags nor ``id`` attributes::
+
+ >>> f = ContactForm(auto_id=False)
+ >>> print f.as_table()
+ <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
+ <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
+ <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
+ <li>Message: <input type="text" name="message" /></li>
+ <li>Sender: <input type="text" name="sender" /></li>
+ <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+ >>> print f.as_p()
+ <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
+ <p>Message: <input type="text" name="message" /></p>
+ <p>Sender: <input type="text" name="sender" /></p>
+ <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
+
+If ``auto_id`` is set to ``True``, then the form output *will* include
+``<label>`` tags and will simply use the field name as its ``id`` for each form
+field::
+
+ >>> f = ContactForm(auto_id=True)
+ >>> print f.as_table()
+ <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
+ <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
+ <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
+ <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
+ <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
+ >>> print f.as_p()
+ <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
+ <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
+ <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
+
+If ``auto_id`` is set to a string containing the format character ``'%s'``,
+then the form output will include ``<label>`` tags, and will generate ``id``
+attributes based on the format string. For example, for a format string
+``'field_%s'``, a field named ``subject`` will get the ``id`` value
+``'field_subject'``. Continuing our example::
+
+ >>> f = ContactForm(auto_id='id_for_%s')
+ >>> print f.as_table()
+ <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
+ <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
+ <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
+ <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
+ <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
+ >>> print f.as_p()
+ <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
+ <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
+ <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
+
+If ``auto_id`` is set to any other true value -- such as a string that doesn't
+include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.
+
+By default, ``auto_id`` is set to the string ``'id_%s'``.
+
+Normally, a colon (``:``) will be appended after any label name when a form is
+rendered. It's possible to change the colon to another character, or omit it
+entirely, using the ``label_suffix`` parameter::
+
+ >>> f = ContactForm(auto_id='id_for_%s', label_suffix='')
+ >>> print f.as_ul()
+ <li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" /></li>
+ <li><label for="id_for_sender">Sender</label> <input type="text" name="sender" id="id_for_sender" /></li>
+ <li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
+ >>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->')
+ >>> print f.as_ul()
+ <li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
+ <li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" /></li>
+ <li><label for="id_for_sender">Sender -></label> <input type="text" name="sender" id="id_for_sender" /></li>
+ <li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
+
+Note that the label suffix is added only if the last character of the
+label isn't a punctuation character (``.``, ``!``, ``?`` or ``:``)
+
+Notes on field ordering
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In the ``as_p()``, ``as_ul()`` and ``as_table()`` shortcuts, the fields are
+displayed in the order in which you define them in your form class. For
+example, in the ``ContactForm`` example, the fields are defined in the order
+``subject``, ``message``, ``sender``, ``cc_myself``. To reorder the HTML
+output, just change the order in which those fields are listed in the class.
+
+How errors are displayed
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you render a bound ``Form`` object, the act of rendering will automatically
+run the form's validation if it hasn't already happened, and the HTML output
+will include the validation errors as a ``<ul class="errorlist">`` near the
+field. The particular positioning of the error messages depends on the output
+method you're using::
+
+ >>> data = {'subject': '',
+ ... 'message': 'Hi there',
+ ... 'sender': 'invalid e-mail address',
+ ... 'cc_myself': True}
+ >>> f = ContactForm(data, auto_id=False)
+ >>> print f.as_table()
+ <tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr>
+ <tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr>
+ <tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" name="sender" value="invalid e-mail address" /></td></tr>
+ <tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li>
+ <li>Message: <input type="text" name="message" value="Hi there" /></li>
+ <li><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul>Sender: <input type="text" name="sender" value="invalid e-mail address" /></li>
+ <li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>
+ >>> print f.as_p()
+ <p><ul class="errorlist"><li>This field is required.</li></ul></p>
+ <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
+ <p>Message: <input type="text" name="message" value="Hi there" /></p>
+ <p><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul></p>
+ <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
+ <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
+
+Customizing the error list format
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, forms use ``django.forms.util.ErrorList`` to format validation
+errors. If you'd like to use an alternate class for displaying errors, you can
+pass that in at construction time::
+
+ >>> from django.forms.util import ErrorList
+ >>> class DivErrorList(ErrorList):
+ ... def __unicode__(self):
+ ... return self.as_divs()
+ ... def as_divs(self):
+ ... if not self: return u''
+ ... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
+ >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
+ >>> f.as_p()
+ <div class="errorlist"><div class="error">This field is required.</div></div>
+ <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
+ <p>Message: <input type="text" name="message" value="Hi there" /></p>
+ <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
+ <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
+ <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
+
+More granular output
+~~~~~~~~~~~~~~~~~~~~
+
+The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
+lazy developers -- they're not the only way a form object can be displayed.
+
+To display the HTML for a single field in your form, use dictionary lookup
+syntax using the field's name as the key, and print the resulting object::
+
+ >>> f = ContactForm()
+ >>> print f['subject']
+ <input id="id_subject" type="text" name="subject" maxlength="100" />
+ >>> print f['message']
+ <input type="text" name="message" id="id_message" />
+ >>> print f['sender']
+ <input type="text" name="sender" id="id_sender" />
+ >>> print f['cc_myself']
+ <input type="checkbox" name="cc_myself" id="id_cc_myself" />
+
+Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
+string or Unicode object, respectively::
+
+ >>> str(f['subject'])
+ '<input id="id_subject" type="text" name="subject" maxlength="100" />'
+ >>> unicode(f['subject'])
+ u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
+
+The field-specific output honors the form object's ``auto_id`` setting::
+
+ >>> f = ContactForm(auto_id=False)
+ >>> print f['message']
+ <input type="text" name="message" />
+ >>> f = ContactForm(auto_id='id_%s')
+ >>> print f['message']
+ <input type="text" name="message" id="id_message" />
+
+For a field's list of errors, access the field's ``errors`` attribute. This
+is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
+when printed::
+
+ >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
+ >>> f = ContactForm(data, auto_id=False)
+ >>> print f['message']
+ <input type="text" name="message" />
+ >>> f['message'].errors
+ [u'This field is required.']
+ >>> print f['message'].errors
+ <ul class="errorlist"><li>This field is required.</li></ul>
+ >>> f['subject'].errors
+ []
+ >>> print f['subject'].errors
+
+ >>> str(f['subject'].errors)
+ ''
+
+Using forms in views and templates
+----------------------------------
+
+Let's put this all together and use the ``ContactForm`` example in a Django
+view and template.
+
+Simple view example
+~~~~~~~~~~~~~~~~~~~
+
+This example view displays the contact form by default and validates/processes
+it if accessed via a POST request::
+
+ def contact(request):
if request.method == 'POST':
- # If data was POSTed, we're trying to create a new Place.
- new_data = request.POST.copy()
-
- # Check for errors.
- errors = manipulator.get_validation_errors(new_data)
- manipulator.do_html2python(new_data)
-
- if not errors:
- # No errors. This means we can save the data!
- new_place = manipulator.save(new_data)
-
- # Redirect to the object's "edit" page. Always use a redirect
- # after POST data, so that reloads don't accidently create
- # duplicate entires, and so users don't see the confusing
- # "Repost POST data?" alert box in their browsers.
- return HttpResponseRedirect("/places/edit/%i/" % new_place.id)
+ form = ContactForm(request.POST)
+ if form.is_valid():
+ # Do form processing here...
+ return HttpResponseRedirect('/url/on_success/')
else:
- # No POST, so we want a brand new form without any data or errors.
- errors = new_data = {}
-
- # Create the FormWrapper, template, context, response.
- form = forms.FormWrapper(manipulator, new_data, errors)
- return render_to_response('places/create_form.html', {'form': form})
+ form = ContactForm()
+ return render_to_response('contact.html', {'form': form})
-and here's the ``create_form`` template::
+Simple template example
+~~~~~~~~~~~~~~~~~~~~~~~
- {% extends "base.html" %}
+The template in the above view example, ``contact.html``, is responsible for
+displaying the form as HTML. To do this, we can use the techniques outlined in
+the "Outputting forms as HTML" section above.
- {% block content %}
- <h1>Create a place:</h1>
-
- {% if form.has_errors %}
- <h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
- {% endif %}
+The simplest way to display a form's HTML is to use the variable on its own,
+like this::
- <form method="post" action=".">
- <p>
- <label for="id_name">Name:</label> {{ form.name }}
- {% if form.name.errors %}*** {{ form.name.errors|join:", " }}{% endif %}
- </p>
- <p>
- <label for="id_address">Address:</label> {{ form.address }}
- {% if form.address.errors %}*** {{ form.address.errors|join:", " }}{% endif %}
- </p>
- <p>
- <label for="id_city">City:</label> {{ form.city }}
- {% if form.city.errors %}*** {{ form.city.errors|join:", " }}{% endif %}
- </p>
- <p>
- <label for="id_state">State:</label> {{ form.state }}
- {% if form.state.errors %}*** {{ form.state.errors|join:", " }}{% endif %}
- </p>
- <p>
- <label for="id_zip_code">Zip:</label> {{ form.zip_code }}
- {% if form.zip_code.errors %}*** {{ form.zip_code.errors|join:", " }}{% endif %}
- </p>
- <p>
- <label for="id_place_type">Place type:</label> {{ form.place_type }}
- {% if form.place_type.errors %}*** {{ form.place_type.errors|join:", " }}{% endif %}
- </p>
+ <form method="post" action="">
+ <table>{{ form }}</table>
<input type="submit" />
</form>
- {% endblock %}
-The second two arguments to ``FormWrapper`` (``new_data`` and ``errors``)
-deserve some mention.
+The above template code will display the form as an HTML table, using the
+``form.as_table()`` method explained previously. This works because Django's
+template system displays an object's ``__str__()`` value, and the ``Form``
+class' ``__str__()`` method calls its ``as_table()`` method.
-The first is any "default" data to be used as values for the fields. Pulling
-the data from ``request.POST``, as is done above, makes sure that if there are
-errors, the values the user put in aren't lost. If you try the above example,
-you'll see this in action.
+The following is equivalent but a bit more explicit::
-The second argument is the error list retrieved from
-``manipulator.get_validation_errors``. When passed into the ``FormWrapper``,
-this gives each field an ``errors`` item (which is a list of error messages
-associated with the field) as well as a ``html_error_list`` item, which is a
-``<ul>`` of error messages. The above template uses these error items to
-display a simple error message next to each field. The error list is saved as
-an ``error_dict`` attribute of the ``FormWrapper`` object.
+ <form method="post" action="">
+ <table>{{ form.as_table }}</table>
+ <input type="submit" />
+ </form>
-Using the ``ChangeManipulator``
--------------------------------
+``form.as_ul`` and ``form.as_p`` are also available, as you may expect.
-The above has covered using the ``AddManipulator`` to create a new object. What
-about editing an existing one? It's shockingly similar to creating a new one::
+Note that in the above two examples, we included the ``<form>``, ``<table>``
+``<input type="submit" />``, ``</table>`` and ``</form>`` tags. The form
+convenience methods (``as_table()``, ``as_ul()`` and ``as_p()``) do not include
+that HTML.
- def edit_place(request, place_id):
- # Get the place in question from the database and create a
- # ChangeManipulator at the same time.
- try:
- manipulator = Place.ChangeManipulator(place_id)
- except Place.DoesNotExist:
- raise Http404
+Complex template output
+~~~~~~~~~~~~~~~~~~~~~~~
- # Grab the Place object in question for future use.
- place = manipulator.original_object
+As we've stressed several times, the ``as_table()``, ``as_ul()`` and ``as_p()``
+methods are just shortcuts for the common case. You can also work with the
+individual fields for complete template control over the form's design.
- if request.method == 'POST':
- new_data = request.POST.copy()
- errors = manipulator.get_validation_errors(new_data)
- manipulator.do_html2python(new_data)
- if not errors:
- manipulator.save(new_data)
-
- # Do a post-after-redirect so that reload works, etc.
- return HttpResponseRedirect("/places/edit/%i/" % place.id)
- else:
- errors = {}
- # This makes sure the form accurate represents the fields of the place.
- new_data = manipulator.flatten_data()
-
- form = forms.FormWrapper(manipulator, new_data, errors)
- return render_to_response('places/edit_form.html', {'form': form, 'place': place})
+The easiest way is to iterate over the form's fields, with
+``{% for field in form %}``. For example::
-The only real differences are:
+ <form method="post" action="">
+ <dl>
+ {% for field in form %}
+ <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 %}
+ {% endfor %}
+ </dl>
+ <input type="submit" />
+ </form>
- * We create a ``ChangeManipulator`` instead of an ``AddManipulator``.
- The argument to a ``ChangeManipulator`` is the ID of the object
- to be changed. As you can see, the initializer will raise an
- ``ObjectDoesNotExist`` exception if the ID is invalid.
+This iteration technique is useful if you want to apply the same HTML
+formatting to each field, or if you don't know the names of the form fields
+ahead of time. Note that the fields will be iterated over in the order in which
+they're defined in the ``Form`` class.
- * ``ChangeManipulator.original_object`` stores the instance of the
- object being edited.
+Alternatively, you can arrange the form's fields explicitly, by name. Do that
+by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
+For example::
- * We set ``new_data`` based upon ``flatten_data()`` from the manipulator.
- ``flatten_data()`` takes the data from the original object under
- manipulation, and converts it into a data dictionary that can be used
- to populate form elements with the existing values for the object.
+ <form method="post" action="">
+ <ul class="myformclass">
+ <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 %}
- * The above example uses a different template, so create and edit can be
- "skinned" differently if needed, but the form chunk itself is completely
- identical to the one in the create form above.
+ <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 %}
-The astute programmer will notice the add and create functions are nearly
-identical and could in fact be collapsed into a single view. This is left as an
-exercise for said programmer.
+ ...
+ </ul>
+ </form>
-(However, the even-more-astute programmer will take heed of the note at the top
-of this document and check out the `generic views`_ documentation if all she
-wishes to do is this type of simple create/update.)
+Highlighting required fields in templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's common to show a user which fields are required. Here's an example of how
+to do that, using the above example modified to insert an asterisk after the
+label of each required field::
+
+ <form method="post" action="">
+ <dl>
+ {% for field in form %}
+ <dt>{{ field.label_tag }}{% if field.field.required %}*{% endif %}</dt>
+ <dd>{{ field }}</dd>
+ {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
+ {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
+ {% endfor %}
+ </dl>
+ <input type="submit" />
+ </form>
-Custom forms and manipulators
-=============================
+The ``{% if field.field.required %}*{% endif %}`` fragment is the relevant
+addition here. It adds the asterisk only if the field is required.
-All the above is fine and dandy if you just want to use the automatically
-created manipulators. But the coolness doesn't end there: You can easily create
-your own custom manipulators for handling custom forms.
+Note that we check ``field.field.required`` and not ``field.required``. In the
+template, ``field`` is a ``forms.forms.BoundField`` instance, which holds
+the actual ``Field`` instance in its ``field`` attribute.
-Custom manipulators are pretty simple. Here's a manipulator that you might use
-for a "contact" form on a website::
+Binding uploaded files to a form
+--------------------------------
- from django import forms
+**New in Django development version**
- urgency_choices = (
- (1, "Extremely urgent"),
- (2, "Urgent"),
- (3, "Normal"),
- (4, "Unimportant"),
- )
-
- class ContactManipulator(forms.Manipulator):
- def __init__(self):
- self.fields = (
- forms.EmailField(field_name="from", is_required=True),
- forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
- forms.SelectField(field_name="urgency", choices=urgency_choices),
- forms.LargeTextField(field_name="contents", is_required=True),
- )
-
-A certain similarity to Django's models should be apparent. The only required
-method of a custom manipulator is ``__init__`` which must define the fields
-present in the manipulator. See the ``django.forms`` module for
-all the form fields provided by Django.
-
-You use this custom manipulator exactly as you would use an auto-generated one.
-Here's a simple function that might drive the above form::
-
- def contact_form(request):
- manipulator = ContactManipulator()
- if request.method == 'POST':
- new_data = request.POST.copy()
- errors = manipulator.get_validation_errors(new_data)
- manipulator.do_html2python(new_data)
- if not errors:
+Dealing with forms that have ``FileField`` and ``ImageField`` fields
+is a little more complicated than a normal form.
- # Send e-mail using new_data here...
+Firstly, in order to upload files, you'll need to make sure that your
+``<form>`` element correctly defines the ``enctype`` as
+``"multipart/form-data"``::
- return HttpResponseRedirect("/contact/thankyou/")
- else:
- errors = new_data = {}
- form = forms.FormWrapper(manipulator, new_data, errors)
- return render_to_response('contact_form.html', {'form': form})
+ <form enctype="multipart/form-data" method="post" action="/foo/">
-Implementing ``flatten_data`` for custom manipulators
-------------------------------------------------------
+Secondly, when you use the form, you need to bind the file data. File
+data is handled separately to normal form data, so when your form
+contains a ``FileField`` and ``ImageField``, you will need to specify
+a second argument when you bind your form. So if we extend our
+ContactForm to include an ``ImageField`` called ``mugshot``, we
+need to bind the file data containing the mugshot image::
-It is possible (although rarely needed) to replace the default automatically
-created manipulators on a model with your own custom manipulators. If you do
-this and you are intending to use those models in generic views, you should
-also define a ``flatten_data`` method in any ``ChangeManipulator`` replacement.
-This should act like the default ``flatten_data`` and return a dictionary
-mapping field names to their values, like so::
+ # Bound form with an image field
+ >>> from django.core.files.uploadedfile import SimpleUploadedFile
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <file data>)}
+ >>> f = ContactFormWithMugshot(data, file_data)
- def flatten_data(self):
- obj = self.original_object
- return dict(
- from = obj.from,
- subject = obj.subject,
- ...
- )
+In practice, you will usually specify ``request.FILES`` as the source
+of file data (just like you use ``request.POST`` as the source of
+form data)::
-In this way, your new change manipulator will act exactly like the default
-version.
+ # Bound form with an image field, data from the request
+ >>> f = ContactFormWithMugshot(request.POST, request.FILES)
-``FileField`` and ``ImageField`` special cases
-==============================================
+Constructing an unbound form is the same as always -- just omit both
+form data *and* file data::
-Dealing with ``FileField`` and ``ImageField`` objects is a little more
-complicated.
+ # Unbound form with a image field
+ >>> f = ContactFormWithMugshot()
-First, you'll need to make sure that your ``<form>`` element correctly defines
-the ``enctype`` as ``"multipart/form-data"``, in order to upload files::
+Testing for multipart forms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
- <form enctype="multipart/form-data" method="post" action="/foo/">
+If you're writing reusable views or templates, you may not know ahead of time
+whether your form is a multipart form or not. The ``is_multipart()`` method
+tells you whether the form requires multipart encoding for submission::
-Next, you'll need to treat the field in the template slightly differently. A
-``FileField`` or ``ImageField`` is represented by *two* HTML form elements.
+ >>> f = ContactFormWithMugshot()
+ >>> f.is_multipart()
+ True
-For example, given this field in a model::
+Here's an example of how you might use this in a template::
- photo = model.ImageField('/path/to/upload/location')
+ {% if form.is_multipart %}
+ <form enctype="multipart/form-data" method="post" action="/foo/">
+ {% else %}
+ <form method="post" action="/foo/">
+ {% endif %}
+ {{ form }}
+ </form>
-You'd need to display two formfields in the template::
+Subclassing forms
+-----------------
+
+If you have multiple ``Form`` classes that share fields, you can use
+subclassing to remove redundancy.
+
+When you subclass a custom ``Form`` class, the resulting subclass will
+include all fields of the parent class(es), followed by the fields you define
+in the subclass.
+
+In this example, ``ContactFormWithPriority`` contains all the fields from
+``ContactForm``, plus an additional field, ``priority``. The ``ContactForm``
+fields are ordered first::
+
+ >>> class ContactFormWithPriority(ContactForm):
+ ... priority = forms.CharField()
+ >>> f = ContactFormWithPriority(auto_id=False)
+ >>> print f.as_ul()
+ <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
+ <li>Message: <input type="text" name="message" /></li>
+ <li>Sender: <input type="text" name="sender" /></li>
+ <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+ <li>Priority: <input type="text" name="priority" /></li>
+
+It's possible to subclass multiple forms, treating forms as "mix-ins." In this
+example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm``
+(in that order), and its field list includes the fields from the parent
+classes::
+
+ >>> class PersonForm(Form):
+ ... first_name = CharField()
+ ... last_name = CharField()
+ >>> class InstrumentForm(Form):
+ ... instrument = CharField()
+ >>> class BeatleForm(PersonForm, InstrumentForm):
+ ... haircut_type = CharField()
+ >>> b = BeatleForm(auto_id=False)
+ >>> print b.as_ul()
+ <li>First name: <input type="text" name="first_name" /></li>
+ <li>Last name: <input type="text" name="last_name" /></li>
+ <li>Instrument: <input type="text" name="instrument" /></li>
+ <li>Haircut type: <input type="text" name="haircut_type" /></li>
+
+Prefixes for forms
+------------------
+
+You can put several Django forms inside one ``<form>`` tag. To give each
+``Form`` its own namespace, use the ``prefix`` keyword argument::
+
+ >>> mother = PersonForm(prefix="mother")
+ >>> father = PersonForm(prefix="father")
+ >>> print mother.as_ul()
+ <li><label for="id_mother-first_name">First name:</label> <input type="text" name="mother-first_name" id="id_mother-first_name" /></li>
+ <li><label for="id_mother-last_name">Last name:</label> <input type="text" name="mother-last_name" id="id_mother-last_name" /></li>
+ >>> print father.as_ul()
+ <li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li>
+ <li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li>
+
+Fields
+======
+
+When you create a ``Form`` class, the most important part is defining the
+fields of the form. Each field has custom validation logic, along with a few
+other hooks.
+
+Although the primary way you'll use ``Field`` classes is in ``Form`` classes,
+you can also instantiate them and use them directly to get a better idea of
+how they work. Each ``Field`` instance has a ``clean()`` method, which takes
+a single argument and either raises a ``django.forms.ValidationError``
+exception or returns the clean value::
+
+ >>> f = forms.EmailField()
+ >>> f.clean('foo@example.com')
+ u'foo@example.com'
+ >>> f.clean(u'foo@example.com')
+ u'foo@example.com'
+ >>> f.clean('invalid e-mail address')
+ Traceback (most recent call last):
+ ...
+ ValidationError: [u'Enter a valid e-mail address.']
+
+If you've used Django's old forms/validation framework, take care in noticing
+this ``ValidationError`` is different than the previous ``ValidationError``.
+This one lives at ``django.forms.ValidationError`` rather than
+``django.core.validators.ValidationError``.
+
+Core field arguments
+--------------------
+
+Each ``Field`` class constructor takes at least these arguments. Some
+``Field`` classes take additional, field-specific arguments, but the following
+should *always* be accepted:
+
+``required``
+~~~~~~~~~~~~
+
+By default, each ``Field`` class assumes the value is required, so if you pass
+an empty value -- either ``None`` or the empty string (``""``) -- then
+``clean()`` will raise a ``ValidationError`` exception::
+
+ >>> f = forms.CharField()
+ >>> f.clean('foo')
+ u'foo'
+ >>> f.clean('')
+ Traceback (most recent call last):
+ ...
+ ValidationError: [u'This field is required.']
+ >>> f.clean(None)
+ Traceback (most recent call last):
+ ...
+ ValidationError: [u'This field is required.']
+ >>> f.clean(' ')
+ u' '
+ >>> f.clean(0)
+ u'0'
+ >>> f.clean(True)
+ u'True'
+ >>> f.clean(False)
+ u'False'
+
+To specify that a field is *not* required, pass ``required=False`` to the
+``Field`` constructor::
+
+ >>> f = forms.CharField(required=False)
+ >>> f.clean('foo')
+ u'foo'
+ >>> f.clean('')
+ u''
+ >>> f.clean(None)
+ u''
+ >>> f.clean(0)
+ u'0'
+ >>> f.clean(True)
+ u'True'
+ >>> f.clean(False)
+ u'False'
+
+If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value,
+then ``clean()`` will return a *normalized* empty value rather than raising
+``ValidationError``. For ``CharField``, this will be a Unicode empty string.
+For other ``Field`` classes, it might be ``None``. (This varies from field to
+field.)
+
+``label``
+~~~~~~~~~
+
+The ``label`` argument lets you specify the "human-friendly" label for this
+field. This is used when the ``Field`` is displayed in a ``Form``.
+
+As explained in "Outputting forms as HTML" above, the default label for a
+``Field`` is generated from the field name by converting all underscores to
+spaces and upper-casing the first letter. Specify ``label`` if that default
+behavior doesn't result in an adequate label.
+
+Here's a full example ``Form`` that implements ``label`` for two of its fields.
+We've specified ``auto_id=False`` to simplify the output::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField(label='Your name')
+ ... url = forms.URLField(label='Your Web site', required=False)
+ ... comment = forms.CharField()
+ >>> f = CommentForm(auto_id=False)
+ >>> print f
+ <tr><th>Your name:</th><td><input type="text" name="name" /></td></tr>
+ <tr><th>Your Web site:</th><td><input type="text" name="url" /></td></tr>
+ <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+
+``initial``
+~~~~~~~~~~~
+
+The ``initial`` argument lets you specify the initial value to use when
+rendering this ``Field`` in an unbound ``Form``.
+
+The use-case for this is when you want to display an "empty" form in which a
+field is initialized to a particular value. For example::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField(initial='Your name')
+ ... url = forms.URLField(initial='http://')
+ ... comment = forms.CharField()
+ >>> f = CommentForm(auto_id=False)
+ >>> print f
+ <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
+ <tr><th>Url:</th><td><input type="text" name="url" value="http://" /></td></tr>
+ <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+
+You may be thinking, why not just pass a dictionary of the initial values as
+data when displaying the form? Well, if you do that, you'll trigger validation,
+and the HTML output will include any validation errors::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField()
+ ... url = forms.URLField()
+ ... comment = forms.CharField()
+ >>> default_data = {'name': 'Your name', 'url': 'http://'}
+ >>> f = CommentForm(default_data, auto_id=False)
+ >>> print f
+ <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
+ <tr><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="text" name="url" value="http://" /></td></tr>
+ <tr><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" /></td></tr>
+
+This is why ``initial`` values are only displayed for unbound forms. For bound
+forms, the HTML output will use the bound data.
+
+Also note that ``initial`` values are *not* used as "fallback" data in
+validation if a particular field's value is not given. ``initial`` values are
+*only* intended for initial form display::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField(initial='Your name')
+ ... url = forms.URLField(initial='http://')
+ ... comment = forms.CharField()
+ >>> data = {'name': '', 'url': '', 'comment': 'Foo'}
+ >>> f = CommentForm(data)
+ >>> f.is_valid()
+ False
+ # The form does *not* fall back to using the initial values.
+ >>> f.errors
+ {'url': [u'This field is required.'], 'name': [u'This field is required.']}
+
+``widget``
+~~~~~~~~~~
+
+The ``widget`` argument lets you specify a ``Widget`` class to use when
+rendering this ``Field``. See `Widgets`_ below for more information.
+
+``help_text``
+~~~~~~~~~~~~~
+
+The ``help_text`` argument lets you specify descriptive text for this
+``Field``. If you provide ``help_text``, it will be displayed next to the
+``Field`` when the ``Field`` is rendered by one of the convenience ``Form``
+methods (e.g., ``as_ul()``).
+
+Here's a full example ``Form`` that implements ``help_text`` for two of its
+fields. We've specified ``auto_id=False`` to simplify the output::
+
+ >>> class HelpTextContactForm(forms.Form):
+ ... subject = forms.CharField(max_length=100, help_text='100 characters max.')
+ ... message = forms.CharField()
+ ... sender = forms.EmailField(help_text='A valid e-mail address, please.')
+ ... cc_myself = forms.BooleanField(required=False)
+ >>> f = HelpTextContactForm(auto_id=False)
+ >>> print f.as_table()
+ <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /><br />100 characters max.</td></tr>
+ <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
+ <tr><th>Sender:</th><td><input type="text" name="sender" /><br />A valid e-mail address, please.</td></tr>
+ <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
+ >>> print f.as_ul()
+ <li>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</li>
+ <li>Message: <input type="text" name="message" /></li>
+ <li>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</li>
+ <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+ >>> print f.as_p()
+ <p>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</p>
+ <p>Message: <input type="text" name="message" /></p>
+ <p>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</p>
+ <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
+
+``error_messages``
+~~~~~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+The ``error_messages`` argument lets you override the default messages that the
+field will raise. Pass in a dictionary with keys matching the error messages you
+want to override. For example, here is the default error message::
+
+ >>> generic = forms.CharField()
+ >>> generic.clean('')
+ Traceback (most recent call last):
+ ...
+ ValidationError: [u'This field is required.']
+
+And here is a custom error message::
+
+ >>> name = forms.CharField(error_messages={'required': 'Please enter your name'})
+ >>> name.clean('')
+ Traceback (most recent call last):
+ ...
+ ValidationError: [u'Please enter your name']
+
+In the `built-in Field classes`_ section below, each ``Field`` defines the
+error message keys it uses.
+
+Dynamic initial values
+----------------------
+
+The ``initial`` argument to ``Field`` (explained above) lets you hard-code the
+initial value for a ``Field`` -- but what if you want to declare the initial
+value at runtime? For example, you might want to fill in a ``username`` field
+with the username of the current session.
+
+To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
+if given, should be a dictionary mapping field names to initial values. Only
+include the fields for which you're specifying an initial value; it's not
+necessary to include every field in your form. For example::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField()
+ ... url = forms.URLField()
+ ... comment = forms.CharField()
+ >>> f = CommentForm(initial={'name': 'your username'}, auto_id=False)
+ >>> print f
+ <tr><th>Name:</th><td><input type="text" name="name" value="your username" /></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>
+ >>> f = CommentForm(initial={'name': 'another username'}, auto_id=False)
+ >>> print f
+ <tr><th>Name:</th><td><input type="text" name="name" value="another username" /></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>
+
+Just like the ``initial`` parameter to ``Field``, these values are only
+displayed for unbound forms, and they're not used as fallback values if a
+particular value isn't provided.
+
+Finally, note that if a ``Field`` defines ``initial`` *and* you include
+``initial`` when instantiating the ``Form``, then the latter ``initial`` will
+have precedence. In this example, ``initial`` is provided both at the field
+level and at the form instance level, and the latter gets precedence::
+
+ >>> class CommentForm(forms.Form):
+ ... name = forms.CharField(initial='class')
+ ... url = forms.URLField()
+ ... comment = forms.CharField()
+ >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
+ >>> print f
+ <tr><th>Name:</th><td><input type="text" name="name" value="instance" /></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>
+
+Built-in ``Field`` classes
+--------------------------
+
+Naturally, the ``forms`` library comes with a set of ``Field`` classes that
+represent common validation needs. This section documents each built-in field.
+
+For each field, we describe the default widget used if you don't specify
+``widget``. We also specify the value returned when you provide an empty value
+(see the section on ``required`` above to understand what that means).
+
+``BooleanField``
+~~~~~~~~~~~~~~~~
+
+ * Default widget: ``CheckboxInput``
+ * Empty value: ``False``
+ * Normalizes to: A Python ``True`` or ``False`` value.
+ * Validates that the check box is checked (i.e. the value is ``True``) if
+ the field has ``required=True``.
+ * Error message keys: ``required``
+
+**New in Django development version:** The empty value for a ``CheckboxInput``
+(and hence the standard ``BooleanField``) has changed to return ``False``
+instead of ``None`` in the development version.
+
+.. note::
+ Since all ``Field`` subclasses have ``required=True`` by default, the
+ validation condition here is important. If you want to include a checkbox
+ in your form that can be either checked or unchecked, you must remember to
+ pass in ``required=False`` when creating the ``BooleanField``.
+
+``CharField``
+~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates ``max_length`` or ``min_length``, if they are provided.
+ Otherwise, all inputs are valid.
+ * Error message keys: ``required``, ``max_length``, ``min_length``
+
+Has two optional arguments for validation, ``max_length`` and ``min_length``.
+If provided, these arguments ensure that the string is at most or at least the
+given length.
+
+``ChoiceField``
+~~~~~~~~~~~~~~~
+
+ * Default widget: ``Select``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates that the given value exists in the list of choices.
+ * Error message keys: ``required``, ``invalid_choice``
+
+Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
+tuple) of 2-tuples to use as choices for this field. This argument accepts
+the same formats as the ``choices`` argument to a model field. See the
+`model API documentation on choices`_ for more details.
+
+.. _model API documentation on choices: ../model-api#choices
+
+``DateField``
+~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``None``
+ * Normalizes to: A Python ``datetime.date`` object.
+ * Validates that the given value is either a ``datetime.date``,
+ ``datetime.datetime`` or string formatted in a particular date format.
+ * Error message keys: ``required``, ``invalid``
+
+Takes one optional argument, ``input_formats``, which is a list of formats used
+to attempt to convert a string to a valid ``datetime.date`` object.
+
+If no ``input_formats`` argument is provided, the default input formats are::
+
+ '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
+ '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
+ '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
+ '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
+ '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
+
+``DateTimeField``
+~~~~~~~~~~~~~~~~~
+
+ * Default widget: ``DateTimeInput``
+ * Empty value: ``None``
+ * Normalizes to: A Python ``datetime.datetime`` object.
+ * Validates that the given value is either a ``datetime.datetime``,
+ ``datetime.date`` or string formatted in a particular datetime format.
+ * Error message keys: ``required``, ``invalid``
+
+Takes one optional argument, ``input_formats``, which is a list of formats used
+to attempt to convert a string to a valid ``datetime.datetime`` object.
+
+If no ``input_formats`` argument is provided, the default input formats are::
+
+ '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
+ '%Y-%m-%d %H:%M', # '2006-10-25 14:30'
+ '%Y-%m-%d', # '2006-10-25'
+ '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59'
+ '%m/%d/%Y %H:%M', # '10/25/2006 14:30'
+ '%m/%d/%Y', # '10/25/2006'
+ '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59'
+ '%m/%d/%y %H:%M', # '10/25/06 14:30'
+ '%m/%d/%y', # '10/25/06'
+
+**New in Django development version:** The ``DateTimeField`` used to use a
+``TextInput`` widget by default. This has now changed.
+
+``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.
+ * Error message keys: ``required``, ``invalid``, ``max_value``,
+ ``min_value``, ``max_digits``, ``max_decimal_places``,
+ ``max_whole_digits``
+
+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``
+~~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates that the given value is a valid e-mail address, using a
+ moderately complex regular expression.
+ * Error message keys: ``required``, ``invalid``
+
+Has two optional arguments for validation, ``max_length`` and ``min_length``.
+If provided, these arguments ensure that the string is at most or at least the
+given length.
+
+``FileField``
+~~~~~~~~~~~~~
+
+**New in Django development version**
+
+ * Default widget: ``FileInput``
+ * Empty value: ``None``
+ * Normalizes to: An ``UploadedFile`` object that wraps the file content
+ and file name into a single object.
+ * Validates that non-empty file data has been bound to the form.
+ * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``
+
+To learn more about the ``UploadedFile`` object, see the `file uploads documentation`_.
+
+When you use a ``FileField`` in a form, you must also remember to
+`bind the file data to the form`_.
+
+.. _file uploads documentation: ../upload_handling/
+.. _`bind the file data to the form`: `Binding uploaded files to a form`_
+
+``FilePathField``
+~~~~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+ * Default widget: ``Select``
+ * Empty value: ``None``
+ * Normalizes to: A unicode object
+ * Validates that the selected choice exists in the list of choices.
+ * Error message keys: ``required``, ``invalid_choice``
+
+The field allows choosing from files inside a certain directory. It takes three
+extra arguments:
+
+ ============== ========== ===============================================
+ Argument Required? Description
+ ============== ========== ===============================================
+ ``path`` Yes The absolute path to the directory whose
+ contents you want listed. This directory must
+ exist.
+
+ ``recursive`` No If ``False`` (the default) only the direct
+ contents of ``path`` will be offered as choices.
+ If ``True``, the directory will be descended
+ into recursively and all descendants will be
+ listed as choices.
+
+ ``match`` No A regular expression pattern; only files with
+ names matching this expression will be allowed
+ as choices.
+ ============== ========== ===============================================
+
+``FloatField``
+~~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``None``
+ * Normalizes to: A Python float.
+ * Validates that the given value is an float. Leading and trailing
+ whitespace is allowed, as in Python's ``float()`` function.
+ * Error message keys: ``required``, ``invalid``, ``max_value``,
+ ``min_value``
+
+Takes two optional arguments for validation, ``max_value`` and ``min_value``.
+These control the range of values permitted in the field.
+
+``ImageField``
+~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+ * Default widget: ``FileInput``
+ * Empty value: ``None``
+ * Normalizes to: An ``UploadedFile`` object that wraps the file content
+ and file name into a single object.
+ * Validates that file data has been bound to the form, and that the
+ file is of an image format understood by PIL.
+ * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
+ ``invalid_image``
+
+Using an ImageField requires that the `Python Imaging Library`_ is installed.
+
+When you use an ``ImageField`` in a form, you must also remember to
+`bind the file data to the form`_.
+
+.. _Python Imaging Library: http://www.pythonware.com/products/pil/
+
+``IntegerField``
+~~~~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``None``
+ * Normalizes to: A Python integer or long integer.
+ * Validates that the given value is an integer. Leading and trailing
+ whitespace is allowed, as in Python's ``int()`` function.
+ * Error message keys: ``required``, ``invalid``, ``max_value``,
+ ``min_value``
+
+Takes two optional arguments for validation, ``max_value`` and ``min_value``.
+These control the range of values permitted in the field.
+
+``IPAddressField``
+~~~~~~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates that the given value is a valid IPv4 address, using a regular
+ expression.
+ * Error message keys: ``required``, ``invalid``
+
+``MultipleChoiceField``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+ * Default widget: ``SelectMultiple``
+ * Empty value: ``[]`` (an empty list)
+ * Normalizes to: A list of Unicode objects.
+ * Validates that every value in the given list of values exists in the list
+ of choices.
+ * Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
+
+Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
+tuple) of 2-tuples to use as choices for this field. This argument accepts
+the same formats as the ``choices`` argument to a model field. See the
+`model API documentation on choices`_ for more details.
+
+``NullBooleanField``
+~~~~~~~~~~~~~~~~~~~~
+
+ * Default widget: ``NullBooleanSelect``
+ * Empty value: ``None``
+ * Normalizes to: A Python ``True``, ``False`` or ``None`` value.
+ * Validates nothing (i.e., it never raises a ``ValidationError``).
+
+``RegexField``
+~~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates that the given value matches against a certain regular
+ expression.
+ * Error message keys: ``required``, ``invalid``
+
+Takes one required argument, ``regex``, which is a regular expression specified
+either as a string or a compiled regular expression object.
+
+Also takes the following optional arguments:
+
+ ====================== =====================================================
+ Argument Description
+ ====================== =====================================================
+ ``max_length`` Ensures the string has at most this many characters.
+ ``min_length`` Ensures the string has at least this many characters.
+ ====================== =====================================================
+
+The optional argument ``error_message`` is also accepted for backwards
+compatibility. The preferred way to provide an error message is to use the
+``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
+and the error message as the value.
+
+``TimeField``
+~~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``None``
+ * Normalizes to: A Python ``datetime.time`` object.
+ * Validates that the given value is either a ``datetime.time`` or string
+ formatted in a particular time format.
+ * Error message keys: ``required``, ``invalid``
+
+Takes one optional argument, ``input_formats``, which is a list of formats used
+to attempt to convert a string to a valid ``datetime.time`` object.
+
+If no ``input_formats`` argument is provided, the default input formats are::
+
+ '%H:%M:%S', # '14:30:59'
+ '%H:%M', # '14:30'
+
+``URLField``
+~~~~~~~~~~~~
+
+ * Default widget: ``TextInput``
+ * Empty value: ``''`` (an empty string)
+ * Normalizes to: A Unicode object.
+ * Validates that the given value is a valid URL.
+ * Error message keys: ``required``, ``invalid``, ``invalid_link``
+
+Takes the following optional arguments:
+
+ ======================== =====================================================
+ Argument Description
+ ======================== =====================================================
+ ``max_length`` Ensures the string has at most this many characters.
+ ``min_length`` Ensures the string has at least this many characters.
+ ``verify_exists`` If ``True``, the validator will attempt to load the
+ given URL, raising ``ValidationError`` if the page
+ gives a 404. Defaults to ``False``.
+ ``validator_user_agent`` String used as the user-agent used when checking for
+ a URL's existence. Defaults to the value of the
+ ``URL_VALIDATOR_USER_AGENT`` setting.
+ ======================== =====================================================
+
+Slightly complex built-in ``Field`` classes
+-------------------------------------------
+
+The following are not yet documented here. See the unit tests, linked-to from
+the bottom of this document, for examples of their use.
+
+``ComboField``
+~~~~~~~~~~~~~~
+
+``MultiValueField``
+~~~~~~~~~~~~~~~~~~~
+
+``SplitDateTimeField``
+~~~~~~~~~~~~~~~~~~~~~~
+
+Fields which handle relationships
+---------------------------------
+
+For representing relationships between models, two fields are
+provided which can derive their choices from a ``QuerySet``, and which
+place one or more model objects into the ``cleaned_data`` dictionary
+of forms in which they're used. Both of these fields have an
+additional required argument:
+
+``queryset``
+ A ``QuerySet`` of model objects from which the choices for the
+ field will be derived, and which will be used to validate the
+ user's selection.
+
+``ModelChoiceField``
+~~~~~~~~~~~~~~~~~~~~
+
+Allows the selection of a single model object, suitable for
+representing a foreign key.
+
+The ``__unicode__`` method of the model will be called to generate
+string representations of the objects for use in the field's choices;
+to provide customized representations, subclass ``ModelChoiceField``
+and override ``label_from_instance``. This method will receive a model
+object, and should return a string suitable for representing it. For
+example::
+
+ class MyModelChoiceField(ModelChoiceField):
+ def label_from_instance(self, obj):
+ return "My Object #%i" % obj.id
+
+``ModelMultipleChoiceField``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Allows the selection of one or more model objects, suitable for
+representing a many-to-many relation. As with ``ModelChoiceField``,
+you can use ``label_from_instance`` to customize the object
+representations.
+
+Creating custom fields
+----------------------
+
+If the built-in ``Field`` classes don't meet your needs, you can easily create
+custom ``Field`` classes. To do this, just create a subclass of
+``django.forms.Field``. Its only requirements are that it implement a
+``clean()`` method and that its ``__init__()`` method accept the core arguments
+mentioned above (``required``, ``label``, ``initial``, ``widget``,
+``help_text``).
+
+Custom form and field validation
+---------------------------------
+
+Form validation happens when the data is cleaned. If you want to customize
+this process, there are various places you can change, each one serving a
+different purpose. Three types of cleaning methods are run during form
+processing. These are normally executed when you call the ``is_valid()``
+method on a form. There are other things that can trigger cleaning and
+validation (accessing the ``errors`` attribute or calling ``full_clean()``
+directly), but normally they won't be needed.
+
+In general, any cleaning method can raise ``ValidationError`` if there is a
+problem with the data it is processing, passing the relevant error message to
+the ``ValidationError`` constructor. If no ``ValidationError`` is raised, the
+method should return the cleaned (normalized) data as a Python object.
+
+If you detect multiple errors during a cleaning method and wish to signal all
+of them to the form submitter, it is possible to pass a list of errors to the
+``ValidationError`` constructor.
+
+The three types of cleaning methods are:
+
+ * The ``clean()`` method on a Field subclass. This is responsible
+ for cleaning the data in a way that is generic for that type of field.
+ For example, a FloatField will turn the data into a Python ``float`` or
+ raise a ``ValidationError``.
+
+ * The ``clean_<fieldname>()`` method in a form subclass -- where
+ ``<fieldname>`` is replaced with the name of the form field attribute.
+ This method does any cleaning that is specific to that particular
+ attribute, unrelated to the type of field that it is. This method is not
+ passed any parameters. You will need to look up the value of the field
+ in ``self.cleaned_data`` and remember that it will be a Python object
+ at this point, not the original string submitted in the form (it will be
+ in ``cleaned_data`` because the general field ``clean()`` method, above,
+ has already cleaned the data once).
+
+ For example, if you wanted to validate that the contents of a
+ ``CharField`` called ``serialnumber`` was unique,
+ ``clean_serialnumber()`` would be the right place to do this. You don't
+ need a specific field (it's just a ``CharField``), but you want a
+ formfield-specific piece of validation and, possibly,
+ cleaning/normalizing the data.
+
+ * The Form subclass's ``clean()`` method. This method can perform
+ any validation that requires access to multiple fields from the form at
+ once. This is where you might put in things to check that if field ``A``
+ is supplied, field ``B`` must contain a valid e-mail address and the
+ like. The data that this method returns is the final ``cleaned_data``
+ attribute for the form, so don't forget to return the full list of
+ cleaned data if you override this method (by default, ``Form.clean()``
+ just returns ``self.cleaned_data``).
+
+ Note that any errors raised by your ``Form.clean()`` override will not
+ be associated with any field in particular. They go into a special
+ "field" (called ``__all__``), which you can access via the
+ ``non_field_errors()`` method if you need to.
+
+These methods are run in the order given above, one field at a time. That is,
+for each field in the form (in the order they are declared in the form
+definition), the ``Field.clean()`` method (or its override) is run, then
+``clean_<fieldname>()``. Finally, once those two methods are run for every
+field, the ``Form.clean()`` method, or its override, is executed.
+
+As mentioned above, any of these methods can raise a ``ValidationError``. For
+any field, if the ``Field.clean()`` method raises a ``ValidationError``, any
+field-specific cleaning method is not called. However, the cleaning methods
+for all remaining fields are still executed.
+
+The ``clean()`` method for the ``Form`` class or subclass is always run. If
+that method raises a ``ValidationError``, ``cleaned_data`` will be an empty
+dictionary.
+
+The previous paragraph means that if you are overriding ``Form.clean()``, you
+should iterate through ``self.cleaned_data.items()``, possibly considering the
+``_errors`` dictionary attribute on the form as well. In this way, you will
+already know which fields have passed their individual validation requirements.
+
+A simple example
+~~~~~~~~~~~~~~~~
+
+Here's a simple example of a custom field that validates its input is a string
+containing comma-separated e-mail addresses, with at least one address. We'll
+keep it simple and assume e-mail validation is contained in a function called
+``is_valid_email()``. The full class::
- <p><label for="id_photo">Photo:</label> {{ form.photo }}{{ form.photo_file }}</p>
+ from django import forms
-The first bit (``{{ form.photo }}``) displays the currently-selected file,
-while the second (``{{ form.photo_file }}``) actually contains the file upload
-form field. Thus, at the validation layer you need to check the ``photo_file``
-key.
+ class MultiEmailField(forms.Field):
+ def clean(self, value):
+ if not value:
+ raise forms.ValidationError('Enter at least one e-mail address.')
+ emails = value.split(',')
+ for email in emails:
+ if not is_valid_email(email):
+ raise forms.ValidationError('%s is not a valid e-mail address.' % email)
+ return emails
+
+Let's alter the ongoing ``ContactForm`` example to demonstrate how you'd use
+this in a form. Simply use ``MultiEmailField`` instead of ``forms.EmailField``,
+like so::
+
+ class ContactForm(forms.Form):
+ subject = forms.CharField(max_length=100)
+ message = forms.CharField()
+ senders = MultiEmailField()
+ cc_myself = forms.BooleanField(required=False)
+
+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' ...``
+ ``DateTimeInput`` ``<input type='text' ...``
+ ``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.
+ ============================ ===========================================
+
+**New in Django development version:** The ``DateTimeInput`` has been added
+since the last release.
+
+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
+----------------------------
-Finally, in your view, make sure to access ``request.FILES``, rather than
-``request.POST``, for the uploaded files. This is necessary because
-``request.POST`` does not contain file-upload data.
+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 input 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
+default ``size`` attribute as a custom extension to the ``TextInput`` widget::
+
+ class CommentWidget(forms.TextInput):
+ def __init__(self, *args, **kwargs):
+ attrs = kwargs.setdefault('attrs',{})
+ if 'size' not in attrs:
+ attrs['size'] = 40
+ super(CommentWidget, self).__init__(*args, **kwargs)
+
+We allow the ``size`` attribute to be overridden by the user, but, by default,
+this widget will behave as if ``attrs={'size': 40}`` was always passed into the
+constructor.
+
+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
+===========================
-For example, following the ``new_data`` convention, you might do something like
-this::
+The prefered way of generating forms that work with models is explained in the
+`ModelForms documentation`_.
- new_data = request.POST.copy()
- new_data.update(request.FILES)
+Looking for the ``form_for_model`` and ``form_for_instance`` documentation?
+They've been deprecated, but you can still `view the documentation`_.
-Validators
-==========
+.. _ModelForms documentation: ../modelforms/
+.. _view the documentation: ../form_for_model/
-One useful feature of manipulators is the automatic validation. Validation is
-done using a simple validation API: A validator is a callable that raises a
-``ValidationError`` if there's something wrong with the data.
-``django.core.validators`` defines a host of validator functions (see below),
-but defining your own couldn't be easier::
+Media
+=====
- from django.core import validators
- from django import forms
+Rendering an attractive and easy-to-use web form requires more than just
+HTML - it also requires CSS stylesheets, and if you want to use fancy
+"Web2.0" widgets, you may also need to include some JavaScript on each
+page. The exact combination of CSS and JavaScript that is required for
+any given page will depend upon the widgets that are in use on that page.
- class ContactManipulator(forms.Manipulator):
- def __init__(self):
- self.fields = (
- # ... snip fields as above ...
- forms.EmailField(field_name="to", validator_list=[self.isValidToAddress])
- )
+This is where Django media definitions come in. Django allows you to
+associate different media files with the forms and widgets that require
+that media. For example, if you want to use a calendar to render DateFields,
+you can define a custom Calendar widget. This widget can then be associated
+with the CSS and JavaScript that is required to render the calendar. When
+the Calendar widget is used on a form, Django is able to identify the CSS and
+JavaScript files that are required, and provide the list of file names
+in a form suitable for easy inclusion on your web page.
- def isValidToAddress(self, field_data, all_data):
- if not field_data.endswith("@example.com"):
- raise validators.ValidationError("You can only send messages to example.com e-mail addresses.")
+.. admonition:: Media and Django Admin
-Above, we've added a "to" field to the contact form, but required that the "to"
-address end with "@example.com" by adding the ``isValidToAddress`` validator to
-the field's ``validator_list``.
+ The Django Admin application defines a number of customized widgets
+ for calendars, filtered selections, and so on. These widgets define
+ media requirements, and the Django Admin uses the custom widgets
+ in place of the Django defaults. The Admin templates will only include
+ those media files that are required to render the widgets on any
+ given page.
-The arguments to a validator function take a little explanation. ``field_data``
-is the value of the field in question, and ``all_data`` is a dictionary of all
-the data being validated.
+ If you like the widgets that the Django Admin application uses,
+ feel free to use them in your own application! They're all stored
+ in ``django.contrib.admin.widgets``.
-.. admonition:: Note::
+.. admonition:: Which JavaScript toolkit?
- At the point validators are called all data will still be
- strings (as ``do_html2python`` hasn't been called yet).
+ Many JavaScript toolkits exist, and many of them include widgets (such
+ as calendar widgets) that can be used to enhance your application.
+ Django has deliberately avoided blessing any one JavaScript toolkit.
+ Each toolkit has its own relative strengths and weaknesses - use
+ whichever toolkit suits your requirements. Django is able to integrate
+ with any JavaScript toolkit.
-Also, because consistency in user interfaces is important, we strongly urge you
-to put punctuation at the end of your validation messages.
+Media as a static definition
+----------------------------
-When are validators called?
+The easiest way to define media is as a static definition. Using this method,
+the media declaration is an inner class. The properties of the inner class
+define the media requirements.
+
+Here's a simple example::
+
+ class CalendarWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all': ('pretty.css',)
+ }
+ js = ('animations.js', 'actions.js')
+
+This code defines a ``CalendarWidget``, which will be based on ``TextInput``.
+Every time the CalendarWidget is used on a form, that form will be directed
+to include the CSS file ``pretty.css``, and the JavaScript files
+``animations.js`` and ``actions.js``.
+
+This static media definition is converted at runtime into a widget property
+named ``media``. The media for a CalendarWidget instance can be retrieved
+through this property::
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+
+Here's a list of all possible ``Media`` options. There are no required options.
+
+``css``
+~~~~~~~
+
+A dictionary describing the CSS files required for various forms of output
+media.
+
+The values in the dictionary should be a tuple/list of file names. See
+`the section on media paths`_ for details of how to specify paths to media
+files.
+
+.. _the section on media paths: `Paths in media definitions`_
+
+The keys in the dictionary are the output media types. These are the same
+types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
+'embossed', 'handheld', 'print', 'projection', 'screen', 'tty' and 'tv'. If
+you need to have different stylesheets for different media types, provide
+a list of CSS files for each output medium. The following example would
+provide two CSS options -- one for the screen, and one for print::
+
+ class Media:
+ css = {
+ 'screen': ('pretty.css',),
+ 'print': ('newspaper.css',)
+ }
+
+If a group of CSS files are appropriate for multiple output media types,
+the dictionary key can be a comma separated list of output media types.
+In the following example, TV's and projectors will have the same media
+requirements::
+
+ class Media:
+ css = {
+ 'screen': ('pretty.css',),
+ 'tv,projector': ('lo_res.css',),
+ 'print': ('newspaper.css',)
+ }
+
+If this last CSS definition were to be rendered, it would become the following HTML::
+
+ <link href="http://media.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet" />
+ <link href="http://media.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet" />
+ <link href="http://media.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet" />
+
+``js``
+~~~~~~
+
+A tuple describing the required JavaScript files. See
+`the section on media paths`_ for details of how to specify paths to media
+files.
+
+``extend``
+~~~~~~~~~~
+
+A boolean defining inheritance behavior for media declarations.
+
+By default, any object using a static media definition will inherit all the
+media associated with the parent widget. This occurs regardless of how the
+parent defines its media requirements. For example, if we were to extend our
+basic Calendar widget from the example above::
+
+ class FancyCalendarWidget(CalendarWidget):
+ class Media:
+ css = {
+ 'all': ('fancy.css',)
+ }
+ js = ('whizbang.js',)
+
+ >>> w = FancyCalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+The FancyCalendar widget inherits all the media from it's parent widget. If
+you don't want media to be inherited in this way, add an ``extend=False``
+declaration to the media declaration::
+
+ class FancyCalendar(Calendar):
+ class Media:
+ extend = False
+ css = {
+ 'all': ('fancy.css',)
+ }
+ js = ('whizbang.js',)
+
+ >>> w = FancyCalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+If you require even more control over media inheritance, define your media
+using a `dynamic property`_. Dynamic properties give you complete control over
+which media files are inherited, and which are not.
+
+.. _dynamic property: `Media as a dynamic property`_
+
+Media as a dynamic property
---------------------------
-After a form has been submitted, Django validates each field in turn. First,
-if the field is required, Django checks that it is present and non-empty. Then,
-if that test passes *and the form submission contained data* for that field, all
-the validators for that field are called in turn. The emphasized portion in the
-last sentence is important: if a form field is not submitted (because it
-contains no data -- which is normal HTML behavior), the validators are not
-run against the field.
-
-This feature is particularly important for models using
-``models.BooleanField`` or custom manipulators using things like
-``forms.CheckBoxField``. If the checkbox is not selected, it will not
-contribute to the form submission.
-
-If you would like your validator to run *always*, regardless of whether its
-attached field contains any data, set the ``always_test`` attribute on the
-validator function. For example::
-
- def my_custom_validator(field_data, all_data):
- # ...
- my_custom_validator.always_test = True
-
-This validator will always be executed for any field it is attached to.
-
-Ready-made validators
----------------------
-
-Writing your own validator is not difficult, but there are some situations
-that come up over and over again. Django comes with a number of validators
-that can be used directly in your code. All of these functions and classes
-reside in ``django/core/validators.py``.
-
-The following validators should all be self-explanatory. Each one provides a
-check for the given property:
-
- * isAlphaNumeric
- * isAlphaNumericURL
- * isSlug
- * isLowerCase
- * isUpperCase
- * isCommaSeparatedIntegerList
- * isCommaSeparatedEmailList
- * isValidIPAddress4
- * isNotEmpty
- * isOnlyDigits
- * isNotOnlyDigits
- * isInteger
- * isOnlyLetters
- * isValidANSIDate
- * isValidANSITime
- * isValidEmail
- * isValidFloat
- * isValidImage
- * isValidImageURL
- * isValidPhone
- * isValidQuicktimeVideoURL
- * isValidURL
- * isValidHTML
- * isWellFormedXml
- * isWellFormedXmlFragment
- * isExistingURL
- * isValidUSState
- * hasNoProfanities
-
-There are also a group of validators that are slightly more flexible. For
-these validators, you create a validator instance, passing in the parameters
-described below. The returned object is a callable that can be used as a
-validator.
+If you need to perform some more sophisticated manipulation of media
+requirements, you can define the media property directly. This is done
+by defining a model property that returns an instance of ``forms.Media``.
+The constructor for ``forms.Media`` accepts ``css`` and ``js`` keyword
+arguments in the same format as that used in a static media definition.
+
+For example, the static media definition for our Calendar Widget could
+also be defined in a dynamic fashion::
+
+ class CalendarWidget(forms.TextInput):
+ def _media(self):
+ return forms.Media(css={'all': ('pretty.css',)},
+ js=('animations.js', 'actions.js'))
+ media = property(_media)
+
+See the section on `Media objects`_ for more details on how to construct
+return values for dynamic media properties.
+
+Paths in media definitions
+--------------------------
+
+Paths used to specify media can be either relative or absolute. If a path
+starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
+path, and left as-is. All other paths will be prepended with the value of
+``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
+``http://media.example.com/``::
+
+ class CalendarWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all': ('/css/pretty.css',),
+ }
+ js = ('animations.js', 'http://othersite.com/actions.js')
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://othersite.com/actions.js"></script>
+
+Media objects
+-------------
+
+When you interrogate the media attribute of a widget or form, the value that
+is returned is a ``forms.Media`` object. As we have already seen, the string
+representation of a Media object is the HTML required to include media
+in the ``<head>`` block of your HTML page.
+
+However, Media objects have some other interesting properties.
+
+Media subsets
+~~~~~~~~~~~~~
+
+If you only want media of a particular type, you can use the subscript operator
+to filter out a medium of interest. For example::
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+
+ >>> print w.media['css']
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+
+When you use the subscript operator, the value that is returned is a new
+Media object -- but one that only contains the media of interest.
+
+Combining media objects
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Media objects can also be added together. When two media objects are added,
+the resulting Media object contains the union of the media from both files::
+
+ class CalendarWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all': ('pretty.css',)
+ }
+ js = ('animations.js', 'actions.js')
+
+ class OtherWidget(forms.TextInput):
+ class Media:
+ js = ('whizbang.js',)
+
+ >>> w1 = CalendarWidget()
+ >>> w2 = OtherWidget()
+ >>> print w1.media + w2.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+Media on Forms
+--------------
+
+Widgets aren't the only objects that can have media definitions -- forms
+can also define media. The rules for media definitions on forms are the
+same as the rules for widgets: declarations can be static or dynamic;
+path and inheritance rules for those declarations are exactly the same.
+
+Regardless of whether you define a media declaration, *all* Form objects
+have a media property. The default value for this property is the result
+of adding the media definitions for all widgets that are part of the form::
+
+ class ContactForm(forms.Form):
+ date = DateField(widget=CalendarWidget)
+ name = CharField(max_length=40, widget=OtherWidget)
+
+ >>> f = ContactForm()
+ >>> f.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+If you want to associate additional media with a form -- for example, CSS for form
+layout -- simply add a media declaration to the form::
+
+ class ContactForm(forms.Form):
+ date = DateField(widget=CalendarWidget)
+ name = CharField(max_length=40, widget=OtherWidget)
+
+ class Media:
+ css = {
+ 'all': ('layout.css',)
+ }
+
+ >>> f = ContactForm()
+ >>> f.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <link href="http://media.example.com/layout.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+Formsets
+========
+
+A formset is a layer of abstraction to working with multiple forms on the same
+page. It can be best compared to a data grid. Let's say you have the following
+form::
+
+ >>> from django import forms
+ >>> class ArticleForm(forms.Form):
+ ... title = forms.CharField()
+ ... pub_date = forms.DateField()
+
+You might want to allow the user to create several articles at once. To create
+a formset of out of an ``ArticleForm`` you would do::
+
+ >>> from django.forms.formsets import formset_factory
+ >>> ArticleFormSet = formset_factory(ArticleForm)
+
+You now have created a formset named ``ArticleFormSet``. The formset gives you
+the ability to iterate over the forms in the formset and display them as you
+would with a regular form::
+
+ >>> formset = ArticleFormSet()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+
+As you can see it only displayed one form. This is because by default the
+``formset_factory`` defines one extra form. This can be controlled with the
+``extra`` parameter::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
+
+Using initial data with a formset
+---------------------------------
+
+Initial data is what drives the main usability of a formset. As shown above
+you can define the number of extra forms. What this means is that you are
+telling the formset how many additional forms to show in addition to the
+number of forms it generates from the initial data. Lets take a look at an
+example::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Django is now open source',
+ ... 'pub_date': datetime.date.today()},
+ ... ])
+
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+
+There are now a total of three forms showing above. One for the initial data
+that was passed in and two extra forms. Also note that we are passing in a
+list of dictionaries as the initial data.
+
+Limiting the maximum number of forms
+------------------------------------
+
+The ``max_num`` parameter to ``formset_factory`` gives you the ability to
+force the maximum number of forms the formset will display::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2, max_num=1)
+ >>> formset = ArticleFormset()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+
+The default value of ``max_num`` is ``0`` which is the same as saying put no
+limit on the number forms displayed.
+
+Formset validation
+------------------
+
+Validation with a formset is about identical to a regular ``Form``. There is
+an ``is_valid`` method on the formset to provide a convenient way to validate
+each form in the formset::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm)
+ >>> formset = ArticleFormSet({})
+ >>> formset.is_valid()
+ True
+
+We passed in no data to the formset which is resulting in a valid form. The
+formset is smart enough to ignore extra forms that were not changed. If we
+attempt to provide an article, but fail to do so::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'1',
+ ... 'form-INITIAL_FORMS': u'1',
+ ... 'form-0-title': u'Test',
+ ... 'form-0-pub_date': u'',
+ ... }
+ >>> formset = ArticleFormSet(data)
+ >>> formset.is_valid()
+ False
+ >>> formset.errors
+ [{'pub_date': [u'This field is required.']}]
+
+As we can see the formset properly performed validation and gave us the
+expected errors.
+
+Understanding the ManagementForm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You may have noticed the additional data that was required in the formset's
+data above. This data is coming from the ``ManagementForm``. This form is
+dealt with internally to the formset. If you don't use it, it will result in
+an exception::
+
+ >>> data = {
+ ... 'form-0-title': u'Test',
+ ... 'form-0-pub_date': u'',
+ ... }
+ >>> formset = ArticleFormSet(data)
+ Traceback (most recent call last):
+ ...
+ django.forms.util.ValidationError: [u'ManagementForm data is missing or has been tampered with']
+
+It is used to keep track of how many form instances are being displayed. If
+you are adding new forms via JavaScript, you should increment the count fields
+in this form as well.
+
+Custom formset validation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A formset has a ``clean`` method similar to the one on a ``Form`` class. This
+is where you define your own validation that deals at the formset level::
+
+ >>> from django.forms.formsets import BaseFormSet
+
+ >>> class BaseArticleFormSet(BaseFormSet):
+ ... def clean(self):
+ ... raise forms.ValidationError, u'An error occured.'
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
+ >>> formset = ArticleFormSet({})
+ >>> formset.is_valid()
+ False
+ >>> formset.non_form_errors()
+ [u'An error occured.']
+
+The formset ``clean`` method is called after all the ``Form.clean`` methods
+have been called. The errors will be found using the ``non_form_errors()``
+method on the formset.
+
+Dealing with ordering and deletion of forms
+-------------------------------------------
+
+Common use cases with a formset is dealing with ordering and deletion of the
+form instances. This has been dealt with for you. The ``formset_factory``
+provides two optional parameters ``can_order`` and ``can_delete`` that will do
+the extra work of adding the extra fields and providing simpler ways of
+getting to that data.
+
+``can_order``
+~~~~~~~~~~~~~
+
+Default: ``False``
+
+Lets create a formset with the ability to order::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, can_order=True)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-ORDER">Order:</label></th><td><input type="text" name="form-0-ORDER" value="1" id="id_form-0-ORDER" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-ORDER">Order:</label></th><td><input type="text" name="form-1-ORDER" value="2" id="id_form-1-ORDER" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-ORDER">Order:</label></th><td><input type="text" name="form-2-ORDER" id="id_form-2-ORDER" /></td></tr>
+
+This adds an additional field to each form. This new field is named ``ORDER``
+and is an ``forms.IntegerField``. For the forms that came from the initial
+data it automatically assigned them a numeric value. Lets look at what will
+happen when the user changes these values::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'3',
+ ... 'form-INITIAL_FORMS': u'2',
+ ... 'form-0-title': u'Article #1',
+ ... 'form-0-pub_date': u'2008-05-10',
+ ... 'form-0-ORDER': u'2',
+ ... 'form-1-title': u'Article #2',
+ ... 'form-1-pub_date': u'2008-05-11',
+ ... 'form-1-ORDER': u'1',
+ ... 'form-2-title': u'Article #3',
+ ... 'form-2-pub_date': u'2008-05-01',
+ ... 'form-2-ORDER': u'0',
+ ... }
+
+ >>> formset = ArticleFormSet(data, initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> formset.is_valid()
+ True
+ >>> for form in formset.ordered_forms:
+ ... print form.cleaned_data
+ {'pub_date': datetime.date(2008, 5, 1), 'ORDER': 0, 'title': u'Article #3'}
+ {'pub_date': datetime.date(2008, 5, 11), 'ORDER': 1, 'title': u'Article #2'}
+ {'pub_date': datetime.date(2008, 5, 10), 'ORDER': 2, 'title': u'Article #1'}
+
+``can_delete``
+~~~~~~~~~~~~~~
+
+Default: ``False``
+
+Lets create a formset with the ability to delete::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, can_delete=True)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> for form in formset.forms:
+ .... print form.as_table()
+ <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" />
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-DELETE">Delete:</label></th><td><input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-DELETE">Delete:</label></th><td><input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-DELETE">Delete:</label></th><td><input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /></td></tr>
+
+Similar to ``can_order`` this adds a new field to each form named ``DELETE``
+and is a ``forms.BooleanField``. When data comes through marking any of the
+delete fields you can access them with ``deleted_forms``::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'3',
+ ... 'form-INITIAL_FORMS': u'2',
+ ... 'form-0-title': u'Article #1',
+ ... 'form-0-pub_date': u'2008-05-10',
+ ... 'form-0-DELETE': u'on',
+ ... 'form-1-title': u'Article #2',
+ ... 'form-1-pub_date': u'2008-05-11',
+ ... 'form-1-DELETE': u'',
+ ... 'form-2-title': u'',
+ ... 'form-2-pub_date': u'',
+ ... 'form-2-DELETE': u'',
+ ... }
+
+ >>> formset = ArticleFormSet(data, initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> [form.cleaned_data for form in formset.deleted_forms]
+ [{'DELETE': True, 'pub_date': datetime.date(2008, 5, 10), 'title': u'Article #1'}]
+
+Adding additional fields to a formset
+-------------------------------------
+
+If you need to add additional fields to the formset this can be easily
+accomplished. The formset base class provides an ``add_fields`` method. You
+can simply override this method to add your own fields or even redefine the
+default fields/attributes of the order and deletion fields::
+
+ >>> class BaseArticleFormSet(BaseFormSet):
+ ... def add_fields(self, form, index):
+ ... super(BaseArticleFormSet, self).add_fields(form, index)
+ ... form.fields["my_field"] = forms.CharField()
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
+ >>> formset = ArticleFormSet()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-my_field">My field:</label></th><td><input type="text" name="form-0-my_field" id="id_form-0-my_field" /></td></tr>
+
+Using a formset in views and templates
+--------------------------------------
+
+Using a formset inside a view is as easy as using a regular ``Form`` class.
+The only thing you will want to be aware of is making sure to use the
+management form inside the template. Lets look at a sample view::
+
+ def manage_articles(request):
+ ArticleFormSet = formset_factory(ArticleForm)
+ if request.method == 'POST':
+ formset = ArticleFormSet(request.POST, request.FILES)
+ if formset.is_valid():
+ # do something with the formset.cleaned_data
+ else:
+ formset = ArticleFormSet()
+ return render_to_response('manage_articles.html', {'formset': formset})
+
+The ``manage_articles.html`` template might look like this::
+
+ <form method="POST" action="">
+ {{ formset.management_form }}
+ <table>
+ {% for form in formset.forms %}
+ {{ form }}
+ {% endfor %}
+ </table>
+ </form>
-For example::
+However the above can be slightly shortcutted and let the formset itself deal
+with the management form::
- from django.core import validators
- from django import forms
+ <form method="POST" action="">
+ <table>
+ {{ formset }}
+ </table>
+ </form>
- power_validator = validators.IsAPowerOf(2)
-
- class InstallationManipulator(forms.Manipulator)
- def __init__(self):
- self.fields = (
- ...
- forms.IntegerField(field_name = "size", validator_list=[power_validator])
- )
-
-Here, ``validators.IsAPowerOf(...)`` returned something that could be used as
-a validator (in this case, a check that a number was a power of 2).
-
-Each of the standard validators that take parameters have an optional final
-argument (``error_message``) that is the message returned when validation
-fails. If no message is passed in, a default message is used.
-
-``AlwaysMatchesOtherField``
- Takes a field name and the current field is valid if and only if its value
- matches the contents of the other field.
-
-``ValidateIfOtherFieldEquals``
- Takes three parameters: ``other_field``, ``other_value`` and
- ``validator_list``, in that order. If ``other_field`` has a value of
- ``other_value``, then the validators in ``validator_list`` are all run
- against the current field.
-
-``RequiredIfOtherFieldGiven``
- Takes a field name of the current field is only required if the other
- field has a value.
-
-``RequiredIfOtherFieldsGiven``
- Similar to ``RequiredIfOtherFieldGiven``, except that it takes a list of
- field names and if any one of the supplied fields has a value provided,
- the current field being validated is required.
-
-``RequiredIfOtherFieldNotGiven``
- Takes the name of the other field and this field is only required if the
- other field has no value.
-
-``RequiredIfOtherFieldEquals`` and ``RequiredIfOtherFieldDoesNotEqual``
- Each of these validator classes takes a field name and a value (in that
- order). If the given field does (or does not have, in the latter case) the
- given value, then the current field being validated is required.
-
- An optional ``other_label`` argument can be passed which, if given, is used
- in error messages instead of the value. This allows more user friendly error
- messages if the value itself is not descriptive enough.
-
- Note that because validators are called before any ``do_html2python()``
- functions, the value being compared against is a string. So
- ``RequiredIfOtherFieldEquals('choice', '1')`` is correct, whilst
- ``RequiredIfOtherFieldEquals('choice', 1)`` will never result in the
- equality test succeeding.
-
-``IsLessThanOtherField``
- Takes a field name and validates that the current field being validated
- has a value that is less than (or equal to) the other field's value.
- Again, comparisons are done using strings, so be cautious about using
- this function to compare data that should be treated as another type. The
- string "123" is less than the string "2", for example. If you don't want
- string comparison here, you will need to write your own validator.
-
-``NumberIsInRange``
- Takes two boundary numbers, ``lower`` and ``upper``, and checks that the
- field is greater than ``lower`` (if given) and less than ``upper`` (if
- given).
-
- Both checks are inclusive. That is, ``NumberIsInRange(10, 20)`` will allow
- values of both 10 and 20. This validator only checks numeric values
- (e.g., float and integer values).
-
-``IsAPowerOf``
- Takes an integer argument and when called as a validator, checks that the
- field being validated is a power of the integer.
-
-``IsValidDecimal``
- Takes a maximum number of digits and number of decimal places (in that
- order) and validates whether the field is a decimal with no more than the
- maximum number of digits and decimal places.
-
-``MatchesRegularExpression``
- Takes a regular expression (a string) as a parameter and validates the
- field value against it.
-
-``AnyValidator``
- Takes a list of validators as a parameter. At validation time, if the
- field successfully validates against any one of the validators, it passes
- validation. The validators are tested in the order specified in the
- original list.
-
-``URLMimeTypeCheck``
- Used to validate URL fields. Takes a list of MIME types (such as
- ``text/plain``) at creation time. At validation time, it verifies that the
- field is indeed a URL and then tries to retrieve the content at the URL.
- Validation succeeds if the content could be retrieved and it has a content
- type from the list used to create the validator.
-
-``RelaxNGCompact``
- Used to validate an XML document against a Relax NG compact schema. Takes
- a file path to the location of the schema and an optional root element
- (which is wrapped around the XML fragment before validation, if supplied).
- At validation time, the XML fragment is validated against the schema using
- the executable specified in the ``JING_PATH`` setting (see the settings_
- document for more details).
-
-.. _`generic views`: ../generic_views/
-.. _`models API`: ../model-api/
-.. _settings: ../settings/
+The above ends up calling the ``as_table`` method on the formset class.
diff --git a/docs/generic_views.txt b/docs/generic_views.txt
index a7602524a9..8c0fec2ded 100644
--- a/docs/generic_views.txt
+++ b/docs/generic_views.txt
@@ -83,24 +83,29 @@ and issuing a redirect.
``django.views.generic.simple.direct_to_template``
--------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
Renders a given template, passing it a ``{{ params }}`` template variable,
which is a dictionary of the parameters captured in the URL.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``template``: The full name of a template to use.
+``template``
+ The full name of a template to use.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
**Example:**
@@ -118,7 +123,8 @@ variable ``{{ params.id }}`` that is set to ``15``.
``django.views.generic.simple.redirect_to``
-------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
Redirects to a given URL.
@@ -127,10 +133,12 @@ interpolated against the parameters captured in the URL.
If the given URL is ``None``, Django will return an ``HttpResponseGone`` (410).
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``url``: The URL to redirect to, as a string. Or ``None`` to raise a 410
- (Gone) HTTP error.
+``url``
+ The URL to redirect to, as a string. Or ``None`` to raise a 410 (Gone)
+ HTTP error.
**Example:**
@@ -155,57 +163,69 @@ are views for displaying drilldown pages for date-based data.
``django.views.generic.date_based.archive_index``
-------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A top-level index page showing the "latest" objects, by date. Objects with
a date in the *future* are not included unless you set ``allow_future`` to
``True``.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``queryset``: A ``QuerySet`` of objects for which the archive serves.
+``queryset``
+ A ``QuerySet`` of objects for which the archive serves.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the date-based archive should use to determine the objects on
+ the page.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``num_latest``: The number of latest objects to send to the template
- context. By default, it's 15.
+``num_latest``
+ The number of latest objects to send to the template context. By default,
+ it's 15.
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``True``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``True``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
- * **New in Django development version:** ``template_object_name``:
- Designates the name of the template variable to use in the template
- context. By default, this is ``'latest'``.
+``template_object_name`` (**New in Django development version**)
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'latest'``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_archive.html`` by default, where:
@@ -217,365 +237,435 @@ If ``template_name`` isn't specified, this view will use the template
your model's app. For example, if your model lives in
``apps/blog/models.py``, that'd be ``blog``.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``date_list``: A list of ``datetime.date`` objects representing all
- years that have objects available according to ``queryset``. These are
- ordered in reverse. This is equivalent to
- ``queryset.dates(date_field, 'year')[::-1]``.
+``date_list``
+ A list of ``datetime.date`` objects representing all years that have
+ objects available according to ``queryset``. These are ordered in reverse.
+ This is equivalent to ``queryset.dates(date_field, 'year')[::-1]``.
- * ``latest``: The ``num_latest`` objects in the system, ordered descending
- by ``date_field``. For example, if ``num_latest`` is ``10``, then
- ``latest`` will be a list of the latest 10 objects in ``queryset``.
+``latest``
+ The ``num_latest`` objects in the system, ordered descending by
+ ``date_field``. For example, if ``num_latest`` is ``10``, then ``latest``
+ will be a list of the latest 10 objects in ``queryset``.
- **New in Django development version:** This variable's name depends on
- the ``template_object_name`` parameter, which is ``'latest'`` by default.
- If ``template_object_name`` is ``'foo'``, this variable's name will be
- ``foo``.
+ **New in Django development version:** This variable's name depends on the
+ ``template_object_name`` parameter, which is ``'latest'`` by default.
+ If ``template_object_name`` is ``'foo'``, this variable's name will be
+ ``foo``.
.. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext
``django.views.generic.date_based.archive_year``
------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A yearly archive page showing all available months in a given year. Objects
with a date in the *future* are not displayed unless you set ``allow_future``
to ``True``.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``year``: The four-digit year for which the archive serves.
+``year``
+ The four-digit year for which the archive serves.
- * ``queryset``: A ``QuerySet`` of objects for which the archive serves.
+``queryset``
+ A ``QuerySet`` of objects for which the archive serves.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the date-based archive should use to determine the objects on
+ the page.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``False``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``False``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``. The
- view will append ``'_list'`` to the value of this parameter in
- determining the variable's name.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``. The view will append ``'_list'``
+ to the value of this parameter in determining the variable's name.
- * ``make_object_list``: A boolean specifying whether to retrieve the full
- list of objects for this year and pass those to the template. If ``True``,
- this list of objects will be made available to the template as
- ``object_list``. (The name ``object_list`` may be different; see the docs
- for ``object_list`` in the "Template context" section below.) By default,
- this is ``False``.
+``make_object_list``
+ A boolean specifying whether to retrieve the full list of objects for this
+ year and pass those to the template. If ``True``, this list of objects will
+ be made available to the template as ``object_list``. (The name
+ ``object_list`` may be different; see the docs for ``object_list`` in the
+ "Template context" section below.) By default, this is ``False``.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_archive_year.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``date_list``: A list of ``datetime.date`` objects representing all
- months that have objects available in the given year, according to
- ``queryset``, in ascending order.
+``date_list``
+ A list of ``datetime.date`` objects representing all months that have
+ objects available in the given year, according to ``queryset``, in
+ ascending order.
- * ``year``: The given year, as a four-character string.
+``year``
+ The given year, as a four-character string.
- * ``object_list``: If the ``make_object_list`` parameter is ``True``, this
- will be set to a list of objects available for the given year, ordered by
- the date field. This variable's name depends on the
- ``template_object_name`` parameter, which is ``'object'`` by default. If
- ``template_object_name`` is ``'foo'``, this variable's name will be
- ``foo_list``.
+``object_list``
+ If the ``make_object_list`` parameter is ``True``, this will be set to a
+ list of objects available for the given year, ordered by the date field.
+ This variable's name depends on the ``template_object_name`` parameter,
+ which is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
+ this variable's name will be ``foo_list``.
- If ``make_object_list`` is ``False``, ``object_list`` will be passed to
- the template as an empty list.
+ If ``make_object_list`` is ``False``, ``object_list`` will be passed to the
+ template as an empty list.
``django.views.generic.date_based.archive_month``
-------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A monthly archive page showing all objects in a given month. Objects with a
date in the *future* are not displayed unless you set ``allow_future`` to
``True``.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``year``: The four-digit year for which the archive serves (a string).
+``year``
+ The four-digit year for which the archive serves (a string).
- * ``month``: The month for which the archive serves, formatted according to
- the ``month_format`` argument.
+``month``
+ The month for which the archive serves, formatted according to the
+ ``month_format`` argument.
- * ``queryset``: A ``QuerySet`` of objects for which the archive serves.
+``queryset``
+ A ``QuerySet`` of objects for which the archive serves.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the date-based archive should use to determine the objects on
+ the page.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``month_format``: A format string that regulates what format the
- ``month`` parameter uses. This should be in the syntax accepted by
- Python's ``time.strftime``. (See the `strftime docs`_.) It's set to
- ``"%b"`` by default, which is a three-letter month abbreviation. To
- change it to use numbers, use ``"%m"``.
+``month_format``
+ A format string that regulates what format the ``month`` parameter uses.
+ This should be in the syntax accepted by Python's ``time.strftime``. (See
+ the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
+ letter month abbreviation. To change it to use numbers, use ``"%m"``.
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``False``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``False``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``. The
- view will append ``'_list'`` to the value of this parameter in
- determining the variable's name.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``. The view will append ``'_list'``
+ to the value of this parameter in determining the variable's name.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_archive_month.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``month``: A ``datetime.date`` object representing the given month.
+``month``
+ A ``datetime.date`` object representing the given month.
- * ``next_month``: A ``datetime.date`` object representing the first day of
- the next month. If the next month is in the future, this will be
- ``None``.
+``next_month``
+ A ``datetime.date`` object representing the first day of the next month. If
+ the next month is in the future, this will be ``None``.
- * ``previous_month``: A ``datetime.date`` object representing the first day
- of the previous month. Unlike ``next_month``, this will never be
- ``None``.
+``previous_month``
+ A ``datetime.date`` object representing the first day of the previous
+ month. Unlike ``next_month``, this will never be ``None``.
- * ``object_list``: A list of objects available for the given month. This
- variable's name depends on the ``template_object_name`` parameter, which
- is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
- this variable's name will be ``foo_list``.
+``object_list``
+ A list of objects available for the given month. This variable's name
+ depends on the ``template_object_name`` parameter, which is ``'object'`` by
+ default. If ``template_object_name`` is ``'foo'``, this variable's name
+ will be ``foo_list``.
.. _strftime docs: http://www.python.org/doc/current/lib/module-time.html#l2h-1941
``django.views.generic.date_based.archive_week``
------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A weekly archive page showing all objects in a given week. Objects with a date
in the *future* are not displayed unless you set ``allow_future`` to ``True``.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``year``: The four-digit year for which the archive serves (a string).
+``year``
+ The four-digit year for which the archive serves (a string).
- * ``week``: The week of the year for which the archive serves (a string).
- Weeks start with Sunday.
+``week``
+ The week of the year for which the archive serves (a string). Weeks start
+ with Sunday.
- * ``queryset``: A ``QuerySet`` of objects for which the archive serves.
+``queryset``
+ A ``QuerySet`` of objects for which the archive serves.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the date-based archive should use to determine the objects on
+ the page.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``True``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``True``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``. The
- view will append ``'_list'`` to the value of this parameter in
- determining the variable's name.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``. The view will append ``'_list'``
+ to the value of this parameter in determining the variable's name.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_archive_week.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``week``: A ``datetime.date`` object representing the first day of the
- given week.
+``week``
+ A ``datetime.date`` object representing the first day of the given week.
- * ``object_list``: A list of objects available for the given week. This
- variable's name depends on the ``template_object_name`` parameter, which
- is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
- this variable's name will be ``foo_list``.
+``object_list``
+ A list of objects available for the given week. This variable's name
+ depends on the ``template_object_name`` parameter, which is ``'object'`` by
+ default. If ``template_object_name`` is ``'foo'``, this variable's name
+ will be ``foo_list``.
``django.views.generic.date_based.archive_day``
-----------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A day archive page showing all objects in a given day. Days in the future throw
a 404 error, regardless of whether any objects exist for future days, unless
you set ``allow_future`` to ``True``.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``year``: The four-digit year for which the archive serves (a string).
+``year``
+ The four-digit year for which the archive serves (a string).
- * ``month``: The month for which the archive serves, formatted according to
- the ``month_format`` argument.
+``month``
+ The month for which the archive serves, formatted according to the
+ ``month_format`` argument.
- * ``day``: The day for which the archive serves, formatted according to the
- ``day_format`` argument.
+``day``
+ The day for which the archive serves, formatted according to the
+ ``day_format`` argument.
- * ``queryset``: A ``QuerySet`` of objects for which the archive serves.
+``queryset``
+ A ``QuerySet`` of objects for which the archive serves.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the date-based archive should use to determine the objects on
+ the page.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``month_format``: A format string that regulates what format the
- ``month`` parameter uses. This should be in the syntax accepted by
- Python's ``time.strftime``. (See the `strftime docs`_.) It's set to
- ``"%b"`` by default, which is a three-letter month abbreviation. To
- change it to use numbers, use ``"%m"``.
+``month_format``
+ A format string that regulates what format the ``month`` parameter uses.
+ This should be in the syntax accepted by Python's ``time.strftime``. (See
+ the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
+ letter month abbreviation. To change it to use numbers, use ``"%m"``.
- * ``day_format``: Like ``month_format``, but for the ``day`` parameter.
- It defaults to ``"%d"`` (day of the month as a decimal number, 01-31).
+``day_format``
+ Like ``month_format``, but for the ``day`` parameter. It defaults to
+ ``"%d"`` (day of the month as a decimal number, 01-31).
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``False``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``False``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``. The
- view will append ``'_list'`` to the value of this parameter in
- determining the variable's name.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``. The view will append
+ ``'_list'`` to the value of this parameter in determining the variable's
+ name.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_archive_day.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``day``: A ``datetime.date`` object representing the given day.
+``day``
+ A ``datetime.date`` object representing the given day.
- * ``next_day``: A ``datetime.date`` object representing the next day. If
- the next day is in the future, this will be ``None``.
+``next_day``
+ A ``datetime.date`` object representing the next day. If the next day is in
+ the future, this will be ``None``.
- * ``previous_day``: A ``datetime.date`` object representing the given day.
- Unlike ``next_day``, this will never be ``None``.
+``previous_day``
+ A ``datetime.date`` object representing the given day. Unlike ``next_day``,
+ this will never be ``None``.
- * ``object_list``: A list of objects available for the given day. This
- variable's name depends on the ``template_object_name`` parameter, which
- is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
- this variable's name will be ``foo_list``.
+``object_list``
+ A list of objects available for the given day. This variable's name depends
+ on the ``template_object_name`` parameter, which is ``'object'`` by
+ default. If ``template_object_name`` is ``'foo'``, this variable's name
+ will be ``foo_list``.
``django.views.generic.date_based.archive_today``
-------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A day archive page showing all objects for *today*. This is exactly the same as
``archive_day``, except the ``year``/``month``/``day`` arguments are not used,
@@ -584,95 +674,108 @@ and today's date is used instead.
``django.views.generic.date_based.object_detail``
-------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A page representing an individual object. If the object has a date value in the
future, the view will throw a 404 error by default, unless you set
``allow_future`` to ``True``.
-**Required arguments:**
-
- * ``year``: The object's four-digit year (a string).
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``month``: The object's month , formatted according to the
- ``month_format`` argument.
+``year``
+ The object's four-digit year (a string).
- * ``day``: The object's day , formatted according to the ``day_format``
- argument.
+``month``
+ The object's month , formatted according to the ``month_format`` argument.
- * ``queryset``: A ``QuerySet`` that contains the object.
+``day``
+ The object's day , formatted according to the ``day_format`` argument.
- * ``date_field``: The name of the ``DateField`` or ``DateTimeField`` in
- the ``QuerySet``'s model that the generic view should use to look up the
- object according to ``year``, ``month`` and ``day``.
+``queryset``
+ A ``QuerySet`` that contains the object.
- * Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
+``date_field``
+ The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
+ model that the generic view should use to look up the object according to
+ ``year``, ``month`` and ``day``.
- If you provide ``object_id``, it should be the value of the primary-key
- field for the object being displayed on this page.
+Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
+ If you provide ``object_id``, it should be the value of the primary-key
+ field for the object being displayed on this page.
- 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. By default, ``slug_field`` is ``'slug'``.
+ 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. By default, ``slug_field`` is ``'slug'``.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``month_format``: A format string that regulates what format the
- ``month`` parameter uses. This should be in the syntax accepted by
- Python's ``time.strftime``. (See the `strftime docs`_.) It's set to
- ``"%b"`` by default, which is a three-letter month abbreviation. To
- change it to use numbers, use ``"%m"``.
+``month_format``
+ A format string that regulates what format the ``month`` parameter uses.
+ This should be in the syntax accepted by Python's ``time.strftime``. (See
+ the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
+ letter month abbreviation. To change it to use numbers, use ``"%m"``.
- * ``day_format``: Like ``month_format``, but for the ``day`` parameter.
- It defaults to ``"%d"`` (day of the month as a decimal number, 01-31).
+``day_format``
+ Like ``month_format``, but for the ``day`` parameter. It defaults to
+ ``"%d"`` (day of the month as a decimal number, 01-31).
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_name_field``: The name of a field on the object whose value is
- the template name to use. This lets you store template names in the data.
- In other words, if your object has a field ``'the_template'`` that
- contains a string ``'foo.html'``, and you set ``template_name_field`` to
- ``'the_template'``, then the generic view for this object will use the
- template ``'foo.html'``.
+``template_name_field``
+ The name of a field on the object whose value is the template name to use.
+ This lets you store template names in the data. In other words, if your
+ object has a field ``'the_template'`` that contains a string
+ ``'foo.html'``, and you set ``template_name_field`` to ``'the_template'``,
+ then the generic view for this object will use the template ``'foo.html'``.
- It's a bit of a brain-bender, but it's useful in some cases.
+ It's a bit of a brain-bender, but it's useful in some cases.
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
- * ``allow_future``: A boolean specifying whether to include "future"
- objects on this page, where "future" means objects in which the field
- specified in ``date_field`` is greater than the current date/time. By
- default, this is ``False``.
+``allow_future``
+ A boolean specifying whether to include "future" objects on this page,
+ where "future" means objects in which the field specified in ``date_field``
+ is greater than the current date/time. By default, this is ``False``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_detail.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``object``: The object. This variable's name depends on the
- ``template_object_name`` parameter, which is ``'object'`` by default. If
- ``template_object_name`` is ``'foo'``, this variable's name will be
- ``foo``.
+``object``
+ The object. This variable's name depends on the ``template_object_name``
+ parameter, which is ``'object'`` by default. If ``template_object_name`` is
+ ``'foo'``, this variable's name will be ``foo``.
List/detail generic views
=========================
@@ -685,113 +788,95 @@ object page.
``django.views.generic.list_detail.object_list``
------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A page representing a list of objects.
-**Required arguments:**
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * ``queryset``: A ``QuerySet`` that represents the objects.
+``queryset``
+ A ``QuerySet`` that represents the objects.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``paginate_by``: An integer specifying how many objects should be
- displayed per page. If this is given, the view will paginate objects with
- ``paginate_by`` objects per page. The view will expect either a ``page``
- query string parameter (via ``GET``) or a ``page`` variable specified in
- the URLconf. See `Notes on pagination`_ below.
+``paginate_by``
+ An integer specifying how many objects should be displayed per page. If
+ this is given, the view will paginate objects with ``paginate_by`` objects
+ per page. The view will expect either a ``page`` query string parameter
+ (via ``GET``) or a ``page`` variable specified in the URLconf. See `Notes
+ on pagination`_ below.
- * ``page``: The current page number, as an integer. This is 1-based.
- See `Notes on pagination`_ below.
+``page``
+ The current (1-based) page number, as an integer, or the string ``'last'``.
+ See `Notes on pagination`_ below.
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``allow_empty``: A boolean specifying whether to display the page if no
- objects are available. If this is ``False`` and no objects are available,
- the view will raise a 404 instead of displaying an empty page. By
- default, this is ``True``.
+``allow_empty``
+ A boolean specifying whether to display the page if no objects are
+ available. If this is ``False`` and no objects are available, the view will
+ raise a 404 instead of displaying an empty page. By default, this is
+ ``True``.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``. The
- view will append ``'_list'`` to the value of this parameter in
- determining the variable's name.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``. The view will append ``'_list'``
+ to the value of this parameter in determining the variable's name.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_list.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``object_list``: The list of objects. This variable's name depends on the
- ``template_object_name`` parameter, which is ``'object'`` by default. If
- ``template_object_name`` is ``'foo'``, this variable's name will be
- ``foo_list``.
+``object_list``
+ The list of objects. This variable's name depends on the
+ ``template_object_name`` parameter, which is ``'object'`` by default. If
+ ``template_object_name`` is ``'foo'``, this variable's name will be
+ ``foo_list``.
- * ``is_paginated``: A boolean representing whether the results are
- paginated. Specifically, this is set to ``False`` if the number of
- available objects is less than or equal to ``paginate_by``.
+``is_paginated``
+ A boolean representing whether the results are paginated. Specifically,
+ this is set to ``False`` if the number of available objects is less than or
+ equal to ``paginate_by``.
If the results are paginated, the context will contain these extra variables:
- * **New in Django development version:** ``paginator``: An instance of
- ``django.core.paginator.Paginator``.
-
- * **New in Django development version:** ``page_obj``: An instance of
- ``django.core.paginator.Page``.
-
-In older versions of Django, before ``paginator`` and ``page_obj`` were added
-to this template's context, the template included several other variables
-related to pagination. Note that you should *NOT* use these variables anymore;
-use ``paginator`` and ``page_obj`` instead, because they let you do everything
-these old variables let you do (and more!). But for legacy installations,
-here's a list of those old template variables:
-
- * ``results_per_page``: The number of objects per page. (Same as the
- ``paginate_by`` parameter.)
-
- * ``has_next``: A boolean representing whether there's a next page.
-
- * ``has_previous``: A boolean representing whether there's a previous page.
-
- * ``page``: The current page number, as an integer. This is 1-based.
+``paginator`` (**New in Django development version**)
+ An instance of ``django.core.paginator.Paginator``.
- * ``next``: The next page number, as an integer. If there's no next page,
- this will still be an integer representing the theoretical next-page
- number. This is 1-based.
+``page_obj`` (**New in Django development version**)
+ An instance of ``django.core.paginator.Page``.
- * ``previous``: The previous page number, as an integer. This is 1-based.
-
- * ``last_on_page``: The number of the
- last result on the current page. This is 1-based.
-
- * ``first_on_page``: The number of the
- first result on the current page. This is 1-based.
-
- * ``pages``: The total number of pages, as an integer.
-
- * ``hits``: The total number of objects across *all* pages, not just this
- page.
-
- * ``page_range``: A list of the page numbers that are available. This is
- 1-based.
+See the `pagination documentation`_ for more information on the ``Paginator``
+and ``Page`` objects.
Notes on pagination
~~~~~~~~~~~~~~~~~~~
@@ -817,7 +902,7 @@ These values and lists are 1-based, not 0-based, so the first page would be
represented as page ``1``.
For more on pagination, read the `pagination documentation`_.
-
+
.. _`pagination documentation`: ../pagination/
**New in Django development version:**
@@ -838,67 +923,77 @@ any other value for ``page`` will result in a 404 error.
A page representing an individual object.
-**Description:**
+Description
+~~~~~~~~~~~
A page representing an individual object.
-**Required arguments:**
-
- * ``queryset``: A ``QuerySet`` that contains the object.
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
+``queryset``
+ A ``QuerySet`` that contains the object.
- If you provide ``object_id``, it should be the value of the primary-key
- field for the object being displayed on this page.
+Either ``object_id`` or (``slug`` *and* ``slug_field``)
+ If you provide ``object_id``, it should be the value of the primary-key
+ field for the object being displayed on this page.
- 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. By default, ``slug_field`` is ``'slug'``.
+ 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. By default, ``slug_field`` is ``'slug'``.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_name_field``: The name of a field on the object whose value is
- the template name to use. This lets you store template names in the data.
- In other words, if your object has a field ``'the_template'`` that
- contains a string ``'foo.html'``, and you set ``template_name_field`` to
- ``'the_template'``, then the generic view for this object will use the
- template ``'foo.html'``.
+``template_name_field``
+ The name of a field on the object whose value is the template name to use.
+ This lets you store template names in the data. In other words, if your
+ object has a field ``'the_template'`` that contains a string
+ ``'foo.html'``, and you set ``template_name_field`` to ``'the_template'``,
+ then the generic view for this object will use the template ``'foo.html'``.
- It's a bit of a brain-bender, but it's useful in some cases.
+ It's a bit of a brain-bender, but it's useful in some cases.
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``.
- * ``mimetype``: The MIME type to use for the resulting document. Defaults
- to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the ``DEFAULT_CONTENT_TYPE`` setting.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_detail.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``object``: The object. This variable's name depends on the
- ``template_object_name`` parameter, which is ``'object'`` by default. If
- ``template_object_name`` is ``'foo'``, this variable's name will be
- ``foo``.
+``object``
+ The object. This variable's name depends on the ``template_object_name``
+ parameter, which is ``'object'`` by default. If ``template_object_name`` is
+ ``'foo'``, this variable's name will be ``foo``.
Create/update/delete generic views
==================================
@@ -909,242 +1004,270 @@ for creating, editing and deleting objects.
**Changed in Django development version:**
``django.views.generic.create_update.create_object`` and
-``django.views.generic.create_update.update_object`` now use `newforms`_ to
-build and display the form.
+``django.views.generic.create_update.update_object`` now use the new `forms
+library`_ to build and display the form.
-.. _newforms: ../newforms/
+.. _forms library: ../forms/
``django.views.generic.create_update.create_object``
----------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A page that displays a form for creating an object, redisplaying the form with
validation errors (if there are any) and saving the object.
-**Required arguments:**
-
- * Either ``form_class`` or ``model`` is required.
+Required arguments
+~~~~~~~~~~~~~~~~~~
- If you provide ``form_class``, it should be a
- ``django.newforms.ModelForm`` subclass. Use this argument when you need
- to customize the model's form. See the `ModelForm docs`_ for more
- information.
+Either ``form_class`` or ``model``
+ If you provide ``form_class``, it should be a ``django.forms.ModelForm``
+ subclass. Use this argument when you need to customize the model's form.
+ See the `ModelForm docs`_ for more information.
- Otherwise, ``model`` should be a Django model class and the form used
- will be a standard ``ModelForm`` for ``model``.
+ Otherwise, ``model`` should be a Django model class and the form used will
+ be a standard ``ModelForm`` for ``model``.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``post_save_redirect``: A URL to which the view will redirect after
- saving the object. By default, it's ``object.get_absolute_url()``.
+``post_save_redirect``
+ A URL to which the view will redirect after saving the object. By default,
+ it's ``object.get_absolute_url()``.
- ``post_save_redirect`` may contain dictionary string formatting, which
- will be interpolated against the object's field attributes. For example,
- you could use ``post_save_redirect="/polls/%(slug)s/"``.
+ ``post_save_redirect`` may contain dictionary string formatting, which will
+ be interpolated against the object's field attributes. For example, you
+ could use ``post_save_redirect="/polls/%(slug)s/"``.
- * ``login_required``: A boolean that designates whether a user must be
- logged in, in order to see the page and save changes. This hooks into the
- Django `authentication system`_. By default, this is ``False``.
+``login_required``
+ A boolean that designates whether a user must be logged in, in order to see
+ the page and save changes. This hooks into the Django `authentication
+ system`_. By default, this is ``False``.
- If this is ``True``, and a non-logged-in user attempts to visit this page
- or save the form, Django will redirect the request to ``/accounts/login/``.
+ If this is ``True``, and a non-logged-in user attempts to visit this page
+ or save the form, Django will redirect the request to ``/accounts/login/``.
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_form.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``form``: A ``django.newforms.ModelForm`` instance representing the form
- for creating the object. This lets you refer to form fields easily in the
- template system.
+``form``
+ A ``django.forms.ModelForm`` instance representing the form for creating
+ the object. This lets you refer to form fields easily in the template
+ system.
- For example, if the model has two fields, ``name`` and ``address``::
+ For example, if the model has two fields, ``name`` and ``address``::
- <form action="" method="post">
- <p>{{ form.name.label_tag }} {{ form.name }}</p>
- <p>{{ form.address.label_tag }} {{ form.address }}</p>
- </form>
+ <form action="" method="post">
+ <p>{{ form.name.label_tag }} {{ form.name }}</p>
+ <p>{{ form.address.label_tag }} {{ form.address }}</p>
+ </form>
- See the `newforms documentation`_ for more information about using
- ``Form`` objects in templates.
+ See the `forms documentation`_ for more information about using ``Form``
+ objects in templates.
.. _authentication system: ../authentication/
-.. _ModelForm docs: ../newforms/modelforms
-.. _newforms documentation: ../newforms/
+.. _ModelForm docs: ../modelforms/
+.. _forms documentation: ../forms/
``django.views.generic.create_update.update_object``
----------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A page that displays a form for editing an existing object, redisplaying the
form with validation errors (if there are any) and saving changes to the
-object. This uses the automatic manipulators that come with Django models.
-
-**Required arguments:**
+object. This uses a form automatically generated from the object's
+model class.
- * Either ``form_class`` or ``model`` is required.
+Required arguments
+~~~~~~~~~~~~~~~~~~
- If you provide ``form_class``, it should be a
- ``django.newforms.ModelForm`` subclass. Use this argument when you need
- to customize the model's form. See the `ModelForm docs`_ for more
- information.
+Either ``form_class`` or ``model``
+ If you provide ``form_class``, it should be a ``django.forms.ModelForm``
+ subclass. Use this argument when you need to customize the model's form.
+ See the `ModelForm docs`_ for more information.
- Otherwise, ``model`` should be a Django model class and the form used
- will be a standard ``ModelForm`` for ``model``.
+ Otherwise, ``model`` should be a Django model class and the form used will
+ be a standard ``ModelForm`` for ``model``.
- * Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
+Either ``object_id`` or (``slug`` *and* ``slug_field``)
+ If you provide ``object_id``, it should be the value of the primary-key
+ field for the object being displayed on this page.
- If you provide ``object_id``, it should be the value of the primary-key
- field for the object being displayed on this page.
+ 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. By default, ``slug_field`` is ``'slug'``.
- 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. By default, ``slug_field`` is ``'slug'``.
+Optional arguments
+~~~~~~~~~~~~~~~~~~
-**Optional arguments:**
+``post_save_redirect``
+ A URL to which the view will redirect after saving the object. By default,
+ it's ``object.get_absolute_url()``.
- * ``post_save_redirect``: A URL to which the view will redirect after
- saving the object. By default, it's ``object.get_absolute_url()``.
+ ``post_save_redirect`` may contain dictionary string formatting, which will
+ be interpolated against the object's field attributes. For example, you
+ could use ``post_save_redirect="/polls/%(slug)s/"``.
- ``post_save_redirect`` may contain dictionary string formatting, which
- will be interpolated against the object's field attributes. For example,
- you could use ``post_save_redirect="/polls/%(slug)s/"``.
+``login_required``
+ A boolean that designates whether a user must be logged in, in order to see
+ the page and save changes. This hooks into the Django `authentication
+ system`_. By default, this is ``False``.
- * ``login_required``: A boolean that designates whether a user must be
- logged in, in order to see the page and save changes. This hooks into the
- Django `authentication system`_. By default, this is ``False``.
+ If this is ``True``, and a non-logged-in user attempts to visit this page
+ or save the form, Django will redirect the request to ``/accounts/login/``.
- If this is ``True``, and a non-logged-in user attempts to visit this page
- or save the form, Django will redirect the request to ``/accounts/login/``.
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
-
- * ``context_processors``: A list of template-context processors to apply to
+``context_processors``: A list of template-context processors to apply to
the view's template. See the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_form.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``form``: A ``django.newforms.ModelForm`` instance representing the form
- for editing the object. This lets you refer to form fields easily in the
- template system.
+``form``
+ A ``django.forms.ModelForm`` instance representing the form for editing the
+ object. This lets you refer to form fields easily in the template system.
- For example, if the model has two fields, ``name`` and ``address``::
+ For example, if the model has two fields, ``name`` and ``address``::
- <form action="" method="post">
- <p>{{ form.name.label_tag }} {{ form.name }}</p>
- <p>{{ form.address.label_tag }} {{ form.address }}</p>
- </form>
+ <form action="" method="post">
+ <p>{{ form.name.label_tag }} {{ form.name }}</p>
+ <p>{{ form.address.label_tag }} {{ form.address }}</p>
+ </form>
- See the `newforms documentation`_ for more information about using
- ``Form`` objects in templates.
+ See the `forms documentation`_ for more information about using ``Form``
+ objects in templates.
- * ``object``: The original object being edited. This variable's name
- depends on the ``template_object_name`` parameter, which is ``'object'``
- by default. If ``template_object_name`` is ``'foo'``, this variable's
- name will be ``foo``.
+``object``
+ The original object being edited. This variable's name depends on the
+ ``template_object_name`` parameter, which is ``'object'`` by default. If
+ ``template_object_name`` is ``'foo'``, this variable's name will be
+ ``foo``.
``django.views.generic.create_update.delete_object``
----------------------------------------------------
-**Description:**
+Description
+~~~~~~~~~~~
A view that displays a confirmation page and deletes an existing object. The
given object will only be deleted if the request method is ``POST``. If this
view is fetched via ``GET``, it will display a confirmation page that should
contain a form that POSTs to the same URL.
-**Required arguments:**
-
- * ``model``: The Django model class of the object that the form will
- create.
+Required arguments
+~~~~~~~~~~~~~~~~~~
- * Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
+``model``
+ The Django model class of the object that the form will create.
- If you provide ``object_id``, it should be the value of the primary-key
- field for the object being displayed on this page.
+Either ``object_id`` or (``slug`` *and* ``slug_field``)
+ If you provide ``object_id``, it should be the value of the primary-key
+ field for the object being displayed on this page.
- 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. By default, ``slug_field`` is ``'slug'``.
+ 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. By default, ``slug_field`` is ``'slug'``.
- * ``post_delete_redirect``: A URL to which the view will redirect after
- deleting the object.
+``post_delete_redirect``
+ A URL to which the view will redirect after deleting the object.
-**Optional arguments:**
+Optional arguments
+~~~~~~~~~~~~~~~~~~
- * ``login_required``: A boolean that designates whether a user must be
- logged in, in order to see the page and save changes. This hooks into the
- Django `authentication system`_. By default, this is ``False``.
+``login_required``
+ A boolean that designates whether a user must be logged in, in order to see
+ the page and save changes. This hooks into the Django `authentication
+ system`_. By default, this is ``False``.
- If this is ``True``, and a non-logged-in user attempts to visit this page
- or save the form, Django will redirect the request to ``/accounts/login/``.
+ If this is ``True``, and a non-logged-in user attempts to visit this page
+ or save the form, Django will redirect the request to ``/accounts/login/``.
- * ``template_name``: The full name of a template to use in rendering the
- page. This lets you override the default template name (see below).
+``template_name``
+ The full name of a template to use in rendering the page. This lets you
+ override the default template name (see below).
- * ``template_loader``: The template loader to use when loading the
- template. By default, it's ``django.template.loader``.
+``template_loader``
+ The template loader to use when loading the template. By default, it's
+ ``django.template.loader``.
- * ``extra_context``: A dictionary of values to add to the template
- context. By default, this is an empty dictionary. If a value in the
- dictionary is callable, the generic view will call it
- just before rendering the template.
+``extra_context``
+ A dictionary of values to add to the template context. By default, this is
+ an empty dictionary. If a value in the dictionary is callable, the generic
+ view will call it just before rendering the template.
- * ``context_processors``: A list of template-context processors to apply to
- the view's template. See the `RequestContext docs`_.
+``context_processors``
+ A list of template-context processors to apply to the view's template. See
+ the `RequestContext docs`_.
- * ``template_object_name``: Designates the name of the template variable
- to use in the template context. By default, this is ``'object'``.
+``template_object_name``
+ Designates the name of the template variable to use in the template
+ context. By default, this is ``'object'``.
-**Template name:**
+Template name
+~~~~~~~~~~~~~
If ``template_name`` isn't specified, this view will use the template
``<app_label>/<model_name>_confirm_delete.html`` by default.
-**Template context:**
+Template context
+~~~~~~~~~~~~~~~~
In addition to ``extra_context``, the template's context will be:
- * ``object``: The original object that's about to be deleted. This
- variable's name depends on the ``template_object_name`` parameter, which
- is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
- this variable's name will be ``foo``.
+``object``
+ The original object that's about to be deleted. This variable's name
+ depends on the ``template_object_name`` parameter, which is ``'object'`` by
+ default. If ``template_object_name`` is ``'foo'``, this variable's name
+ will be ``foo``.
diff --git a/docs/i18n.txt b/docs/i18n.txt
index c221b43718..5269024e96 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -434,6 +434,12 @@ do the same, but the location of the locale directory is ``locale/LANG/LC_MESSAG
message file (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a
starting point; it's just an empty translation file.
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilites so
+ ``django-admin makemessages`` works see `gettext on Windows`_ for more
+ information.
+
The format of ``.po`` files is straightforward. Each ``.po`` file contains a
small bit of metadata, such as the translation maintainer's contact
information, but the bulk of the file is a list of **messages** -- simple
@@ -513,6 +519,12 @@ That's it. Your translations are ready for use.
.. _Submitting and maintaining translations: ../contributing/
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilites so
+ ``django-admin compilemessages`` works see `gettext on Windows`_ for more
+ information.
+
3. How Django discovers language preference
===========================================
@@ -888,10 +900,31 @@ does translation:
* The string domain is ``django`` or ``djangojs``. This string domain is
used to differentiate between different programs that store their data
in a common message-file library (usually ``/usr/share/locale/``). The
- ``django`` domain is used for python and template translation strings
+ ``django`` domain is used for Python and template translation strings
and is loaded into the global translation catalogs. The ``djangojs``
domain is only used for JavaScript translation catalogs to make sure
that those are as small as possible.
* Django doesn't use ``xgettext`` alone. It uses Python wrappers around
``xgettext`` and ``msgfmt``. This is mostly for convenience.
+``gettext`` on Windows
+======================
+
+This is only needed for people who either want to extract message IDs or
+compile ``.po`` files. Translation work itself just involves editing existing
+``.po`` files, but if you want to create your own .po files, or want to test
+or compile a changed ``.po`` file, you will need the ``gettext`` utilities:
+
+ * Download the following zip files from http://sourceforge.net/projects/gettext
+
+ * ``gettext-runtime-X.bin.woe32.zip``
+ * ``gettext-tools-X.bin.woe32.zip``
+ * ``libiconv-X.bin.woe32.zip``
+
+ * Extract the 3 files in the same folder (i.e. ``C:\Program Files\gettext-utils``)
+
+ * Update the system PATH:
+
+ * ``Control Panel > System > Advanced > Environment Variables``
+ * In the ``System variables`` list, click ``Path``, click ``Edit``
+ * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the ``Variable value``
diff --git a/docs/index.txt b/docs/index.txt
index 385ada455c..36a0273819 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -33,7 +33,7 @@ Reference
transactions
templates
templates_python
- newforms
+ forms
modelforms
testing
sessions
diff --git a/docs/install.txt b/docs/install.txt
index bfe85fff8a..cd21bd7ec1 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -18,7 +18,7 @@ Install Apache and mod_python
=============================
If you just want to experiment with Django, skip ahead to the next
-section; Django includes a lightweight web server you can use for
+section; Django includes a lightweight Web server you can use for
testing, so you won't need to set up Apache until you're ready to
deploy Django in production.
@@ -64,7 +64,7 @@ installed.
You will also want to read the database-specific notes for the `MySQL backend`_.
* If you're using SQLite and either Python 2.3 or Python 2.4, you'll need
- pysqlite_. Use version 2.0.3 or higher. Python 2.5 ships with an sqlite
+ pysqlite_. Use version 2.0.3 or higher. Python 2.5 ships with an SQLite
wrapper in the standard library, so you don't need to install anything extra
in that case.
diff --git a/docs/localflavor.txt b/docs/localflavor.txt
index 5a2e5b8fda..71e353c5d8 100644
--- a/docs/localflavor.txt
+++ b/docs/localflavor.txt
@@ -11,7 +11,7 @@ Inside that package, country- or culture-specific code is organized into
subpackages, named using `ISO 3166 country codes`_.
Most of the ``localflavor`` add-ons are localized form components deriving from
-the newforms_ framework -- for example, a ``USStateField`` that knows how to
+the forms_ framework -- for example, a ``USStateField`` that knows how to
validate U.S. state abbreviations, and a ``FISocialSecurityNumber`` that knows
how to validate Finnish social security numbers.
@@ -19,7 +19,7 @@ To use one of these localized components, just import the relevant subpackage.
For example, here's how you can create a form with a field representing a
French telephone number::
- from django import newforms as forms
+ from django import forms
from django.contrib.localflavor import fr
class MyForm(forms.Form):
@@ -32,6 +32,7 @@ Countries currently supported by ``localflavor`` are:
* Argentina_
* Australia_
+ * Austria_
* Brazil_
* Canada_
* Chile_
@@ -47,6 +48,7 @@ Countries currently supported by ``localflavor`` are:
* Norway_
* Peru_
* Poland_
+ * Romania_
* Slovakia_
* `South Africa`_
* Spain_
@@ -57,10 +59,10 @@ Countries currently supported by ``localflavor`` are:
The ``localflavor`` package also includes a ``generic`` subpackage, containing
useful code that is not specific to one particular country or culture.
Currently, it defines date and datetime input fields based on those from
-newforms_, but with non-US default formats. Here's an example of how to use
+forms_, but with non-US default formats. Here's an example of how to use
them::
- from django import newforms as forms
+ from django import forms
from django.contrib.localflavor import generic
class MyForm(forms.Form):
@@ -69,6 +71,7 @@ them::
.. _ISO 3166 country codes: http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm
.. _Argentina: `Argentina (django.contrib.localflavor.ar)`_
.. _Australia: `Australia (django.contrib.localflavor.au)`_
+.. _Austria: `Austria (django.contrib.localflavor.at)`_
.. _Brazil: `Brazil (django.contrib.localflavor.br)`_
.. _Canada: `Canada (django.contrib.localflavor.ca)`_
.. _Chile: `Chile (django.contrib.localflavor.cl)`_
@@ -84,13 +87,14 @@ them::
.. _Norway: `Norway (django.contrib.localflavor.no)`_
.. _Peru: `Peru (django.contrib.localflavor.pe)`_
.. _Poland: `Poland (django.contrib.localflavor.pl)`_
+.. _Romania: `Romania (django.contrib.localflavor.ro)`_
.. _Slovakia: `Slovakia (django.contrib.localflavor.sk)`_
.. _South Africa: `South Africa (django.contrib.localflavor.za)`_
.. _Spain: `Spain (django.contrib.localflavor.es)`_
.. _Switzerland: `Switzerland (django.contrib.localflavor.ch)`_
.. _United Kingdom: `United Kingdom (django.contrib.localflavor.uk)`_
.. _United States of America: `United States of America (django.contrib.localflavor.us)`_
-.. _newforms: ../newforms/
+.. _forms: ../forms/
Adding flavors
==============
@@ -151,6 +155,24 @@ AUStateSelect
A ``Select`` widget that uses a list of Australian states/territories as its
choices.
+Austria (``django.contrib.localflavor.at``)
+=============================================
+
+ATZipCodeField
+---------------
+
+A form field that validates its input as an Austrian zip code.
+
+ATStateSelect
+-------------
+
+A ``Select`` widget that uses a list of Austrian states as its choices.
+
+ATSocialSecurityNumberField
+---------------------------
+
+A form field that validates its input as an Austrian social security number.
+
Brazil (``django.contrib.localflavor.br``)
==========================================
@@ -497,6 +519,52 @@ PLVoivodeshipSelect
A ``Select`` widget that uses a list of Polish voivodeships (administrative
provinces) as its choices.
+Romania (``django.contrib.localflavor.ro``)
+============================================
+
+ROCIFField
+----------
+
+A form field that validates Romanian fiscal identification codes (CIF). The
+return value strips the leading RO, if given.
+
+ROCNPField
+----------
+
+A form field that validates Romanian personal numeric codes (CNP).
+
+ROCountyField
+-------------
+
+A form field that validates its input as a Romanian county (judet) name or
+abbreviation. It normalizes the input to the standard vehicle registration
+abbreviation for the given county. This field will only accept names written
+with diacritics; consider using ROCountySelect as an alternative.
+
+ROCountySelect
+--------------
+
+A ``Select`` widget that uses a list of Romanian counties (judete) as its
+choices.
+
+ROIBANField
+-----------
+
+A form field that validates its input as a Romanian International Bank
+Account Number (IBAN). The valid format is ROXX-XXXX-XXXX-XXXX-XXXX-XXXX,
+with or without hyphens.
+
+ROPhoneNumberField
+------------------
+
+A form field that validates Romanian phone numbers, short special numbers
+excluded.
+
+ROPostalCodeField
+-----------------
+
+A form field that validates Romanian postal codes.
+
Slovakia (``django.contrib.localflavor.sk``)
============================================
diff --git a/docs/middleware.txt b/docs/middleware.txt
index a2853e2965..8f93d7185d 100644
--- a/docs/middleware.txt
+++ b/docs/middleware.txt
@@ -104,7 +104,7 @@ 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
+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 4975953b97..93b27b8c11 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -112,7 +112,7 @@ class. Django uses the field class types to determine a few things:
* The widget to use in Django's admin interface, if you care to use it
(e.g. ``<input type="text">``, ``<select>``).
* The minimal validation requirements, used in Django's admin and in
- manipulators.
+ automatically-generated forms.
Here are all available field types:
@@ -144,10 +144,6 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
(in characters) of the field. The max_length is enforced at the database level
and in Django's validation.
-Django veterans: Note that the argument is now called ``max_length`` to
-provide consistency throughout Django. There is full legacy support for
-the old ``maxlength`` argument, but ``max_length`` is preferred.
-
``CommaSeparatedIntegerField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -641,9 +637,8 @@ callable it will be called every time a new object is created.
``editable``
~~~~~~~~~~~~
-If ``False``, the field will not be editable in the admin or via form
-processing using the object's ``AddManipulator`` or ``ChangeManipulator``
-classes. Default is ``True``.
+If ``False``, the field will not be editable in the admin or via forms
+automatically generated from the model class. Default is ``True``.
``help_text``
~~~~~~~~~~~~~
@@ -656,7 +651,10 @@ Note that this value is *not* HTML-escaped when it's displayed in the admin
interface. This lets you include HTML in ``help_text`` if you so desire. For
example::
- help_text="Please use the following format: <em>YYYY-MM-DD</em>."
+ help_text="Please use the following format: <em>YYYY-MM-DD</em>."
+
+Alternatively you can use plain text and
+``django.utils.html.escape()`` to escape any HTML special characters.
``primary_key``
~~~~~~~~~~~~~~~
@@ -716,7 +714,7 @@ that takes the parameters ``field_data, all_data`` and raises
Django comes with quite a few validators. They're in ``django.core.validators``.
-.. _validator docs: ../forms/#validators
+.. _validator docs: ../oldforms/#validators
Verbose field names
-------------------
@@ -942,6 +940,139 @@ the relationship should work. All are optional:
======================= ============================================================
+Extra fields on many-to-many relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+When you're only dealing with simple many-to-many relationships such as
+mixing and matching pizzas and toppings, a standard ``ManyToManyField``
+is all you need. However, sometimes you may need to associate data with the
+relationship between two models.
+
+For example, consider the case of an application tracking the musical groups
+which musicians belong to. There is a many-to-many relationship between a person
+and the groups of which they are a member, so you could use a ManyToManyField
+to represent this relationship. However, there is a lot of detail about the
+membership that you might want to collect, such as the date at which the person
+joined the group.
+
+For these situations, Django allows you to specify the model that will be used
+to govern the many-to-many relationship. You can then put extra fields on the
+intermediate model. The intermediate model is associated with the
+``ManyToManyField`` using the ``through`` argument to point to the model
+that will act as an intermediary. For our musician example, the code would look
+something like this::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ def __unicode__(self):
+ return self.name
+
+ class Group(models.Model):
+ name = models.CharField(max_length=128)
+ members = models.ManyToManyField(Person, through='Membership')
+
+ def __unicode__(self):
+ return self.name
+
+ class Membership(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ date_joined = models.DateField()
+ invite_reason = models.CharField(max_length=64)
+
+When you set up the intermediary model, you explicitly specify foreign
+keys to the models that are involved in the ManyToMany relation. This
+explicit declaration defines how the two models are related.
+
+There are a few restrictions on the intermediate model:
+
+ * Your intermediate model must contain one - and *only* one - foreign key
+ on the target model (this would be ``Person`` in our example). If you
+ have more than one foreign key, a validation error will be raised.
+
+ * Your intermediate model must contain one - and *only* one - foreign key
+ on the source model (this would be ``Group`` in our example). If you
+ have more than one foreign key, a validation error will be raised.
+
+ * The only exception to this is a model which has a many-to-many
+ relationship to itself, through an intermediary model. In this
+ case, two foreign keys to the same model are permitted, but they
+ will be treated as the two (different) sides of the many-to-many
+ relation.
+
+ * When defining a many-to-many relationship from a model to
+ itself, using an intermediary model, you *must* use
+ ``symmetrical=False`` (see the documentation for
+ ``ManyToManyField`` above).
+
+Now that you have set up your ``ManyToManyField`` to use your intermediary
+model (Membership, in this case), you're ready to start creating some
+many-to-many relationships. You do this by creating instances of the
+intermediate model::
+
+ >>> ringo = Person.objects.create(name="Ringo Starr")
+ >>> paul = Person.objects.create(name="Paul McCartney")
+ >>> beatles = Group.objects.create(name="The Beatles")
+ >>> m1 = Membership(person=ringo, group=beatles,
+ ... date_joined=date(1962, 8, 16),
+ ... invite_reason= "Needed a new drummer.")
+ >>> m1.save()
+ >>> beatles.members.all()
+ [<Person: Ringo Starr>]
+ >>> ringo.group_set.all()
+ [<Group: The Beatles>]
+ >>> m2 = Membership.objects.create(person=paul, group=beatles,
+ ... date_joined=date(1960, 8, 1),
+ ... invite_reason= "Wanted to form a band.")
+ >>> beatles.members.all()
+ [<Person: Ringo Starr>, <Person: Paul McCartney>]
+
+Unlike normal many-to-many fields, you *can't* use ``add``, ``create``,
+or assignment (i.e., ``beatles.members = [...]``) to create relationships::
+
+ # THIS WILL NOT WORK
+ >>> beatles.members.add(john)
+ # NEITHER WILL THIS
+ >>> beatles.members.create(name="George Harrison")
+ # AND NEITHER WILL THIS
+ >>> beatles.members = [john, paul, ringo, george]
+
+Why? You can't just create a relationship between a Person and a Group - you
+need to specify all the detail for the relationship required by the
+Membership table. The simple ``add``, ``create`` and assignment calls
+don't provide a way to specify this extra detail. As a result, they are
+disabled for many-to-many relationships that use an intermediate model.
+The only way to create a many-to-many relationship with an intermediate table
+is to create instances of the intermediate model.
+
+The ``remove`` method is disabled for similar reasons. However, the
+``clear()`` method can be used to remove all many-to-many relationships
+for an instance::
+
+ # Beatles have broken up
+ >>> beatles.members.clear()
+
+Once you have established the many-to-many relationships by creating instances
+of your intermediate model, you can issue queries. Just as with normal
+many-to-many relationships, you can query using the attributes of the
+many-to-many-related model::
+
+ # Find all the groups with a member whose name starts with 'Paul'
+ >>> Groups.objects.filter(person__name__startswith='Paul')
+ [<Group: The Beatles>]
+
+As you are using an intermediate table, you can also query on the attributes
+of the intermediate model::
+
+ # Find all the members of the Beatles that joined after 1 Jan 1961
+ >>> Person.objects.filter(
+ ... group__name='The Beatles',
+ ... membership__date_joined__gt=date(1961,1,1))
+ [<Person: Ringo Starr]
+
One-to-one relationships
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1143,7 +1274,7 @@ any parent classes in ``unique_together``.
For convenience, unique_together can be a single list when dealing
with a single set of fields::
- unique_together = ("driver", "restaurant")
+ unique_together = ("driver", "restaurant")
``verbose_name``
----------------
@@ -1376,6 +1507,19 @@ good idea to be careful in your choice of default manager, in order to
avoid a situation where overriding of ``get_query_set()`` results in
an inability to retrieve objects you'd like to work with.
+Using managers for related object access
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, Django uses a "bare" (i.e. default) manager when accessing related
+objects (i.e. ``choice.poll``). If this default isn't appropriate for your
+default manager, you can force Django to use a custom manager for related object
+attributes by giving it a ``use_for_related_fields`` property::
+
+ class MyManager(models.Manager)::
+ use_for_related_fields = True
+
+ ...
+
Model methods
=============
diff --git a/docs/modelforms.txt b/docs/modelforms.txt
index 9c06bc409d..1be7c3a882 100644
--- a/docs/modelforms.txt
+++ b/docs/modelforms.txt
@@ -1,6 +1,6 @@
-==========================
-Using newforms with models
-==========================
+=======================
+Using forms with models
+=======================
``ModelForm``
=============
@@ -16,7 +16,7 @@ class from a Django model.
For example::
- >>> from django.newforms import ModelForm
+ >>> from django.forms import ModelForm
# Create the form class.
>>> class ArticleForm(ModelForm):
@@ -86,11 +86,11 @@ the full list of conversions:
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
types are special cases:
- * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``,
+ * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
* ``ManyToManyField`` is represented by
- ``django.newforms.ModelMultipleChoiceField``, which is a
+ ``django.forms.ModelMultipleChoiceField``, which is a
``MultipleChoiceField`` whose choices are a model ``QuerySet``.
In addition, each generated form field has attributes set as follows:
@@ -121,7 +121,7 @@ A full example
Consider this set of models::
from django.db import models
- from django.newforms import ModelForm
+ from django.forms import ModelForm
TITLE_CHOICES = (
('MR', 'Mr.'),
@@ -240,14 +240,14 @@ For example::
>>> new_author = f.save()
Other than the ``save()`` and ``save_m2m()`` methods, a ``ModelForm``
-works exactly the same way as any other ``newforms`` form. For
+works exactly the same way as any other ``forms`` form. For
example, the ``is_valid()`` method is used to check for validity, the
``is_multipart()`` method is used to determine whether a form requires
multipart file upload (and hence whether ``request.FILES`` must be
-passed to the form), etc. See `the standard newforms documentation`_
+passed to the form), etc. See `the standard forms documentation`_
for more information.
-.. _the standard newforms documentation: ../newforms/
+.. _the standard forms documentation: ../forms/
Using a subset of fields on the form
------------------------------------
@@ -384,7 +384,7 @@ Similar to regular formsets there are a couple enhanced formset classes that
provide all the right things to work with your models. Lets reuse the
``Author`` model from above::
- >>> from django.newforms.models import modelformset_factory
+ >>> from django.forms.models import modelformset_factory
>>> AuthorFormSet = modelformset_factory(Author)
This will create a formset that is capable of working with the data associated
@@ -417,7 +417,7 @@ configurable::
Alternatively, you can use a subclassing based approach::
- from django.newforms.models import BaseModelFormSet
+ from django.forms.models import BaseModelFormSet
class BaseAuthorFormSet(BaseModelFormSet):
def get_queryset(self):
@@ -494,7 +494,7 @@ with related objects through a foreign key. Suppose you have two models
``Author`` and ``Book``. You want to create a formset that works with the
books of a specific author. Here is how you could accomplish this::
- >>> from django.newforms.models import inlineformset_factory
+ >>> from django.forms.models import inlineformset_factory
>>> BookFormSet = inlineformset_factory(Author, Book)
>>> author = Author.objects.get(name=u'Orson Scott Card')
>>> formset = BookFormSet(instance=author)
diff --git a/docs/modpython.txt b/docs/modpython.txt
index aa1acf5864..44de0e1bd2 100644
--- a/docs/modpython.txt
+++ b/docs/modpython.txt
@@ -35,6 +35,7 @@ Then edit your ``httpd.conf`` file and add the following::
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonOption django.root /mysite
PythonDebug On
</Location>
@@ -45,6 +46,24 @@ This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the
Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE``
so mod_python knows which settings to use.
+**New in Django development version:** Because mod_python does not know we are
+serving this site from underneath the ``/mysite/`` prefix, this value needs to
+be passed through to the mod_python handler in Django, via the ``PythonOption
+django.root ...`` line. The value set on that line (the last item) should
+match the string given in the ``<Location ...>`` directive. The effect of this
+is that Django will automatically strip the ``/mysite`` string from the front
+of any URLs before matching them against your ``URLConf`` patterns. If you
+later move your site to live under ``/mysite2``, you will not have to change
+anything except the ``django.root`` option in the config file.
+
+When using ``django.root`` you should make sure that what's left, after the
+prefix has been removed, begins with a slash. Your URLConf patterns that are
+expecting an initial slash will then work correctly. In the above example,
+since we want to send things like ``/mysite/admin/`` to ``/admin/``, we need
+to remove the string ``/mysite`` from the beginning, so that is the
+``django.root`` value. It would be an error to use ``/mysite/`` (with a
+trailing slash) in this case.
+
Note that we're using the ``<Location>`` directive, not the ``<Directory>``
directive. The latter is used for pointing at places on your filesystem,
whereas ``<Location>`` points at places in the URL structure of a Web site.
@@ -59,6 +78,7 @@ computer, you'll have to tell mod_python where your project can be found:
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonOption django.root /mysite
PythonDebug On
**PythonPath "['/path/to/project'] + sys.path"**
</Location>
diff --git a/docs/newforms.txt b/docs/newforms.txt
deleted file mode 100644
index 88b25be915..0000000000
--- a/docs/newforms.txt
+++ /dev/null
@@ -1,2522 +0,0 @@
-====================
-The newforms library
-====================
-
-``django.newforms`` is Django's fantastic new form-handling library. It's a
-replacement for ``django.forms``, the old form/manipulator/validation
-framework. This document explains how to use this new library.
-
-Migration plan
-==============
-
-``django.newforms`` is new in Django's 0.96 release, but, as it won't be new
-forever, we plan to rename it to ``django.forms`` in the future. The current
-``django.forms`` package will be available as ``django.oldforms`` until Django
-1.0, when we plan to remove it for good.
-
-That has direct repercussions on the forward compatibility of your code. Please
-read the following migration plan and code accordingly:
-
- * The old forms framework (the current ``django.forms``) has been copied to
- ``django.oldforms``. Thus, you can start upgrading your code *now*,
- rather than waiting for the future backwards-incompatible change, by
- changing your import statements like this::
-
- from django import forms # old
- from django import oldforms as forms # new
-
- * In the next Django release (0.97), we will move the current
- ``django.newforms`` to ``django.forms``. This will be a
- backwards-incompatible change, and anybody who is still using the old
- version of ``django.forms`` at that time will need to change their import
- statements, as described in the previous bullet.
-
- * We will remove ``django.oldforms`` in the release *after* the next Django
- release -- either 0.98 or 1.0, whichever comes first.
-
-With this in mind, we recommend you use the following import statement when
-using ``django.newforms``::
-
- from django import newforms as forms
-
-This way, your code can refer to the ``forms`` module, and when
-``django.newforms`` is renamed to ``django.forms``, you'll only have to change
-your ``import`` statements.
-
-If you prefer "``import *``" syntax, you can do the following::
-
- from django.newforms import *
-
-This will import all fields, widgets, form classes and other various utilities
-into your local namespace. Some people find this convenient; others find it
-too messy. The choice is yours.
-
-Overview
-========
-
-As with the ``django.forms`` ("manipulators") system before it,
-``django.newforms`` is intended to handle HTML form display, data processing
-(validation) and redisplay. It's what you use if you want to perform
-server-side validation for an HTML form.
-
-For example, if your Web site has a contact form that visitors can use to
-send you e-mail, you'd use this library to implement the display of the HTML
-form fields, along with the form validation. Any time you need to use an HTML
-``<form>``, you can use this library.
-
-The library deals with these concepts:
-
- * **Widget** -- A class that corresponds to an HTML form widget, e.g.
- ``<input type="text">`` or ``<textarea>``. This handles rendering of the
- widget as HTML.
-
- * **Field** -- A class that is responsible for doing validation, e.g.
- an ``EmailField`` that makes sure its data is a valid e-mail address.
-
- * **Form** -- A collection of fields that knows how to validate itself and
- display itself as HTML.
-
- * **Media** -- A definition of the CSS and JavaScript resources that are
- required to render a form.
-
-The library is decoupled from the other Django components, such as the database
-layer, views and templates. It relies only on Django settings, a couple of
-``django.utils`` helper functions and Django's internationalization hooks (but
-you're not required to be using internationalization features to use this
-library).
-
-Form objects
-============
-
-The primary way of using the ``newforms`` library is to create a form object.
-Do this by subclassing ``django.newforms.Form`` and specifying the form's
-fields, in a declarative style that you'll be familiar with if you've used
-Django database models. In this section, we'll iteratively develop a form
-object that you might use to implement "contact me" functionality on your
-personal Web site.
-
-Start with this basic ``Form`` subclass, which we'll call ``ContactForm``::
-
- from django import newforms as forms
-
- class ContactForm(forms.Form):
- subject = forms.CharField(max_length=100)
- message = forms.CharField()
- sender = forms.EmailField()
- cc_myself = forms.BooleanField(required=False)
-
-A form is composed of ``Field`` objects. In this case, our form has four
-fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. We'll explain
-the different types of fields -- e.g., ``CharField`` and ``EmailField`` --
-shortly.
-
-Creating ``Form`` instances
----------------------------
-
-A ``Form`` instance is either **bound** to a set of data, or **unbound**.
-
- * If it's **bound** to a set of data, it's capable of validating that data
- and rendering the form as HTML with the data displayed in the HTML.
-
- * If it's **unbound**, it cannot do validation (because there's no data to
- validate!), but it can still render the blank form as HTML.
-
-To create an unbound ``Form`` instance, simply instantiate the class::
-
- >>> f = ContactForm()
-
-To bind data to a form, pass the data as a dictionary as the first parameter to
-your ``Form`` class constructor::
-
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
-
-In this dictionary, the keys are the field names, which correspond to the
-attributes in your ``Form`` class. The values are the data you're trying
-to validate. These will usually be strings, but there's no requirement that
-they be strings; the type of data you pass depends on the ``Field``, as we'll
-see in a moment.
-
-If you need to distinguish between bound and unbound form instances at runtime,
-check the value of the form's ``is_bound`` attribute::
-
- >>> f = ContactForm()
- >>> f.is_bound
- False
- >>> f = ContactForm({'subject': 'hello'})
- >>> f.is_bound
- True
-
-Note that passing an empty dictionary creates a *bound* form with empty data::
-
- >>> f = ContactForm({})
- >>> f.is_bound
- True
-
-If you have a bound ``Form`` instance and want to change the data somehow, or
-if you want to bind an unbound ``Form`` instance to some data, create another
-``Form`` instance. There is no way to change data in a ``Form`` instance. Once
-a ``Form`` instance has been created, you should consider its data immutable,
-whether it has data or not.
-
-Using forms to validate data
-----------------------------
-
-The primary task of a ``Form`` object is to validate data. With a bound
-``Form`` instance, call the ``is_valid()`` method to run validation and return
-a boolean designating whether the data was valid::
-
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
- >>> f.is_valid()
- True
-
-Let's try with some invalid data. In this case, ``subject`` is blank (an error,
-because all fields are required by default) and ``sender`` is not a valid
-e-mail address::
-
- >>> data = {'subject': '',
- ... 'message': 'Hi there',
- ... 'sender': 'invalid e-mail address',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
- >>> f.is_valid()
- False
-
-Access the ``errors`` attribute to get a dictionary of error messages::
-
- >>> f.errors
- {'sender': [u'Enter a valid e-mail address.'], 'subject': [u'This field is required.']}
-
-In this dictionary, the keys are the field names, and the values are lists of
-Unicode strings representing the error messages. The error messages are stored
-in lists because a field can have multiple error messages.
-
-You can access ``errors`` without having to call ``is_valid()`` first. The
-form's data will be validated the first time either you call ``is_valid()`` or
-access ``errors``.
-
-The validation routines will only get called once, regardless of how many times
-you access ``errors`` or call ``is_valid()``. This means that if validation has
-side effects, those side effects will only be triggered once.
-
-Behavior of unbound forms
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's meaningless to validate a form with no data, but, for the record, here's
-what happens with unbound forms::
-
- >>> f = ContactForm()
- >>> f.is_valid()
- False
- >>> f.errors
- {}
-
-Accessing "clean" data
-----------------------
-
-Each ``Field`` in a ``Form`` class is responsible not only for validating data,
-but also for "cleaning" it -- normalizing it to a consistent format. This is a
-nice feature, because it allows data for a particular field to be input in
-a variety of ways, always resulting in consistent output.
-
-For example, ``DateField`` normalizes input into a Python ``datetime.date``
-object. Regardless of whether you pass it a string in the format
-``'1994-07-15'``, a ``datetime.date`` object or a number of other formats,
-``DateField`` will always normalize it to a ``datetime.date`` object as long as
-it's valid.
-
-Once you've created a ``Form`` instance with a set of data and validated it,
-you can access the clean data via the ``cleaned_data`` attribute of the ``Form``
-object::
-
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
- >>> f.is_valid()
- True
- >>> f.cleaned_data
- {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
-
-.. note::
- **New in Django development version** The ``cleaned_data`` attribute was
- called ``clean_data`` in earlier releases.
-
-Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
-always cleans the input into a Unicode string. We'll cover the encoding
-implications later in this document.
-
-If your data does *not* validate, your ``Form`` instance will not have a
-``cleaned_data`` attribute::
-
- >>> data = {'subject': '',
- ... 'message': 'Hi there',
- ... 'sender': 'invalid e-mail address',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
- >>> f.is_valid()
- False
- >>> f.cleaned_data
- Traceback (most recent call last):
- ...
- AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
-
-``cleaned_data`` will always *only* contain a key for fields defined in the
-``Form``, even if you pass extra data when you define the ``Form``. In this
-example, we pass a bunch of extra fields to the ``ContactForm`` constructor,
-but ``cleaned_data`` contains only the form's fields::
-
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True,
- ... 'extra_field_1': 'foo',
- ... 'extra_field_2': 'bar',
- ... 'extra_field_3': 'baz'}
- >>> f = ContactForm(data)
- >>> f.is_valid()
- True
- >>> f.cleaned_data # Doesn't contain extra_field_1, etc.
- {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
-
-``cleaned_data`` will include a key and value for *all* fields defined in the
-``Form``, even if the data didn't include a value for fields that are not
-required. In this example, the data dictionary doesn't include a value for the
-``nick_name`` field, but ``cleaned_data`` includes it, with an empty value::
-
- >>> class OptionalPersonForm(Form):
- ... first_name = CharField()
- ... last_name = CharField()
- ... nick_name = CharField(required=False)
- >>> data = {'first_name': u'John', 'last_name': u'Lennon'}
- >>> f = OptionalPersonForm(data)
- >>> f.is_valid()
- True
- >>> f.cleaned_data
- {'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
-
-In this above example, the ``cleaned_data`` value for ``nick_name`` is set to an
-empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
-empty values as an empty string. Each field type knows what its "blank" value
-is -- e.g., for ``DateField``, it's ``None`` instead of the empty string. For
-full details on each field's behavior in this case, see the "Empty value" note
-for each field in the "Built-in ``Field`` classes" section below.
-
-You can write code to perform validation for particular form fields (based on
-their name) or for the form as a whole (considering combinations of various
-fields). More information about this is in the `Custom form and field
-validation`_ section, below.
-
-Behavior of unbound forms
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's meaningless to request "cleaned" data in a form with no data, but, for the
-record, here's what happens with unbound forms::
-
- >>> f = ContactForm()
- >>> f.cleaned_data
- Traceback (most recent call last):
- ...
- AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
-
-Outputting forms as HTML
-------------------------
-
-The second task of a ``Form`` object is to render itself as HTML. To do so,
-simply ``print`` it::
-
- >>> f = ContactForm()
- >>> print f
- <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
- <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
- <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
-
-If the form is bound to data, the HTML output will include that data
-appropriately. For example, if a field is represented by an
-``<input type="text">``, the data will be in the ``value`` attribute. If a
-field is represented by an ``<input type="checkbox">``, then that HTML will
-include ``checked="checked"`` if appropriate::
-
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True}
- >>> f = ContactForm(data)
- >>> print f
- <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr>
- <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr>
- <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" value="foo@example.com" /></td></tr>
- <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
-
-This default output is a two-column HTML table, with a ``<tr>`` for each field.
-Notice the following:
-
- * For flexibility, the output does *not* include the ``<table>`` and
- ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
- tags or an ``<input type="submit">`` tag. It's your job to do that.
-
- * Each field type has a default HTML representation. ``CharField`` and
- ``EmailField`` are represented by an ``<input type="text">``.
- ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
- these are merely sensible defaults; you can specify which HTML to use for
- a given field by using widgets, which we'll explain shortly.
-
- * The HTML ``name`` for each tag is taken directly from its attribute name
- in the ``ContactForm`` class.
-
- * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
- ``'Cc myself:'`` is generated from the field name by converting all
- underscores to spaces and upper-casing the first letter. Again, note
- these are merely sensible defaults; you can also specify labels manually.
-
- * Each text label is surrounded in an HTML ``<label>`` tag, which points
- to the appropriate form field via its ``id``. Its ``id``, in turn, is
- generated by prepending ``'id_'`` to the field name. The ``id``
- attributes and ``<label>`` tags are included in the output by default, to
- follow best practices, but you can change that behavior.
-
-Although ``<table>`` output is the default output style when you ``print`` a
-form, other output styles are available. Each style is available as a method on
-a form object, and each rendering method returns a Unicode object.
-
-``as_p()``
-~~~~~~~~~~
-
-``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
-containing one field::
-
- >>> f = ContactForm()
- >>> f.as_p()
- u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
- >>> print f.as_p()
- <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
- <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
- <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
- <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
-
-``as_ul()``
-~~~~~~~~~~~
-
-``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
-``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
-so that you can specify any HTML attributes on the ``<ul>`` for flexibility::
-
- >>> f = ContactForm()
- >>> f.as_ul()
- u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
- >>> print f.as_ul()
- <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
- <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
- <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
-
-``as_table()``
-~~~~~~~~~~~~~~
-
-Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
-exactly the same as ``print``. In fact, when you ``print`` a form object, it
-calls its ``as_table()`` method behind the scenes::
-
- >>> f = ContactForm()
- >>> f.as_table()
- u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
- >>> print f.as_table()
- <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
- <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
- <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
-
-Configuring HTML ``<label>`` tags
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An HTML ``<label>`` tag designates which label text is associated with which
-form element. This small enhancement makes forms more usable and more accessible
-to assistive devices. It's always a good idea to use ``<label>`` tags.
-
-By default, the form rendering methods include HTML ``id`` attributes on the
-form elements and corresponding ``<label>`` tags around the labels. The ``id``
-attribute values are generated by prepending ``id_`` to the form field names.
-This behavior is configurable, though, if you want to change the ``id``
-convention or remove HTML ``id`` attributes and ``<label>`` tags entirely.
-
-Use the ``auto_id`` argument to the ``Form`` constructor to control the label
-and ``id`` behavior. This argument must be ``True``, ``False`` or a string.
-
-If ``auto_id`` is ``False``, then the form output will not include ``<label>``
-tags nor ``id`` attributes::
-
- >>> f = ContactForm(auto_id=False)
- >>> print f.as_table()
- <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
- <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
- <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
- >>> print f.as_ul()
- <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
- <li>Message: <input type="text" name="message" /></li>
- <li>Sender: <input type="text" name="sender" /></li>
- <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
- >>> print f.as_p()
- <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
- <p>Message: <input type="text" name="message" /></p>
- <p>Sender: <input type="text" name="sender" /></p>
- <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
-
-If ``auto_id`` is set to ``True``, then the form output *will* include
-``<label>`` tags and will simply use the field name as its ``id`` for each form
-field::
-
- >>> f = ContactForm(auto_id=True)
- >>> print f.as_table()
- <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
- <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
- <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
- >>> print f.as_ul()
- <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
- <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
- <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
- >>> print f.as_p()
- <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
- <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
- <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
- <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
-
-If ``auto_id`` is set to a string containing the format character ``'%s'``,
-then the form output will include ``<label>`` tags, and will generate ``id``
-attributes based on the format string. For example, for a format string
-``'field_%s'``, a field named ``subject`` will get the ``id`` value
-``'field_subject'``. Continuing our example::
-
- >>> f = ContactForm(auto_id='id_for_%s')
- >>> print f.as_table()
- <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
- <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
- <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
- >>> print f.as_ul()
- <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
- <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
- <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
- >>> print f.as_p()
- <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
- <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
- <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
- <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
-
-If ``auto_id`` is set to any other true value -- such as a string that doesn't
-include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.
-
-By default, ``auto_id`` is set to the string ``'id_%s'``.
-
-Normally, a colon (``:``) will be appended after any label name when a form is
-rendered. It's possible to change the colon to another character, or omit it
-entirely, using the ``label_suffix`` parameter::
-
- >>> f = ContactForm(auto_id='id_for_%s', label_suffix='')
- >>> print f.as_ul()
- <li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" /></li>
- <li><label for="id_for_sender">Sender</label> <input type="text" name="sender" id="id_for_sender" /></li>
- <li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
- >>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->')
- >>> print f.as_ul()
- <li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
- <li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" /></li>
- <li><label for="id_for_sender">Sender -></label> <input type="text" name="sender" id="id_for_sender" /></li>
- <li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
-
-Note that the label suffix is added only if the last character of the
-label isn't a punctuation character (``.``, ``!``, ``?`` or ``:``)
-
-Notes on field ordering
-~~~~~~~~~~~~~~~~~~~~~~~
-
-In the ``as_p()``, ``as_ul()`` and ``as_table()`` shortcuts, the fields are
-displayed in the order in which you define them in your form class. For
-example, in the ``ContactForm`` example, the fields are defined in the order
-``subject``, ``message``, ``sender``, ``cc_myself``. To reorder the HTML
-output, just change the order in which those fields are listed in the class.
-
-How errors are displayed
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you render a bound ``Form`` object, the act of rendering will automatically
-run the form's validation if it hasn't already happened, and the HTML output
-will include the validation errors as a ``<ul class="errorlist">`` near the
-field. The particular positioning of the error messages depends on the output
-method you're using::
-
- >>> data = {'subject': '',
- ... 'message': 'Hi there',
- ... 'sender': 'invalid e-mail address',
- ... 'cc_myself': True}
- >>> f = ContactForm(data, auto_id=False)
- >>> print f.as_table()
- <tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr>
- <tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr>
- <tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" name="sender" value="invalid e-mail address" /></td></tr>
- <tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>
- >>> print f.as_ul()
- <li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li>
- <li>Message: <input type="text" name="message" value="Hi there" /></li>
- <li><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul>Sender: <input type="text" name="sender" value="invalid e-mail address" /></li>
- <li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>
- >>> print f.as_p()
- <p><ul class="errorlist"><li>This field is required.</li></ul></p>
- <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
- <p>Message: <input type="text" name="message" value="Hi there" /></p>
- <p><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul></p>
- <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
- <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
-
-Customizing the error list format
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, forms use ``django.newforms.util.ErrorList`` to format validation
-errors. If you'd like to use an alternate class for displaying errors, you can
-pass that in at construction time::
-
- >>> from django.newforms.util import ErrorList
- >>> class DivErrorList(ErrorList):
- ... def __unicode__(self):
- ... return self.as_divs()
- ... def as_divs(self):
- ... if not self: return u''
- ... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
- >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
- >>> f.as_p()
- <div class="errorlist"><div class="error">This field is required.</div></div>
- <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
- <p>Message: <input type="text" name="message" value="Hi there" /></p>
- <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
- <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
- <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
-
-More granular output
-~~~~~~~~~~~~~~~~~~~~
-
-The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
-lazy developers -- they're not the only way a form object can be displayed.
-
-To display the HTML for a single field in your form, use dictionary lookup
-syntax using the field's name as the key, and print the resulting object::
-
- >>> f = ContactForm()
- >>> print f['subject']
- <input id="id_subject" type="text" name="subject" maxlength="100" />
- >>> print f['message']
- <input type="text" name="message" id="id_message" />
- >>> print f['sender']
- <input type="text" name="sender" id="id_sender" />
- >>> print f['cc_myself']
- <input type="checkbox" name="cc_myself" id="id_cc_myself" />
-
-Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
-string or Unicode object, respectively::
-
- >>> str(f['subject'])
- '<input id="id_subject" type="text" name="subject" maxlength="100" />'
- >>> unicode(f['subject'])
- u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
-
-The field-specific output honors the form object's ``auto_id`` setting::
-
- >>> f = ContactForm(auto_id=False)
- >>> print f['message']
- <input type="text" name="message" />
- >>> f = ContactForm(auto_id='id_%s')
- >>> print f['message']
- <input type="text" name="message" id="id_message" />
-
-For a field's list of errors, access the field's ``errors`` attribute. This
-is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
-when printed::
-
- >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
- >>> f = ContactForm(data, auto_id=False)
- >>> print f['message']
- <input type="text" name="message" />
- >>> f['message'].errors
- [u'This field is required.']
- >>> print f['message'].errors
- <ul class="errorlist"><li>This field is required.</li></ul>
- >>> f['subject'].errors
- []
- >>> print f['subject'].errors
-
- >>> str(f['subject'].errors)
- ''
-
-Using forms in views and templates
-----------------------------------
-
-Let's put this all together and use the ``ContactForm`` example in a Django
-view and template.
-
-Simple view example
-~~~~~~~~~~~~~~~~~~~
-
-This example view displays the contact form by default and validates/processes
-it if accessed via a POST request::
-
- def contact(request):
- if request.method == 'POST':
- form = ContactForm(request.POST)
- if form.is_valid():
- # Do form processing here...
- return HttpResponseRedirect('/url/on_success/')
- else:
- form = ContactForm()
- return render_to_response('contact.html', {'form': form})
-
-Simple template example
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The template in the above view example, ``contact.html``, is responsible for
-displaying the form as HTML. To do this, we can use the techniques outlined in
-the "Outputting forms as HTML" section above.
-
-The simplest way to display a form's HTML is to use the variable on its own,
-like this::
-
- <form method="post" action="">
- <table>{{ form }}</table>
- <input type="submit" />
- </form>
-
-The above template code will display the form as an HTML table, using the
-``form.as_table()`` method explained previously. This works because Django's
-template system displays an object's ``__str__()`` value, and the ``Form``
-class' ``__str__()`` method calls its ``as_table()`` method.
-
-The following is equivalent but a bit more explicit::
-
- <form method="post" action="">
- <table>{{ form.as_table }}</table>
- <input type="submit" />
- </form>
-
-``form.as_ul`` and ``form.as_p`` are also available, as you may expect.
-
-Note that in the above two examples, we included the ``<form>``, ``<table>``
-``<input type="submit" />``, ``</table>`` and ``</form>`` tags. The form
-convenience methods (``as_table()``, ``as_ul()`` and ``as_p()``) do not include
-that HTML.
-
-Complex template output
-~~~~~~~~~~~~~~~~~~~~~~~
-
-As we've stressed several times, the ``as_table()``, ``as_ul()`` and ``as_p()``
-methods are just shortcuts for the common case. You can also work with the
-individual fields for complete template control over the form's design.
-
-The easiest way is to iterate over the form's fields, with
-``{% for field in form %}``. For example::
-
- <form method="post" action="">
- <dl>
- {% for field in form %}
- <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 %}
- {% endfor %}
- </dl>
- <input type="submit" />
- </form>
-
-This iteration technique is useful if you want to apply the same HTML
-formatting to each field, or if you don't know the names of the form fields
-ahead of time. Note that the fields will be iterated over in the order in which
-they're defined in the ``Form`` class.
-
-Alternatively, you can arrange the form's fields explicitly, by name. Do that
-by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
-For example::
-
- <form method="post" action="">
- <ul class="myformclass">
- <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_tag }} {{ form.subject }}</li>
- <li class="helptext">{{ form.subject.help_text }}</li>
- {% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</ul>{% endif %}
-
- ...
- </ul>
- </form>
-
-Highlighting required fields in templates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's common to show a user which fields are required. Here's an example of how
-to do that, using the above example modified to insert an asterisk after the
-label of each required field::
-
- <form method="post" action="">
- <dl>
- {% for field in form %}
- <dt>{{ field.label_tag }}{% if field.field.required %}*{% endif %}</dt>
- <dd>{{ field }}</dd>
- {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
- {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
- {% endfor %}
- </dl>
- <input type="submit" />
- </form>
-
-The ``{% if field.field.required %}*{% endif %}`` fragment is the relevant
-addition here. It adds the asterisk only if the field is required.
-
-Note that we check ``field.field.required`` and not ``field.required``. In the
-template, ``field`` is a ``newforms.forms.BoundField`` instance, which holds
-the actual ``Field`` instance in its ``field`` attribute.
-
-Binding uploaded files to a form
---------------------------------
-
-**New in Django development version**
-
-Dealing with forms that have ``FileField`` and ``ImageField`` fields
-is a little more complicated than a normal form.
-
-Firstly, in order to upload files, you'll need to make sure that your
-``<form>`` element correctly defines the ``enctype`` as
-``"multipart/form-data"``::
-
- <form enctype="multipart/form-data" method="post" action="/foo/">
-
-Secondly, when you use the form, you need to bind the file data. File
-data is handled separately to normal form data, so when your form
-contains a ``FileField`` and ``ImageField``, you will need to specify
-a second argument when you bind your form. So if we extend our
-ContactForm to include an ``ImageField`` called ``mugshot``, we
-need to bind the file data containing the mugshot image::
-
- # Bound form with an image field
- >>> from django.core.files.uploadedfile import SimpleUploadedFile
- >>> data = {'subject': 'hello',
- ... 'message': 'Hi there',
- ... 'sender': 'foo@example.com',
- ... 'cc_myself': True}
- >>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <file data>)}
- >>> f = ContactFormWithMugshot(data, file_data)
-
-In practice, you will usually specify ``request.FILES`` as the source
-of file data (just like you use ``request.POST`` as the source of
-form data)::
-
- # Bound form with an image field, data from the request
- >>> f = ContactFormWithMugshot(request.POST, request.FILES)
-
-Constructing an unbound form is the same as always -- just omit both
-form data *and* file data::
-
- # Unbound form with a image field
- >>> f = ContactFormWithMugshot()
-
-Testing for multipart forms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you're writing reusable views or templates, you may not know ahead of time
-whether your form is a multipart form or not. The ``is_multipart()`` method
-tells you whether the form requires multipart encoding for submission::
-
- >>> f = ContactFormWithMugshot()
- >>> f.is_multipart()
- True
-
-Here's an example of how you might use this in a template::
-
- {% if form.is_multipart %}
- <form enctype="multipart/form-data" method="post" action="/foo/">
- {% else %}
- <form method="post" action="/foo/">
- {% endif %}
- {% form %}
- </form>
-
-Subclassing forms
------------------
-
-If you have multiple ``Form`` classes that share fields, you can use
-subclassing to remove redundancy.
-
-When you subclass a custom ``Form`` class, the resulting subclass will
-include all fields of the parent class(es), followed by the fields you define
-in the subclass.
-
-In this example, ``ContactFormWithPriority`` contains all the fields from
-``ContactForm``, plus an additional field, ``priority``. The ``ContactForm``
-fields are ordered first::
-
- >>> class ContactFormWithPriority(ContactForm):
- ... priority = forms.CharField()
- >>> f = ContactFormWithPriority(auto_id=False)
- >>> print f.as_ul()
- <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
- <li>Message: <input type="text" name="message" /></li>
- <li>Sender: <input type="text" name="sender" /></li>
- <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
- <li>Priority: <input type="text" name="priority" /></li>
-
-It's possible to subclass multiple forms, treating forms as "mix-ins." In this
-example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm``
-(in that order), and its field list includes the fields from the parent
-classes::
-
- >>> class PersonForm(Form):
- ... first_name = CharField()
- ... last_name = CharField()
- >>> class InstrumentForm(Form):
- ... instrument = CharField()
- >>> class BeatleForm(PersonForm, InstrumentForm):
- ... haircut_type = CharField()
- >>> b = BeatleForm(auto_id=False)
- >>> print b.as_ul()
- <li>First name: <input type="text" name="first_name" /></li>
- <li>Last name: <input type="text" name="last_name" /></li>
- <li>Instrument: <input type="text" name="instrument" /></li>
- <li>Haircut type: <input type="text" name="haircut_type" /></li>
-
-Prefixes for forms
-------------------
-
-You can put several Django forms inside one ``<form>`` tag. To give each
-``Form`` its own namespace, use the ``prefix`` keyword argument::
-
- >>> mother = PersonForm(prefix="mother")
- >>> father = PersonForm(prefix="father")
- >>> print mother.as_ul()
- <li><label for="id_mother-first_name">First name:</label> <input type="text" name="mother-first_name" id="id_mother-first_name" /></li>
- <li><label for="id_mother-last_name">Last name:</label> <input type="text" name="mother-last_name" id="id_mother-last_name" /></li>
- >>> print father.as_ul()
- <li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li>
- <li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li>
-
-Fields
-======
-
-When you create a ``Form`` class, the most important part is defining the
-fields of the form. Each field has custom validation logic, along with a few
-other hooks.
-
-Although the primary way you'll use ``Field`` classes is in ``Form`` classes,
-you can also instantiate them and use them directly to get a better idea of
-how they work. Each ``Field`` instance has a ``clean()`` method, which takes
-a single argument and either raises a ``django.newforms.ValidationError``
-exception or returns the clean value::
-
- >>> f = forms.EmailField()
- >>> f.clean('foo@example.com')
- u'foo@example.com'
- >>> f.clean(u'foo@example.com')
- u'foo@example.com'
- >>> f.clean('invalid e-mail address')
- Traceback (most recent call last):
- ...
- ValidationError: [u'Enter a valid e-mail address.']
-
-If you've used Django's old forms/validation framework, take care in noticing
-this ``ValidationError`` is different than the previous ``ValidationError``.
-This one lives at ``django.newforms.ValidationError`` rather than
-``django.core.validators.ValidationError``.
-
-Core field arguments
---------------------
-
-Each ``Field`` class constructor takes at least these arguments. Some
-``Field`` classes take additional, field-specific arguments, but the following
-should *always* be accepted:
-
-``required``
-~~~~~~~~~~~~
-
-By default, each ``Field`` class assumes the value is required, so if you pass
-an empty value -- either ``None`` or the empty string (``""``) -- then
-``clean()`` will raise a ``ValidationError`` exception::
-
- >>> f = forms.CharField()
- >>> f.clean('foo')
- u'foo'
- >>> f.clean('')
- Traceback (most recent call last):
- ...
- ValidationError: [u'This field is required.']
- >>> f.clean(None)
- Traceback (most recent call last):
- ...
- ValidationError: [u'This field is required.']
- >>> f.clean(' ')
- u' '
- >>> f.clean(0)
- u'0'
- >>> f.clean(True)
- u'True'
- >>> f.clean(False)
- u'False'
-
-To specify that a field is *not* required, pass ``required=False`` to the
-``Field`` constructor::
-
- >>> f = forms.CharField(required=False)
- >>> f.clean('foo')
- u'foo'
- >>> f.clean('')
- u''
- >>> f.clean(None)
- u''
- >>> f.clean(0)
- u'0'
- >>> f.clean(True)
- u'True'
- >>> f.clean(False)
- u'False'
-
-If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value,
-then ``clean()`` will return a *normalized* empty value rather than raising
-``ValidationError``. For ``CharField``, this will be a Unicode empty string.
-For other ``Field`` classes, it might be ``None``. (This varies from field to
-field.)
-
-``label``
-~~~~~~~~~
-
-The ``label`` argument lets you specify the "human-friendly" label for this
-field. This is used when the ``Field`` is displayed in a ``Form``.
-
-As explained in "Outputting forms as HTML" above, the default label for a
-``Field`` is generated from the field name by converting all underscores to
-spaces and upper-casing the first letter. Specify ``label`` if that default
-behavior doesn't result in an adequate label.
-
-Here's a full example ``Form`` that implements ``label`` for two of its fields.
-We've specified ``auto_id=False`` to simplify the output::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField(label='Your name')
- ... url = forms.URLField(label='Your Web site', required=False)
- ... comment = forms.CharField()
- >>> f = CommentForm(auto_id=False)
- >>> print f
- <tr><th>Your name:</th><td><input type="text" name="name" /></td></tr>
- <tr><th>Your Web site:</th><td><input type="text" name="url" /></td></tr>
- <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-``initial``
-~~~~~~~~~~~
-
-The ``initial`` argument lets you specify the initial value to use when
-rendering this ``Field`` in an unbound ``Form``.
-
-The use-case for this is when you want to display an "empty" form in which a
-field is initialized to a particular value. For example::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField(initial='Your name')
- ... url = forms.URLField(initial='http://')
- ... comment = forms.CharField()
- >>> f = CommentForm(auto_id=False)
- >>> print f
- <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
- <tr><th>Url:</th><td><input type="text" name="url" value="http://" /></td></tr>
- <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-You may be thinking, why not just pass a dictionary of the initial values as
-data when displaying the form? Well, if you do that, you'll trigger validation,
-and the HTML output will include any validation errors::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField()
- ... url = forms.URLField()
- ... comment = forms.CharField()
- >>> default_data = {'name': 'Your name', 'url': 'http://'}
- >>> f = CommentForm(default_data, auto_id=False)
- >>> print f
- <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
- <tr><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="text" name="url" value="http://" /></td></tr>
- <tr><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" /></td></tr>
-
-This is why ``initial`` values are only displayed for unbound forms. For bound
-forms, the HTML output will use the bound data.
-
-Also note that ``initial`` values are *not* used as "fallback" data in
-validation if a particular field's value is not given. ``initial`` values are
-*only* intended for initial form display::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField(initial='Your name')
- ... url = forms.URLField(initial='http://')
- ... comment = forms.CharField()
- >>> data = {'name': '', 'url': '', 'comment': 'Foo'}
- >>> f = CommentForm(data)
- >>> f.is_valid()
- False
- # The form does *not* fall back to using the initial values.
- >>> f.errors
- {'url': [u'This field is required.'], 'name': [u'This field is required.']}
-
-``widget``
-~~~~~~~~~~
-
-The ``widget`` argument lets you specify a ``Widget`` class to use when
-rendering this ``Field``. See `Widgets`_ below for more information.
-
-``help_text``
-~~~~~~~~~~~~~
-
-The ``help_text`` argument lets you specify descriptive text for this
-``Field``. If you provide ``help_text``, it will be displayed next to the
-``Field`` when the ``Field`` is rendered by one of the convenience ``Form``
-methods (e.g., ``as_ul()``).
-
-Here's a full example ``Form`` that implements ``help_text`` for two of its
-fields. We've specified ``auto_id=False`` to simplify the output::
-
- >>> class HelpTextContactForm(forms.Form):
- ... subject = forms.CharField(max_length=100, help_text='100 characters max.')
- ... message = forms.CharField()
- ... sender = forms.EmailField(help_text='A valid e-mail address, please.')
- ... cc_myself = forms.BooleanField(required=False)
- >>> f = HelpTextContactForm(auto_id=False)
- >>> print f.as_table()
- <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /><br />100 characters max.</td></tr>
- <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
- <tr><th>Sender:</th><td><input type="text" name="sender" /><br />A valid e-mail address, please.</td></tr>
- <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
- >>> print f.as_ul()
- <li>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</li>
- <li>Message: <input type="text" name="message" /></li>
- <li>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</li>
- <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
- >>> print f.as_p()
- <p>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</p>
- <p>Message: <input type="text" name="message" /></p>
- <p>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</p>
- <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
-
-``error_messages``
-~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-The ``error_messages`` argument lets you override the default messages that the
-field will raise. Pass in a dictionary with keys matching the error messages you
-want to override. For example, here is the default error message::
-
- >>> generic = forms.CharField()
- >>> generic.clean('')
- Traceback (most recent call last):
- ...
- ValidationError: [u'This field is required.']
-
-And here is a custom error message::
-
- >>> name = forms.CharField(error_messages={'required': 'Please enter your name'})
- >>> name.clean('')
- Traceback (most recent call last):
- ...
- ValidationError: [u'Please enter your name']
-
-In the `built-in Field classes`_ section below, each ``Field`` defines the
-error message keys it uses.
-
-Dynamic initial values
-----------------------
-
-The ``initial`` argument to ``Field`` (explained above) lets you hard-code the
-initial value for a ``Field`` -- but what if you want to declare the initial
-value at runtime? For example, you might want to fill in a ``username`` field
-with the username of the current session.
-
-To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
-if given, should be a dictionary mapping field names to initial values. Only
-include the fields for which you're specifying an initial value; it's not
-necessary to include every field in your form. For example::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField()
- ... url = forms.URLField()
- ... comment = forms.CharField()
- >>> f = CommentForm(initial={'name': 'your username'}, auto_id=False)
- >>> print f
- <tr><th>Name:</th><td><input type="text" name="name" value="your username" /></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>
- >>> f = CommentForm(initial={'name': 'another username'}, auto_id=False)
- >>> print f
- <tr><th>Name:</th><td><input type="text" name="name" value="another username" /></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>
-
-Just like the ``initial`` parameter to ``Field``, these values are only
-displayed for unbound forms, and they're not used as fallback values if a
-particular value isn't provided.
-
-Finally, note that if a ``Field`` defines ``initial`` *and* you include
-``initial`` when instantiating the ``Form``, then the latter ``initial`` will
-have precedence. In this example, ``initial`` is provided both at the field
-level and at the form instance level, and the latter gets precedence::
-
- >>> class CommentForm(forms.Form):
- ... name = forms.CharField(initial='class')
- ... url = forms.URLField()
- ... comment = forms.CharField()
- >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
- >>> print f
- <tr><th>Name:</th><td><input type="text" name="name" value="instance" /></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>
-
-Built-in ``Field`` classes
---------------------------
-
-Naturally, the ``newforms`` library comes with a set of ``Field`` classes that
-represent common validation needs. This section documents each built-in field.
-
-For each field, we describe the default widget used if you don't specify
-``widget``. We also specify the value returned when you provide an empty value
-(see the section on ``required`` above to understand what that means).
-
-``BooleanField``
-~~~~~~~~~~~~~~~~
-
- * Default widget: ``CheckboxInput``
- * Empty value: ``False``
- * Normalizes to: A Python ``True`` or ``False`` value.
- * Validates that the check box is checked (i.e. the value is ``True``) if
- the field has ``required=True``.
- * Error message keys: ``required``
-
-**New in Django development version:** The empty value for a ``CheckboxInput``
-(and hence the standard ``BooleanField``) has changed to return ``False``
-instead of ``None`` in the development version.
-
-.. note::
- Since all ``Field`` subclasses have ``required=True`` by default, the
- validation condition here is important. If you want to include a checkbox
- in your form that can be either checked or unchecked, you must remember to
- pass in ``required=False`` when creating the ``BooleanField``.
-
-``CharField``
-~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates ``max_length`` or ``min_length``, if they are provided.
- Otherwise, all inputs are valid.
- * Error message keys: ``required``, ``max_length``, ``min_length``
-
-Has two optional arguments for validation, ``max_length`` and ``min_length``.
-If provided, these arguments ensure that the string is at most or at least the
-given length.
-
-``ChoiceField``
-~~~~~~~~~~~~~~~
-
- * Default widget: ``Select``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates that the given value exists in the list of choices.
- * Error message keys: ``required``, ``invalid_choice``
-
-Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
-tuple) of 2-tuples to use as choices for this field. This argument accepts
-the same formats as the ``choices`` argument to a model field. See the
-`model API documentation on choices`_ for more details.
-
-.. _model API documentation on choices: ../model-api#choices
-
-``DateField``
-~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``None``
- * Normalizes to: A Python ``datetime.date`` object.
- * Validates that the given value is either a ``datetime.date``,
- ``datetime.datetime`` or string formatted in a particular date format.
- * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.date`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
- '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
- '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
- '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
- '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
- '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
-
-``DateTimeField``
-~~~~~~~~~~~~~~~~~
-
- * Default widget: ``DateTimeInput``
- * Empty value: ``None``
- * Normalizes to: A Python ``datetime.datetime`` object.
- * Validates that the given value is either a ``datetime.datetime``,
- ``datetime.date`` or string formatted in a particular datetime format.
- * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.datetime`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
- '%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
- '%Y-%m-%d %H:%M', # '2006-10-25 14:30'
- '%Y-%m-%d', # '2006-10-25'
- '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59'
- '%m/%d/%Y %H:%M', # '10/25/2006 14:30'
- '%m/%d/%Y', # '10/25/2006'
- '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59'
- '%m/%d/%y %H:%M', # '10/25/06 14:30'
- '%m/%d/%y', # '10/25/06'
-
-**New in Django development version:** The ``DateTimeField`` used to use a
-``TextInput`` widget by default. This has now changed.
-
-``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.
- * Error message keys: ``required``, ``invalid``, ``max_value``,
- ``min_value``, ``max_digits``, ``max_decimal_places``,
- ``max_whole_digits``
-
-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``
-~~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates that the given value is a valid e-mail address, using a
- moderately complex regular expression.
- * Error message keys: ``required``, ``invalid``
-
-Has two optional arguments for validation, ``max_length`` and ``min_length``.
-If provided, these arguments ensure that the string is at most or at least the
-given length.
-
-``FileField``
-~~~~~~~~~~~~~
-
-**New in Django development version**
-
- * Default widget: ``FileInput``
- * Empty value: ``None``
- * Normalizes to: An ``UploadedFile`` object that wraps the file content
- and file name into a single object.
- * Validates that non-empty file data has been bound to the form.
- * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``
-
-To learn more about the ``UploadedFile`` object, see the `file uploads documentation`_.
-
-When you use a ``FileField`` in a form, you must also remember to
-`bind the file data to the form`_.
-
-.. _file uploads documentation: ../upload_handling/
-.. _`bind the file data to the form`: `Binding uploaded files to a form`_
-
-``FilePathField``
-~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
- * Default widget: ``Select``
- * Empty value: ``None``
- * Normalizes to: A unicode object
- * Validates that the selected choice exists in the list of choices.
- * Error message keys: ``required``, ``invalid_choice``
-
-The field allows choosing from files inside a certain directory. It takes three
-extra arguments:
-
- ============== ========== ===============================================
- Argument Required? Description
- ============== ========== ===============================================
- ``path`` Yes The absolute path to the directory whose
- contents you want listed. This directory must
- exist.
-
- ``recursive`` No If ``False`` (the default) only the direct
- contents of ``path`` will be offered as choices.
- If ``True``, the directory will be descended
- into recursively and all descendants will be
- listed as choices.
-
- ``match`` No A regular expression pattern; only files with
- names matching this expression will be allowed
- as choices.
- ============== ========== ===============================================
-
-``FloatField``
-~~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``None``
- * Normalizes to: A Python float.
- * Validates that the given value is an float. Leading and trailing
- whitespace is allowed, as in Python's ``float()`` function.
- * Error message keys: ``required``, ``invalid``, ``max_value``,
- ``min_value``
-
-Takes two optional arguments for validation, ``max_value`` and ``min_value``.
-These control the range of values permitted in the field.
-
-``ImageField``
-~~~~~~~~~~~~~~
-
-**New in Django development version**
-
- * Default widget: ``FileInput``
- * Empty value: ``None``
- * Normalizes to: An ``UploadedFile`` object that wraps the file content
- and file name into a single object.
- * Validates that file data has been bound to the form, and that the
- file is of an image format understood by PIL.
- * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
- ``invalid_image``
-
-Using an ImageField requires that the `Python Imaging Library`_ is installed.
-
-When you use an ``ImageField`` in a form, you must also remember to
-`bind the file data to the form`_.
-
-.. _Python Imaging Library: http://www.pythonware.com/products/pil/
-
-``IntegerField``
-~~~~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``None``
- * Normalizes to: A Python integer or long integer.
- * Validates that the given value is an integer. Leading and trailing
- whitespace is allowed, as in Python's ``int()`` function.
- * Error message keys: ``required``, ``invalid``, ``max_value``,
- ``min_value``
-
-Takes two optional arguments for validation, ``max_value`` and ``min_value``.
-These control the range of values permitted in the field.
-
-``IPAddressField``
-~~~~~~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates that the given value is a valid IPv4 address, using a regular
- expression.
- * Error message keys: ``required``, ``invalid``
-
-``MultipleChoiceField``
-~~~~~~~~~~~~~~~~~~~~~~~
-
- * Default widget: ``SelectMultiple``
- * Empty value: ``[]`` (an empty list)
- * Normalizes to: A list of Unicode objects.
- * Validates that every value in the given list of values exists in the list
- of choices.
- * Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
-
-Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
-tuple) of 2-tuples to use as choices for this field. This argument accepts
-the same formats as the ``choices`` argument to a model field. See the
-`model API documentation on choices`_ for more details.
-
-``NullBooleanField``
-~~~~~~~~~~~~~~~~~~~~
-
- * Default widget: ``NullBooleanSelect``
- * Empty value: ``None``
- * Normalizes to: A Python ``True``, ``False`` or ``None`` value.
- * Validates nothing (i.e., it never raises a ``ValidationError``).
-
-``RegexField``
-~~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates that the given value matches against a certain regular
- expression.
- * Error message keys: ``required``, ``invalid``
-
-Takes one required argument, ``regex``, which is a regular expression specified
-either as a string or a compiled regular expression object.
-
-Also takes the following optional arguments:
-
- ====================== =====================================================
- Argument Description
- ====================== =====================================================
- ``max_length`` Ensures the string has at most this many characters.
- ``min_length`` Ensures the string has at least this many characters.
- ====================== =====================================================
-
-The optional argument ``error_message`` is also accepted for backwards
-compatibility. The preferred way to provide an error message is to use the
-``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
-and the error message as the value.
-
-``TimeField``
-~~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``None``
- * Normalizes to: A Python ``datetime.time`` object.
- * Validates that the given value is either a ``datetime.time`` or string
- formatted in a particular time format.
- * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.time`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
- '%H:%M:%S', # '14:30:59'
- '%H:%M', # '14:30'
-
-``URLField``
-~~~~~~~~~~~~
-
- * Default widget: ``TextInput``
- * Empty value: ``''`` (an empty string)
- * Normalizes to: A Unicode object.
- * Validates that the given value is a valid URL.
- * Error message keys: ``required``, ``invalid``, ``invalid_link``
-
-Takes the following optional arguments:
-
- ======================== =====================================================
- Argument Description
- ======================== =====================================================
- ``max_length`` Ensures the string has at most this many characters.
- ``min_length`` Ensures the string has at least this many characters.
- ``verify_exists`` If ``True``, the validator will attempt to load the
- given URL, raising ``ValidationError`` if the page
- gives a 404. Defaults to ``False``.
- ``validator_user_agent`` String used as the user-agent used when checking for
- a URL's existence. Defaults to the value of the
- ``URL_VALIDATOR_USER_AGENT`` setting.
- ======================== =====================================================
-
-Slightly complex built-in ``Field`` classes
--------------------------------------------
-
-The following are not yet documented here. See the unit tests, linked-to from
-the bottom of this document, for examples of their use.
-
-``ComboField``
-~~~~~~~~~~~~~~
-
-``MultiValueField``
-~~~~~~~~~~~~~~~~~~~
-
-``SplitDateTimeField``
-~~~~~~~~~~~~~~~~~~~~~~
-
-Fields which handle relationships
----------------------------------
-
-For representing relationships between models, two fields are
-provided which can derive their choices from a ``QuerySet``, and which
-place one or more model objects into the ``cleaned_data`` dictionary
-of forms in which they're used. Both of these fields have an
-additional required argument:
-
-``queryset``
- A ``QuerySet`` of model objects from which the choices for the
- field will be derived, and which will be used to validate the
- user's selection.
-
-``ModelChoiceField``
-~~~~~~~~~~~~~~~~~~~~
-
-Allows the selection of a single model object, suitable for
-representing a foreign key.
-
-The ``__unicode__`` method of the model will be called to generate
-string representations of the objects for use in the field's choices;
-to provide customized representations, subclass ``ModelChoiceField``
-and override ``label_from_instance``. This method will receive a model
-object, and should return a string suitable for representing it. For
-example::
-
- class MyModelChoiceField(ModelChoiceField):
- def label_from_instance(self, obj):
- return "My Object #%i" % obj.id
-
-``ModelMultipleChoiceField``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Allows the selection of one or more model objects, suitable for
-representing a many-to-many relation. As with ``ModelChoiceField``,
-you can use ``label_from_instance`` to customize the object
-representations.
-
-Creating custom fields
-----------------------
-
-If the built-in ``Field`` classes don't meet your needs, you can easily create
-custom ``Field`` classes. To do this, just create a subclass of
-``django.newforms.Field``. Its only requirements are that it implement a
-``clean()`` method and that its ``__init__()`` method accept the core arguments
-mentioned above (``required``, ``label``, ``initial``, ``widget``,
-``help_text``).
-
-Custom form and field validation
----------------------------------
-
-Form validation happens when the data is cleaned. If you want to customise
-this process, there are various places you can change, each one serving a
-different purpose. Three types of cleaning methods are run during form
-processing. These are normally executed when you call the ``is_valid()``
-method on a form. There are other things that can trigger cleaning and
-validation (accessing the ``errors`` attribute or calling ``full_clean()``
-directly), but normally they won't be needed.
-
-In general, any cleaning method can raise ``ValidationError`` if there is a
-problem with the data it is processing, passing the relevant error message to
-the ``ValidationError`` constructor. If no ``ValidationError`` is raised, the
-method should return the cleaned (normalised) data as a Python object.
-
-If you detect multiple errors during a cleaning method and wish to signal all
-of them to the form submitter, it is possible to pass a list of errors to the
-``ValidationError`` constructor.
-
-The three types of cleaning methods are:
-
- * The ``clean()`` method on a Field subclass. This is responsible
- for cleaning the data in a way that is generic for that type of field.
- For example, a FloatField will turn the data into a Python ``float`` or
- raise a ``ValidationError``.
-
- * The ``clean_<fieldname>()`` method in a form subclass -- where
- ``<fieldname>`` is replaced with the name of the form field attribute.
- This method does any cleaning that is specific to that particular
- attribute, unrelated to the type of field that it is. This method is not
- passed any parameters. You will need to look up the value of the field
- in ``self.cleaned_data`` and remember that it will be a Python object
- at this point, not the original string submitted in the form (it will be
- in ``cleaned_data`` because the general field ``clean()`` method, above,
- has already cleaned the data once).
-
- For example, if you wanted to validate that the contents of a
- ``CharField`` called ``serialnumber`` was unique,
- ``clean_serialnumber()`` would be the right place to do this. You don't
- need a specific field (it's just a ``CharField``), but you want a
- formfield-specific piece of validation and, possibly,
- cleaning/normalizing the data.
-
- * The Form subclass's ``clean()`` method. This method can perform
- any validation that requires access to multiple fields from the form at
- once. This is where you might put in things to check that if field ``A``
- is supplied, field ``B`` must contain a valid email address and the
- like. The data that this method returns is the final ``cleaned_data``
- attribute for the form, so don't forget to return the full list of
- cleaned data if you override this method (by default, ``Form.clean()``
- just returns ``self.cleaned_data``).
-
- Note that any errors raised by your ``Form.clean()`` override will not
- be associated with any field in particular. They go into a special
- "field" (called ``__all__``), which you can access via the
- ``non_field_errors()`` method if you need to.
-
-These methods are run in the order given above, one field at a time. That is,
-for each field in the form (in the order they are declared in the form
-definition), the ``Field.clean()`` method (or its override) is run, then
-``clean_<fieldname>()``. Finally, once those two methods are run for every
-field, the ``Form.clean()`` method, or its override, is executed.
-
-As mentioned above, any of these methods can raise a ``ValidationError``. For
-any field, if the ``Field.clean()`` method raises a ``ValidationError``, any
-field-specific cleaning method is not called. However, the cleaning methods
-for all remaining fields are still executed.
-
-The ``clean()`` method for the ``Form`` class or subclass is always run. If
-that method raises a ``ValidationError``, ``cleaned_data`` will be an empty
-dictionary.
-
-The previous paragraph means that if you are overriding ``Form.clean()``, you
-should iterate through ``self.cleaned_data.items()``, possibly considering the
-``_errors`` dictionary attribute on the form as well. In this way, you will
-already know which fields have passed their individual validation requirements.
-
-A simple example
-~~~~~~~~~~~~~~~~
-
-Here's a simple example of a custom field that validates its input is a string
-containing comma-separated e-mail addresses, with at least one address. We'll
-keep it simple and assume e-mail validation is contained in a function called
-``is_valid_email()``. The full class::
-
- from django import newforms as forms
-
- class MultiEmailField(forms.Field):
- def clean(self, value):
- if not value:
- raise forms.ValidationError('Enter at least one e-mail address.')
- emails = value.split(',')
- for email in emails:
- if not is_valid_email(email):
- raise forms.ValidationError('%s is not a valid e-mail address.' % email)
- return emails
-
-Let's alter the ongoing ``ContactForm`` example to demonstrate how you'd use
-this in a form. Simply use ``MultiEmailField`` instead of ``forms.EmailField``,
-like so::
-
- class ContactForm(forms.Form):
- subject = forms.CharField(max_length=100)
- message = forms.CharField()
- senders = MultiEmailField()
- cc_myself = forms.BooleanField(required=False)
-
-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' ...``
- ``DateTimeInput`` ``<input type='text' ...``
- ``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.
- ============================ ===========================================
-
-**New in Django development version:** The ``DateTimeInput`` has been added
-since the last release.
-
-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 input 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
-default ``size`` attribute as a custom extension to the ``TextInput`` widget::
-
- class CommentWidget(forms.TextInput):
- def __init__(self, *args, **kwargs):
- attrs = kwargs.setdefault('attrs',{})
- if 'size' not in attrs:
- attrs['size'] = 40
- super(CommentWidget, self).__init__(*args, **kwargs)
-
-We allow the ``size`` attribute to be overridden by the user, but, by default,
-this widget will behave as if ``attrs={'size': 40}`` was always passed into the
-constructor.
-
-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
-===========================
-
-The prefered way of generating forms that work with models is explained in the
-`ModelForms documentation`_.
-
-Looking for the ``form_for_model`` and ``form_for_instance`` documentation?
-They've been deprecated, but you can still `view the documentation`_.
-
-.. _ModelForms documentation: ../modelforms/
-.. _view the documentation: ../form_for_model/
-
-Media
-=====
-
-Rendering an attractive and easy-to-use web form requires more than just
-HTML - it also requires CSS stylesheets, and if you want to use fancy
-"Web2.0" widgets, you may also need to include some JavaScript on each
-page. The exact combination of CSS and JavaScript that is required for
-any given page will depend upon the widgets that are in use on that page.
-
-This is where Django media definitions come in. Django allows you to
-associate different media files with the forms and widgets that require
-that media. For example, if you want to use a calendar to render DateFields,
-you can define a custom Calendar widget. This widget can then be associated
-with the CSS and Javascript that is required to render the calendar. When
-the Calendar widget is used on a form, Django is able to identify the CSS and
-JavaScript files that are required, and provide the list of file names
-in a form suitable for easy inclusion on your web page.
-
-.. admonition:: Media and Django Admin
-
- The Django Admin application defines a number of customized widgets
- for calendars, filtered selections, and so on. These widgets define
- media requirements, and the Django Admin uses the custom widgets
- in place of the Django defaults. The Admin templates will only include
- those media files that are required to render the widgets on any
- given page.
-
- If you like the widgets that the Django Admin application uses,
- feel free to use them in your own application! They're all stored
- in ``django.contrib.admin.widgets``.
-
-.. admonition:: Which JavaScript toolkit?
-
- Many JavaScript toolkits exist, and many of them include widgets (such
- as calendar widgets) that can be used to enhance your application.
- Django has deliberately avoided blessing any one JavaScript toolkit.
- Each toolkit has its own relative strengths and weaknesses - use
- whichever toolkit suits your requirements. Django is able to integrate
- with any JavaScript toolkit.
-
-Media as a static definition
-----------------------------
-
-The easiest way to define media is as a static definition. Using this method,
-the media declaration is an inner class. The properties of the inner class
-define the media requirements.
-
-Here's a simple example::
-
- class CalendarWidget(forms.TextInput):
- class Media:
- css = {
- 'all': ('pretty.css',)
- }
- js = ('animations.js', 'actions.js')
-
-This code defines a ``CalendarWidget``, which will be based on ``TextInput``.
-Every time the CalendarWidget is used on a form, that form will be directed
-to include the CSS file ``pretty.css``, and the JavaScript files
-``animations.js`` and ``actions.js``.
-
-This static media definition is converted at runtime into a widget property
-named ``media``. The media for a CalendarWidget instance can be retrieved
-through this property::
-
- >>> w = CalendarWidget()
- >>> print w.media
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-
-Here's a list of all possible ``Media`` options. There are no required options.
-
-``css``
-~~~~~~~
-
-A dictionary describing the CSS files required for various forms of output
-media.
-
-The values in the dictionary should be a tuple/list of file names. See
-`the section on media paths`_ for details of how to specify paths to media
-files.
-
-.. _the section on media paths: `Paths in media definitions`_
-
-The keys in the dictionary are the output media types. These are the same
-types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
-'embossed', 'handheld', 'print', 'projection', 'screen', 'tty' and 'tv'. If
-you need to have different stylesheets for different media types, provide
-a list of CSS files for each output medium. The following example would
-provide two CSS options -- one for the screen, and one for print::
-
- class Media:
- css = {
- 'screen': ('pretty.css',),
- 'print': ('newspaper.css',)
- }
-
-If a group of CSS files are appropriate for multiple output media types,
-the dictionary key can be a comma separated list of output media types.
-In the following example, TV's and projectors will have the same media
-requirements::
-
- class Media:
- css = {
- 'screen': ('pretty.css',),
- 'tv,projector': ('lo_res.css',),
- 'print': ('newspaper.css',)
- }
-
-If this last CSS definition were to be rendered, it would become the following HTML::
-
- <link href="http://media.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet" />
- <link href="http://media.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet" />
- <link href="http://media.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet" />
-
-``js``
-~~~~~~
-
-A tuple describing the required javascript files. See
-`the section on media paths`_ for details of how to specify paths to media
-files.
-
-``extend``
-~~~~~~~~~~
-
-A boolean defining inheritance behavior for media declarations.
-
-By default, any object using a static media definition will inherit all the
-media associated with the parent widget. This occurs regardless of how the
-parent defines its media requirements. For example, if we were to extend our
-basic Calendar widget from the example above::
-
- class FancyCalendarWidget(CalendarWidget):
- class Media:
- css = {
- 'all': ('fancy.css',)
- }
- js = ('whizbang.js',)
-
- >>> w = FancyCalendarWidget()
- >>> print w.media
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
- <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-The FancyCalendar widget inherits all the media from it's parent widget. If
-you don't want media to be inherited in this way, add an ``extend=False``
-declaration to the media declaration::
-
- class FancyCalendar(Calendar):
- class Media:
- extend = False
- css = {
- 'all': ('fancy.css',)
- }
- js = ('whizbang.js',)
-
- >>> w = FancyCalendarWidget()
- >>> print w.media
- <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-If you require even more control over media inheritance, define your media
-using a `dynamic property`_. Dynamic properties give you complete control over
-which media files are inherited, and which are not.
-
-.. _dynamic property: `Media as a dynamic property`_
-
-Media as a dynamic property
----------------------------
-
-If you need to perform some more sophisticated manipulation of media
-requirements, you can define the media property directly. This is done
-by defining a model property that returns an instance of ``forms.Media``.
-The constructor for ``forms.Media`` accepts ``css`` and ``js`` keyword
-arguments in the same format as that used in a static media definition.
-
-For example, the static media definition for our Calendar Widget could
-also be defined in a dynamic fashion::
-
- class CalendarWidget(forms.TextInput):
- def _media(self):
- return forms.Media(css={'all': ('pretty.css',)},
- js=('animations.js', 'actions.js'))
- media = property(_media)
-
-See the section on `Media objects`_ for more details on how to construct
-return values for dynamic media properties.
-
-Paths in media definitions
---------------------------
-
-Paths used to specify media can be either relative or absolute. If a path
-starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
-path, and left as-is. All other paths will be prepended with the value of
-``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
-``http://media.example.com/``::
-
- class CalendarWidget(forms.TextInput):
- class Media:
- css = {
- 'all': ('/css/pretty.css',),
- }
- js = ('animations.js', 'http://othersite.com/actions.js')
-
- >>> w = CalendarWidget()
- >>> print w.media
- <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://othersite.com/actions.js"></script>
-
-Media objects
--------------
-
-When you interrogate the media attribute of a widget or form, the value that
-is returned is a ``forms.Media`` object. As we have already seen, the string
-representation of a Media object is the HTML required to include media
-in the ``<head>`` block of your HTML page.
-
-However, Media objects have some other interesting properties.
-
-Media subsets
-~~~~~~~~~~~~~
-
-If you only want media of a particular type, you can use the subscript operator
-to filter out a medium of interest. For example::
-
- >>> w = CalendarWidget()
- >>> print w.media
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-
- >>> print w.media['css']
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-
-When you use the subscript operator, the value that is returned is a new
-Media object -- but one that only contains the media of interest.
-
-Combining media objects
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Media objects can also be added together. When two media objects are added,
-the resulting Media object contains the union of the media from both files::
-
- class CalendarWidget(forms.TextInput):
- class Media:
- css = {
- 'all': ('pretty.css',)
- }
- js = ('animations.js', 'actions.js')
-
- class OtherWidget(forms.TextInput):
- class Media:
- js = ('whizbang.js',)
-
- >>> w1 = CalendarWidget()
- >>> w2 = OtherWidget()
- >>> print w1+w2
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
- <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-Media on Forms
---------------
-
-Widgets aren't the only objects that can have media definitions -- forms
-can also define media. The rules for media definitions on forms are the
-same as the rules for widgets: declarations can be static or dynamic;
-path and inheritance rules for those declarations are exactly the same.
-
-Regardless of whether you define a media declaration, *all* Form objects
-have a media property. The default value for this property is the result
-of adding the media definitions for all widgets that are part of the form::
-
- class ContactForm(forms.Form):
- date = DateField(widget=CalendarWidget)
- name = CharField(max_length=40, widget=OtherWidget)
-
- >>> f = ContactForm()
- >>> f.media
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
- <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-If you want to associate additional media with a form -- for example, CSS for form
-layout -- simply add a media declaration to the form::
-
- class ContactForm(forms.Form):
- date = DateField(widget=CalendarWidget)
- name = CharField(max_length=40, widget=OtherWidget)
-
- class Media:
- css = {
- 'all': ('layout.css',)
- }
-
- >>> f = ContactForm()
- >>> f.media
- <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <link href="http://media.example.com/layout.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
- <script type="text/javascript" src="http://media.example.com/actions.js"></script>
- <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-Formsets
-========
-
-A formset is a layer of abstraction to working with multiple forms on the same
-page. It can be best compared to a data grid. Let's say you have the following
-form::
-
- >>> from django import newforms as forms
- >>> class ArticleForm(forms.Form):
- ... title = forms.CharField()
- ... pub_date = forms.DateField()
-
-You might want to allow the user to create several articles at once. To create
-a formset of out of an ``ArticleForm`` you would do::
-
- >>> from django.newforms.formsets import formset_factory
- >>> ArticleFormSet = formset_factory(ArticleForm)
-
-You now have created a formset named ``ArticleFormSet``. The formset gives you
-the ability to iterate over the forms in the formset and display them as you
-would with a regular form::
-
- >>> formset = ArticleFormSet()
- >>> for form in formset.forms:
- ... print form.as_table()
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-
-As you can see it only displayed one form. This is because by default the
-``formset_factory`` defines one extra form. This can be controlled with the
-``extra`` parameter::
-
- >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
-
-Using initial data with a formset
----------------------------------
-
-Initial data is what drives the main usability of a formset. As shown above
-you can define the number of extra forms. What this means is that you are
-telling the formset how many additional forms to show in addition to the
-number of forms it generates from the initial data. Lets take a look at an
-example::
-
- >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
- >>> formset = ArticleFormSet(initial=[
- ... {'title': u'Django is now open source',
- ... 'pub_date': datetime.date.today()},
- ... ])
-
- >>> for form in formset.forms:
- ... print form.as_table()
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date" /></td></tr>
- <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" id="id_form-1-title" /></td></tr>
- <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" id="id_form-1-pub_date" /></td></tr>
- <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
- <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
-
-There are now a total of three forms showing above. One for the initial data
-that was passed in and two extra forms. Also note that we are passing in a
-list of dictionaries as the initial data.
-
-Limiting the maximum number of forms
-------------------------------------
-
-The ``max_num`` parameter to ``formset_factory`` gives you the ability to
-force the maximum number of forms the formset will display::
-
- >>> ArticleFormSet = formset_factory(ArticleForm, extra=2, max_num=1)
- >>> formset = ArticleFormset()
- >>> for form in formset.forms:
- ... print form.as_table()
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-
-The default value of ``max_num`` is ``0`` which is the same as saying put no
-limit on the number forms displayed.
-
-Formset validation
-------------------
-
-Validation with a formset is about identical to a regular ``Form``. There is
-an ``is_valid`` method on the formset to provide a convenient way to validate
-each form in the formset::
-
- >>> ArticleFormSet = formset_factory(ArticleForm)
- >>> formset = ArticleFormSet({})
- >>> formset.is_valid()
- True
-
-We passed in no data to the formset which is resulting in a valid form. The
-formset is smart enough to ignore extra forms that were not changed. If we
-attempt to provide an article, but fail to do so::
-
- >>> data = {
- ... 'form-TOTAL_FORMS': u'1',
- ... 'form-INITIAL_FORMS': u'1',
- ... 'form-0-title': u'Test',
- ... 'form-0-pub_date': u'',
- ... }
- >>> formset = ArticleFormSet(data)
- >>> formset.is_valid()
- False
- >>> formset.errors
- [{'pub_date': [u'This field is required.']}]
-
-As we can see the formset properly performed validation and gave us the
-expected errors.
-
-Understanding the ManagementForm
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You may have noticed the additional data that was required in the formset's
-data above. This data is coming from the ``ManagementForm``. This form is
-dealt with internally to the formset. If you don't use it, it will result in
-an exception::
-
- >>> data = {
- ... 'form-0-title': u'Test',
- ... 'form-0-pub_date': u'',
- ... }
- >>> formset = ArticleFormSet(data)
- Traceback (most recent call last):
- ...
- django.newforms.util.ValidationError: [u'ManagementForm data is missing or has been tampered with']
-
-It is used to keep track of how many form instances are being displayed. If
-you are adding new forms via javascript, you should increment the count fields
-in this form as well.
-
-Custom formset validation
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A formset has a ``clean`` method similar to the one on a ``Form`` class. This
-is where you define your own validation that deals at the formset level::
-
- >>> from django.newforms.formsets import BaseFormSet
-
- >>> class BaseArticleFormSet(BaseFormSet):
- ... def clean(self):
- ... raise forms.ValidationError, u'An error occured.'
-
- >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
- >>> formset = ArticleFormSet({})
- >>> formset.is_valid()
- False
- >>> formset.non_form_errors()
- [u'An error occured.']
-
-The formset ``clean`` method is called after all the ``Form.clean`` methods
-have been called. The errors will be found using the ``non_form_errors()``
-method on the formset.
-
-Dealing with ordering and deletion of forms
--------------------------------------------
-
-Common use cases with a formset is dealing with ordering and deletion of the
-form instances. This has been dealt with for you. The ``formset_factory``
-provides two optional parameters ``can_order`` and ``can_delete`` that will do
-the extra work of adding the extra fields and providing simpler ways of
-getting to that data.
-
-``can_order``
-~~~~~~~~~~~~~
-
-Default: ``False``
-
-Lets create a formset with the ability to order::
-
- >>> ArticleFormSet = formset_factory(ArticleForm, can_order=True)
- >>> formset = ArticleFormSet(initial=[
- ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
- ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
- ... ])
- >>> for form in formset.forms:
- ... print form.as_table()
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
- <tr><th><label for="id_form-0-ORDER">Order:</label></th><td><input type="text" name="form-0-ORDER" value="1" id="id_form-0-ORDER" /></td></tr>
- <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
- <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
- <tr><th><label for="id_form-1-ORDER">Order:</label></th><td><input type="text" name="form-1-ORDER" value="2" id="id_form-1-ORDER" /></td></tr>
- <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
- <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
- <tr><th><label for="id_form-2-ORDER">Order:</label></th><td><input type="text" name="form-2-ORDER" id="id_form-2-ORDER" /></td></tr>
-
-This adds an additional field to each form. This new field is named ``ORDER``
-and is an ``forms.IntegerField``. For the forms that came from the initial
-data it automatically assigned them a numeric value. Lets look at what will
-happen when the user changes these values::
-
- >>> data = {
- ... 'form-TOTAL_FORMS': u'3',
- ... 'form-INITIAL_FORMS': u'2',
- ... 'form-0-title': u'Article #1',
- ... 'form-0-pub_date': u'2008-05-10',
- ... 'form-0-ORDER': u'2',
- ... 'form-1-title': u'Article #2',
- ... 'form-1-pub_date': u'2008-05-11',
- ... 'form-1-ORDER': u'1',
- ... 'form-2-title': u'Article #3',
- ... 'form-2-pub_date': u'2008-05-01',
- ... 'form-2-ORDER': u'0',
- ... }
-
- >>> formset = ArticleFormSet(data, initial=[
- ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
- ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
- ... ])
- >>> formset.is_valid()
- True
- >>> for form in formset.ordered_forms:
- ... print form.cleaned_data
- {'pub_date': datetime.date(2008, 5, 1), 'ORDER': 0, 'title': u'Article #3'}
- {'pub_date': datetime.date(2008, 5, 11), 'ORDER': 1, 'title': u'Article #2'}
- {'pub_date': datetime.date(2008, 5, 10), 'ORDER': 2, 'title': u'Article #1'}
-
-``can_delete``
-~~~~~~~~~~~~~~
-
-Default: ``False``
-
-Lets create a formset with the ability to delete::
-
- >>> ArticleFormSet = formset_factory(ArticleForm, can_delete=True)
- >>> formset = ArticleFormSet(initial=[
- ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
- ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
- ... ])
- >>> for form in formset.forms:
- .... print form.as_table()
- <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" />
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
- <tr><th><label for="id_form-0-DELETE">Delete:</label></th><td><input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /></td></tr>
- <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
- <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
- <tr><th><label for="id_form-1-DELETE">Delete:</label></th><td><input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /></td></tr>
- <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
- <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
- <tr><th><label for="id_form-2-DELETE">Delete:</label></th><td><input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /></td></tr>
-
-Similar to ``can_order`` this adds a new field to each form named ``DELETE``
-and is a ``forms.BooleanField``. When data comes through marking any of the
-delete fields you can access them with ``deleted_forms``::
-
- >>> data = {
- ... 'form-TOTAL_FORMS': u'3',
- ... 'form-INITIAL_FORMS': u'2',
- ... 'form-0-title': u'Article #1',
- ... 'form-0-pub_date': u'2008-05-10',
- ... 'form-0-DELETE': u'on',
- ... 'form-1-title': u'Article #2',
- ... 'form-1-pub_date': u'2008-05-11',
- ... 'form-1-DELETE': u'',
- ... 'form-2-title': u'',
- ... 'form-2-pub_date': u'',
- ... 'form-2-DELETE': u'',
- ... }
-
- >>> formset = ArticleFormSet(data, initial=[
- ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
- ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
- ... ])
- >>> [form.cleaned_data for form in formset.deleted_forms]
- [{'DELETE': True, 'pub_date': datetime.date(2008, 5, 10), 'title': u'Article #1'}]
-
-Adding additional fields to a formset
--------------------------------------
-
-If you need to add additional fields to the formset this can be easily
-accomplished. The formset base class provides an ``add_fields`` method. You
-can simply override this method to add your own fields or even redefine the
-default fields/attributes of the order and deletion fields::
-
- >>> class BaseArticleFormSet(BaseFormSet):
- ... def add_fields(self, form, index):
- ... super(BaseArticleFormSet, self).add_fields(form, index)
- ... form.fields["my_field"] = forms.CharField()
-
- >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
- >>> formset = ArticleFormSet()
- >>> for form in formset.forms:
- ... print form.as_table()
- <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
- <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
- <tr><th><label for="id_form-0-my_field">My field:</label></th><td><input type="text" name="form-0-my_field" id="id_form-0-my_field" /></td></tr>
-
-Using a formset in views and templates
---------------------------------------
-
-Using a formset inside a view is as easy as using a regular ``Form`` class.
-The only thing you will want to be aware of is making sure to use the
-management form inside the template. Lets look at a sample view::
-
- def manage_articles(request):
- ArticleFormSet = formset_factory(ArticleForm)
- if request.method == 'POST':
- formset = ArticleFormSet(request.POST, request.FILES)
- if formset.is_valid():
- # do something with the formset.cleaned_data
- else:
- formset = ArticleFormSet()
- return render_to_response('manage_articles.html', {'formset': formset})
-
-The ``manage_articles.html`` template might look like this::
-
- <form method="POST" action="">
- {{ formset.management_form }}
- <table>
- {% for form in formset.forms %}
- {{ form }}
- {% endfor %}
- </table>
- </form>
-
-However the above can be slightly shortcutted and let the formset itself deal
-with the management form::
-
- <form method="POST" action="">
- <table>
- {{ formset }}
- </table>
- </form>
-
-The above ends up calling the ``as_table`` method on the formset class.
-
-More coming soon
-================
-
-That's all the documentation for now. For more, see the file
-http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms
--- the unit tests for ``django.newforms``. This can give you a good idea of
-what's possible. (Each submodule there contains separate tests.)
-
-If you're really itching to learn and use this library, please be patient.
-We're working hard on finishing both the code and documentation.
diff --git a/docs/oldforms.txt b/docs/oldforms.txt
new file mode 100644
index 0000000000..7703483f5d
--- /dev/null
+++ b/docs/oldforms.txt
@@ -0,0 +1,696 @@
+===============================
+Forms, fields, and manipulators
+===============================
+
+Forwards-compatibility note
+===========================
+
+The legacy forms/manipulators system described in this document is going to be
+replaced in the next Django release. If you're starting from scratch, we
+strongly encourage you not to waste your time learning this. Instead, learn and
+use the new `forms library`_.
+
+.. _forms library: ../forms/
+
+Introduction
+============
+
+Once you've got a chance to play with Django's admin interface, you'll probably
+wonder if the fantastic form validation framework it uses is available to user
+code. It is, and this document explains how the framework works.
+
+We'll take a top-down approach to examining Django's form validation framework,
+because much of the time you won't need to use the lower-level APIs. Throughout
+this document, we'll be working with the following model, a "place" object::
+
+ from django.db import models
+
+ PLACE_TYPES = (
+ (1, 'Bar'),
+ (2, 'Restaurant'),
+ (3, 'Movie Theater'),
+ (4, 'Secret Hideout'),
+ )
+
+ class Place(models.Model):
+ name = models.CharField(max_length=100)
+ address = models.CharField(max_length=100, blank=True)
+ city = models.CharField(max_length=50, blank=True)
+ state = models.USStateField()
+ zip_code = models.CharField(max_length=5, blank=True)
+ place_type = models.IntegerField(choices=PLACE_TYPES)
+
+ class Admin:
+ pass
+
+ def __unicode__(self):
+ return self.name
+
+Defining the above class is enough to create an admin interface to a ``Place``,
+but what if you want to allow public users to submit places?
+
+Automatic Manipulators
+======================
+
+The highest-level interface for object creation and modification is the
+**automatic Manipulator** framework. An automatic manipulator is a utility
+class tied to a given model that "knows" how to create or modify instances of
+that model and how to validate data for the object. Automatic Manipulators come
+in two flavors: ``AddManipulators`` and ``ChangeManipulators``. Functionally
+they are quite similar, but the former knows how to create new instances of the
+model, while the latter modifies existing instances. Both types of classes are
+automatically created when you define a new class::
+
+ >>> from mysite.myapp.models import Place
+ >>> Place.AddManipulator
+ <class 'django.models.manipulators.AddManipulator'>
+ >>> Place.ChangeManipulator
+ <class 'django.models.manipulators.ChangeManipulator'>
+
+Using the ``AddManipulator``
+----------------------------
+
+We'll start with the ``AddManipulator``. Here's a very simple view that takes
+POSTed data from the browser and creates a new ``Place`` object::
+
+ from django.shortcuts import render_to_response
+ from django.http import Http404, HttpResponse, HttpResponseRedirect
+ from django import oldforms as forms
+ from mysite.myapp.models import Place
+
+ def naive_create_place(request):
+ """A naive approach to creating places; don't actually use this!"""
+ # Create the AddManipulator.
+ manipulator = Place.AddManipulator()
+
+ # Make a copy of the POSTed data so that do_html2python can
+ # modify it in place (request.POST is immutable).
+ new_data = request.POST.copy()
+
+ # Convert the request data (which will all be strings) into the
+ # appropriate Python types for those fields.
+ manipulator.do_html2python(new_data)
+
+ # Save the new object.
+ new_place = manipulator.save(new_data)
+
+ # It worked!
+ return HttpResponse("Place created: %s" % new_place)
+
+The ``naive_create_place`` example works, but as you probably can tell, this
+view has a number of problems:
+
+ * No validation of any sort is performed. If, for example, the ``name`` field
+ isn't given in ``request.POST``, the save step will cause a database error
+ because that field is required. Ugly.
+
+ * Even if you *do* perform validation, there's still no way to give that
+ information to the user in any sort of useful way.
+
+ * You'll have to separately create a form (and view) that submits to this
+ page, which is a pain and is redundant.
+
+Let's dodge these problems momentarily to take a look at how you could create a
+view with a form that submits to this flawed creation view::
+
+ def naive_create_place_form(request):
+ """Simplistic place form view; don't actually use anything like this!"""
+ # Create a FormWrapper object that the template can use. Ignore
+ # the last two arguments to FormWrapper for now.
+ form = forms.FormWrapper(Place.AddManipulator(), {}, {})
+ return render_to_response('places/naive_create_form.html', {'form': form})
+
+(This view, as well as all the following ones, has the same imports as in the
+first example above.)
+
+The ``forms.FormWrapper`` object is a wrapper that templates can
+easily deal with to create forms. Here's the ``naive_create_form.html``
+template::
+
+ {% extends "base.html" %}
+
+ {% block content %}
+ <h1>Create a place:</h1>
+
+ <form method="post" action="../do_new/">
+ <p><label for="id_name">Name:</label> {{ form.name }}</p>
+ <p><label for="id_address">Address:</label> {{ form.address }}</p>
+ <p><label for="id_city">City:</label> {{ form.city }}</p>
+ <p><label for="id_state">State:</label> {{ form.state }}</p>
+ <p><label for="id_zip_code">Zip:</label> {{ form.zip_code }}</p>
+ <p><label for="id_place_type">Place type:</label> {{ form.place_type }}</p>
+ <input type="submit" />
+ </form>
+ {% endblock %}
+
+Before we get back to the problems with these naive set of views, let's go over
+some salient points of the above template:
+
+ * Field "widgets" are handled for you: ``{{ form.field }}`` automatically
+ creates the "right" type of widget for the form, as you can see with the
+ ``place_type`` field above.
+
+ * There isn't a way just to spit out the form. You'll still need to define
+ how the form gets laid out. This is a feature: Every form should be
+ designed differently. Django doesn't force you into any type of mold.
+ If you must use tables, use tables. If you're a semantic purist, you can
+ probably find better HTML than in the above template.
+
+ * To avoid name conflicts, the ``id`` values of form elements take the
+ form "id_*fieldname*".
+
+By creating a creation form we've solved problem number 3 above, but we still
+don't have any validation. Let's revise the validation issue by writing a new
+creation view that takes validation into account::
+
+ def create_place_with_validation(request):
+ manipulator = Place.AddManipulator()
+ new_data = request.POST.copy()
+
+ # Check for validation errors
+ errors = manipulator.get_validation_errors(new_data)
+ manipulator.do_html2python(new_data)
+ if errors:
+ return render_to_response('places/errors.html', {'errors': errors})
+ else:
+ new_place = manipulator.save(new_data)
+ return HttpResponse("Place created: %s" % new_place)
+
+In this new version, errors will be found -- ``manipulator.get_validation_errors``
+handles all the validation for you -- and those errors can be nicely presented
+on an error page (templated, of course)::
+
+ {% extends "base.html" %}
+
+ {% block content %}
+
+ <h1>Please go back and correct the following error{{ errors|pluralize }}:</h1>
+ <ul>
+ {% for e in errors.items %}
+ <li>Field "{{ e.0 }}": {{ e.1|join:", " }}</li>
+ {% endfor %}
+ </ul>
+
+ {% endblock %}
+
+Still, this has its own problems:
+
+ * There's still the issue of creating a separate (redundant) view for the
+ submission form.
+
+ * Errors, though nicely presented, are on a separate page, so the user will
+ have to use the "back" button to fix errors. That's ridiculous and unusable.
+
+The best way to deal with these issues is to collapse the two views -- the form
+and the submission -- into a single view. This view will be responsible for
+creating the form, validating POSTed data, and creating the new object (if the
+data is valid). An added bonus of this approach is that errors and the form will
+both be available on the same page, so errors with fields can be presented in
+context.
+
+.. admonition:: Philosophy:
+
+ Finally, for the HTTP purists in the audience (and the authorship), this
+ nicely matches the "true" meanings of HTTP GET and HTTP POST: GET fetches
+ the form, and POST creates the new object.
+
+Below is the finished view::
+
+ def create_place(request):
+ manipulator = Place.AddManipulator()
+
+ if request.method == 'POST':
+ # If data was POSTed, we're trying to create a new Place.
+ new_data = request.POST.copy()
+
+ # Check for errors.
+ errors = manipulator.get_validation_errors(new_data)
+ manipulator.do_html2python(new_data)
+
+ if not errors:
+ # No errors. This means we can save the data!
+ new_place = manipulator.save(new_data)
+
+ # Redirect to the object's "edit" page. Always use a redirect
+ # after POST data, so that reloads don't accidently create
+ # duplicate entires, and so users don't see the confusing
+ # "Repost POST data?" alert box in their browsers.
+ return HttpResponseRedirect("/places/edit/%i/" % new_place.id)
+ else:
+ # No POST, so we want a brand new form without any data or errors.
+ errors = new_data = {}
+
+ # Create the FormWrapper, template, context, response.
+ form = forms.FormWrapper(manipulator, new_data, errors)
+ return render_to_response('places/create_form.html', {'form': form})
+
+and here's the ``create_form`` template::
+
+ {% extends "base.html" %}
+
+ {% block content %}
+ <h1>Create a place:</h1>
+
+ {% if form.has_errors %}
+ <h2>Please correct the following error{{ form.error_dict|pluralize }}:</h2>
+ {% endif %}
+
+ <form method="post" action=".">
+ <p>
+ <label for="id_name">Name:</label> {{ form.name }}
+ {% if form.name.errors %}*** {{ form.name.errors|join:", " }}{% endif %}
+ </p>
+ <p>
+ <label for="id_address">Address:</label> {{ form.address }}
+ {% if form.address.errors %}*** {{ form.address.errors|join:", " }}{% endif %}
+ </p>
+ <p>
+ <label for="id_city">City:</label> {{ form.city }}
+ {% if form.city.errors %}*** {{ form.city.errors|join:", " }}{% endif %}
+ </p>
+ <p>
+ <label for="id_state">State:</label> {{ form.state }}
+ {% if form.state.errors %}*** {{ form.state.errors|join:", " }}{% endif %}
+ </p>
+ <p>
+ <label for="id_zip_code">Zip:</label> {{ form.zip_code }}
+ {% if form.zip_code.errors %}*** {{ form.zip_code.errors|join:", " }}{% endif %}
+ </p>
+ <p>
+ <label for="id_place_type">Place type:</label> {{ form.place_type }}
+ {% if form.place_type.errors %}*** {{ form.place_type.errors|join:", " }}{% endif %}
+ </p>
+ <input type="submit" />
+ </form>
+ {% endblock %}
+
+The second two arguments to ``FormWrapper`` (``new_data`` and ``errors``)
+deserve some mention.
+
+The first is any "default" data to be used as values for the fields. Pulling
+the data from ``request.POST``, as is done above, makes sure that if there are
+errors, the values the user put in aren't lost. If you try the above example,
+you'll see this in action.
+
+The second argument is the error list retrieved from
+``manipulator.get_validation_errors``. When passed into the ``FormWrapper``,
+this gives each field an ``errors`` item (which is a list of error messages
+associated with the field) as well as a ``html_error_list`` item, which is a
+``<ul>`` of error messages. The above template uses these error items to
+display a simple error message next to each field. The error list is saved as
+an ``error_dict`` attribute of the ``FormWrapper`` object.
+
+Using the ``ChangeManipulator``
+-------------------------------
+
+The above has covered using the ``AddManipulator`` to create a new object. What
+about editing an existing one? It's shockingly similar to creating a new one::
+
+ def edit_place(request, place_id):
+ # Get the place in question from the database and create a
+ # ChangeManipulator at the same time.
+ try:
+ manipulator = Place.ChangeManipulator(place_id)
+ except Place.DoesNotExist:
+ raise Http404
+
+ # Grab the Place object in question for future use.
+ place = manipulator.original_object
+
+ if request.method == 'POST':
+ new_data = request.POST.copy()
+ errors = manipulator.get_validation_errors(new_data)
+ manipulator.do_html2python(new_data)
+ if not errors:
+ manipulator.save(new_data)
+
+ # Do a post-after-redirect so that reload works, etc.
+ return HttpResponseRedirect("/places/edit/%i/" % place.id)
+ else:
+ errors = {}
+ # This makes sure the form accurate represents the fields of the place.
+ new_data = manipulator.flatten_data()
+
+ form = forms.FormWrapper(manipulator, new_data, errors)
+ return render_to_response('places/edit_form.html', {'form': form, 'place': place})
+
+The only real differences are:
+
+ * We create a ``ChangeManipulator`` instead of an ``AddManipulator``.
+ The argument to a ``ChangeManipulator`` is the ID of the object
+ to be changed. As you can see, the initializer will raise an
+ ``ObjectDoesNotExist`` exception if the ID is invalid.
+
+ * ``ChangeManipulator.original_object`` stores the instance of the
+ object being edited.
+
+ * We set ``new_data`` based upon ``flatten_data()`` from the manipulator.
+ ``flatten_data()`` takes the data from the original object under
+ manipulation, and converts it into a data dictionary that can be used
+ to populate form elements with the existing values for the object.
+
+ * The above example uses a different template, so create and edit can be
+ "skinned" differently if needed, but the form chunk itself is completely
+ identical to the one in the create form above.
+
+The astute programmer will notice the add and create functions are nearly
+identical and could in fact be collapsed into a single view. This is left as an
+exercise for said programmer.
+
+(However, the even-more-astute programmer will take heed of the note at the top
+of this document and check out the `generic views`_ documentation if all she
+wishes to do is this type of simple create/update.)
+
+Custom forms and manipulators
+=============================
+
+All the above is fine and dandy if you just want to use the automatically
+created manipulators. But the coolness doesn't end there: You can easily create
+your own custom manipulators for handling custom forms.
+
+Custom manipulators are pretty simple. Here's a manipulator that you might use
+for a "contact" form on a website::
+
+ from django import oldforms as forms
+
+ urgency_choices = (
+ (1, "Extremely urgent"),
+ (2, "Urgent"),
+ (3, "Normal"),
+ (4, "Unimportant"),
+ )
+
+ class ContactManipulator(forms.Manipulator):
+ def __init__(self):
+ self.fields = (
+ forms.EmailField(field_name="from", is_required=True),
+ forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
+ forms.SelectField(field_name="urgency", choices=urgency_choices),
+ forms.LargeTextField(field_name="contents", is_required=True),
+ )
+
+A certain similarity to Django's models should be apparent. The only required
+method of a custom manipulator is ``__init__`` which must define the fields
+present in the manipulator. See the ``django.forms`` module for
+all the form fields provided by Django.
+
+You use this custom manipulator exactly as you would use an auto-generated one.
+Here's a simple function that might drive the above form::
+
+ def contact_form(request):
+ manipulator = ContactManipulator()
+ if request.method == 'POST':
+ new_data = request.POST.copy()
+ errors = manipulator.get_validation_errors(new_data)
+ manipulator.do_html2python(new_data)
+ if not errors:
+
+ # Send e-mail using new_data here...
+
+ return HttpResponseRedirect("/contact/thankyou/")
+ else:
+ errors = new_data = {}
+ form = forms.FormWrapper(manipulator, new_data, errors)
+ return render_to_response('contact_form.html', {'form': form})
+
+Implementing ``flatten_data`` for custom manipulators
+------------------------------------------------------
+
+It is possible (although rarely needed) to replace the default automatically
+created manipulators on a model with your own custom manipulators. If you do
+this and you are intending to use those models in generic views, you should
+also define a ``flatten_data`` method in any ``ChangeManipulator`` replacement.
+This should act like the default ``flatten_data`` and return a dictionary
+mapping field names to their values, like so::
+
+ def flatten_data(self):
+ obj = self.original_object
+ return dict(
+ from = obj.from,
+ subject = obj.subject,
+ ...
+ )
+
+In this way, your new change manipulator will act exactly like the default
+version.
+
+``FileField`` and ``ImageField`` special cases
+==============================================
+
+Dealing with ``FileField`` and ``ImageField`` objects is a little more
+complicated.
+
+First, you'll need to make sure that your ``<form>`` element correctly defines
+the ``enctype`` as ``"multipart/form-data"``, in order to upload files::
+
+ <form enctype="multipart/form-data" method="post" action="/foo/">
+
+Next, you'll need to treat the field in the template slightly differently. A
+``FileField`` or ``ImageField`` is represented by *two* HTML form elements.
+
+For example, given this field in a model::
+
+ photo = model.ImageField('/path/to/upload/location')
+
+You'd need to display two formfields in the template::
+
+ <p><label for="id_photo">Photo:</label> {{ form.photo }}{{ form.photo_file }}</p>
+
+The first bit (``{{ form.photo }}``) displays the currently-selected file,
+while the second (``{{ form.photo_file }}``) actually contains the file upload
+form field. Thus, at the validation layer you need to check the ``photo_file``
+key.
+
+Finally, in your view, make sure to access ``request.FILES``, rather than
+``request.POST``, for the uploaded files. This is necessary because
+``request.POST`` does not contain file-upload data.
+
+For example, following the ``new_data`` convention, you might do something like
+this::
+
+ new_data = request.POST.copy()
+ new_data.update(request.FILES)
+
+Validators
+==========
+
+One useful feature of manipulators is the automatic validation. Validation is
+done using a simple validation API: A validator is a callable that raises a
+``ValidationError`` if there's something wrong with the data.
+``django.core.validators`` defines a host of validator functions (see below),
+but defining your own couldn't be easier::
+
+ from django.core import validators
+ from django import oldforms as forms
+
+ class ContactManipulator(forms.Manipulator):
+ def __init__(self):
+ self.fields = (
+ # ... snip fields as above ...
+ forms.EmailField(field_name="to", validator_list=[self.isValidToAddress])
+ )
+
+ def isValidToAddress(self, field_data, all_data):
+ if not field_data.endswith("@example.com"):
+ raise validators.ValidationError("You can only send messages to example.com e-mail addresses.")
+
+Above, we've added a "to" field to the contact form, but required that the "to"
+address end with "@example.com" by adding the ``isValidToAddress`` validator to
+the field's ``validator_list``.
+
+The arguments to a validator function take a little explanation. ``field_data``
+is the value of the field in question, and ``all_data`` is a dictionary of all
+the data being validated.
+
+.. admonition:: Note::
+
+ At the point validators are called all data will still be
+ strings (as ``do_html2python`` hasn't been called yet).
+
+Also, because consistency in user interfaces is important, we strongly urge you
+to put punctuation at the end of your validation messages.
+
+When are validators called?
+---------------------------
+
+After a form has been submitted, Django validates each field in turn. First,
+if the field is required, Django checks that it is present and non-empty. Then,
+if that test passes *and the form submission contained data* for that field, all
+the validators for that field are called in turn. The emphasized portion in the
+last sentence is important: if a form field is not submitted (because it
+contains no data -- which is normal HTML behavior), the validators are not
+run against the field.
+
+This feature is particularly important for models using
+``models.BooleanField`` or custom manipulators using things like
+``forms.CheckBoxField``. If the checkbox is not selected, it will not
+contribute to the form submission.
+
+If you would like your validator to run *always*, regardless of whether its
+attached field contains any data, set the ``always_test`` attribute on the
+validator function. For example::
+
+ def my_custom_validator(field_data, all_data):
+ # ...
+ my_custom_validator.always_test = True
+
+This validator will always be executed for any field it is attached to.
+
+Ready-made validators
+---------------------
+
+Writing your own validator is not difficult, but there are some situations
+that come up over and over again. Django comes with a number of validators
+that can be used directly in your code. All of these functions and classes
+reside in ``django/core/validators.py``.
+
+The following validators should all be self-explanatory. Each one provides a
+check for the given property:
+
+ * isAlphaNumeric
+ * isAlphaNumericURL
+ * isSlug
+ * isLowerCase
+ * isUpperCase
+ * isCommaSeparatedIntegerList
+ * isCommaSeparatedEmailList
+ * isValidIPAddress4
+ * isNotEmpty
+ * isOnlyDigits
+ * isNotOnlyDigits
+ * isInteger
+ * isOnlyLetters
+ * isValidANSIDate
+ * isValidANSITime
+ * isValidEmail
+ * isValidFloat
+ * isValidImage
+ * isValidImageURL
+ * isValidPhone
+ * isValidQuicktimeVideoURL
+ * isValidURL
+ * isValidHTML
+ * isWellFormedXml
+ * isWellFormedXmlFragment
+ * isExistingURL
+ * isValidUSState
+ * hasNoProfanities
+
+There are also a group of validators that are slightly more flexible. For
+these validators, you create a validator instance, passing in the parameters
+described below. The returned object is a callable that can be used as a
+validator.
+
+For example::
+
+ from django.core import validators
+ from django import oldforms as forms
+
+ power_validator = validators.IsAPowerOf(2)
+
+ class InstallationManipulator(forms.Manipulator)
+ def __init__(self):
+ self.fields = (
+ ...
+ forms.IntegerField(field_name = "size", validator_list=[power_validator])
+ )
+
+Here, ``validators.IsAPowerOf(...)`` returned something that could be used as
+a validator (in this case, a check that a number was a power of 2).
+
+Each of the standard validators that take parameters have an optional final
+argument (``error_message``) that is the message returned when validation
+fails. If no message is passed in, a default message is used.
+
+``AlwaysMatchesOtherField``
+ Takes a field name and the current field is valid if and only if its value
+ matches the contents of the other field.
+
+``ValidateIfOtherFieldEquals``
+ Takes three parameters: ``other_field``, ``other_value`` and
+ ``validator_list``, in that order. If ``other_field`` has a value of
+ ``other_value``, then the validators in ``validator_list`` are all run
+ against the current field.
+
+``RequiredIfOtherFieldGiven``
+ Takes a field name of the current field is only required if the other
+ field has a value.
+
+``RequiredIfOtherFieldsGiven``
+ Similar to ``RequiredIfOtherFieldGiven``, except that it takes a list of
+ field names and if any one of the supplied fields has a value provided,
+ the current field being validated is required.
+
+``RequiredIfOtherFieldNotGiven``
+ Takes the name of the other field and this field is only required if the
+ other field has no value.
+
+``RequiredIfOtherFieldEquals`` and ``RequiredIfOtherFieldDoesNotEqual``
+ Each of these validator classes takes a field name and a value (in that
+ order). If the given field does (or does not have, in the latter case) the
+ given value, then the current field being validated is required.
+
+ An optional ``other_label`` argument can be passed which, if given, is used
+ in error messages instead of the value. This allows more user friendly error
+ messages if the value itself is not descriptive enough.
+
+ Note that because validators are called before any ``do_html2python()``
+ functions, the value being compared against is a string. So
+ ``RequiredIfOtherFieldEquals('choice', '1')`` is correct, whilst
+ ``RequiredIfOtherFieldEquals('choice', 1)`` will never result in the
+ equality test succeeding.
+
+``IsLessThanOtherField``
+ Takes a field name and validates that the current field being validated
+ has a value that is less than (or equal to) the other field's value.
+ Again, comparisons are done using strings, so be cautious about using
+ this function to compare data that should be treated as another type. The
+ string "123" is less than the string "2", for example. If you don't want
+ string comparison here, you will need to write your own validator.
+
+``NumberIsInRange``
+ Takes two boundary numbers, ``lower`` and ``upper``, and checks that the
+ field is greater than ``lower`` (if given) and less than ``upper`` (if
+ given).
+
+ Both checks are inclusive. That is, ``NumberIsInRange(10, 20)`` will allow
+ values of both 10 and 20. This validator only checks numeric values
+ (e.g., float and integer values).
+
+``IsAPowerOf``
+ Takes an integer argument and when called as a validator, checks that the
+ field being validated is a power of the integer.
+
+``IsValidDecimal``
+ Takes a maximum number of digits and number of decimal places (in that
+ order) and validates whether the field is a decimal with no more than the
+ maximum number of digits and decimal places.
+
+``MatchesRegularExpression``
+ Takes a regular expression (a string) as a parameter and validates the
+ field value against it.
+
+``AnyValidator``
+ Takes a list of validators as a parameter. At validation time, if the
+ field successfully validates against any one of the validators, it passes
+ validation. The validators are tested in the order specified in the
+ original list.
+
+``URLMimeTypeCheck``
+ Used to validate URL fields. Takes a list of MIME types (such as
+ ``text/plain``) at creation time. At validation time, it verifies that the
+ field is indeed a URL and then tries to retrieve the content at the URL.
+ Validation succeeds if the content could be retrieved and it has a content
+ type from the list used to create the validator.
+
+``RelaxNGCompact``
+ Used to validate an XML document against a Relax NG compact schema. Takes
+ a file path to the location of the schema and an optional root element
+ (which is wrapped around the XML fragment before validation, if supplied).
+ At validation time, the XML fragment is validated against the schema using
+ the executable specified in the ``JING_PATH`` setting (see the settings_
+ document for more details).
+
+.. _`generic views`: ../generic_views/
+.. _`models API`: ../model-api/
+.. _settings: ../settings/
diff --git a/docs/overview.txt b/docs/overview.txt
index 0fd1be5c85..dae0ffbd76 100644
--- a/docs/overview.txt
+++ b/docs/overview.txt
@@ -33,7 +33,7 @@ quick example::
class Article(models.Model):
pub_date = models.DateTimeField()
headline = models.CharField(max_length=200)
- article = models.TextField()
+ content = models.TextField()
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
@@ -95,7 +95,7 @@ is created on the fly, no code generation necessary::
# Create an article.
>>> from datetime import datetime
>>> a = Article(pub_date=datetime.now(), headline='Django is cool',
- ... article='Yeah.', reporter=r)
+ ... content='Yeah.', reporter=r)
>>> a.save()
# Now the article is in the database.
@@ -135,7 +135,7 @@ your model classes::
class Article(models.Model):
pub_date = models.DateTimeField()
headline = models.CharField(max_length=200)
- article = models.TextField()
+ content = models.TextField()
reporter = models.ForeignKey(Reporter)
class Admin: pass
diff --git a/docs/pagination.txt b/docs/pagination.txt
index bfdf8eea1c..c36f56244f 100644
--- a/docs/pagination.txt
+++ b/docs/pagination.txt
@@ -59,28 +59,65 @@ page::
...
InvalidPage
-Note that you can give ``Paginator`` a list/tuple or a Django ``QuerySet``. The
-only difference is in implementation; if you pass a ``QuerySet``, the
-``Paginator`` will call its ``count()`` method instead of using ``len()``,
-because the former is more efficient.
-
``Paginator`` objects
=====================
+Required arguments
+------------------
+
+``object_list``
+ A list, tuple, Django ``QuerySet``, or other sliceable object with a
+ ``count()`` or ``__len__()`` method.
+
+``per_page``
+ The maximum number of items to include on a page, not including orphans
+ (see the ``orphans`` optional argument below).
+
+Optional arguments
+------------------
+
+``orphans``
+ The minimum number of items allowed on the last page, defaults to zero.
+ Use this when you don't want to have a last page with very few items.
+ If the last page would normally have a number of items less than or equal
+ to ``orphans``, then those items will be added to the previous page (which
+ becomes the last page) instead of leaving the items on a page by
+ themselves. For example, with 23 items, ``per_page=10``, and
+ ``orphans=3``, there will be two pages; the first page with 10 items and
+ the second (and last) page with 13 items.
+
+``allow_empty_first_page``
+ Whether or not the first page is allowed to be empty. If ``False`` and
+ ``object_list`` is empty, then a ``EmptyPage`` error will be raised.
+
Methods
-------
-``page(number)`` -- Returns a ``Page`` object with the given 1-based index.
-Raises ``InvalidPage`` if the given page number doesn't exist.
+``page(number)``
+ Returns a ``Page`` object with the given 1-based index. Raises
+ ``InvalidPage`` if the given page number doesn't exist.
Attributes
----------
-``count`` -- The total number of objects, across all pages.
+In addition to the arguments above, which get stored as attributes, a
+``Paginator`` object also has the following attributes:
+
+``count``
+ The total number of objects, across all pages.
+
+ **Note**: When determining the number of objects contained in
+ ``object_list``, ``Paginator`` will first try calling
+ ``object_list.count()``. If ``object_list`` has no ``count()`` method, then
+ ``Paginator`` will fallback to using ``object_list.__len__()``. This allows
+ objects, such as Django's ``QuerySet``, to use a more efficient ``count()``
+ method when available.
-``num_pages`` -- The total number of pages.
+``num_pages``
+ The total number of pages.
-``page_range`` -- A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
+``page_range``
+ A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
``InvalidPage`` exceptions
==========================
@@ -90,9 +127,12 @@ The ``page()`` method raises ``InvalidPage`` if the requested page is invalid
the ``InvalidPage`` exception, but if you'd like more granularity, you can trap
either of the following exceptions:
-``PageNotAnInteger`` -- Raised when ``page()`` is given a value that isn't an integer.
+``PageNotAnInteger``
+ Raised when ``page()`` is given a value that isn't an integer.
-``EmptyPage`` -- Raised when ``page()`` is given a valid value but no objects exist on that page.
+``EmptyPage``
+ Raised when ``page()`` is given a valid value but no objects exist on that
+ page.
Both of the exceptions are subclasses of ``InvalidPage``, so you can handle
them both with a simple ``except InvalidPage``.
@@ -103,44 +143,43 @@ them both with a simple ``except InvalidPage``.
Methods
-------
-``has_next()`` -- Returns ``True`` if there's a next page.
+``has_next()``
+ Returns ``True`` if there's a next page.
-``has_previous()`` -- Returns ``True`` if there's a previous page.
+``has_previous()``
+ Returns ``True`` if there's a previous page.
-``has_other_pages()`` -- Returns ``True`` if there's a next *or* previous page.
+``has_other_pages()``
+ Returns ``True`` if there's a next *or* previous page.
-``next_page_number()`` -- Returns the next page number. Note that this is
-"dumb" and will return the next page number regardless of whether a subsequent
-page exists.
+``next_page_number()``
+ Returns the next page number. Note that this is "dumb" and will return the
+ next page number regardless of whether a subsequent page exists.
-``previous_page_number()`` -- Returns the previous page number. Note that this
-is "dumb" and will return the previous page number regardless of whether a
-previous page exists.
+``previous_page_number()``
+ Returns the previous page number. Note that this is "dumb" and will return
+ the previous page number regardless of whether a previous page exists.
-``start_index()`` -- Returns the 1-based index of the first object on the page,
-relative to all of the objects in the paginator's list. For example, when
-paginating a list of 5 objects with 2 objects per page, the second page's
-``start_index()`` would return ``3``.
+``start_index()``
+ Returns the 1-based index of the first object on the page, relative to all
+ of the objects in the paginator's list. For example, when paginating a list
+ of 5 objects with 2 objects per page, the second page's ``start_index()``
+ would return ``3``.
-``end_index()`` -- Returns the 1-based index of the last object on the page,
-relative to all of the objects in the paginator's list. For example, when
-paginating a list of 5 objects with 2 objects per page, the second page's
-``end_index()`` would return ``4``.
+``end_index()``
+ Returns the 1-based index of the last object on the page, relative to all
+ of the objects in the paginator's list. For example, when paginating a list
+ of 5 objects with 2 objects per page, the second page's ``end_index()``
+ would return ``4``.
Attributes
----------
-``object_list`` -- The list of objects on this page.
-
-``number`` -- The 1-based page number for this page.
-
-``paginator`` -- The associated ``Paginator`` object.
+``object_list``
+ The list of objects on this page.
-The legacy ``ObjectPaginator`` class
-====================================
+``number``
+ The 1-based page number for this page.
-The ``Paginator`` and ``Page`` classes are new in the Django development
-version, as of revision 7306. In previous versions, Django provided an
-``ObjectPaginator`` class that offered similar functionality but wasn't as
-convenient. This class still exists, for backwards compatibility, but Django
-now issues a ``DeprecationWarning`` if you try to use it.
+``paginator``
+ The associated ``Paginator`` object.
diff --git a/docs/release_notes_0.95.txt b/docs/release_notes_0.95.txt
index f2ecbb66e6..a61b10d567 100644
--- a/docs/release_notes_0.95.txt
+++ b/docs/release_notes_0.95.txt
@@ -99,7 +99,7 @@ Problem reports and getting help
================================
Need help resolving a problem with Django? The documentation in the
-distribution is also available online_ at the `Django website`_. The FAQ_
+distribution is also available online_ at the `Django Web site`_. The FAQ_
document is especially recommended, as it contains a number of issues that
come up time and again.
@@ -115,7 +115,7 @@ Django users and developers from around the world. Friendly people are usually
available at any hour of the day -- to help, or just to chat.
.. _online: http://www.djangoproject.com/documentation/0.95/
-.. _Django website: http://www.djangoproject.com/
+.. _Django Web site: http://www.djangoproject.com/
.. _FAQ: http://www.djangoproject.com/documentation/faq/
.. _django-users: http://groups.google.com/group/django-users
diff --git a/docs/release_notes_1.0_alpha.txt b/docs/release_notes_1.0_alpha.txt
new file mode 100644
index 0000000000..6fce66532e
--- /dev/null
+++ b/docs/release_notes_1.0_alpha.txt
@@ -0,0 +1,163 @@
+================================
+Django 1.0 alpha release notes
+================================
+
+Welcome to Django 1.0 alpha!
+
+This is the first in a series of preview/development releases leading
+up to the eventual release of Django 1.0, currently scheduled to take
+place in early September 2008. This release is primarily targeted at
+developers who are interested in testing the Django codebase and
+helping to identify and resolve bugs prior to the final 1.0 release.
+
+As such, this release is *not* intended for production use, and any
+such use is strongly discouraged.
+
+
+What's new in Django 1.0 alpha
+==============================
+
+Django's development trunk has been the site of nearly constant
+activity over the past year, with several major new features landing
+since the 0.96 release. Some of the highlights include:
+
+Refactored admin application (newforms-admin)
+ The Django administrative interface (``django.contrib.admin``) has
+ been completely refactored; admin definitions are now completely
+ decoupled from model definitions (no more ``class Admin``
+ declaration in models!), rewritten to use Django's new
+ form-handling library (introduced in the 0.96 release as
+ ``django.newforms``, and now available as simply ``django.forms``)
+ and redesigned with extensibility and customization in mind. Full
+ documentation for the admin application is available online in the
+ official Django documentation:
+
+ http://www.djangoproject.com/documentation/admin/
+
+Improved Unicode handling
+ Django's internals have been refactored to use Unicode throughout;
+ this drastically simplifies the task of dealing with
+ non-Western-European content and data in Django. Additionally,
+ utility functions have been provided to ease interoperability with
+ third-party libraries and systems which may or may not handle
+ Unicode gracefully. Details are available in Django's
+ Unicode-handling documentation:
+
+ http://www.djangoproject.com/documentation/unicode/
+
+An improved Django ORM
+ Django's object-relational mapper -- the component which provides
+ the mapping between Django model classes and your database, and
+ which mediates your database queries -- has been dramatically
+ improved by a massive refactoring. For most users of Django this
+ is backwards-compatible; the public-facing API for database
+ querying underwent a few minor changes, but most of the updates
+ took place in the ORM's internals. A guide to the changes,
+ including backwards-incompatible modifications and mentions of new
+ features opened up by this refactoring, is available on the Django
+ wiki:
+
+ http://code.djangoproject.com/wiki/QuerysetRefactorBranch
+
+Automatic escaping of template variables
+ To provide improved security against cross-site scripting (XSS)
+ vulnerabilities, Django's template system now automatically
+ escapes the output of variables. This behavior is configurable,
+ and allows both variables and larger template constructs to be
+ marked as safe (requiring no escaping) or unsafe (requiring
+ escaping). A full guide to this feature is in the documentation
+ for the Django template system:
+
+ http://www.djangoproject.com/documentation/templates/#automatic-html-escaping
+
+There are many more new features, many bugfixes and many enhancements
+to existing features from previous releases. The ``newforms`` library,
+for example, has undergone massive improvements including several
+useful add-ons in ``django.contrib`` which complement and build on
+Django's form-handling capabilities, and Django's file-uploading
+handlers have been refactored to allow finer-grained control over the
+uploading process as well as streaming uploads of large files.
+
+Along with these improvements and additions, we've made a number of
+of backwards-incompatible changes to the framework, as features have been
+fleshed out and APIs have been finalized for the 1.0 release. A
+complete guide to these changes will be available as part of the final
+Django 1.0 release, and a comprehensive list of backwards-incompatible
+changes is also available on the Django wiki for those who want to
+begin developing and testing their upgrade process:
+
+ http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+
+
+The Django 1.0 roadmap
+======================
+
+One of the primary goals of this alpha release is to focus attention
+on the remaining features to be implemented for Django 1.0, and on the
+bugs that need to be resolved before the final release. Following
+this release, we'll be conducting a series of sprints building up to a
+series of beta releases and a release-candidate stage, followed soon
+after by Django 1.0. The timeline is projected to be:
+
+* August 1, 2008: Sprint (based in Washington, DC, and online).
+
+* August 5, 2008: Django 1.0 beta 1 release. This will also constitute
+ the feature freeze for 1.0. Any feature to be included in 1.0 must
+ be completed and in trunk by this time.
+
+* August 8, 2008: Sprint (based in Lawrence, KS, and online).
+
+* August 12, 2008: Django 1.0 beta 2 release.
+
+* August 15, 2008: Sprint (based in Austin, TX, and online).
+
+* August 19, 2008: Django 1.0 release candidate 1.
+
+* August 22, 2008: Sprint (based in Portland, OR, and online).
+
+* August 26, 2008: Django 1.0 release candidate 2.
+
+* September 2, 2008: Django 1.0 final release. The official Django 1.0
+ release party will take place during the first-ever DjangoCon, to be
+ held in Mountain View, CA, September 6-7.
+
+Of course, like any estimated timeline, this is subject to change as
+requirements dictate. The latest information will always be available
+on the Django project wiki:
+
+ http://code.djangoproject.com/wiki/VersionOneRoadmap
+
+
+What you can do to help
+=======================
+
+In order to provide a high-quality 1.0 release, we need your
+help. Although this alpha release is, again, *not* intended for
+production use, you can help the Django team by trying out the alpha
+codebase in a safe test environment and reporting any bugs or issues
+you encounter. The Django ticket tracker is the central place to
+search for open issues:
+
+ http://code.djangoproject.com/timeline
+
+Please open new tickets if no existing ticket corresponds to a problem
+you're running into.
+
+Additionally, discussion of Django development, including progress
+toward the 1.0 release, takes place daily on the django-developers
+mailing list:
+
+ http://groups.google.com/group/django-developers
+
+...and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If
+you're interested in helping out with Django's development, feel free
+to join the discussions there.
+
+Django's online documentation also includes pointers on how to
+contribute to Django:
+
+ http://www.djangoproject.com/documentation/contributing/
+
+Contributions on any level -- developing code, writing
+documentation or simply triaging tickets and helping to test proposed
+bugfixes -- are always welcome and appreciated.
diff --git a/docs/request_response.txt b/docs/request_response.txt
index 54fc24df9e..9b3f6dd0e3 100644
--- a/docs/request_response.txt
+++ b/docs/request_response.txt
@@ -170,18 +170,6 @@ All attributes except ``session`` should be considered read-only.
Methods
-------
-``__getitem__(key)``
- Returns the GET/POST value for the given key, checking POST first, then
- GET. Raises ``KeyError`` if the key doesn't exist.
-
- This lets you use dictionary-accessing syntax on an ``HttpRequest``
- instance. Example: ``request["foo"]`` would return ``True`` if either
- ``request.POST`` or ``request.GET`` had a ``"foo"`` key.
-
-``has_key()``
- Returns ``True`` or ``False``, designating whether ``request.GET`` or
- ``request.POST`` has the given key.
-
``get_host()``
**New in Django development version**
diff --git a/docs/serialization.txt b/docs/serialization.txt
index 2a3e7038da..971103747c 100644
--- a/docs/serialization.txt
+++ b/docs/serialization.txt
@@ -2,13 +2,6 @@
Serializing Django objects
==========================
-.. note::
-
- This API is currently under heavy development and may change --
- perhaps drastically -- in the future.
-
- You have been warned.
-
Django's serialization framework provides a mechanism for "translating" Django
objects into other formats. Usually these other formats will be text-based and
used for sending Django objects over a wire, but it's possible for a
@@ -58,10 +51,10 @@ be serialized.
.. note::
- Depending on your model, you may find that it is not possible to deserialize
- a model that only serializes a subset of its fields. If a serialized object
- doesn't specify all the fields that are required by a model, the deserializer
- will not be able to save deserialized instances.
+ Depending on your model, you may find that it is not possible to
+ deserialize a model that only serializes a subset of its fields. If a
+ serialized object doesn't specify all the fields that are required by a
+ model, the deserializer will not be able to save deserialized instances.
Inherited Models
~~~~~~~~~~~~~~~~
@@ -75,13 +68,13 @@ However, if you have a model that uses `multi-table inheritance`_, you also
need to serialize all of the base classes for the model. This is because only
the fields that are locally defined on the model will be serialized. For
example, consider the following models::
-
+
class Place(models.Model):
name = models.CharField(max_length=50)
-
+
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
-
+
If you only serialize the Restaurant model::
data = serializers.serialize('xml', Restaurant.objects.all())
@@ -126,7 +119,8 @@ something like::
deserialized_object.save()
In other words, the usual use is to examine the deserialized objects to make
-sure that they are "appropriate" for saving before doing so. Of course, if you trust your data source you could just save the object and move on.
+sure that they are "appropriate" for saving before doing so. Of course, if you
+trust your data source you could just save the object and move on.
The Django object itself can be inspected as ``deserialized_object.object``.
diff --git a/docs/sessions.txt b/docs/sessions.txt
index 648832b85d..b5c9ba8394 100644
--- a/docs/sessions.txt
+++ b/docs/sessions.txt
@@ -65,10 +65,10 @@ you've configured your cache; see the `cache documentation`_ for details.
.. note::
You should probably only use cache-based sessions if you're using the
- memcached cache backend. The local memory and simple cache backends
- don't retain data long enough to be good choices, and it'll be faster
- to use file or database sessions directly instead of sending everything
- through the file or database cache backends.
+ Memcached cache backend. The local-memory cache backend doesn't retain data
+ long enough to be a good choice, and it'll be faster to use file or
+ database sessions directly instead of sending everything through the file
+ or database cache backends.
Using sessions in views
=======================
diff --git a/docs/settings.txt b/docs/settings.txt
index fbe23b5e88..1d1627d41e 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -537,8 +537,8 @@ FILE_UPLOAD_HANDLERS
Default::
- ("django.core.files.fileuploadhandler.MemoryFileUploadHandler",
- "django.core.files.fileuploadhandler.TemporaryFileUploadHandler",)
+ ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
A tuple of handlers to use for uploading. See `file uploads`_ for details.
@@ -563,7 +563,7 @@ Default: ``None``
The directory to store data temporarily while uploading files. If ``None``,
Django will use the standard temporary directory for the operating system. For
-example, this will default to '/tmp' on *nix-style operating systems.
+example, this will default to '/tmp' on \*nix-style operating systems.
See `file uploads`_ for details.
@@ -578,6 +578,16 @@ these paths should use Unix-style forward slashes, even on Windows. See
.. _Testing Django Applications: ../testing/
+FORCE_SCRIPT_NAME
+------------------
+
+Default: ``None``
+
+If not ``None``, this will be used as the value of the ``SCRIPT_NAME``
+environment variable in any HTTP request. This setting can be used to override
+the server-provided value of ``SCRIPT_NAME``, which may be a rewritten version
+of the preferred value or not supplied at all.
+
IGNORABLE_404_ENDS
------------------
diff --git a/docs/sitemaps.txt b/docs/sitemaps.txt
index 6a16e61879..3e7411c168 100644
--- a/docs/sitemaps.txt
+++ b/docs/sitemaps.txt
@@ -282,6 +282,10 @@ This will automatically generate a ``sitemap.xml`` file that references
both ``sitemap-flatpages.xml`` and ``sitemap-blog.xml``. The ``Sitemap``
classes and the ``sitemaps`` dict don't change at all.
+If one of your sitemaps is going to have more than 50,000 URLs you should
+create an index file. Your sitemap will be paginated and the index will
+reflect that.
+
Pinging Google
==============
diff --git a/docs/templates.txt b/docs/templates.txt
index 04a46580c5..587c5915f0 100644
--- a/docs/templates.txt
+++ b/docs/templates.txt
@@ -703,9 +703,9 @@ You can loop over a list in reverse by using ``{% for obj in list reversed %}``.
**New in Django development version**
If you need to loop over a list of lists, you can unpack the values
-in eachs sub-list into a set of known names. For example, if your context contains
-a list of (x,y) coordinates called ``points``, you could use the following
-to output the list of points::
+in each sub-list into individual variables. For example, if your context
+contains a list of (x,y) coordinates called ``points``, you could use the
+following to output the list of points::
{% for x, y in points %}
There is a point at {{ x }},{{ y }}
@@ -828,6 +828,19 @@ The 'ifchanged' block tag is used within a loop. It has two possible uses.
{% endifchanged %}
{% endfor %}
+The ``ifchanged`` tag also takes an optional ``{% else %}`` clause that will
+be displayed if the value has not changed::
+
+ {% for match in matches %}
+ <div style="background-color:
+ {% ifchanged match.ballot_id %}
+ {% cycle red,blue %}
+ {% else %}
+ grey
+ {% endifchanged %}
+ ">{{ match }}</div>
+ {% endfor %}
+
ifequal
~~~~~~~
@@ -1550,7 +1563,7 @@ For example::
{{ value|linebreaks }}
-If ``value`` is ``Joel\nis a slug``, the output will be ``<p>Joe<br>is a
+If ``value`` is ``Joel\nis a slug``, the output will be ``<p>Joel<br>is a
slug</p>``.
linebreaksbr
@@ -1592,9 +1605,9 @@ For example::
{{ value|make_list }}
-If ``value`` is the string ``"Joe"``, the output would be the list
-``[u'J', u'o', u'e']``. If ``value`` is ``123``, the output will be the list
-``[1, 2, 3]``.
+If ``value`` is the string ``"Joel"``, the output would be the list
+``[u'J', u'o', u'e', u'l']``. If ``value`` is ``123``, the output will be the
+list ``[1, 2, 3]``.
phone2numeric
~~~~~~~~~~~~~
@@ -1945,7 +1958,7 @@ information.
django.contrib.webdesign
------------------------
-A collection of template tags that can be useful while designing a website,
+A collection of template tags that can be useful while designing a Web site,
such as a generator of Lorem Ipsum text. See the `webdesign documentation`_.
.. _webdesign documentation: ../webdesign/
diff --git a/docs/testing.txt b/docs/testing.txt
index bb091bfd6b..c9b23c2948 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -25,13 +25,6 @@ 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
- slightly before the next official Django release.
-
- (That's *no* excuse not to write tests, though!)
-
Writing tests
=============
@@ -58,7 +51,7 @@ frameworks are:
import unittest
- class MyFuncTestCase(unittest.TestCase)
+ class MyFuncTestCase(unittest.TestCase):
def testBasic(self):
a = ['larry', 'curly', 'moe']
self.assertEquals(my_func(a, 0), 'larry')
@@ -815,12 +808,12 @@ In order to provide a reliable URL space for your test,
configuration for the duration of the execution of a test suite.
If your ``TestCase`` instance defines an ``urls`` attribute, the
``TestCase`` will use the value of that attribute as the ``ROOT_URLCONF``
-for the duration of that test.
+for the duration of that test.
For example::
from django.test import TestCase
-
+
class TestMyViews(TestCase):
urls = 'myapp.test_urls'
@@ -864,7 +857,7 @@ useful for testing Web applications:
rendered on the form.
``form`` is the name the ``Form`` instance was given in the template
- context. Note that this works only for ``newforms.Form`` instances, not
+ context. Note that this works only for ``forms.Form`` instances, not
``oldforms.Form`` instances.
``field`` is the name of the field on the form to check. If ``field``
diff --git a/docs/tutorial02.txt b/docs/tutorial02.txt
index c69fd1459f..7ed04be643 100644
--- a/docs/tutorial02.txt
+++ b/docs/tutorial02.txt
@@ -29,12 +29,36 @@ The Django admin site is not activated by default -- it's an opt-in thing. To
activate the admin site for your installation, do these three things:
* Add ``"django.contrib.admin"`` to your ``INSTALLED_APPS`` setting.
+
* Run ``python manage.py syncdb``. Since you have added a new application
to ``INSTALLED_APPS``, the database tables need to be updated.
+
* Edit your ``mysite/urls.py`` file and uncomment the lines below the
"Uncomment this for admin:" comments. This file is a URLconf; we'll dig
into URLconfs in the next tutorial. For now, all you need to know is that
- it maps URL roots to applications.
+ it maps URL roots to applications. In the end, you should have a
+ ``urls.py`` file that looks like this:
+
+ .. parsed-literal::
+
+ from django.conf.urls.defaults import *
+
+ # Uncomment the next two lines to enable the admin:
+ **from django.contrib import admin**
+ **admin.autodiscover()**
+
+ urlpatterns = patterns('',
+ # Example:
+ # (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
+
+ # Uncomment the next line to enable admin documentation:
+ # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+ # Uncomment the next line for to enable the admin:
+ **(r'^admin/(.*)', admin.site.root),**
+ )
+
+ (The bold lines are the ones that needed to be uncommented.)
Start the development server
============================
@@ -192,7 +216,7 @@ aren't commonly used::
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
- ('Date information', {'fields': ['pub_date'], 'classes': 'pub_date'}),
+ ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin09.png
@@ -242,7 +266,7 @@ registration code to read::
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
- ('Date information', {'fields': ['pub_date'], 'classes': 'pub_date'}),
+ ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt
index d49a417dcf..2ac106229f 100644
--- a/docs/tutorial03.txt
+++ b/docs/tutorial03.txt
@@ -441,11 +441,11 @@ Here's what happens if a user goes to "/polls/34/" in this system:
* Django will find the match at ``'^polls/'``
* It will strip off the matching text (``"polls/"``) and send the remaining
- text -- ``"34/"`` -- to the 'mysite.polls.urls' urlconf for
+ text -- ``"34/"`` -- to the 'mysite.polls.urls' URLconf for
further processing.
Now that we've decoupled that, we need to decouple the
-'mysite.polls.urls' urlconf by removing the leading "polls/" from each
+'mysite.polls.urls' URLconf by removing the leading "polls/" from each
line::
urlpatterns = patterns('mysite.polls.views',
diff --git a/docs/upload_handling.txt b/docs/upload_handling.txt
index e11d0d94f0..c0e8605686 100644
--- a/docs/upload_handling.txt
+++ b/docs/upload_handling.txt
@@ -17,7 +17,7 @@ Basic file uploads
Consider a simple form containing a ``FileField``::
- from django import newforms as forms
+ from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
@@ -48,7 +48,7 @@ something like::
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
-.. _binding uploaded files to a form: ../newforms/#binding-uploaded-files-to-a- form
+.. _binding uploaded files to a form: ../forms/#binding-uploaded-files-to-a- form
Notice that we have to pass ``request.FILES`` into the form's constructor; this
is how file data gets bound into a form.
@@ -79,10 +79,10 @@ methods to access the uploaded content:
In practice, it's often easiest simply to use ``chunks()`` all the time;
see the example below.
- ``UploadedFile.file_name``
+ ``UploadedFile.name``
The name of the uploaded file (e.g. ``my_file.txt``).
- ``UploadedFile.file_size``
+ ``UploadedFile.size``
The size, in bytes, of the uploaded file.
There are a few other methods and attributes available on ``UploadedFile``
@@ -169,10 +169,10 @@ All ``UploadedFile`` objects define the following methods/attributes:
Returns ``True`` if you can expect more than one chunk when calling
``UploadedFile.chunks(self, chunk_size)``.
- ``UploadedFile.file_size``
+ ``UploadedFile.size``
The size, in bytes, of the uploaded file.
- ``UploadedFile.file_name``
+ ``UploadedFile.name``
The name of the uploaded file as provided by the user.
``UploadedFile.content_type``
diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt
index 7d67cd5b53..266e4a5799 100644
--- a/docs/url_dispatch.txt
+++ b/docs/url_dispatch.txt
@@ -373,7 +373,7 @@ Including other URLconfs
At any point, your ``urlpatterns`` can "include" other URLconf modules. This
essentially "roots" a set of URLs below other ones.
-For example, here's the URLconf for the `Django website`_ itself. It includes a
+For example, here's the URLconf for the `Django Web site`_ itself. It includes a
number of other URLconfs::
from django.conf.urls.defaults import *
@@ -390,7 +390,7 @@ Django encounters ``include()``, it chops off whatever part of the URL matched
up to that point and sends the remaining string to the included URLconf for
further processing.
-.. _`Django website`: http://www.djangoproject.com/
+.. _`Django Web site`: http://www.djangoproject.com/
Captured parameters
-------------------
diff --git a/setup.py b/setup.py
index 081cdb4c4b..c5ae133b34 100644
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,27 @@
from distutils.core import setup
+from distutils.command.install_data import install_data
from distutils.command.install import INSTALL_SCHEMES
import os
import sys
+class osx_install_data(install_data):
+ # On MacOS, the platform-specific lib dir is /System/Library/Framework/Python/.../
+ # which is wrong. Python 2.5 supplied with MacOS 10.5 has an Apple-specific fix
+ # for this in distutils.command.install_data#306. It fixes install_lib but not
+ # install_data, which is why we roll our own install_data class.
+
+ def finalize_options(self):
+ # By the time finalize_options is called, install.install_lib is set to the
+ # fixed directory, so we set the installdir to install_lib. The
+ # install_data class uses ('install_data', 'install_dir') instead.
+ self.set_undefined_options('install', ('install_lib', 'install_dir'))
+ install_data.finalize_options(self)
+
+if sys.platform == "darwin":
+ cmdclasses = {'install_data': osx_install_data}
+else:
+ cmdclasses = {'install_data': install_data}
+
def fullsplit(path, result=None):
"""
Split a pathname into components (the opposite of os.path.join) in a
@@ -55,6 +74,7 @@ setup(
author_email = 'foundation@djangoproject.com',
description = 'A high-level Python Web framework that encourages rapid development and clean, pragmatic design.',
packages = packages,
+ cmdclass = cmdclasses,
data_files = data_files,
scripts = ['django/bin/django-admin.py'],
)
diff --git a/tests/modeltests/choices/models.py b/tests/modeltests/choices/models.py
index 550e655e46..e378260598 100644
--- a/tests/modeltests/choices/models.py
+++ b/tests/modeltests/choices/models.py
@@ -36,4 +36,15 @@ __test__ = {'API_TESTS':"""
u'Male'
>>> s.get_gender_display()
u'Female'
+
+# If the value for the field doesn't correspond to a valid choice,
+# the value itself is provided as a display value.
+>>> a.gender = ''
+>>> a.get_gender_display()
+u''
+
+>>> a.gender = 'U'
+>>> a.get_gender_display()
+u'U'
+
"""}
diff --git a/tests/modeltests/custom_methods/models.py b/tests/modeltests/custom_methods/models.py
index b0ca4131a5..d420871373 100644
--- a/tests/modeltests/custom_methods/models.py
+++ b/tests/modeltests/custom_methods/models.py
@@ -31,7 +31,8 @@ class Article(models.Model):
SELECT id, headline, pub_date
FROM custom_methods_article
WHERE pub_date = %s
- AND id != %s""", [str(self.pub_date), self.id])
+ AND id != %s""", [connection.ops.value_to_db_date(self.pub_date),
+ self.id])
# The asterisk in "(*row)" tells Python to expand the list into
# positional arguments to Article().
return [self.__class__(*row) for row in cursor.fetchall()]
diff --git a/tests/modeltests/delete/models.py b/tests/modeltests/delete/models.py
index f5b423e9ff..49aab1fb1b 100644
--- a/tests/modeltests/delete/models.py
+++ b/tests/modeltests/delete/models.py
@@ -42,7 +42,9 @@ class F(DefaultRepr, models.Model):
__test__ = {'API_TESTS': """
-# First, some tests for the datastructure we use
+### Tests for models A,B,C,D ###
+
+## First, test the CollectedObjects data structure directly
>>> from django.db.models.query import CollectedObjects
@@ -72,6 +74,7 @@ Traceback (most recent call last):
CyclicDependency: There is a cyclic dependency of items to be processed.
+## Second, test the usage of CollectedObjects by Model.delete()
# Due to the way that transactions work in the test harness,
# doing m.delete() here can work but fail in a real situation,
@@ -84,14 +87,21 @@ CyclicDependency: There is a cyclic dependency of items to be processed.
# then try again with a known 'tricky' order. Slightly naughty
# access to internals here :-)
+# If implementation changes, then the tests may need to be simplified:
+# - remove the lines that set the .keyOrder and clear the related
+# object caches
+# - remove the second set of tests (with a2, b2 etc)
+
>>> from django.db.models.loading import cache
+>>> def clear_rel_obj_caches(models):
+... for m in models:
+... if hasattr(m._meta, '_related_objects_cache'):
+... del m._meta._related_objects_cache
+
# Nice order
>>> cache.app_models['delete'].keyOrder = ['a', 'b', 'c', 'd']
->>> del A._meta._related_objects_cache
->>> del B._meta._related_objects_cache
->>> del C._meta._related_objects_cache
->>> del D._meta._related_objects_cache
+>>> clear_rel_obj_caches([A, B, C, D])
>>> a1 = A()
>>> a1.save()
@@ -110,10 +120,7 @@ CyclicDependency: There is a cyclic dependency of items to be processed.
# Same again with a known bad order
>>> cache.app_models['delete'].keyOrder = ['d', 'c', 'b', 'a']
->>> del A._meta._related_objects_cache
->>> del B._meta._related_objects_cache
->>> del C._meta._related_objects_cache
->>> del D._meta._related_objects_cache
+>>> clear_rel_obj_caches([A, B, C, D])
>>> a2 = A()
>>> a2.save()
@@ -130,7 +137,9 @@ CyclicDependency: There is a cyclic dependency of items to be processed.
[<class 'modeltests.delete.models.D'>, <class 'modeltests.delete.models.C'>, <class 'modeltests.delete.models.B'>, <class 'modeltests.delete.models.A'>]
>>> a2.delete()
-# Tests for nullable related fields
+### Tests for models E,F - nullable related fields ###
+
+## First, test the CollectedObjects data structure directly
>>> g = CollectedObjects()
>>> g.add("key1", 1, "item1", None)
@@ -142,6 +151,8 @@ True
>>> g.ordered_keys()
['key1', 'key2']
+## Second, test the usage of CollectedObjects by Model.delete()
+
>>> e1 = E()
>>> e1.save()
>>> f1 = F(e=e1)
diff --git a/tests/modeltests/generic_relations/models.py b/tests/modeltests/generic_relations/models.py
index ff86823d07..d6a7c38e63 100644
--- a/tests/modeltests/generic_relations/models.py
+++ b/tests/modeltests/generic_relations/models.py
@@ -27,11 +27,32 @@ class TaggedItem(models.Model):
def __unicode__(self):
return self.tag
+class Comparison(models.Model):
+ """
+ A model that tests having multiple GenericForeignKeys
+ """
+ comparative = models.CharField(max_length=50)
+
+ content_type1 = models.ForeignKey(ContentType, related_name="comparative1_set")
+ object_id1 = models.PositiveIntegerField()
+
+ content_type2 = models.ForeignKey(ContentType, related_name="comparative2_set")
+ object_id2 = models.PositiveIntegerField()
+
+ first_obj = generic.GenericForeignKey(ct_field="content_type1", fk_field="object_id1")
+ other_obj = generic.GenericForeignKey(ct_field="content_type2", fk_field="object_id2")
+
+ def __unicode__(self):
+ return u"%s is %s than %s" % (self.first_obj, self.comparative, self.other_obj)
+
class Animal(models.Model):
common_name = models.CharField(max_length=150)
latin_name = models.CharField(max_length=150)
tags = generic.GenericRelation(TaggedItem)
+ comparisons = generic.GenericRelation(Comparison,
+ object_id_field="object_id1",
+ content_type_field="content_type1")
def __unicode__(self):
return self.common_name
@@ -136,4 +157,38 @@ __test__ = {'API_TESTS':"""
>>> Animal.objects.filter(tags__content_type=ctype)
[<Animal: Platypus>]
+# Simple tests for multiple GenericForeignKeys
+# only uses one model, since the above tests should be sufficient.
+>>> tiger, cheetah, bear = Animal(common_name="tiger"), Animal(common_name="cheetah"), Animal(common_name="bear")
+>>> for o in [tiger, cheetah, bear]: o.save()
+
+# Create directly
+>>> Comparison(first_obj=cheetah, other_obj=tiger, comparative="faster").save()
+>>> Comparison(first_obj=tiger, other_obj=cheetah, comparative="cooler").save()
+
+# Create using GenericRelation
+>>> tiger.comparisons.create(other_obj=bear, comparative="cooler")
+<Comparison: tiger is cooler than bear>
+>>> tiger.comparisons.create(other_obj=cheetah, comparative="stronger")
+<Comparison: tiger is stronger than cheetah>
+
+>>> cheetah.comparisons.all()
+[<Comparison: cheetah is faster than tiger>]
+
+# Filtering works
+>>> tiger.comparisons.filter(comparative="cooler")
+[<Comparison: tiger is cooler than cheetah>, <Comparison: tiger is cooler than bear>]
+
+# Filtering and deleting works
+>>> subjective = ["cooler"]
+>>> tiger.comparisons.filter(comparative__in=subjective).delete()
+>>> Comparison.objects.all()
+[<Comparison: cheetah is faster than tiger>, <Comparison: tiger is stronger than cheetah>]
+
+# If we delete cheetah, Comparisons with cheetah as 'first_obj' will be deleted
+# since Animal has an explicit GenericRelation to Comparison through first_obj.
+# Comparisons with cheetah as 'other_obj' will not be deleted.
+>>> cheetah.delete()
+>>> Comparison.objects.all()
+[<Comparison: tiger is stronger than None>]
"""}
diff --git a/tests/modeltests/invalid_models/models.py b/tests/modeltests/invalid_models/models.py
index 48e574af48..470afff4fe 100644
--- a/tests/modeltests/invalid_models/models.py
+++ b/tests/modeltests/invalid_models/models.py
@@ -110,6 +110,63 @@ class Car(models.Model):
class MissingRelations(models.Model):
rel1 = models.ForeignKey("Rel1")
rel2 = models.ManyToManyField("Rel2")
+
+class MissingManualM2MModel(models.Model):
+ name = models.CharField(max_length=5)
+ missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
+
+class Person(models.Model):
+ name = models.CharField(max_length=5)
+
+class Group(models.Model):
+ name = models.CharField(max_length=5)
+ primary = models.ManyToManyField(Person, through="Membership", related_name="primary")
+ secondary = models.ManyToManyField(Person, through="Membership", related_name="secondary")
+ tertiary = models.ManyToManyField(Person, through="RelationshipDoubleFK", related_name="tertiary")
+
+class GroupTwo(models.Model):
+ name = models.CharField(max_length=5)
+ primary = models.ManyToManyField(Person, through="Membership")
+ secondary = models.ManyToManyField(Group, through="MembershipMissingFK")
+
+class Membership(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ not_default_or_null = models.CharField(max_length=5)
+
+class MembershipMissingFK(models.Model):
+ person = models.ForeignKey(Person)
+
+class PersonSelfRefM2M(models.Model):
+ name = models.CharField(max_length=5)
+ friends = models.ManyToManyField('self', through="Relationship")
+ too_many_friends = models.ManyToManyField('self', through="RelationshipTripleFK")
+
+class PersonSelfRefM2MExplicit(models.Model):
+ name = models.CharField(max_length=5)
+ friends = models.ManyToManyField('self', through="ExplicitRelationship", symmetrical=True)
+
+class Relationship(models.Model):
+ first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
+ second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
+ date_added = models.DateTimeField()
+
+class ExplicitRelationship(models.Model):
+ first = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_from_set")
+ second = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_to_set")
+ date_added = models.DateTimeField()
+
+class RelationshipTripleFK(models.Model):
+ first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set_2")
+ second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set_2")
+ third = models.ForeignKey(PersonSelfRefM2M, related_name="too_many_by_far")
+ date_added = models.DateTimeField()
+
+class RelationshipDoubleFK(models.Model):
+ first = models.ForeignKey(Person, related_name="first_related_name")
+ second = models.ForeignKey(Person, related_name="second_related_name")
+ third = models.ForeignKey(Group, related_name="rel_to_set")
+ date_added = models.DateTimeField()
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute.
invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
@@ -195,4 +252,12 @@ invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_3' clashes wi
invalid_models.selfclashm2m: Reverse query name for m2m field 'm2m_4' clashes with field 'SelfClashM2M.selfclashm2m'. Add a related_name argument to the definition for 'm2m_4'.
invalid_models.missingrelations: 'rel2' has m2m relation with model Rel2, which has not been installed
invalid_models.missingrelations: 'rel1' has relation with model Rel1, which has not been installed
+invalid_models.grouptwo: 'primary' has a manually-defined m2m relation through model Membership, which does not have foreign keys to Person and GroupTwo
+invalid_models.grouptwo: 'secondary' has a manually-defined m2m relation through model MembershipMissingFK, which does not have foreign keys to Group and GroupTwo
+invalid_models.missingmanualm2mmodel: 'missing_m2m' specifies an m2m relation through model MissingM2MModel, which has not been installed
+invalid_models.group: The model Group has two manually-defined m2m relations through the model Membership, which is not permitted. Please consider using an extra field on your intermediary model instead.
+invalid_models.group: Intermediary model RelationshipDoubleFK has more than one foreign key to Person, which is ambiguous and is not permitted.
+invalid_models.personselfrefm2m: Many-to-many fields with intermediate tables cannot be symmetrical.
+invalid_models.personselfrefm2m: Intermediary model RelationshipTripleFK has more than two foreign keys to PersonSelfRefM2M, which is ambiguous and is not permitted.
+invalid_models.personselfrefm2mexplicit: Many-to-many fields with intermediate tables cannot be symmetrical.
"""
diff --git a/tests/modeltests/m2m_through/__init__.py b/tests/modeltests/m2m_through/__init__.py
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/tests/modeltests/m2m_through/__init__.py
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/modeltests/m2m_through/models.py b/tests/modeltests/m2m_through/models.py
new file mode 100644
index 0000000000..fa9fa714a5
--- /dev/null
+++ b/tests/modeltests/m2m_through/models.py
@@ -0,0 +1,337 @@
+from django.db import models
+from datetime import datetime
+
+# M2M described on one of the models
+class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ class Meta:
+ ordering = ('name',)
+
+ def __unicode__(self):
+ return self.name
+
+class Group(models.Model):
+ name = models.CharField(max_length=128)
+ members = models.ManyToManyField(Person, through='Membership')
+ custom_members = models.ManyToManyField(Person, through='CustomMembership', related_name="custom")
+ nodefaultsnonulls = models.ManyToManyField(Person, through='TestNoDefaultsOrNulls', related_name="testnodefaultsnonulls")
+
+ class Meta:
+ ordering = ('name',)
+
+ def __unicode__(self):
+ return self.name
+
+class Membership(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ date_joined = models.DateTimeField(default=datetime.now)
+ invite_reason = models.CharField(max_length=64, null=True)
+
+ class Meta:
+ ordering = ('date_joined', 'invite_reason', 'group')
+
+ def __unicode__(self):
+ return "%s is a member of %s" % (self.person.name, self.group.name)
+
+class CustomMembership(models.Model):
+ person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name")
+ group = models.ForeignKey(Group)
+ weird_fk = models.ForeignKey(Membership, null=True)
+ date_joined = models.DateTimeField(default=datetime.now)
+
+ def __unicode__(self):
+ return "%s is a member of %s" % (self.person.name, self.group.name)
+
+ class Meta:
+ db_table = "test_table"
+
+class TestNoDefaultsOrNulls(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ nodefaultnonull = models.CharField(max_length=5)
+
+class PersonSelfRefM2M(models.Model):
+ name = models.CharField(max_length=5)
+ friends = models.ManyToManyField('self', through="Friendship", symmetrical=False)
+
+ def __unicode__(self):
+ return self.name
+
+class Friendship(models.Model):
+ first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
+ second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
+ date_friended = models.DateTimeField()
+
+__test__ = {'API_TESTS':"""
+>>> from datetime import datetime
+
+### Creation and Saving Tests ###
+
+>>> bob = Person.objects.create(name='Bob')
+>>> jim = Person.objects.create(name='Jim')
+>>> jane = Person.objects.create(name='Jane')
+>>> rock = Group.objects.create(name='Rock')
+>>> roll = Group.objects.create(name='Roll')
+
+# We start out by making sure that the Group 'rock' has no members.
+>>> rock.members.all()
+[]
+
+# To make Jim a member of Group Rock, simply create a Membership object.
+>>> m1 = Membership.objects.create(person=jim, group=rock)
+
+# We can do the same for Jane and Rock.
+>>> m2 = Membership.objects.create(person=jane, group=rock)
+
+# Let's check to make sure that it worked. Jane and Jim should be members of Rock.
+>>> rock.members.all()
+[<Person: Jane>, <Person: Jim>]
+
+# Now we can add a bunch more Membership objects to test with.
+>>> m3 = Membership.objects.create(person=bob, group=roll)
+>>> m4 = Membership.objects.create(person=jim, group=roll)
+>>> m5 = Membership.objects.create(person=jane, group=roll)
+
+# We can get Jim's Group membership as with any ForeignKey.
+>>> jim.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+# Querying the intermediary model works like normal.
+# In this case we get Jane's membership to Rock.
+>>> m = Membership.objects.get(person=jane, group=rock)
+>>> m
+<Membership: Jane is a member of Rock>
+
+# Now we set some date_joined dates for further testing.
+>>> m2.invite_reason = "She was just awesome."
+>>> m2.date_joined = datetime(2006, 1, 1)
+>>> m2.save()
+
+>>> m5.date_joined = datetime(2004, 1, 1)
+>>> m5.save()
+
+>>> m3.date_joined = datetime(2004, 1, 1)
+>>> m3.save()
+
+# It's not only get that works. Filter works like normal as well.
+>>> Membership.objects.filter(person=jim)
+[<Membership: Jim is a member of Rock>, <Membership: Jim is a member of Roll>]
+
+
+### Forward Descriptors Tests ###
+
+# Due to complications with adding via an intermediary model,
+# the add method is not provided.
+>>> rock.members.add(bob)
+Traceback (most recent call last):
+...
+AttributeError: 'ManyRelatedManager' object has no attribute 'add'
+
+# Create is also disabled as it suffers from the same problems as add.
+>>> rock.members.create(name='Anne')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Remove has similar complications, and is not provided either.
+>>> rock.members.remove(jim)
+Traceback (most recent call last):
+...
+AttributeError: 'ManyRelatedManager' object has no attribute 'remove'
+
+# Here we back up the list of all members of Rock.
+>>> backup = list(rock.members.all())
+
+# ...and we verify that it has worked.
+>>> backup
+[<Person: Jane>, <Person: Jim>]
+
+# The clear function should still work.
+>>> rock.members.clear()
+
+# Now there will be no members of Rock.
+>>> rock.members.all()
+[]
+
+# Assignment should not work with models specifying a through model for many of
+# the same reasons as adding.
+>>> rock.members = backup
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Let's re-save those instances that we've cleared.
+>>> m1.save()
+>>> m2.save()
+
+# Verifying that those instances were re-saved successfully.
+>>> rock.members.all()
+[<Person: Jane>, <Person: Jim>]
+
+
+### Reverse Descriptors Tests ###
+
+# Due to complications with adding via an intermediary model,
+# the add method is not provided.
+>>> bob.group_set.add(rock)
+Traceback (most recent call last):
+...
+AttributeError: 'ManyRelatedManager' object has no attribute 'add'
+
+# Create is also disabled as it suffers from the same problems as add.
+>>> bob.group_set.create(name='Funk')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Remove has similar complications, and is not provided either.
+>>> jim.group_set.remove(rock)
+Traceback (most recent call last):
+...
+AttributeError: 'ManyRelatedManager' object has no attribute 'remove'
+
+# Here we back up the list of all of Jim's groups.
+>>> backup = list(jim.group_set.all())
+>>> backup
+[<Group: Rock>, <Group: Roll>]
+
+# The clear function should still work.
+>>> jim.group_set.clear()
+
+# Now Jim will be in no groups.
+>>> jim.group_set.all()
+[]
+
+# Assignment should not work with models specifying a through model for many of
+# the same reasons as adding.
+>>> jim.group_set = backup
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Let's re-save those instances that we've cleared.
+>>> m1.save()
+>>> m4.save()
+
+# Verifying that those instances were re-saved successfully.
+>>> jim.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+### Custom Tests ###
+
+# Let's see if we can query through our second relationship.
+>>> rock.custom_members.all()
+[]
+
+# We can query in the opposite direction as well.
+>>> bob.custom.all()
+[]
+
+# Let's create some membership objects in this custom relationship.
+>>> cm1 = CustomMembership.objects.create(person=bob, group=rock)
+>>> cm2 = CustomMembership.objects.create(person=jim, group=rock)
+
+# If we get the number of people in Rock, it should be both Bob and Jim.
+>>> rock.custom_members.all()
+[<Person: Bob>, <Person: Jim>]
+
+# Bob should only be in one custom group.
+>>> bob.custom.all()
+[<Group: Rock>]
+
+# Let's make sure our new descriptors don't conflict with the FK related_name.
+>>> bob.custom_person_related_name.all()
+[<CustomMembership: Bob is a member of Rock>]
+
+### SELF-REFERENTIAL TESTS ###
+
+# Let's first create a person who has no friends.
+>>> tony = PersonSelfRefM2M.objects.create(name="Tony")
+>>> tony.friends.all()
+[]
+
+# Now let's create another person for Tony to be friends with.
+>>> chris = PersonSelfRefM2M.objects.create(name="Chris")
+>>> f = Friendship.objects.create(first=tony, second=chris, date_friended=datetime.now())
+
+# Tony should now show that Chris is his friend.
+>>> tony.friends.all()
+[<PersonSelfRefM2M: Chris>]
+
+# But we haven't established that Chris is Tony's Friend.
+>>> chris.friends.all()
+[]
+
+# So let's do that now.
+>>> f2 = Friendship.objects.create(first=chris, second=tony, date_friended=datetime.now())
+
+# Having added Chris as a friend, let's make sure that his friend set reflects
+# that addition.
+>>> chris.friends.all()
+[<PersonSelfRefM2M: Tony>]
+
+# Chris gets mad and wants to get rid of all of his friends.
+>>> chris.friends.clear()
+
+# Now he should not have any more friends.
+>>> chris.friends.all()
+[]
+
+# Since this isn't a symmetrical relation, Tony's friend link still exists.
+>>> tony.friends.all()
+[<PersonSelfRefM2M: Chris>]
+
+
+
+### QUERY TESTS ###
+
+# We can query for the related model by using its attribute name (members, in
+# this case).
+>>> Group.objects.filter(members__name='Bob')
+[<Group: Roll>]
+
+# To query through the intermediary model, we specify its model name.
+# In this case, membership.
+>>> Group.objects.filter(membership__invite_reason="She was just awesome.")
+[<Group: Rock>]
+
+# If we want to query in the reverse direction by the related model, use its
+# model name (group, in this case).
+>>> Person.objects.filter(group__name="Rock")
+[<Person: Jane>, <Person: Jim>]
+
+# If the m2m field has specified a related_name, using that will work.
+>>> Person.objects.filter(custom__name="Rock")
+[<Person: Bob>, <Person: Jim>]
+
+# To query through the intermediary model in the reverse direction, we again
+# specify its model name (membership, in this case).
+>>> Person.objects.filter(membership__invite_reason="She was just awesome.")
+[<Person: Jane>]
+
+# Let's see all of the groups that Jane joined after 1 Jan 2005:
+>>> Group.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__person =jane)
+[<Group: Rock>]
+
+# Queries also work in the reverse direction: Now let's see all of the people
+# that have joined Rock since 1 Jan 2005:
+>>> Person.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__group=rock)
+[<Person: Jane>, <Person: Jim>]
+
+# Conceivably, queries through membership could return correct, but non-unique
+# querysets. To demonstrate this, we query for all people who have joined a
+# group after 2004:
+>>> Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1))
+[<Person: Jane>, <Person: Jim>, <Person: Jim>]
+
+# Jim showed up twice, because he joined two groups ('Rock', and 'Roll'):
+>>> [(m.person.name, m.group.name) for m in
+... Membership.objects.filter(date_joined__gt=datetime(2004, 1, 1))]
+[(u'Jane', u'Rock'), (u'Jim', u'Rock'), (u'Jim', u'Roll')]
+
+# QuerySet's distinct() method can correct this problem.
+>>> Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)).distinct()
+[<Person: Jane>, <Person: Jim>]
+"""} \ No newline at end of file
diff --git a/tests/modeltests/many_to_one/models.py b/tests/modeltests/many_to_one/models.py
index 081cffb807..2dd1226e97 100644
--- a/tests/modeltests/many_to_one/models.py
+++ b/tests/modeltests/many_to_one/models.py
@@ -46,8 +46,12 @@ __test__ = {'API_TESTS':"""
# Article objects have access to their related Reporter objects.
>>> r = a.reporter
+
+# These are strings instead of unicode strings because that's what was used in
+# the creation of this reporter (and we haven't refreshed the data from the
+# database, which always returns unicode strings).
>>> r.first_name, r.last_name
-(u'John', u'Smith')
+('John', 'Smith')
# Create an Article via the Reporter object.
>>> new_article = r.article_set.create(headline="John's second story", pub_date=datetime(2005, 7, 29))
@@ -176,7 +180,7 @@ False
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]
# You can also use a queryset instead of a literal list of instances.
-# The queryset must be reduced to a list of values using values(),
+# The queryset must be reduced to a list of values using values(),
# then converted into a query
>>> Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John').values('pk').query).distinct()
[<Article: John's second story>, <Article: This is a test>]
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index cc9efd0f94..be2a8ba835 100644
--- a/tests/modeltests/model_forms/models.py
+++ b/tests/modeltests/model_forms/models.py
@@ -69,8 +69,10 @@ class ImageFile(models.Model):
description = models.CharField(max_length=20)
try:
# If PIL is available, try testing PIL.
- # Otherwise, it's equivalent to TextFile above.
- import Image
+ # Checking for the existence of Image is enough for CPython, but
+ # for PyPy, you need to check for the underlying modules
+ # If PIL is not available, this test is equivalent to TextFile above.
+ import Image, _imaging
image = models.ImageField(upload_to=tempfile.gettempdir())
except ImportError:
image = models.FileField(upload_to=tempfile.gettempdir())
diff --git a/tests/modeltests/model_formsets/models.py b/tests/modeltests/model_formsets/models.py
index 5958b8c27a..5b66d1560b 100644
--- a/tests/modeltests/model_formsets/models.py
+++ b/tests/modeltests/model_formsets/models.py
@@ -1,8 +1,16 @@
from django.db import models
+try:
+ sorted
+except NameError:
+ from django.utils.itercompat import sorted
+
class Author(models.Model):
name = models.CharField(max_length=100)
+ class Meta:
+ ordering = ('name',)
+
def __unicode__(self):
return self.name
@@ -17,10 +25,14 @@ class AuthorMeeting(models.Model):
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
created = models.DateField(editable=False)
-
+
def __unicode__(self):
return self.name
+class CustomPrimaryKey(models.Model):
+ my_pk = models.CharField(max_length=10, primary_key=True)
+ some_field = models.CharField(max_length=100)
+
__test__ = {'API_TESTS': """
@@ -41,7 +53,6 @@ __test__ = {'API_TESTS': """
>>> data = {
... 'form-TOTAL_FORMS': '3', # the number of forms rendered
... 'form-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'form-MAX_FORMS': '0', # the max number of forms
... 'form-0-name': 'Charles Baudelaire',
... 'form-1-name': 'Arthur Rimbaud',
... 'form-2-name': '',
@@ -79,7 +90,6 @@ them in alphabetical order by name.
>>> data = {
... 'form-TOTAL_FORMS': '3', # the number of forms rendered
... 'form-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'form-MAX_FORMS': '0', # the max number of forms
... 'form-0-id': '2',
... 'form-0-name': 'Arthur Rimbaud',
... 'form-1-id': '1',
@@ -123,7 +133,6 @@ deltetion, make sure we don't save that form.
>>> data = {
... 'form-TOTAL_FORMS': '4', # the number of forms rendered
... 'form-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'form-MAX_FORMS': '0', # the max number of forms
... 'form-0-id': '2',
... 'form-0-name': 'Arthur Rimbaud',
... 'form-1-id': '1',
@@ -153,7 +162,6 @@ Let's edit a record to ensure save only returns that one record.
>>> data = {
... 'form-TOTAL_FORMS': '4', # the number of forms rendered
... 'form-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'form-MAX_FORMS': '0', # the max number of forms
... 'form-0-id': '2',
... 'form-0-name': 'Walt Whitman',
... 'form-1-id': '1',
@@ -184,7 +192,6 @@ Test the behavior of commit=False and save_m2m
>>> data = {
... 'form-TOTAL_FORMS': '2', # the number of forms rendered
... 'form-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'form-MAX_FORMS': '0', # the max number of forms
... 'form-0-id': '1',
... 'form-0-name': '2nd Tuesday of the Week Meeting',
... 'form-0-authors': [2, 1, 3, 4],
@@ -201,7 +208,7 @@ True
... instance.save()
>>> formset.save_m2m()
>>> instances[0].authors.all()
-[<Author: Charles Baudelaire>, <Author: Walt Whitman>, <Author: Paul Verlaine>, <Author: John Steinbeck>]
+[<Author: Charles Baudelaire>, <Author: John Steinbeck>, <Author: Paul Verlaine>, <Author: Walt Whitman>]
# delete the author we created to allow later tests to continue working.
>>> new_author.delete()
@@ -214,13 +221,14 @@ used.
>>> AuthorFormSet = modelformset_factory(Author, max_num=2)
>>> formset = AuthorFormSet(queryset=qs)
->>> formset.initial
-[{'id': 1, 'name': u'Charles Baudelaire'}, {'id': 3, 'name': u'Paul Verlaine'}]
+>>> [sorted(x.items()) for x in formset.initial]
+[[('id', 1), ('name', u'Charles Baudelaire')], [('id', 3), ('name', u'Paul Verlaine')]]
>>> AuthorFormSet = modelformset_factory(Author, max_num=3)
>>> formset = AuthorFormSet(queryset=qs)
->>> formset.initial
-[{'id': 1, 'name': u'Charles Baudelaire'}, {'id': 3, 'name': u'Paul Verlaine'}, {'id': 2, 'name': u'Walt Whitman'}]
+>>> [sorted(x.items()) for x in formset.initial]
+[[('id', 1), ('name', u'Charles Baudelaire')], [('id', 3), ('name', u'Paul Verlaine')], [('id', 2), ('name', u'Walt Whitman')]]
+
# Inline Formsets ############################################################
@@ -242,7 +250,6 @@ admin system's edit inline functionality works.
>>> data = {
... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered
... 'book_set-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'book_set-MAX_FORMS': '0', # the max number of forms
... 'book_set-0-title': 'Les Fleurs du Mal',
... 'book_set-1-title': '',
... 'book_set-2-title': '',
@@ -277,7 +284,6 @@ book.
>>> data = {
... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered
... 'book_set-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'book_set-MAX_FORMS': '0', # the max number of forms
... 'book_set-0-id': '1',
... 'book_set-0-title': 'Les Fleurs du Mal',
... 'book_set-1-title': 'Le Spleen de Paris',
@@ -293,10 +299,10 @@ True
As you can see, 'Le Spleen de Paris' is now a book belonging to Charles Baudelaire.
->>> for book in author.book_set.order_by('title'):
+>>> for book in author.book_set.order_by('id'):
... print book.title
-Le Spleen de Paris
Les Fleurs du Mal
+Le Spleen de Paris
The save_as_new parameter lets you re-associate the data to a new instance.
This is used in the admin for save_as functionality.
@@ -304,7 +310,6 @@ This is used in the admin for save_as functionality.
>>> data = {
... 'book_set-TOTAL_FORMS': '3', # the number of forms rendered
... 'book_set-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'book_set-MAX_FORMS': '0', # the max number of forms
... 'book_set-0-id': '1',
... 'book_set-0-title': 'Les Fleurs du Mal',
... 'book_set-1-id': '2',
@@ -321,4 +326,23 @@ True
>>> [book for book in formset.save() if book.author.pk == new_author.pk]
[<Book: Les Fleurs du Mal>, <Book: Le Spleen de Paris>]
+Test using a custom prefix on an inline formset.
+
+>>> formset = AuthorBooksFormSet(prefix="test")
+>>> for form in formset.forms:
+... print form.as_p()
+<p><label for="id_test-0-title">Title:</label> <input id="id_test-0-title" type="text" name="test-0-title" maxlength="100" /><input type="hidden" name="test-0-id" id="id_test-0-id" /></p>
+<p><label for="id_test-1-title">Title:</label> <input id="id_test-1-title" type="text" name="test-1-title" maxlength="100" /><input type="hidden" name="test-1-id" id="id_test-1-id" /></p>
+
+# Test a custom primary key ###################################################
+
+We need to ensure that it is displayed
+
+>>> CustomPrimaryKeyFormSet = modelformset_factory(CustomPrimaryKey)
+>>> formset = CustomPrimaryKeyFormSet()
+>>> for form in formset.forms:
+... print form.as_p()
+<p><label for="id_form-0-my_pk">My pk:</label> <input id="id_form-0-my_pk" type="text" name="form-0-my_pk" maxlength="10" /></p>
+<p><label for="id_form-0-some_field">Some field:</label> <input id="id_form-0-some_field" type="text" name="form-0-some_field" maxlength="100" /></p>
+
"""}
diff --git a/tests/modeltests/pagination/models.py b/tests/modeltests/pagination/models.py
index 4b564f2f90..9b79a6a74e 100644
--- a/tests/modeltests/pagination/models.py
+++ b/tests/modeltests/pagination/models.py
@@ -4,11 +4,6 @@
Django provides a framework for paginating a list of objects in a few lines
of code. This is often useful for dividing search results or long lists of
objects into easily readable pages.
-
-In Django 0.96 and earlier, a single ObjectPaginator class implemented this
-functionality. In the Django development version, the behavior is split across
-two classes -- Paginator and Page -- that are more easier to use. The legacy
-ObjectPaginator class is deprecated.
"""
from django.db import models
@@ -27,9 +22,9 @@ __test__ = {'API_TESTS':"""
... a = Article(headline='Article %s' % x, pub_date=datetime(2005, 7, 29))
... a.save()
-####################################
-# New/current API (Paginator/Page) #
-####################################
+##################
+# Paginator/Page #
+##################
>>> from django.core.paginator import Paginator
>>> paginator = Paginator(Article.objects.all(), 5)
@@ -140,84 +135,26 @@ True
>>> p.end_index()
5
-################################
-# Legacy API (ObjectPaginator) #
-################################
-
-# Don't print out the deprecation warnings during testing.
->>> from warnings import filterwarnings
->>> filterwarnings("ignore")
-
->>> from django.core.paginator import ObjectPaginator, EmptyPage
->>> paginator = ObjectPaginator(Article.objects.all(), 5)
->>> paginator.hits
-9
->>> paginator.pages
-2
->>> paginator.page_range
-[1, 2]
-
-# Get the first page.
->>> paginator.get_page(0)
-[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>, <Article: Article 5>]
->>> paginator.has_next_page(0)
-True
->>> paginator.has_previous_page(0)
-False
->>> paginator.first_on_page(0)
-1
->>> paginator.last_on_page(0)
-5
-
-# Get the second page.
->>> paginator.get_page(1)
-[<Article: Article 6>, <Article: Article 7>, <Article: Article 8>, <Article: Article 9>]
->>> paginator.has_next_page(1)
-False
->>> paginator.has_previous_page(1)
-True
->>> paginator.first_on_page(1)
-6
->>> paginator.last_on_page(1)
-9
-
-# Invalid pages raise EmptyPage.
->>> paginator.get_page(-1)
-Traceback (most recent call last):
-...
-EmptyPage: ...
->>> paginator.get_page(2)
-Traceback (most recent call last):
-...
-EmptyPage: ...
-
-# Empty paginators with allow_empty_first_page=True.
->>> paginator = ObjectPaginator(Article.objects.filter(id=0), 5)
+# Paginator can be passed other objects with a count() method.
+>>> class CountContainer:
+... def count(self):
+... return 42
+>>> paginator = Paginator(CountContainer(), 10)
>>> paginator.count
-0
+42
>>> paginator.num_pages
-1
->>> paginator.page_range
-[1]
-
-# ObjectPaginator can be passed lists too.
->>> paginator = ObjectPaginator([1, 2, 3], 5)
->>> paginator.hits
-3
->>> paginator.pages
-1
+5
>>> paginator.page_range
-[1]
-
+[1, 2, 3, 4, 5]
-# ObjectPaginator can be passed other objects with a count() method.
->>> class Container:
+# Paginator can be passed other objects that implement __len__.
+>>> class LenContainer:
... def __len__(self):
... return 42
->>> paginator = ObjectPaginator(Container(), 10)
->>> paginator.hits
+>>> paginator = Paginator(LenContainer(), 10)
+>>> paginator.count
42
->>> paginator.pages
+>>> paginator.num_pages
5
>>> paginator.page_range
[1, 2, 3, 4, 5]
@@ -237,17 +174,7 @@ EmptyPage: ...
1
# With orphans only set to 1, we should get two pages.
->>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=1)
+>>> paginator = Paginator(Article.objects.all(), 10, orphans=1)
>>> paginator.num_pages
2
-
-# LEGACY: With orphans set to 3 and 10 items per page, we should get all 12 items on a single page.
->>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=3)
->>> paginator.pages
-1
-
-# LEGACY: With orphans only set to 1, we should get two pages.
->>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=1)
->>> paginator.pages
-2
"""}
diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py
index 63f9f7a361..7ed9d66674 100644
--- a/tests/modeltests/validation/models.py
+++ b/tests/modeltests/validation/models.py
@@ -16,6 +16,7 @@ class Person(models.Model):
birthdate = models.DateField()
favorite_moment = models.DateTimeField()
email = models.EmailField()
+ best_time = models.TimeField()
def __unicode__(self):
return self.name
@@ -28,7 +29,8 @@ __test__ = {'API_TESTS':"""
... 'name': 'John',
... 'birthdate': datetime.date(2000, 5, 3),
... 'favorite_moment': datetime.datetime(2002, 4, 3, 13, 23),
-... 'email': 'john@example.com'
+... 'email': 'john@example.com',
+... 'best_time': datetime.time(16, 20),
... }
>>> p = Person(**valid_params)
>>> p.validate()
@@ -130,6 +132,22 @@ datetime.datetime(2002, 4, 3, 13, 23)
>>> p.favorite_moment
datetime.datetime(2002, 4, 3, 0, 0)
+>>> p = Person(**dict(valid_params, best_time='16:20:00'))
+>>> p.validate()
+{}
+>>> p.best_time
+datetime.time(16, 20)
+
+>>> p = Person(**dict(valid_params, best_time='16:20'))
+>>> p.validate()
+{}
+>>> p.best_time
+datetime.time(16, 20)
+
+>>> p = Person(**dict(valid_params, best_time='bar'))
+>>> p.validate()['best_time']
+[u'Enter a valid time in HH:MM[:ss[.uuuuuu]] format.']
+
>>> p = Person(**dict(valid_params, email='john@example.com'))
>>> p.validate()
{}
@@ -153,5 +171,7 @@ u'john@example.com'
[u'This field is required.']
>>> errors['birthdate']
[u'This field is required.']
+>>> errors['best_time']
+[u'This field is required.']
"""}
diff --git a/tests/regressiontests/admin_registration/__init__.py b/tests/regressiontests/admin_registration/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/admin_registration/__init__.py
diff --git a/tests/regressiontests/admin_registration/models.py b/tests/regressiontests/admin_registration/models.py
new file mode 100644
index 0000000000..fdfa3691b8
--- /dev/null
+++ b/tests/regressiontests/admin_registration/models.py
@@ -0,0 +1,64 @@
+"""
+Tests for various ways of registering models with the admin site.
+"""
+
+from django.db import models
+from django.contrib import admin
+
+class Person(models.Model):
+ name = models.CharField(max_length=200)
+
+class Place(models.Model):
+ name = models.CharField(max_length=200)
+
+__test__ = {'API_TESTS':"""
+
+
+# Bare registration
+>>> site = admin.AdminSite()
+>>> site.register(Person)
+>>> site._registry[Person]
+<django.contrib.admin.options.ModelAdmin object at ...>
+
+# Registration with a ModelAdmin
+>>> site = admin.AdminSite()
+>>> class NameAdmin(admin.ModelAdmin):
+... list_display = ['name']
+... save_on_top = True
+
+>>> site.register(Person, NameAdmin)
+>>> site._registry[Person]
+<regressiontests.admin_registration.models.NameAdmin object at ...>
+
+# You can't register the same model twice
+>>> site.register(Person)
+Traceback (most recent call last):
+ ...
+AlreadyRegistered: The model Person is already registered
+
+# Registration using **options
+>>> site = admin.AdminSite()
+>>> site.register(Person, search_fields=['name'])
+>>> site._registry[Person].search_fields
+['name']
+
+# With both admin_class and **options the **options override the fields in
+# the admin class.
+>>> site = admin.AdminSite()
+>>> site.register(Person, NameAdmin, search_fields=["name"], list_display=['__str__'])
+>>> site._registry[Person].search_fields
+['name']
+>>> site._registry[Person].list_display
+['__str__']
+>>> site._registry[Person].save_on_top
+True
+
+# You can also register iterables instead of single classes -- a nice shortcut
+>>> site = admin.AdminSite()
+>>> site.register([Person, Place], search_fields=['name'])
+>>> site._registry[Person]
+<django.contrib.admin.sites.PersonAdmin object at ...>
+>>> site._registry[Place]
+<django.contrib.admin.sites.PlaceAdmin object at ...>
+
+"""}
diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
index 442f357782..f1b167eec7 100644
--- a/tests/regressiontests/admin_scripts/tests.py
+++ b/tests/regressiontests/admin_scripts/tests.py
@@ -1,18 +1,20 @@
"""
-A series of tests to establish that the command-line managment tools work as
+A series of tests to establish that the command-line managment tools work as
advertised - especially with regards to the handling of the DJANGO_SETTINGS_MODULE
and default settings.py files.
"""
import os
import unittest
import shutil
+import sys
+import re
from django import conf, bin, get_version
from django.conf import settings
class AdminScriptTestCase(unittest.TestCase):
def write_settings(self, filename, apps=None):
- test_dir = os.path.dirname(os.path.dirname(__file__))
+ test_dir = os.path.dirname(os.path.dirname(__file__))
settings_file = open(os.path.join(test_dir,filename), 'w')
settings_file.write('# Settings file automatically generated by regressiontests.admin_scripts test case\n')
exports = [
@@ -27,72 +29,93 @@ class AdminScriptTestCase(unittest.TestCase):
for s in exports:
if hasattr(settings,s):
settings_file.write("%s = '%s'\n" % (s, str(getattr(settings,s))))
-
+
if apps is None:
apps = ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts']
if apps:
settings_file.write("INSTALLED_APPS = %s\n" % apps)
-
+
settings_file.close()
-
+
def remove_settings(self, filename):
- test_dir = os.path.dirname(os.path.dirname(__file__))
- os.remove(os.path.join(test_dir, filename))
- # Also try to remove the pyc file; if it exists, it could
+ test_dir = os.path.dirname(os.path.dirname(__file__))
+ full_name = os.path.join(test_dir, filename)
+ os.remove(full_name)
+
+ # Also try to remove the compiled file; if it exists, it could
# mess up later tests that depend upon the .py file not existing
try:
- os.remove(os.path.join(test_dir, filename + 'c'))
+ if sys.platform.startswith('java'):
+ # Jython produces module$py.class files
+ os.remove(re.sub(r'\.py$', '$py.class', full_name))
+ else:
+ # CPython produces module.pyc files
+ os.remove(full_name + 'c')
except OSError:
pass
-
+
+ def _sys_executable(self):
+ """
+ Returns the command line needed to run a python interpreter, including
+ the options for setting sys.path on Jython, which doesn't recognize
+ PYTHONPATH.
+ """
+ if sys.platform.startswith('java'):
+ return "%s -J-Dpython.path=%s" % \
+ (sys.executable, os.environ['PYTHONPATH'])
+ else:
+ return sys.executable
+
def run_test(self, script, args, settings_file=None, apps=None):
test_dir = os.path.dirname(os.path.dirname(__file__))
project_dir = os.path.dirname(test_dir)
base_dir = os.path.dirname(project_dir)
-
- # Build the command line
- cmd = 'python "%s"' % script
- cmd += ''.join([' %s' % arg for arg in args])
-
+
# Remember the old environment
old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None)
old_python_path = os.environ.get('PYTHONPATH', None)
old_cwd = os.getcwd()
-
+
# Set the test environment
if settings_file:
os.environ['DJANGO_SETTINGS_MODULE'] = settings_file
elif 'DJANGO_SETTINGS_MODULE' in os.environ:
del os.environ['DJANGO_SETTINGS_MODULE']
-
- os.environ['PYTHONPATH'] = os.pathsep.join([test_dir,base_dir])
+
+ if old_python_path:
+ os.environ['PYTHONPATH'] = os.pathsep.join([test_dir, base_dir, old_python_path])
+ else:
+ os.environ['PYTHONPATH'] = os.pathsep.join([test_dir, base_dir])
+
+ # Build the command line
+ cmd = '%s "%s"' % (self._sys_executable(), script)
+ cmd += ''.join([' %s' % arg for arg in args])
# Move to the test directory and run
os.chdir(test_dir)
stdin, stdout, stderr = os.popen3(cmd)
out, err = stdout.read(), stderr.read()
-
+
# Restore the old environment
if old_django_settings_module:
os.environ['DJANGO_SETTINGS_MODULE'] = old_django_settings_module
if old_python_path:
os.environ['PYTHONPATH'] = old_python_path
-
# Move back to the old working directory
os.chdir(old_cwd)
-
+
return out, err
-
+
def run_django_admin(self, args, settings_file=None):
bin_dir = os.path.dirname(bin.__file__)
return self.run_test(os.path.join(bin_dir,'django-admin.py'), args, settings_file)
-
+
def run_manage(self, args, settings_file=None):
conf_dir = os.path.dirname(conf.__file__)
template_manage_py = os.path.join(conf_dir, 'project_template', 'manage.py')
- test_dir = os.path.dirname(os.path.dirname(__file__))
+ test_dir = os.path.dirname(os.path.dirname(__file__))
test_manage_py = os.path.join(test_dir, 'manage.py')
shutil.copyfile(template_manage_py, test_manage_py)
@@ -100,7 +123,7 @@ class AdminScriptTestCase(unittest.TestCase):
# Cleanup - remove the generated manage.py script
os.remove(test_manage_py)
-
+
return stdout, stderr
def assertNoOutput(self, stream):
@@ -119,14 +142,14 @@ class AdminScriptTestCase(unittest.TestCase):
class DjangoAdminNoSettings(AdminScriptTestCase):
"A series of tests for django-admin.py when there is no settings.py file."
-
+
def test_builtin_command(self):
"no settings: django-admin builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
-
+
def test_builtin_with_bad_settings(self):
"no settings: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=bad_settings', 'admin_scripts']
@@ -148,17 +171,17 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
-
+
def test_builtin_command(self):
"default: django-admin builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
-
+
def test_builtin_with_settings(self):
"default: django-admin builtin commands succeed if settings are provided as argument"
args = ['sqlall','--settings=settings', 'admin_scripts']
@@ -193,14 +216,14 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_settings(self):
"default: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_environment(self):
"default: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command']
@@ -214,17 +237,17 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
-
+
def tearDown(self):
self.remove_settings('settings.py')
-
+
def test_builtin_command(self):
"minimal: django-admin builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
-
+
def test_builtin_with_settings(self):
"minimal: django-admin builtin commands fail if settings are provided as argument"
args = ['sqlall','--settings=settings', 'admin_scripts']
@@ -252,21 +275,21 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'bad_settings'")
-
+
def test_custom_command(self):
"minimal: django-admin can't execute user commands"
args = ['noargs_command']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_settings(self):
"minimal: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_environment(self):
"minimal: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command']
@@ -280,10 +303,10 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('alternate_settings.py')
-
+
def tearDown(self):
self.remove_settings('alternate_settings.py')
-
+
def test_builtin_command(self):
"alternate: django-admin builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
@@ -344,17 +367,17 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
class DjangoAdminMultipleSettings(AdminScriptTestCase):
"""A series of tests for django-admin.py when multiple settings files
(including the default 'settings.py') are available. The default settings
- file is insufficient for performing the operations described, so the
+ file is insufficient for performing the operations described, so the
alternate settings must be used by the running script.
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
self.write_settings('alternate_settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
self.remove_settings('alternate_settings.py')
-
+
def test_builtin_command(self):
"alternate: django-admin builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
@@ -409,7 +432,7 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
##########################################################################
# MANAGE.PY TESTS
# This next series of test classes checks the environment processing
@@ -418,14 +441,14 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
class ManageNoSettings(AdminScriptTestCase):
"A series of tests for manage.py when there is no settings.py file."
-
+
def test_builtin_command(self):
"no settings: manage.py builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
out, err = self.run_manage(args)
self.assertNoOutput(out)
self.assertOutput(err, "Can't find the file 'settings.py' in the directory containing './manage.py'")
-
+
def test_builtin_with_bad_settings(self):
"no settings: manage.py builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=bad_settings', 'admin_scripts']
@@ -447,17 +470,17 @@ class ManageDefaultSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
-
+
def test_builtin_command(self):
"default: manage.py builtin commands succeed when default settings are appropriate"
args = ['sqlall','admin_scripts']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE')
-
+
def test_builtin_with_settings(self):
"default: manage.py builtin commands succeed if settings are provided as argument"
args = ['sqlall','--settings=settings', 'admin_scripts']
@@ -492,14 +515,14 @@ class ManageDefaultSettings(AdminScriptTestCase):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
-
+
def test_custom_command_with_settings(self):
"default: manage.py can execute user commands when settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
-
+
def test_custom_command_with_environment(self):
"default: manage.py can execute user commands when settings are provided in environment"
args = ['noargs_command']
@@ -513,17 +536,17 @@ class ManageMinimalSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
-
+
def tearDown(self):
self.remove_settings('settings.py')
-
+
def test_builtin_command(self):
"minimal: manage.py builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
out, err = self.run_manage(args)
self.assertNoOutput(out)
self.assertOutput(err, 'App with label admin_scripts could not be found')
-
+
def test_builtin_with_settings(self):
"minimal: manage.py builtin commands fail if settings are provided as argument"
args = ['sqlall','--settings=settings', 'admin_scripts']
@@ -551,21 +574,21 @@ class ManageMinimalSettings(AdminScriptTestCase):
out, err = self.run_manage(args,'bad_settings')
self.assertNoOutput(out)
self.assertOutput(err, 'App with label admin_scripts could not be found')
-
+
def test_custom_command(self):
"minimal: manage.py can't execute user commands without appropriate settings"
args = ['noargs_command']
out, err = self.run_manage(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_settings(self):
"minimal: manage.py can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=settings']
out, err = self.run_manage(args)
self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'")
-
+
def test_custom_command_with_environment(self):
"minimal: manage.py can't execute user commands, even if settings are provided in environment"
args = ['noargs_command']
@@ -579,10 +602,10 @@ class ManageAlternateSettings(AdminScriptTestCase):
"""
def setUp(self):
self.write_settings('alternate_settings.py')
-
+
def tearDown(self):
self.remove_settings('alternate_settings.py')
-
+
def test_builtin_command(self):
"alternate: manage.py builtin commands fail with an import error when no default settings provided"
args = ['sqlall','admin_scripts']
@@ -643,17 +666,17 @@ class ManageAlternateSettings(AdminScriptTestCase):
class ManageMultipleSettings(AdminScriptTestCase):
"""A series of tests for manage.py when multiple settings files
(including the default 'settings.py') are available. The default settings
- file is insufficient for performing the operations described, so the
+ file is insufficient for performing the operations described, so the
alternate settings must be used by the running script.
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
self.write_settings('alternate_settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
self.remove_settings('alternate_settings.py')
-
+
def test_builtin_command(self):
"multiple: manage.py builtin commands fail with an import error when no settings provided"
args = ['sqlall','admin_scripts']
@@ -721,10 +744,10 @@ class CommandTypes(AdminScriptTestCase):
"Tests for the various types of base command types that can be defined."
def setUp(self):
self.write_settings('settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
-
+
def test_version(self):
"--version is handled as a special case"
args = ['--version']
@@ -737,7 +760,10 @@ class CommandTypes(AdminScriptTestCase):
"--help is handled as a special case"
args = ['--help']
out, err = self.run_manage(args)
- self.assertOutput(out, "Usage: manage.py [options]")
+ if sys.version_info < (2, 5):
+ self.assertOutput(out, "usage: manage.py [options]")
+ else:
+ self.assertOutput(out, "Usage: manage.py [options]")
self.assertOutput(err, "Type 'manage.py help <subcommand>' for help on a specific subcommand.")
def test_specific_help(self):
@@ -746,14 +772,14 @@ class CommandTypes(AdminScriptTestCase):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).")
-
+
def test_base_command(self):
"User BaseCommands can execute when a label is provided"
args = ['base_command','testlabel']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
-
+
def test_base_command_no_label(self):
"User BaseCommands can execute when no labels are provided"
args = ['base_command']
@@ -781,7 +807,7 @@ class CommandTypes(AdminScriptTestCase):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
-
+
def test_noargs(self):
"NoArg Commands can be executed"
args = ['noargs_command']
@@ -794,16 +820,16 @@ class CommandTypes(AdminScriptTestCase):
args = ['noargs_command','argument']
out, err = self.run_manage(args)
self.assertOutput(err, "Error: Command doesn't accept any arguments")
-
+
def test_app_command(self):
"User AppCommands can execute when a single app name is provided"
args = ['app_command', 'auth']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
- self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py']))
+ self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py']))
self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
-
+
def test_app_command_no_apps(self):
"User AppCommands raise an error when no app name is provided"
args = ['app_command']
@@ -816,7 +842,8 @@ class CommandTypes(AdminScriptTestCase):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
- self.assertOutput(out, os.sep.join(['django','contrib','auth','models.pyc']) + "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
+ self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py']))
+ self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
self.assertOutput(out, os.sep.join(['django','contrib','contenttypes','models.py']))
self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
@@ -826,7 +853,7 @@ class CommandTypes(AdminScriptTestCase):
args = ['app_command', 'NOT_AN_APP']
out, err = self.run_manage(args)
self.assertOutput(err, "App with label NOT_AN_APP could not be found")
-
+
def test_app_command_some_invalid_appnames(self):
"User AppCommands can execute when some of the provided app names are invalid"
args = ['app_command', 'auth', 'NOT_AN_APP']
@@ -839,7 +866,7 @@ class CommandTypes(AdminScriptTestCase):
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
-
+
def test_label_command_no_label(self):
"User LabelCommands raise an error if no label is provided"
args = ['label_command']
@@ -859,14 +886,14 @@ class ArgumentOrder(AdminScriptTestCase):
django-admin command arguments are parsed in 2 parts; the core arguments
(--settings, --traceback and --pythonpath) are parsed using a Lax parser.
- This Lax parser ignores any unknown options. Then the full settings are
+ This Lax parser ignores any unknown options. Then the full settings are
passed to the command parser, which extracts commands of interest to the
- individual command.
+ individual command.
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
self.write_settings('alternate_settings.py')
-
+
def tearDown(self):
self.remove_settings('settings.py')
self.remove_settings('alternate_settings.py')
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index ad50928aa9..acdf9f5742 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -102,7 +102,7 @@ class AdminViewPermissionsTest(TestCase):
self.failUnlessEqual(request.status_code, 200)
login = self.client.post('/test_admin/admin/', self.super_login)
self.assertRedirects(login, '/test_admin/admin/')
- self.assertFalse(login.context)
+ self.failIf(login.context)
self.client.get('/test_admin/admin/logout/')
# Test if user enters e-mail address
@@ -124,7 +124,7 @@ class AdminViewPermissionsTest(TestCase):
self.failUnlessEqual(request.status_code, 200)
login = self.client.post('/test_admin/admin/', self.adduser_login)
self.assertRedirects(login, '/test_admin/admin/')
- self.assertFalse(login.context)
+ self.failIf(login.context)
self.client.get('/test_admin/admin/logout/')
# Change User
@@ -132,7 +132,7 @@ class AdminViewPermissionsTest(TestCase):
self.failUnlessEqual(request.status_code, 200)
login = self.client.post('/test_admin/admin/', self.changeuser_login)
self.assertRedirects(login, '/test_admin/admin/')
- self.assertFalse(login.context)
+ self.failIf(login.context)
self.client.get('/test_admin/admin/logout/')
# Delete User
@@ -140,7 +140,7 @@ class AdminViewPermissionsTest(TestCase):
self.failUnlessEqual(request.status_code, 200)
login = self.client.post('/test_admin/admin/', self.deleteuser_login)
self.assertRedirects(login, '/test_admin/admin/')
- self.assertFalse(login.context)
+ self.failIf(login.context)
self.client.get('/test_admin/admin/logout/')
# Regular User should not be able to login.
diff --git a/tests/regressiontests/auth_backends/tests.py b/tests/regressiontests/auth_backends/tests.py
index 3ec2a059ad..d22f0bf939 100644
--- a/tests/regressiontests/auth_backends/tests.py
+++ b/tests/regressiontests/auth_backends/tests.py
@@ -4,7 +4,7 @@ except NameError:
from sets import Set as set # Python 2.3 fallback
__test__ = {'API_TESTS': """
->>> from django.contrib.auth.models import User, Group, Permission
+>>> from django.contrib.auth.models import User, Group, Permission, AnonymousUser
>>> from django.contrib.contenttypes.models import ContentType
# No Permissions assigned yet, should return False except for superuser
@@ -69,4 +69,10 @@ True
True
>>> user.has_perms(['auth.test3', 'auth.test_group'])
True
+
+>>> user = AnonymousUser()
+>>> user.has_perm('test')
+False
+>>> user.has_perms(['auth.test2', 'auth.test3'])
+False
"""}
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index f050348c77..78c32288b6 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -3,11 +3,17 @@
# Unit tests for cache framework
# Uses whatever cache backend is set in the test settings file.
+import os
+import shutil
+import tempfile
import time
import unittest
+
from django.core.cache import cache
-from django.utils.cache import patch_vary_headers
+from django.core.cache.backends.filebased import CacheClass as FileCache
from django.http import HttpResponse
+from django.utils.cache import patch_vary_headers
+from django.utils.hashcompat import md5_constructor
# functions/classes for complex data type tests
def f():
@@ -27,7 +33,7 @@ class Cache(unittest.TestCase):
cache.add("addkey1", "value")
cache.add("addkey1", "newvalue")
self.assertEqual(cache.get("addkey1"), "value")
-
+
def test_non_existent(self):
# get with non-existent keys
self.assertEqual(cache.get("does_not_exist"), None)
@@ -80,9 +86,9 @@ class Cache(unittest.TestCase):
cache.set('expire2', 'very quickly', 1)
cache.set('expire3', 'very quickly', 1)
- time.sleep(2)
+ time.sleep(2)
self.assertEqual(cache.get("expire1"), None)
-
+
cache.add("expire2", "newvalue")
self.assertEqual(cache.get("expire2"), "newvalue")
self.assertEqual(cache.has_key("expire3"), False)
@@ -98,11 +104,6 @@ class Cache(unittest.TestCase):
cache.set(key, value)
self.assertEqual(cache.get(key), value)
-import os
-import md5
-import shutil
-import tempfile
-from django.core.cache.backends.filebased import CacheClass as FileCache
class FileBasedCacheTests(unittest.TestCase):
"""
@@ -112,23 +113,23 @@ class FileBasedCacheTests(unittest.TestCase):
self.dirname = tempfile.mktemp()
os.mkdir(self.dirname)
self.cache = FileCache(self.dirname, {})
-
+
def tearDown(self):
shutil.rmtree(self.dirname)
-
+
def test_hashing(self):
"""Test that keys are hashed into subdirectories correctly"""
self.cache.set("foo", "bar")
- keyhash = md5.new("foo").hexdigest()
+ keyhash = md5_constructor("foo").hexdigest()
keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
self.assert_(os.path.exists(keypath))
-
+
def test_subdirectory_removal(self):
"""
Make sure that the created subdirectories are correctly removed when empty.
"""
self.cache.set("foo", "bar")
- keyhash = md5.new("foo").hexdigest()
+ keyhash = md5_constructor("foo").hexdigest()
keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
self.assert_(os.path.exists(keypath))
@@ -139,9 +140,9 @@ class FileBasedCacheTests(unittest.TestCase):
class CacheUtils(unittest.TestCase):
"""TestCase for django.utils.cache functions."""
-
+
def test_patch_vary_headers(self):
- headers = (
+ headers = (
# Initial vary, new headers, resulting vary.
(None, ('Accept-Encoding',), 'Accept-Encoding'),
('Accept-Encoding', ('accept-encoding',), 'Accept-Encoding'),
diff --git a/tests/regressiontests/context_processors/__init__.py b/tests/regressiontests/context_processors/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/context_processors/__init__.py
diff --git a/tests/regressiontests/context_processors/models.py b/tests/regressiontests/context_processors/models.py
new file mode 100644
index 0000000000..cde172db68
--- /dev/null
+++ b/tests/regressiontests/context_processors/models.py
@@ -0,0 +1 @@
+# Models file for tests to run.
diff --git a/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html b/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html
new file mode 100644
index 0000000000..3978e9d680
--- /dev/null
+++ b/tests/regressiontests/context_processors/templates/context_processors/request_attrs.html
@@ -0,0 +1,13 @@
+{% if request %}
+Have request
+{% else %}
+No request
+{% endif %}
+
+{% if request.is_secure %}
+Secure
+{% else %}
+Not secure
+{% endif %}
+
+{{ request.path }}
diff --git a/tests/regressiontests/context_processors/tests.py b/tests/regressiontests/context_processors/tests.py
new file mode 100644
index 0000000000..eadd6310b1
--- /dev/null
+++ b/tests/regressiontests/context_processors/tests.py
@@ -0,0 +1,38 @@
+"""
+Tests for Django's bundled context processors.
+"""
+
+from django.conf import settings
+from django.test import TestCase
+
+
+class RequestContextProcessorTests(TestCase):
+ """
+ Tests for the ``django.core.context_processors.request`` processor.
+ """
+
+ urls = 'regressiontests.context_processors.urls'
+
+ def test_request_attributes(self):
+ """
+ Test that the request object is available in the template and that its
+ attributes can't be overridden by GET and POST parameters (#3828).
+ """
+ url = '/request_attrs/'
+ # We should have the request object in the template.
+ response = self.client.get(url)
+ self.assertContains(response, 'Have request')
+ # Test is_secure.
+ response = self.client.get(url)
+ self.assertContains(response, 'Not secure')
+ response = self.client.get(url, {'is_secure': 'blah'})
+ self.assertContains(response, 'Not secure')
+ response = self.client.post(url, {'is_secure': 'blah'})
+ self.assertContains(response, 'Not secure')
+ # Test path.
+ response = self.client.get(url)
+ self.assertContains(response, url)
+ response = self.client.get(url, {'path': '/blah/'})
+ self.assertContains(response, url)
+ response = self.client.post(url, {'path': '/blah/'})
+ self.assertContains(response, url)
diff --git a/tests/regressiontests/context_processors/urls.py b/tests/regressiontests/context_processors/urls.py
new file mode 100644
index 0000000000..7e8ba967c1
--- /dev/null
+++ b/tests/regressiontests/context_processors/urls.py
@@ -0,0 +1,8 @@
+from django.conf.urls.defaults import *
+
+import views
+
+
+urlpatterns = patterns('',
+ (r'^request_attrs/$', views.request_processor),
+)
diff --git a/tests/regressiontests/context_processors/views.py b/tests/regressiontests/context_processors/views.py
new file mode 100644
index 0000000000..66e7132c05
--- /dev/null
+++ b/tests/regressiontests/context_processors/views.py
@@ -0,0 +1,8 @@
+from django.core import context_processors
+from django.shortcuts import render_to_response
+from django.template.context import RequestContext
+
+
+def request_processor(request):
+ return render_to_response('context_processors/request_attrs.html',
+ RequestContext(request, {}, processors=[context_processors.request]))
diff --git a/tests/regressiontests/dispatch/tests/test_dispatcher.py b/tests/regressiontests/dispatch/tests/test_dispatcher.py
index 0bc99a1505..f34173972d 100644
--- a/tests/regressiontests/dispatch/tests/test_dispatcher.py
+++ b/tests/regressiontests/dispatch/tests/test_dispatcher.py
@@ -2,6 +2,18 @@ from django.dispatch.dispatcher import *
from django.dispatch import dispatcher, robust
import unittest
import copy
+import sys
+import gc
+
+if sys.platform.startswith('java'):
+ def garbage_collect():
+ """Run the garbage collector and wait a bit to let it do his work"""
+ import time
+ gc.collect()
+ time.sleep(0.1)
+else:
+ def garbage_collect():
+ gc.collect()
def x(a):
return a
@@ -21,6 +33,7 @@ class DispatcherTests(unittest.TestCase):
def setUp(self):
# track the initial state, since it's possible that others have bleed receivers in
+ garbage_collect()
self.sendersBack = copy.copy(dispatcher.sendersBack)
self.connections = copy.copy(dispatcher.connections)
self.senders = copy.copy(dispatcher.senders)
@@ -86,6 +99,7 @@ class DispatcherTests(unittest.TestCase):
connect(a.a, signal, b)
expected = []
del a
+ garbage_collect()
result = send('this',b, a=b)
self.assertEqual(result, expected)
self.assertEqual(list(getAllReceivers(b,signal)), [])
@@ -101,6 +115,7 @@ class DispatcherTests(unittest.TestCase):
connect(a, signal, b)
expected = []
del a
+ garbage_collect()
result = send('this',b, a=b)
self.assertEqual(result, expected)
self.assertEqual(list(getAllReceivers(b,signal)), [])
@@ -123,6 +138,7 @@ class DispatcherTests(unittest.TestCase):
del a
del b
del result
+ garbage_collect()
self._testIsClean()
def testRobust(self):
@@ -141,4 +157,4 @@ def getSuite():
return unittest.makeSuite(DispatcherTests,'test')
if __name__ == "__main__":
- unittest.main ()
+ unittest.main()
diff --git a/tests/regressiontests/file_uploads/models.py b/tests/regressiontests/file_uploads/models.py
index 2d5607b2a7..3701750afe 100644
--- a/tests/regressiontests/file_uploads/models.py
+++ b/tests/regressiontests/file_uploads/models.py
@@ -1,2 +1,9 @@
-# This file unintentionally left blank.
-# Oops. \ No newline at end of file
+import tempfile
+import os
+from django.db import models
+
+UPLOAD_ROOT = tempfile.mkdtemp()
+UPLOAD_TO = os.path.join(UPLOAD_ROOT, 'test_upload')
+
+class FileModel(models.Model):
+ testfile = models.FileField(upload_to=UPLOAD_TO)
diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py
index d2b581686f..dd6b7c4181 100644
--- a/tests/regressiontests/file_uploads/tests.py
+++ b/tests/regressiontests/file_uploads/tests.py
@@ -1,8 +1,15 @@
import os
-import sha
-import tempfile
+import errno
+import shutil
+import unittest
+
+from django.core.files import temp as tempfile
+from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase, client
from django.utils import simplejson
+from django.utils.hashcompat import sha_constructor
+
+from models import FileModel, UPLOAD_ROOT, UPLOAD_TO
class FileUploadTests(TestCase):
def test_simple_upload(self):
@@ -15,7 +22,7 @@ class FileUploadTests(TestCase):
def test_large_upload(self):
tdir = tempfile.gettempdir()
-
+
file1 = tempfile.NamedTemporaryFile(suffix=".file1", dir=tdir)
file1.write('a' * (2 ** 21))
file1.seek(0)
@@ -38,10 +45,10 @@ class FileUploadTests(TestCase):
for key in post_data.keys():
try:
- post_data[key + '_hash'] = sha.new(post_data[key].read()).hexdigest()
+ post_data[key + '_hash'] = sha_constructor(post_data[key].read()).hexdigest()
post_data[key].seek(0)
except AttributeError:
- post_data[key + '_hash'] = sha.new(post_data[key]).hexdigest()
+ post_data[key + '_hash'] = sha_constructor(post_data[key]).hexdigest()
response = self.client.post('/file_uploads/verify/', post_data)
@@ -51,11 +58,11 @@ class FileUploadTests(TestCase):
pass
self.assertEqual(response.status_code, 200)
-
+
def test_dangerous_file_names(self):
"""Uploaded file names should be sanitized before ever reaching the view."""
# This test simulates possible directory traversal attacks by a
- # malicious uploader We have to do some monkeybusiness here to construct
+ # malicious uploader We have to do some monkeybusiness here to construct
# a malicious payload with an invalid file name (containing os.sep or
# os.pardir). This similar to what an attacker would need to do when
# trying such an attack.
@@ -72,7 +79,7 @@ class FileUploadTests(TestCase):
"..\\..\\hax0rd.txt", # Relative path, win-style.
"../..\\hax0rd.txt" # Relative path, mixed.
]
-
+
payload = []
for i, name in enumerate(scary_file_names):
payload.extend([
@@ -86,7 +93,7 @@ class FileUploadTests(TestCase):
'--' + client.BOUNDARY + '--',
'',
])
-
+
payload = "\r\n".join(payload)
r = {
'CONTENT_LENGTH': len(payload),
@@ -102,7 +109,7 @@ class FileUploadTests(TestCase):
for i, name in enumerate(scary_file_names):
got = recieved["file%s" % i]
self.assertEqual(got, "hax0rd.txt")
-
+
def test_filename_overflow(self):
"""File names over 256 characters (dangerous on some platforms) get fixed up."""
name = "%s.txt" % ("f"*500)
@@ -124,26 +131,26 @@ class FileUploadTests(TestCase):
}
got = simplejson.loads(self.client.request(**r).content)
self.assert_(len(got['file']) < 256, "Got a long file name (%s characters)." % len(got['file']))
-
+
def test_custom_upload_handler(self):
- # A small file (under the 5M quota)
+ # A small file (under the 5M quota)
smallfile = tempfile.NamedTemporaryFile()
smallfile.write('a' * (2 ** 21))
# A big file (over the quota)
bigfile = tempfile.NamedTemporaryFile()
bigfile.write('a' * (10 * 2 ** 20))
-
+
# Small file posting should work.
response = self.client.post('/file_uploads/quota/', {'f': open(smallfile.name)})
got = simplejson.loads(response.content)
self.assert_('f' in got)
-
+
# Large files don't go through.
response = self.client.post("/file_uploads/quota/", {'f': open(bigfile.name)})
got = simplejson.loads(response.content)
self.assert_('f' not in got)
-
+
def test_broken_custom_upload_handler(self):
f = tempfile.NamedTemporaryFile()
f.write('a' * (2 ** 21))
@@ -179,3 +186,42 @@ class FileUploadTests(TestCase):
self.assertEqual(got.get('file1'), 1)
self.assertEqual(got.get('file2'), 2)
+
+class DirectoryCreationTests(unittest.TestCase):
+ """
+ Tests for error handling during directory creation
+ via _save_FIELD_file (ticket #6450)
+ """
+ def setUp(self):
+ self.obj = FileModel()
+ if not os.path.isdir(UPLOAD_ROOT):
+ os.makedirs(UPLOAD_ROOT)
+
+ def tearDown(self):
+ os.chmod(UPLOAD_ROOT, 0700)
+ shutil.rmtree(UPLOAD_ROOT)
+
+ def test_readonly_root(self):
+ """Permission errors are not swallowed"""
+ os.chmod(UPLOAD_ROOT, 0500)
+ try:
+ self.obj.save_testfile_file('foo.txt', SimpleUploadedFile('foo.txt', 'x'))
+ except OSError, err:
+ self.assertEquals(err.errno, errno.EACCES)
+ except:
+ self.fail("OSError [Errno %s] not raised" % errno.EACCES)
+
+ def test_not_a_directory(self):
+ """The correct IOError is raised when the upload directory name exists but isn't a directory"""
+ # Create a file with the upload directory name
+ fd = open(UPLOAD_TO, 'w')
+ fd.close()
+ try:
+ self.obj.save_testfile_file('foo.txt', SimpleUploadedFile('foo.txt', 'x'))
+ except IOError, err:
+ # The test needs to be done on a specific string as IOError
+ # is raised even without the patch (just not early enough)
+ self.assertEquals(err.args[0],
+ "%s exists and is not a directory" % UPLOAD_TO)
+ except:
+ self.fail("IOError not raised")
diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py
index c70ff2dff3..a9aae4f442 100644
--- a/tests/regressiontests/forms/fields.py
+++ b/tests/regressiontests/forms/fields.py
@@ -308,18 +308,18 @@ ValidationError: [u'This field is required.']
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
->>> f.clean('1')
-Decimal("1")
+>>> f.clean('1') == Decimal("1")
+True
>>> isinstance(f.clean('1'), Decimal)
True
->>> f.clean('23')
-Decimal("23")
->>> f.clean('3.14')
-Decimal("3.14")
->>> f.clean(3.14)
-Decimal("3.14")
->>> f.clean(Decimal('3.14'))
-Decimal("3.14")
+>>> f.clean('23') == Decimal("23")
+True
+>>> f.clean('3.14') == Decimal("3.14")
+True
+>>> f.clean(3.14) == Decimal("3.14")
+True
+>>> f.clean(Decimal('3.14')) == Decimal("3.14")
+True
>>> f.clean('a')
Traceback (most recent call last):
...
@@ -328,12 +328,12 @@ ValidationError: [u'Enter a number.']
Traceback (most recent call last):
...
ValidationError: [u'Enter a number.']
->>> f.clean('1.0 ')
-Decimal("1.0")
->>> f.clean(' 1.0')
-Decimal("1.0")
->>> f.clean(' 1.0 ')
-Decimal("1.0")
+>>> f.clean('1.0 ') == Decimal("1.0")
+True
+>>> f.clean(' 1.0') == Decimal("1.0")
+True
+>>> f.clean(' 1.0 ') == Decimal("1.0")
+True
>>> f.clean('1.0a')
Traceback (most recent call last):
...
@@ -350,18 +350,18 @@ ValidationError: [u'Ensure that there are no more than 2 decimal places.']
Traceback (most recent call last):
...
ValidationError: [u'Ensure that there are no more than 2 digits before the decimal point.']
->>> f.clean('-12.34')
-Decimal("-12.34")
+>>> f.clean('-12.34') == Decimal("-12.34")
+True
>>> f.clean('-123.45')
Traceback (most recent call last):
...
ValidationError: [u'Ensure that there are no more than 4 digits in total.']
->>> f.clean('-.12')
-Decimal("-0.12")
->>> f.clean('-00.12')
-Decimal("-0.12")
->>> f.clean('-000.12')
-Decimal("-0.12")
+>>> f.clean('-.12') == Decimal("-0.12")
+True
+>>> f.clean('-00.12') == Decimal("-0.12")
+True
+>>> f.clean('-000.12') == Decimal("-0.12")
+True
>>> f.clean('-000.123')
Traceback (most recent call last):
...
@@ -380,8 +380,8 @@ ValidationError: [u'Enter a number.']
>>> f.clean(None)
->>> f.clean('1')
-Decimal("1")
+>>> f.clean('1') == Decimal("1")
+True
DecimalField accepts min_value and max_value just like IntegerField:
>>> f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
@@ -394,14 +394,14 @@ ValidationError: [u'Ensure this value is less than or equal to 1.5.']
Traceback (most recent call last):
...
ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
->>> f.clean('1.5')
-Decimal("1.5")
->>> f.clean('0.5')
-Decimal("0.5")
->>> f.clean('.5')
-Decimal("0.5")
->>> f.clean('00.50')
-Decimal("0.50")
+>>> f.clean('1.5') == Decimal("1.5")
+True
+>>> f.clean('0.5') == Decimal("0.5")
+True
+>>> f.clean('.5') == Decimal("0.5")
+True
+>>> f.clean('00.50') == Decimal("0.50")
+True
# DateField ###################################################################
@@ -802,6 +802,9 @@ ValidationError: [u'The submitted file is empty.']
>>> type(f.clean(SimpleUploadedFile('name', 'Some File Content')))
<class 'django.core.files.uploadedfile.SimpleUploadedFile'>
+>>> type(f.clean(SimpleUploadedFile('我隻氣墊船è£æ»¿æ™’é±”.txt', 'मेरी मà¤à¤¡à¤°à¤¾à¤¨à¥‡ वाली नाव सरà¥à¤ªà¤®à¥€à¤¨à¥‹à¤‚ से भरी ह')))
+<class 'django.core.files.uploadedfile.SimpleUploadedFile'>
+
>>> type(f.clean(SimpleUploadedFile('name', 'Some File Content'), 'files/test4.pdf'))
<class 'django.core.files.uploadedfile.SimpleUploadedFile'>
@@ -817,15 +820,15 @@ Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean('http://localhost')
-u'http://localhost'
+u'http://localhost/'
>>> f.clean('http://example.com')
-u'http://example.com'
+u'http://example.com/'
>>> f.clean('http://www.example.com')
-u'http://www.example.com'
+u'http://www.example.com/'
>>> f.clean('http://www.example.com:8000/test')
u'http://www.example.com:8000/test'
>>> f.clean('http://200.8.9.10')
-u'http://200.8.9.10'
+u'http://200.8.9.10/'
>>> f.clean('http://200.8.9.10:8000/test')
u'http://200.8.9.10:8000/test'
>>> f.clean('foo')
@@ -855,9 +858,9 @@ u''
>>> f.clean(None)
u''
>>> f.clean('http://example.com')
-u'http://example.com'
+u'http://example.com/'
>>> f.clean('http://www.example.com')
-u'http://www.example.com'
+u'http://www.example.com/'
>>> f.clean('foo')
Traceback (most recent call last):
...
@@ -883,7 +886,7 @@ URLField takes an optional verify_exists parameter, which is False by default.
This verifies that the URL is live on the Internet and doesn't return a 404 or 500:
>>> f = URLField(verify_exists=True)
>>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
-u'http://www.google.com'
+u'http://www.google.com/'
>>> f.clean('http://example')
Traceback (most recent call last):
...
@@ -900,29 +903,38 @@ ValidationError: [u'This URL appears to be a broken link.']
>>> f.clean('')
u''
>>> f.clean('http://www.google.com') # This will fail if there's no Internet connection
-u'http://www.google.com'
+u'http://www.google.com/'
URLField also access min_length and max_length parameters, for convenience.
>>> f = URLField(min_length=15, max_length=20)
>>> f.clean('http://f.com')
Traceback (most recent call last):
...
-ValidationError: [u'Ensure this value has at least 15 characters (it has 12).']
+ValidationError: [u'Ensure this value has at least 15 characters (it has 13).']
>>> f.clean('http://example.com')
-u'http://example.com'
+u'http://example.com/'
>>> f.clean('http://abcdefghijklmnopqrstuvwxyz.com')
Traceback (most recent call last):
...
-ValidationError: [u'Ensure this value has at most 20 characters (it has 37).']
+ValidationError: [u'Ensure this value has at most 20 characters (it has 38).']
URLField should prepend 'http://' if no scheme was given
>>> f = URLField(required=False)
>>> f.clean('example.com')
-u'http://example.com'
+u'http://example.com/'
>>> f.clean('')
u''
>>> f.clean('https://example.com')
-u'https://example.com'
+u'https://example.com/'
+
+URLField should append '/' if no path was given
+>>> f = URLField()
+>>> f.clean('http://example.com')
+u'http://example.com/'
+
+URLField shouldn't change the path if it was given
+>>> f.clean('http://example.com/test')
+u'http://example.com/test'
# BooleanField ################################################################
diff --git a/tests/regressiontests/forms/forms.py b/tests/regressiontests/forms/forms.py
index 6e6e4f79bf..d834bdaccc 100644
--- a/tests/regressiontests/forms/forms.py
+++ b/tests/regressiontests/forms/forms.py
@@ -1480,6 +1480,10 @@ not request.POST.
>>> f.is_valid()
True
+>>> f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船è£æ»¿æ™’é±”.txt', 'मेरी मà¤à¤¡à¤°à¤¾à¤¨à¥‡ वाली नाव सरà¥à¤ªà¤®à¥€à¤¨à¥‹à¤‚ से भरी ह')}, auto_id=False)
+>>> print f
+<tr><th>File1:</th><td><input type="file" name="file1" /></td></tr>
+
# Basic form processing in a view #############################################
>>> from django.template import Template, Context
diff --git a/tests/regressiontests/forms/formsets.py b/tests/regressiontests/forms/formsets.py
index bbbd4cee5a..4fd0c17032 100644
--- a/tests/regressiontests/forms/formsets.py
+++ b/tests/regressiontests/forms/formsets.py
@@ -20,7 +20,7 @@ but we'll look at how to do so later.
>>> formset = ChoiceFormSet(auto_id=False, prefix='choices')
>>> print formset
-<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_FORMS" value="0" />
+<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" />
<tr><th>Choice:</th><td><input type="text" name="choices-0-choice" /></td></tr>
<tr><th>Votes:</th><td><input type="text" name="choices-0-votes" /></td></tr>
@@ -34,7 +34,6 @@ the TOTAL_FORMS field appropriately.
>>> data = {
... 'choices-TOTAL_FORMS': '1', # the number of forms rendered
... 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... }
@@ -61,7 +60,6 @@ any of the forms.
>>> data = {
... 'choices-TOTAL_FORMS': '1', # the number of forms rendered
... 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '',
... }
@@ -92,7 +90,6 @@ Let's simulate what would happen if we submitted this form.
>>> data = {
... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-1-choice': '',
@@ -114,7 +111,6 @@ handle that later.
>>> data = {
... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-1-choice': 'The Decemberists',
@@ -134,7 +130,6 @@ handle that case later.
>>> data = {
... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': '', # deleted value
... 'choices-0-votes': '', # deleted value
... 'choices-1-choice': '',
@@ -172,7 +167,6 @@ number of forms to be completed.
>>> data = {
... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
... 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': '',
... 'choices-0-votes': '',
... 'choices-1-choice': '',
@@ -193,7 +187,6 @@ We can just fill out one of the forms.
>>> data = {
... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
... 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-1-choice': '',
@@ -214,7 +207,6 @@ And once again, if we try to partially complete a form, validation will fail.
>>> data = {
... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
... 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-1-choice': 'The Decemberists',
@@ -275,7 +267,6 @@ To delete something, we just need to set that form's special delete field to
>>> data = {
... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
... 'choices-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-0-DELETE': '',
@@ -325,7 +316,6 @@ something at the front of the list, you'd need to set it's order to 0.
>>> data = {
... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
... 'choices-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-0-ORDER': '1',
@@ -352,7 +342,6 @@ they will be sorted below everything else.
>>> data = {
... 'choices-TOTAL_FORMS': '4', # the number of forms rendered
... 'choices-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-0-ORDER': '1',
@@ -414,7 +403,6 @@ Let's delete Fergie, and put The Decemberists ahead of Calexico.
>>> data = {
... 'choices-TOTAL_FORMS': '4', # the number of forms rendered
... 'choices-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'choices-MAX_FORMS': '0', # the max number of forms
... 'choices-0-choice': 'Calexico',
... 'choices-0-votes': '100',
... 'choices-0-ORDER': '1',
@@ -473,7 +461,6 @@ We start out with a some duplicate data.
>>> data = {
... 'drinks-TOTAL_FORMS': '2', # the number of forms rendered
... 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'drinks-MAX_FORMS': '0', # the max number of forms
... 'drinks-0-name': 'Gin and Tonic',
... 'drinks-1-name': 'Gin and Tonic',
... }
@@ -495,7 +482,6 @@ Make sure we didn't break the valid case.
>>> data = {
... 'drinks-TOTAL_FORMS': '2', # the number of forms rendered
... 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'drinks-MAX_FORMS': '0', # the max number of forms
... 'drinks-0-name': 'Gin and Tonic',
... 'drinks-1-name': 'Bloody Mary',
... }
diff --git a/tests/regressiontests/forms/localflavor/at.py b/tests/regressiontests/forms/localflavor/at.py
new file mode 100644
index 0000000000..54ca46898e
--- /dev/null
+++ b/tests/regressiontests/forms/localflavor/at.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+# Tests for the contrib/localflavor/ AT form fields.
+
+tests = r"""
+# ATZipCodeField ###########################################################
+
+>>> from django.contrib.localflavor.at.forms import ATZipCodeField
+>>> f = ATZipCodeField()
+>>> f.clean('1150')
+u'1150'
+>>> f.clean('4020')
+u'4020'
+>>> f.clean('8020')
+u'8020'
+>>> f.clean('111222')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a zip code in the format XXXX.']
+>>> f.clean('eeffee')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a zip code in the format XXXX.']
+>>> f.clean(u'')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+
+>>> f = ATZipCodeField(required=False)
+>>> f.clean('1150')
+u'1150'
+>>> f.clean('4020')
+u'4020'
+>>> f.clean('8020')
+u'8020'
+>>> f.clean('111222')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a zip code in the format XXXX.']
+>>> f.clean('eeffee')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a zip code in the format XXXX.']
+>>> f.clean(None)
+u''
+>>> f.clean('')
+u''
+>>> f.clean(u'')
+u''
+
+# ATStateSelect ##################################################################
+
+>>> from django.contrib.localflavor.at.forms import ATStateSelect
+>>> f = ATStateSelect()
+>>> f.render('bundesland', 'WI')
+u'<select name="bundesland">\n<option value="BL">Burgenland</option>\n<option value="KA">Carinthia</option>\n<option value="NO">Lower Austria</option>\n<option value="OO">Upper Austria</option>\n<option value="SA">Salzburg</option>\n<option value="ST">Styria</option>\n<option value="TI">Tyrol</option>\n<option value="VO">Vorarlberg</option>\n<option value="WI" selected="selected">Vienna</option>\n</select>'
+
+# ATSocialSecurityNumberField ################################################
+
+>>> from django.contrib.localflavor.at.forms import ATSocialSecurityNumberField
+>>> f = ATSocialSecurityNumberField()
+>>> f.clean('1237 010180')
+u'1237 010180'
+>>> f.clean('1237 010181')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Austrian Social Security Number in XXXX XXXXXX format.']
+>>> f.clean('12370 010180')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Austrian Social Security Number in XXXX XXXXXX format.']
+"""
diff --git a/tests/regressiontests/forms/localflavor/ro.py b/tests/regressiontests/forms/localflavor/ro.py
new file mode 100644
index 0000000000..e885030029
--- /dev/null
+++ b/tests/regressiontests/forms/localflavor/ro.py
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+# Tests for the contrib/localflavor/ RO form fields.
+
+tests = r"""
+>>> from django.contrib.localflavor.ro.forms import *
+
+##ROCIFField ################################################################
+
+f = ROCIFField()
+f.clean('21694681')
+u'21694681'
+f.clean('RO21694681')
+u'21694681'
+f.clean('21694680')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CIF']
+f.clean('21694680000')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 10 characters (it has 11).']
+f.clean('0')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 2 characters (it has 1).']
+f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+##ROCNPField #################################################################
+
+f = ROCNPField()
+f.clean('1981211204489')
+u'1981211204489'
+f.clean('1981211204487')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CNP']
+f.clean('1981232204489')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CNP']
+f.clean('9981211204489')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid CNP']
+f.clean('9981211209')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 13 characters (it has 10).']
+f.clean('19812112044891')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 13 characters (it has 14).']
+f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+##ROCountyField ##############################################################
+
+f = ROCountyField()
+f.clean('CJ')
+'CJ'
+f.clean('cj')
+'CJ'
+f.clean('ArgeÅŸ')
+'AG'
+f.clean('argeÅŸ')
+'AG'
+f.clean('Arges')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Romanian county code or name.']
+f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+##ROCountySelect #############################################################
+
+f = ROCountySelect()
+f.render('county','CJ')
+u'<select name="county">\n<option value="AB">Alba</option>\n<option value="AR">A
+rad</option>\n<option value="AG">Arge\u015f</option>\n<option value="BC">Bac\u01
+03u</option>\n<option value="BH">Bihor</option>\n<option value="BN">Bistri\u0163
+a-N\u0103s\u0103ud</option>\n<option value="BT">Boto\u015fani</option>\n<option
+value="BV">Bra\u015fov</option>\n<option value="BR">Br\u0103ila</option>\n<optio
+n value="B">Bucure\u015fti</option>\n<option value="BZ">Buz\u0103u</option>\n<op
+tion value="CS">Cara\u015f-Severin</option>\n<option value="CL">C\u0103l\u0103ra
+\u015fi</option>\n<option value="CJ" selected="selected">Cluj</option>\n<option
+value="CT">Constan\u0163a</option>\n<option value="CV">Covasna</option>\n<option
+ value="DB">D\xe2mbovi\u0163a</option>\n<option value="DJ">Dolj</option>\n<optio
+n value="GL">Gala\u0163i</option>\n<option value="GR">Giurgiu</option>\n<option
+value="GJ">Gorj</option>\n<option value="HR">Harghita</option>\n<option value="H
+D">Hunedoara</option>\n<option value="IL">Ialomi\u0163a</option>\n<option value=
+"IS">Ia\u015fi</option>\n<option value="IF">Ilfov</option>\n<option value="MM">M
+aramure\u015f</option>\n<option value="MH">Mehedin\u0163i</option>\n<option valu
+e="MS">Mure\u015f</option>\n<option value="NT">Neam\u0163</option>\n<option valu
+e="OT">Olt</option>\n<option value="PH">Prahova</option>\n<option value="SM">Sat
+u Mare</option>\n<option value="SJ">S\u0103laj</option>\n<option value="SB">Sibi
+u</option>\n<option value="SV">Suceava</option>\n<option value="TR">Teleorman</o
+ption>\n<option value="TM">Timi\u015f</option>\n<option value="TL">Tulcea</optio
+n>\n<option value="VS">Vaslui</option>\n<option value="VL">V\xe2lcea</option>\n<
+option value="VN">Vrancea</option>\n</select>'
+
+##ROIBANField #################################################################
+
+f = ROIBANField()
+f.clean('RO56RZBR0000060003291177')
+u'RO56RZBR0000060003291177'
+f.clean('RO56RZBR0000060003291176')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format']
+
+f.clean('RO56-RZBR-0000-0600-0329-1177')
+u'RO56RZBR0000060003291177'
+f.clean('AT61 1904 3002 3457 3201')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format']
+
+f.clean('RO56RZBR000006000329117')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 24 characters (it has 23).']
+f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+##ROPhoneNumberField ##########################################################
+
+f = ROPhoneNumberField()
+f.clean('0264485936')
+u'0264485936'
+f.clean('(0264)-485936')
+u'0264485936'
+f.clean('02644859368')
+Traceback (most recent call last):
+...
+ValidationError: [u'Phone numbers must be in XXXX-XXXXXX format.']
+f.clean('026448593')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 10 characters (it has 9).']
+f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+##ROPostalCodeField ###########################################################
+
+f = ROPostalCodeField()
+f.clean('400473')
+u'400473'
+f.clean('40047')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at least 6 characters (it has 5).']
+f.clean('4004731')
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 6 characters (it has 7).']
+f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+"""
diff --git a/tests/regressiontests/forms/models.py b/tests/regressiontests/forms/models.py
index 98b9233d80..a6baa79811 100644
--- a/tests/regressiontests/forms/models.py
+++ b/tests/regressiontests/forms/models.py
@@ -1,6 +1,10 @@
+# -*- coding: utf-8 -*-
import datetime
from django.db import models
+# Can't import as "forms" due to implementation details in the test suite (the
+# current file is called "forms" and is already imported).
+from django import forms as django_forms
class BoundaryModel(models.Model):
positive_integer = models.PositiveIntegerField(null=True, blank=True)
@@ -14,8 +18,23 @@ class ChoiceModel(models.Model):
"""For ModelChoiceField and ModelMultipleChoiceField tests."""
name = models.CharField(max_length=10)
+class FileModel(models.Model):
+ file = models.FileField(upload_to='/')
+
+class FileForm(django_forms.Form):
+ file1 = django_forms.FileField()
+
__test__ = {'API_TESTS': """
>>> from django.forms import form_for_model, form_for_instance
+>>> from django.core.files.uploadedfile import SimpleUploadedFile
+
+# FileModel with unicode filename and data #########################
+>>> f = FileForm(data={}, files={'file1': SimpleUploadedFile('我隻氣墊船è£æ»¿æ™’é±”.txt', 'मेरी मà¤à¤¡à¤°à¤¾à¤¨à¥‡ वाली नाव सरà¥à¤ªà¤®à¥€à¤¨à¥‹à¤‚ से भरी ह')}, auto_id=False)
+>>> f.is_valid()
+True
+>>> f.cleaned_data
+{'file1': <SimpleUploadedFile: 我隻氣墊船è£æ»¿æ™’é±”.txt (text/plain)>}
+>>> m = FileModel.objects.create(file=f.cleaned_data['file1'])
# Boundary conditions on a PostitiveIntegerField #########################
>>> BoundaryForm = form_for_model(BoundaryModel)
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index ff8213c8d9..6a8b017f44 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -4,6 +4,7 @@ from fields import tests as fields_tests
from forms import tests as form_tests
from error_messages import tests as custom_error_message_tests
from localflavor.ar import tests as localflavor_ar_tests
+from localflavor.at import tests as localflavor_at_tests
from localflavor.au import tests as localflavor_au_tests
from localflavor.br import tests as localflavor_br_tests
from localflavor.ca import tests as localflavor_ca_tests
@@ -19,6 +20,7 @@ from localflavor.it import tests as localflavor_it_tests
from localflavor.jp import tests as localflavor_jp_tests
from localflavor.nl import tests as localflavor_nl_tests
from localflavor.pl import tests as localflavor_pl_tests
+from localflavor.ro import tests as localflavor_ro_tests
from localflavor.sk import tests as localflavor_sk_tests
from localflavor.uk import tests as localflavor_uk_tests
from localflavor.us import tests as localflavor_us_tests
@@ -35,6 +37,7 @@ __test__ = {
'form_tests': form_tests,
'custom_error_message_tests': custom_error_message_tests,
'localflavor_ar_tests': localflavor_ar_tests,
+ 'localflavor_at_tests': localflavor_at_tests,
'localflavor_au_tests': localflavor_au_tests,
'localflavor_br_tests': localflavor_br_tests,
'localflavor_ca_tests': localflavor_ca_tests,
@@ -50,6 +53,7 @@ __test__ = {
'localflavor_jp_tests': localflavor_jp_tests,
'localflavor_nl_tests': localflavor_nl_tests,
'localflavor_pl_tests': localflavor_pl_tests,
+ 'localflavor_ro_tests': localflavor_ro_tests,
'localflavor_sk_tests': localflavor_sk_tests,
'localflavor_uk_tests': localflavor_uk_tests,
'localflavor_us_tests': localflavor_us_tests,
diff --git a/tests/regressiontests/m2m_through_regress/__init__.py b/tests/regressiontests/m2m_through_regress/__init__.py
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/tests/regressiontests/m2m_through_regress/__init__.py
@@ -0,0 +1,2 @@
+
+
diff --git a/tests/regressiontests/m2m_through_regress/models.py b/tests/regressiontests/m2m_through_regress/models.py
new file mode 100644
index 0000000000..16d2c4ec1b
--- /dev/null
+++ b/tests/regressiontests/m2m_through_regress/models.py
@@ -0,0 +1,204 @@
+from django.db import models
+from datetime import datetime
+from django.contrib.auth.models import User
+
+# Forward declared intermediate model
+class Membership(models.Model):
+ person = models.ForeignKey('Person')
+ group = models.ForeignKey('Group')
+ date_joined = models.DateTimeField(default=datetime.now)
+
+ def __unicode__(self):
+ return "%s is a member of %s" % (self.person.name, self.group.name)
+
+class UserMembership(models.Model):
+ user = models.ForeignKey(User)
+ group = models.ForeignKey('Group')
+ date_joined = models.DateTimeField(default=datetime.now)
+
+ def __unicode__(self):
+ return "%s is a user and member of %s" % (self.user.username, self.group.name)
+
+class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ def __unicode__(self):
+ return self.name
+
+class Group(models.Model):
+ name = models.CharField(max_length=128)
+ # Membership object defined as a class
+ members = models.ManyToManyField(Person, through=Membership)
+ user_members = models.ManyToManyField(User, through='UserMembership')
+
+ def __unicode__(self):
+ return self.name
+
+__test__ = {'API_TESTS':"""
+# Create some dummy data
+>>> bob = Person.objects.create(name='Bob')
+>>> jim = Person.objects.create(name='Jim')
+
+>>> rock = Group.objects.create(name='Rock')
+>>> roll = Group.objects.create(name='Roll')
+
+>>> frank = User.objects.create_user('frank','frank@example.com','password')
+>>> jane = User.objects.create_user('jane','jane@example.com','password')
+
+# Now test that the forward declared Membership works
+>>> Membership.objects.create(person=bob, group=rock)
+<Membership: Bob is a member of Rock>
+
+>>> Membership.objects.create(person=bob, group=roll)
+<Membership: Bob is a member of Roll>
+
+>>> Membership.objects.create(person=jim, group=rock)
+<Membership: Jim is a member of Rock>
+
+>>> bob.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+>>> roll.members.all()
+[<Person: Bob>]
+
+# Error messages use the model name, not repr of the class name
+>>> bob.group_set = []
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> roll.members = []
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> rock.members.create(name='Anne')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> bob.group_set.create(name='Funk')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Now test that the intermediate with a relationship outside
+# the current app (i.e., UserMembership) workds
+>>> UserMembership.objects.create(user=frank, group=rock)
+<UserMembership: frank is a user and member of Rock>
+
+>>> UserMembership.objects.create(user=frank, group=roll)
+<UserMembership: frank is a user and member of Roll>
+
+>>> UserMembership.objects.create(user=jane, group=rock)
+<UserMembership: jane is a user and member of Rock>
+
+>>> frank.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+>>> roll.user_members.all()
+[<User: frank>]
+
+"""}
+from django.db import models
+from datetime import datetime
+from django.contrib.auth.models import User
+
+# Forward declared intermediate model
+class Membership(models.Model):
+ person = models.ForeignKey('Person')
+ group = models.ForeignKey('Group')
+ date_joined = models.DateTimeField(default=datetime.now)
+
+ def __unicode__(self):
+ return "%s is a member of %s" % (self.person.name, self.group.name)
+
+class UserMembership(models.Model):
+ user = models.ForeignKey(User)
+ group = models.ForeignKey('Group')
+ date_joined = models.DateTimeField(default=datetime.now)
+
+ def __unicode__(self):
+ return "%s is a user and member of %s" % (self.user.username, self.group.name)
+
+class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ def __unicode__(self):
+ return self.name
+
+class Group(models.Model):
+ name = models.CharField(max_length=128)
+ # Membership object defined as a class
+ members = models.ManyToManyField(Person, through=Membership)
+ user_members = models.ManyToManyField(User, through='UserMembership')
+
+ def __unicode__(self):
+ return self.name
+
+__test__ = {'API_TESTS':"""
+# Create some dummy data
+>>> bob = Person.objects.create(name='Bob')
+>>> jim = Person.objects.create(name='Jim')
+
+>>> rock = Group.objects.create(name='Rock')
+>>> roll = Group.objects.create(name='Roll')
+
+>>> frank = User.objects.create_user('frank','frank@example.com','password')
+>>> jane = User.objects.create_user('jane','jane@example.com','password')
+
+# Now test that the forward declared Membership works
+>>> Membership.objects.create(person=bob, group=rock)
+<Membership: Bob is a member of Rock>
+
+>>> Membership.objects.create(person=bob, group=roll)
+<Membership: Bob is a member of Roll>
+
+>>> Membership.objects.create(person=jim, group=rock)
+<Membership: Jim is a member of Rock>
+
+>>> bob.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+>>> roll.members.all()
+[<Person: Bob>]
+
+# Error messages use the model name, not repr of the class name
+>>> bob.group_set = []
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> roll.members = []
+Traceback (most recent call last):
+...
+AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> rock.members.create(name='Anne')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+>>> bob.group_set.create(name='Funk')
+Traceback (most recent call last):
+...
+AttributeError: Cannot use create() on a ManyToManyField which specifies an intermediary model. Use Membership's Manager instead.
+
+# Now test that the intermediate with a relationship outside
+# the current app (i.e., UserMembership) workds
+>>> UserMembership.objects.create(user=frank, group=rock)
+<UserMembership: frank is a user and member of Rock>
+
+>>> UserMembership.objects.create(user=frank, group=roll)
+<UserMembership: frank is a user and member of Roll>
+
+>>> UserMembership.objects.create(user=jane, group=rock)
+<UserMembership: jane is a user and member of Rock>
+
+>>> frank.group_set.all()
+[<Group: Rock>, <Group: Roll>]
+
+>>> roll.user_members.all()
+[<User: frank>]
+
+"""} \ No newline at end of file
diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py
index 9d2e2abe96..be59234342 100644
--- a/tests/regressiontests/mail/tests.py
+++ b/tests/regressiontests/mail/tests.py
@@ -3,6 +3,7 @@ r"""
# Tests for the django.core.mail.
>>> from django.core.mail import EmailMessage
+>>> from django.utils.translation import ugettext_lazy
# Test normal ascii character case:
@@ -36,6 +37,12 @@ r"""
>>> message = email.message()
Traceback (most recent call last):
...
-BadHeaderError: Header values can't contain newlines (got 'Subject\nInjection Test' for header 'Subject')
+BadHeaderError: Header values can't contain newlines (got u'Subject\nInjection Test' for header 'Subject')
+
+>>> email = EmailMessage(ugettext_lazy('Subject\nInjection Test'), 'Content', 'from@example.com', ['to@example.com'])
+>>> message = email.message()
+Traceback (most recent call last):
+ ...
+BadHeaderError: Header values can't contain newlines (got u'Subject\nInjection Test' for header 'Subject')
"""
diff --git a/tests/regressiontests/many_to_one_regress/models.py b/tests/regressiontests/many_to_one_regress/models.py
index 429bdd7558..b87b36cb3b 100644
--- a/tests/regressiontests/many_to_one_regress/models.py
+++ b/tests/regressiontests/many_to_one_regress/models.py
@@ -55,31 +55,46 @@ __test__ = {'API_TESTS':"""
<Child: Child object>
#
-# Tests of ForeignKey assignment and the related-object cache (see #6886)
+# Tests of ForeignKey assignment and the related-object cache (see #6886).
#
>>> p = Parent.objects.create(name="Parent")
>>> c = Child.objects.create(name="Child", parent=p)
-# Look up the object again so that we get a "fresh" object
+# Look up the object again so that we get a "fresh" object.
>>> c = Child.objects.get(name="Child")
>>> p = c.parent
-# Accessing the related object again returns the exactly same object
+# Accessing the related object again returns the exactly same object.
>>> c.parent is p
True
-# But if we kill the cache, we get a new object
+# But if we kill the cache, we get a new object.
>>> del c._parent_cache
>>> c.parent is p
False
-# Assigning a new object results in that object getting cached immediately
+# Assigning a new object results in that object getting cached immediately.
>>> p2 = Parent.objects.create(name="Parent 2")
>>> c.parent = p2
>>> c.parent is p2
True
-# Assigning None fails: Child.parent is null=False
+# Assigning None succeeds if field is null=True.
+>>> p.bestchild = None
+>>> p.bestchild is None
+True
+
+# bestchild should still be None after saving.
+>>> p.save()
+>>> p.bestchild is None
+True
+
+# bestchild should still be None after fetching the object again.
+>>> p = Parent.objects.get(name="Parent")
+>>> p.bestchild is None
+True
+
+# Assigning None fails: Child.parent is null=False.
>>> c.parent = None
Traceback (most recent call last):
...
@@ -91,8 +106,31 @@ Traceback (most recent call last):
...
ValueError: Cannot assign "<First: First object>": "Child.parent" must be a "Parent" instance.
-# Test of multiple ForeignKeys to the same model (bug #7125)
+# Creation using keyword argument should cache the related object.
+>>> p = Parent.objects.get(name="Parent")
+>>> c = Child(parent=p)
+>>> c.parent is p
+True
+
+# Creation using keyword argument and unsaved related instance (#8070).
+>>> p = Parent()
+>>> c = Child(parent=p)
+>>> c.parent is p
+True
+# Creation using attname keyword argument and an id will cause the related
+# object to be fetched.
+>>> p = Parent.objects.get(name="Parent")
+>>> c = Child(parent_id=p.id)
+>>> c.parent is p
+False
+>>> c.parent == p
+True
+
+
+#
+# Test of multiple ForeignKeys to the same model (bug #7125).
+#
>>> c1 = Category.objects.create(name='First')
>>> c2 = Category.objects.create(name='Second')
>>> c3 = Category.objects.create(name='Third')
diff --git a/tests/regressiontests/max_lengths/tests.py b/tests/regressiontests/max_lengths/tests.py
index 0ef407f573..fb62ce634a 100644
--- a/tests/regressiontests/max_lengths/tests.py
+++ b/tests/regressiontests/max_lengths/tests.py
@@ -13,7 +13,7 @@ class MaxLengthArgumentsTests(TestCase):
self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200)
self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100)
- def test_custom_maxlengths(self):
+ def test_custom_max_lengths(self):
self.verify_max_length(PersonWithCustomMaxLengths, 'email', 384)
self.verify_max_length(PersonWithCustomMaxLengths, 'vcard', 1024)
self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 256)
diff --git a/tests/regressiontests/maxlength/tests.py b/tests/regressiontests/maxlength/tests.py
deleted file mode 100644
index c7ed1f91c0..0000000000
--- a/tests/regressiontests/maxlength/tests.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Test access to max_length while still providing full backwards compatibility
-# with legacy maxlength attribute.
-"""
-
-Don't print out the deprecation warnings during testing.
->>> from warnings import filterwarnings
->>> filterwarnings("ignore")
-
-# legacy_maxlength function
-
->>> from django.utils.maxlength import legacy_maxlength
-
->>> legacy_maxlength(None, None)
-
-
->>> legacy_maxlength(10, None)
-10
-
->>> legacy_maxlength(None, 10)
-10
-
->>> legacy_maxlength(10, 12)
-Traceback (most recent call last):
-...
-TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
-
->>> legacy_maxlength(0, 10)
-Traceback (most recent call last):
-...
-TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
-
->>> legacy_maxlength(0, None)
-0
-
->>> legacy_maxlength(None, 0)
-0
-
-#===============================================================================
-# Fields
-#===============================================================================
-
-# Set up fields
->>> from django.db.models import fields
->>> new = fields.Field(max_length=15)
->>> old = fields.Field(maxlength=10)
-
-# Ensure both max_length and legacy maxlength are not able to both be specified
->>> fields.Field(maxlength=10, max_length=15)
-Traceback (most recent call last):
- ...
-TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
-
-# Test max_length
->>> new.max_length
-15
->>> old.max_length
-10
-
-# Test accessing maxlength
->>> new.maxlength
-15
->>> old.maxlength
-10
-
-# Test setting maxlength
->>> new.maxlength += 1
->>> old.maxlength += 1
->>> new.max_length
-16
->>> old.max_length
-11
-
-# SlugField __init__ passes through max_length so test that too
->>> fields.SlugField('new', max_length=15).max_length
-15
->>> fields.SlugField('empty').max_length
-50
->>> fields.SlugField('old', maxlength=10).max_length
-10
-
-#===============================================================================
-# (old)forms
-#===============================================================================
-
->>> from django import oldforms
-
-# Test max_length attribute
-
->>> oldforms.TextField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vTextField" name="new" size="30" value="" maxlength="15" />'
-
->>> oldforms.IntegerField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vIntegerField" name="new" size="10" value="" maxlength="15" />'
-
->>> oldforms.SmallIntegerField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vSmallIntegerField" name="new" size="5" value="" maxlength="15" />'
-
->>> oldforms.PositiveIntegerField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vPositiveIntegerField" name="new" size="10" value="" maxlength="15" />'
-
->>> oldforms.PositiveSmallIntegerField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vPositiveSmallIntegerField" name="new" size="5" value="" maxlength="15" />'
-
->>> oldforms.DatetimeField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vDatetimeField" name="new" size="30" value="" maxlength="15" />'
-
->>> oldforms.EmailField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vEmailField" name="new" size="50" value="" maxlength="15" />'
->>> oldforms.EmailField('new').render('')
-u'<input type="text" id="id_new" class="vEmailField" name="new" size="50" value="" maxlength="75" />'
-
->>> oldforms.URLField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vURLField" name="new" size="50" value="" maxlength="15" />'
->>> oldforms.URLField('new').render('')
-u'<input type="text" id="id_new" class="vURLField" name="new" size="50" value="" maxlength="200" />'
-
->>> oldforms.IPAddressField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vIPAddressField" name="new" size="15" value="" maxlength="15" />'
->>> oldforms.IPAddressField('new').render('')
-u'<input type="text" id="id_new" class="vIPAddressField" name="new" size="15" value="" maxlength="15" />'
-
->>> oldforms.CommaSeparatedIntegerField('new', max_length=15).render('')
-u'<input type="text" id="id_new" class="vCommaSeparatedIntegerField" name="new" size="20" value="" maxlength="15" />'
-
-
-# Test legacy maxlength attribute
-
->>> oldforms.TextField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vTextField" name="old" size="30" value="" maxlength="10" />'
-
->>> oldforms.IntegerField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vIntegerField" name="old" size="10" value="" maxlength="10" />'
-
->>> oldforms.SmallIntegerField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vSmallIntegerField" name="old" size="5" value="" maxlength="10" />'
-
->>> oldforms.PositiveIntegerField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vPositiveIntegerField" name="old" size="10" value="" maxlength="10" />'
-
->>> oldforms.PositiveSmallIntegerField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vPositiveSmallIntegerField" name="old" size="5" value="" maxlength="10" />'
-
->>> oldforms.DatetimeField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vDatetimeField" name="old" size="30" value="" maxlength="10" />'
-
->>> oldforms.EmailField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vEmailField" name="old" size="50" value="" maxlength="10" />'
-
->>> oldforms.URLField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vURLField" name="old" size="50" value="" maxlength="10" />'
-
->>> oldforms.IPAddressField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vIPAddressField" name="old" size="15" value="" maxlength="10" />'
-
->>> oldforms.CommaSeparatedIntegerField('old', maxlength=10).render('')
-u'<input type="text" id="id_old" class="vCommaSeparatedIntegerField" name="old" size="20" value="" maxlength="10" />'
-"""
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
diff --git a/tests/regressiontests/model_fields/models.py b/tests/regressiontests/model_fields/models.py
index 7e07227961..455e2b3ded 100644
--- a/tests/regressiontests/model_fields/models.py
+++ b/tests/regressiontests/model_fields/models.py
@@ -1,8 +1,14 @@
from django.db import models
+try:
+ import decimal
+except ImportError:
+ from django.utils import _decimal as decimal # Python 2.3 fallback
+
class Foo(models.Model):
a = models.CharField(max_length=10)
+ d = models.DecimalField(max_digits=5, decimal_places=3)
def get_foo():
return Foo.objects.get(id=1)
@@ -11,9 +17,25 @@ class Bar(models.Model):
b = models.CharField(max_length=10)
a = models.ForeignKey(Foo, default=get_foo)
+class Whiz(models.Model):
+ CHOICES = (
+ ('Group 1', (
+ (1,'First'),
+ (2,'Second'),
+ )
+ ),
+ ('Group 2', (
+ (3,'Third'),
+ (4,'Fourth'),
+ )
+ ),
+ (0,'Other'),
+ )
+ c = models.IntegerField(choices=CHOICES, null=True)
+
__test__ = {'API_TESTS':"""
# Create a couple of Places.
->>> f = Foo.objects.create(a='abc')
+>>> f = Foo.objects.create(a='abc', d=decimal.Decimal("12.34"))
>>> f.id
1
>>> b = Bar(b = "bcd")
@@ -21,4 +43,40 @@ __test__ = {'API_TESTS':"""
<Foo: Foo object>
>>> b.save()
+# Regression tests for #7913
+# Check that get_choices and get_flatchoices interact with
+# get_FIELD_display to return the expected values.
+
+# Test a nested value
+>>> w = Whiz(c=1)
+>>> w.save()
+>>> w.get_c_display()
+u'First'
+
+# Test a top level value
+>>> w.c = 0
+>>> w.get_c_display()
+u'Other'
+
+# Test an invalid data value
+>>> w.c = 9
+>>> w.get_c_display()
+9
+
+# Test a blank data value
+>>> w.c = None
+>>> print w.get_c_display()
+None
+
+# Test an empty data value
+>>> w.c = ''
+>>> w.get_c_display()
+u''
+
+# Regression test for #8023: should be able to filter decimal fields using
+# strings (which is what gets passed through from, e.g., the admin interface).
+>>> Foo.objects.filter(d=u'1.23')
+[]
+
+
"""}
diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
index c2ba9ee008..5aedcd15fc 100644
--- a/tests/regressiontests/model_fields/tests.py
+++ b/tests/regressiontests/model_fields/tests.py
@@ -1,15 +1,19 @@
"""
>>> from django.db.models.fields import *
+>>> try:
+... from decimal import Decimal
+... except ImportError:
+... from django.utils._decimal import Decimal
# DecimalField
->>> f = DecimalField()
+>>> f = DecimalField(max_digits=4, decimal_places=2)
->>> f.to_python(3)
-Decimal("3")
+>>> f.to_python(3) == Decimal("3")
+True
->>> f.to_python("3.14")
-Decimal("3.14")
+>>> f.to_python("3.14") == Decimal("3.14")
+True
>>> f.to_python("abc")
Traceback (most recent call last):
@@ -20,16 +24,26 @@ ValidationError: [u'This value must be a decimal number.']
>>> x = f.to_python(2)
>>> y = f.to_python('2.6')
->>> f.get_db_prep_save(x)
+>>> f._format(x)
u'2.0'
->>> f.get_db_prep_save(y)
+>>> f._format(y)
u'2.6'
->>> f.get_db_prep_save(None)
->>> f.get_db_prep_lookup('exact', x)
-[u'2.0']
->>> f.get_db_prep_lookup('exact', y)
-[u'2.6']
+>>> f._format(None)
>>> f.get_db_prep_lookup('exact', None)
[None]
+# DateTimeField and TimeField to_python should support usecs:
+>>> f = DateTimeField()
+>>> f.to_python('2001-01-02 03:04:05.000006')
+datetime.datetime(2001, 1, 2, 3, 4, 5, 6)
+>>> f.to_python('2001-01-02 03:04:05.999999')
+datetime.datetime(2001, 1, 2, 3, 4, 5, 999999)
+
+>>> f = TimeField()
+>>> f.to_python('01:02:03.000004')
+datetime.time(1, 2, 3, 4)
+>>> f.to_python('01:02:03.999999')
+datetime.time(1, 2, 3, 999999)
+
+
"""
diff --git a/tests/regressiontests/model_inheritance_regress/models.py b/tests/regressiontests/model_inheritance_regress/models.py
index b78b493e15..716c7f5ad8 100644
--- a/tests/regressiontests/model_inheritance_regress/models.py
+++ b/tests/regressiontests/model_inheritance_regress/models.py
@@ -43,12 +43,22 @@ class ParkingLot(Place):
def __unicode__(self):
return u"%s the parking lot" % self.name
+class Supplier(models.Model):
+ restaurant = models.ForeignKey(Restaurant)
+
class Parent(models.Model):
created = models.DateTimeField(default=datetime.datetime.now)
class Child(Parent):
name = models.CharField(max_length=10)
+class SelfRefParent(models.Model):
+ parent_data = models.IntegerField()
+ self_data = models.ForeignKey('self', null=True)
+
+class SelfRefChild(SelfRefParent):
+ child_data = models.IntegerField()
+
__test__ = {'API_TESTS':"""
# Regression for #7350, #7202
# Check that when you create a Parent object with a specific reference to an
@@ -159,4 +169,29 @@ Traceback (most recent call last):
...
DoesNotExist: ItalianRestaurant matching query does not exist.
+# Regression test for #6755
+>>> r = Restaurant(serves_pizza=False)
+>>> r.save()
+>>> r.id == r.place_ptr_id
+True
+>>> orig_id = r.id
+>>> r = Restaurant(place_ptr_id=orig_id, serves_pizza=True)
+>>> r.save()
+>>> r.id == orig_id
+True
+>>> r.id == r.place_ptr_id
+True
+
+# Regression test for #7488. This looks a little crazy, but it's the equivalent
+# of what the admin interface has to do for the edit-inline case.
+>>> Supplier.objects.filter(restaurant=Restaurant(name='xx', address='yy'))
+[]
+
+# Regression test for #7853
+# If the parent class has a self-referential link, make sure that any updates
+# to that link via the child update the right table.
+
+>>> obj = SelfRefChild.objects.create(child_data=37, parent_data=42)
+>>> obj.delete()
+
"""}
diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py
index 2252531564..9e11b43d2b 100644
--- a/tests/regressiontests/model_regress/models.py
+++ b/tests/regressiontests/model_regress/models.py
@@ -29,6 +29,9 @@ class Movie(models.Model):
class Party(models.Model):
when = models.DateField()
+class Event(models.Model):
+ when = models.DateTimeField()
+
__test__ = {'API_TESTS': """
(NOTE: Part of the regression test here is merely parsing the model
declaration. The verbose_name, in particular, did not always work.)
@@ -68,5 +71,21 @@ u''
>>> [p.when for p in Party.objects.filter(when__year = 1998)]
[datetime.date(1998, 12, 31)]
+# Check that get_next_by_FIELD and get_previous_by_FIELD don't crash when we
+# have usecs values stored on the database
+#
+# [It crashed after the Field.get_db_prep_* refactor, because on most backends
+# DateTimeFields supports usecs, but DateTimeField.to_python didn't recognize
+# them. (Note that Model._get_next_or_previous_by_FIELD coerces values to
+# strings)]
+#
+>>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 16, 0, 0))
+>>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 6, 1, 1))
+>>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 13, 1, 1))
+>>> e = Event.objects.create(when = datetime.datetime(2000, 1, 1, 12, 0, 20, 24))
+>>> e.get_next_by_when().when
+datetime.datetime(2000, 1, 1, 13, 1, 1)
+>>> e.get_previous_by_when().when
+datetime.datetime(2000, 1, 1, 6, 1, 1)
"""
}
diff --git a/tests/regressiontests/modeladmin/models.py b/tests/regressiontests/modeladmin/models.py
index 6a7da7d362..0fdd9afdf1 100644
--- a/tests/regressiontests/modeladmin/models.py
+++ b/tests/regressiontests/modeladmin/models.py
@@ -346,6 +346,20 @@ Traceback (most recent call last):
...
ImproperlyConfigured: Both fieldsets and fields are specified in ValidationTestModelAdmin.
+>>> class ValidationTestModelAdmin(ModelAdmin):
+... fieldsets = [(None, {'fields': ['name', 'name']})]
+>>> validate(ValidationTestModelAdmin, ValidationTestModel)
+Traceback (most recent call last):
+...
+ImproperlyConfigured: There are duplicate field(s) in ValidationTestModelAdmin.fieldsets
+
+>>> class ValidationTestModelAdmin(ModelAdmin):
+... fields = ["name", "name"]
+>>> validate(ValidationTestModelAdmin, ValidationTestModel)
+Traceback (most recent call last):
+...
+ImproperlyConfigured: There are duplicate field(s) in ValidationTestModelAdmin.fields
+
# form
>>> class FakeForm(object):
diff --git a/tests/regressiontests/null_fk/models.py b/tests/regressiontests/null_fk/models.py
index 1bc266c033..529dde5039 100644
--- a/tests/regressiontests/null_fk/models.py
+++ b/tests/regressiontests/null_fk/models.py
@@ -1,8 +1,5 @@
"""
-Regression tests for proper working of ForeignKey(null=True). Tests these bugs:
-
- * #7369: FK non-null after null relationship on select_related() generates an invalid query
-
+Regression tests for proper working of ForeignKey(null=True).
"""
from django.db import models
@@ -38,7 +35,8 @@ __test__ = {'API_TESTS':"""
# Starting from comment, make sure that a .select_related(...) with a specified
# set of fields will properly LEFT JOIN multiple levels of NULLs (and the things
-# that come after the NULLs, or else data that should exist won't).
+# that come after the NULLs, or else data that should exist won't). Regression
+# test for #7369.
>>> c = Comment.objects.select_related().get(id=1)
>>> c.post
<Post: First Post>
@@ -47,9 +45,11 @@ __test__ = {'API_TESTS':"""
None
>>> comments = Comment.objects.select_related('post__forum__system_info').all()
->>> [(c.id, c.post.id) for c in comments]
-[(1, 1), (2, None)]
->>> [(c.comment_text, c.post.title) for c in comments]
-[(u'My first comment', u'First Post'), (u'My second comment', None)]
+>>> [(c.id, c.comment_text, c.post) for c in comments]
+[(1, u'My first comment', <Post: First Post>), (2, u'My second comment', None)]
+
+# Regression test for #7530, #7716.
+>>> Comment.objects.select_related('post').filter(post__isnull=True)[0].post is None
+True
"""}
diff --git a/tests/regressiontests/one_to_one_regress/models.py b/tests/regressiontests/one_to_one_regress/models.py
index 99022882f2..66d00d7223 100644
--- a/tests/regressiontests/one_to_one_regress/models.py
+++ b/tests/regressiontests/one_to_one_regress/models.py
@@ -22,6 +22,10 @@ class Bar(models.Model):
def __unicode__(self):
return u"%s the bar" % self.place.name
+class UndergroundBar(models.Model):
+ place = models.OneToOneField(Place, null=True)
+ serves_cocktails = models.BooleanField()
+
class Favorites(models.Model):
name = models.CharField(max_length = 50)
restaurants = models.ManyToManyField(Restaurant)
@@ -42,7 +46,7 @@ __test__ = {'API_TESTS':"""
>>> f.restaurants.all()
[<Restaurant: Demon Dogs the restaurant>]
-# Regression test for #7173: Check that the name of the cache for the
+# Regression test for #7173: Check that the name of the cache for the
# reverse object is correct.
>>> b = Bar(place=p1, serves_cocktails=False)
>>> b.save()
@@ -53,7 +57,7 @@ __test__ = {'API_TESTS':"""
#
# Regression test for #6886 (the related-object cache)
-#
+#
# Look up the objects again so that we get "fresh" objects
>>> p = Place.objects.get(name="Demon Dogs")
@@ -76,6 +80,12 @@ False
>>> p.restaurant is r2
True
+# Assigning None succeeds if field is null=True.
+>>> ug_bar = UndergroundBar.objects.create(place=p, serves_cocktails=False)
+>>> ug_bar.place = None
+>>> ug_bar.place is None
+True
+
# Assigning None fails: Place.restaurant is null=False
>>> p.restaurant = None
Traceback (most recent call last):
@@ -88,4 +98,25 @@ Traceback (most recent call last):
...
ValueError: Cannot assign "<Place: Demon Dogs the place>": "Place.restaurant" must be a "Restaurant" instance.
+# Creation using keyword argument should cache the related object.
+>>> p = Place.objects.get(name="Demon Dogs")
+>>> r = Restaurant(place=p)
+>>> r.place is p
+True
+
+# Creation using keyword argument and unsaved related instance (#8070).
+>>> p = Place()
+>>> r = Restaurant(place=p)
+>>> r.place is p
+True
+
+# Creation using attname keyword argument and an id will cause the related
+# object to be fetched.
+>>> p = Place.objects.get(name="Demon Dogs")
+>>> r = Restaurant(place_id=p.id)
+>>> r.place is p
+False
+>>> r.place == p
+True
+
"""}
diff --git a/tests/regressiontests/pagination_regress/__init__.py b/tests/regressiontests/pagination_regress/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/pagination_regress/__init__.py
diff --git a/tests/regressiontests/pagination_regress/models.py b/tests/regressiontests/pagination_regress/models.py
new file mode 100644
index 0000000000..cde172db68
--- /dev/null
+++ b/tests/regressiontests/pagination_regress/models.py
@@ -0,0 +1 @@
+# Models file for tests to run.
diff --git a/tests/regressiontests/pagination_regress/tests.py b/tests/regressiontests/pagination_regress/tests.py
new file mode 100644
index 0000000000..08436df355
--- /dev/null
+++ b/tests/regressiontests/pagination_regress/tests.py
@@ -0,0 +1,157 @@
+from unittest import TestCase
+
+from django.core.paginator import Paginator, EmptyPage
+
+class PaginatorTests(TestCase):
+ """
+ Tests for the Paginator and Page classes.
+ """
+
+ def check_paginator(self, params, output):
+ """
+ Helper method that instantiates a Paginator object from the passed
+ params and then checks that its attributes match the passed output.
+ """
+ count, num_pages, page_range = output
+ paginator = Paginator(*params)
+ self.check_attribute('count', paginator, count, params)
+ self.check_attribute('num_pages', paginator, num_pages, params)
+ self.check_attribute('page_range', paginator, page_range, params)
+
+ def check_attribute(self, name, paginator, expected, params):
+ """
+ Helper method that checks a single attribute and gives a nice error
+ message upon test failure.
+ """
+ got = getattr(paginator, name)
+ self.assertEqual(expected, got,
+ "For '%s', expected %s but got %s. Paginator parameters were: %s"
+ % (name, expected, got, params))
+
+ def test_paginator(self):
+ """
+ Tests the paginator attributes using varying inputs.
+ """
+ nine = [1, 2, 3, 4, 5, 6, 7, 8, 9]
+ ten = nine + [10]
+ eleven = ten + [11]
+ tests = (
+ # Each item is two tuples:
+ # First tuple is Paginator parameters - object_list, per_page,
+ # orphans, and allow_empty_first_page.
+ # Second tuple is resulting Paginator attributes - count,
+ # num_pages, and page_range.
+ # Ten items, varying orphans, no empty first page.
+ ((ten, 4, 0, False), (10, 3, [1, 2, 3])),
+ ((ten, 4, 1, False), (10, 3, [1, 2, 3])),
+ ((ten, 4, 2, False), (10, 2, [1, 2])),
+ ((ten, 4, 5, False), (10, 2, [1, 2])),
+ ((ten, 4, 6, False), (10, 1, [1])),
+ # Ten items, varying orphans, allow empty first page.
+ ((ten, 4, 0, True), (10, 3, [1, 2, 3])),
+ ((ten, 4, 1, True), (10, 3, [1, 2, 3])),
+ ((ten, 4, 2, True), (10, 2, [1, 2])),
+ ((ten, 4, 5, True), (10, 2, [1, 2])),
+ ((ten, 4, 6, True), (10, 1, [1])),
+ # One item, varying orphans, no empty first page.
+ (([1], 4, 0, False), (1, 1, [1])),
+ (([1], 4, 1, False), (1, 1, [1])),
+ (([1], 4, 2, False), (1, 1, [1])),
+ # One item, varying orphans, allow empty first page.
+ (([1], 4, 0, True), (1, 1, [1])),
+ (([1], 4, 1, True), (1, 1, [1])),
+ (([1], 4, 2, True), (1, 1, [1])),
+ # Zero items, varying orphans, no empty first page.
+ (([], 4, 0, False), (0, 0, [])),
+ (([], 4, 1, False), (0, 0, [])),
+ (([], 4, 2, False), (0, 0, [])),
+ # Zero items, varying orphans, allow empty first page.
+ (([], 4, 0, True), (0, 1, [1])),
+ (([], 4, 1, True), (0, 1, [1])),
+ (([], 4, 2, True), (0, 1, [1])),
+ # Number if items one less than per_page.
+ (([], 1, 0, True), (0, 1, [1])),
+ (([], 1, 0, False), (0, 0, [])),
+ (([1], 2, 0, True), (1, 1, [1])),
+ ((nine, 10, 0, True), (9, 1, [1])),
+ # Number if items equal to per_page.
+ (([1], 1, 0, True), (1, 1, [1])),
+ (([1, 2], 2, 0, True), (2, 1, [1])),
+ ((ten, 10, 0, True), (10, 1, [1])),
+ # Number if items one more than per_page.
+ (([1, 2], 1, 0, True), (2, 2, [1, 2])),
+ (([1, 2, 3], 2, 0, True), (3, 2, [1, 2])),
+ ((eleven, 10, 0, True), (11, 2, [1, 2])),
+ # Number if items one more than per_page with one orphan.
+ (([1, 2], 1, 1, True), (2, 1, [1])),
+ (([1, 2, 3], 2, 1, True), (3, 1, [1])),
+ ((eleven, 10, 1, True), (11, 1, [1])),
+ )
+ for params, output in tests:
+ self.check_paginator(params, output)
+
+ def check_indexes(self, params, page_num, indexes):
+ """
+ Helper method that instantiates a Paginator object from the passed
+ params and then checks that the start and end indexes of the passed
+ page_num match those given as a 2-tuple in indexes.
+ """
+ paginator = Paginator(*params)
+ if page_num == 'first':
+ page_num = 1
+ elif page_num == 'last':
+ page_num = paginator.num_pages
+ page = paginator.page(page_num)
+ start, end = indexes
+ msg = ("For %s of page %s, expected %s but got %s."
+ " Paginator parameters were: %s")
+ self.assertEqual(start, page.start_index(),
+ msg % ('start index', page_num, start, page.start_index(), params))
+ self.assertEqual(end, page.end_index(),
+ msg % ('end index', page_num, end, page.end_index(), params))
+
+ def test_page_indexes(self):
+ """
+ Tests that paginator pages have the correct start and end indexes.
+ """
+ ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ tests = (
+ # Each item is three tuples:
+ # First tuple is Paginator parameters - object_list, per_page,
+ # orphans, and allow_empty_first_page.
+ # Second tuple is the start and end indexes of the first page.
+ # Third tuple is the start and end indexes of the last page.
+ # Ten items, varying per_page, no orphans.
+ ((ten, 1, 0, True), (1, 1), (10, 10)),
+ ((ten, 2, 0, True), (1, 2), (9, 10)),
+ ((ten, 3, 0, True), (1, 3), (10, 10)),
+ ((ten, 5, 0, True), (1, 5), (6, 10)),
+ # Ten items, varying per_page, with orphans.
+ ((ten, 1, 1, True), (1, 1), (9, 10)),
+ ((ten, 1, 2, True), (1, 1), (8, 10)),
+ ((ten, 3, 1, True), (1, 3), (7, 10)),
+ ((ten, 3, 2, True), (1, 3), (7, 10)),
+ ((ten, 3, 4, True), (1, 3), (4, 10)),
+ ((ten, 5, 1, True), (1, 5), (6, 10)),
+ ((ten, 5, 2, True), (1, 5), (6, 10)),
+ ((ten, 5, 5, True), (1, 10), (1, 10)),
+ # One item, varying orphans, no empty first page.
+ (([1], 4, 0, False), (1, 1), (1, 1)),
+ (([1], 4, 1, False), (1, 1), (1, 1)),
+ (([1], 4, 2, False), (1, 1), (1, 1)),
+ # One item, varying orphans, allow empty first page.
+ (([1], 4, 0, True), (1, 1), (1, 1)),
+ (([1], 4, 1, True), (1, 1), (1, 1)),
+ (([1], 4, 2, True), (1, 1), (1, 1)),
+ # Zero items, varying orphans, allow empty first page.
+ (([], 4, 0, True), (0, 0), (0, 0)),
+ (([], 4, 1, True), (0, 0), (0, 0)),
+ (([], 4, 2, True), (0, 0), (0, 0)),
+ )
+ for params, first, last in tests:
+ self.check_indexes(params, 'first', first)
+ self.check_indexes(params, 'last', last)
+ # When no items and no empty first page, we should get EmptyPage error.
+ self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 0, False), 1, None)
+ self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 1, False), 1, None)
+ self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 2, False), 1, None)
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index 847d515422..3a4acf350a 100644
--- a/tests/regressiontests/queries/models.py
+++ b/tests/regressiontests/queries/models.py
@@ -190,6 +190,32 @@ class CustomPk(models.Model):
class Related(models.Model):
custom = models.ForeignKey(CustomPk)
+# An inter-related setup with a model subclass that has a nullable
+# path to another model, and a return path from that model.
+
+class Celebrity(models.Model):
+ name = models.CharField("Name", max_length=20)
+ greatest_fan = models.ForeignKey("Fan", null=True, unique=True)
+
+class TvChef(Celebrity):
+ pass
+
+class Fan(models.Model):
+ fan_of = models.ForeignKey(Celebrity)
+
+# Multiple foreign keys
+class LeafA(models.Model):
+ data = models.CharField(max_length=10)
+
+ def __unicode__(self):
+ return self.data
+
+class LeafB(models.Model):
+ data = models.CharField(max_length=10)
+
+class Join(models.Model):
+ a = models.ForeignKey(LeafA)
+ b = models.ForeignKey(LeafB)
__test__ = {'API_TESTS':"""
>>> t1 = Tag.objects.create(name='t1')
@@ -321,6 +347,16 @@ constraints.
>>> Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4))
[<Number: 8>]
+Bug #7872
+Another variation on the disjunctive filtering theme.
+
+# For the purposes of this regression test, it's important that there is no
+# Join object releated to the LeafA we create.
+>>> LeafA.objects.create(data='first')
+<LeafA: first>
+>>> LeafA.objects.filter(Q(data='first')|Q(join__b__data='second'))
+[<LeafA: first>]
+
Bug #6074
Merging two empty result sets shouldn't leave a queryset with no constraints
(which would match everything).
@@ -417,9 +453,9 @@ Bug #5324, #6704
>>> query.LOUTER not in [x[2] for x in query.alias_map.values()]
True
-Similarly, when one of the joins cannot possibly, ever, involve NULL values (Author -> ExtraInfo, in the following), it should never be promoted to a left outer join. So hte following query should only involve one "left outer" join (Author -> Item is 0-to-many).
+Similarly, when one of the joins cannot possibly, ever, involve NULL values (Author -> ExtraInfo, in the following), it should never be promoted to a left outer join. So the following query should only involve one "left outer" join (Author -> Item is 0-to-many).
>>> qs = Author.objects.filter(id=a1.id).filter(Q(extra__note=n1)|Q(item__note=n3))
->>> len([x[2] for x in qs.query.alias_map.values() if x[2] == query.LOUTER])
+>>> len([x[2] for x in qs.query.alias_map.values() if x[2] == query.LOUTER and qs.query.alias_refcount[x[1]]])
1
The previous changes shouldn't affect nullable foreign key joins.
@@ -785,6 +821,15 @@ Bug #7204, #7506 -- make sure querysets with related fields can be pickled. If
this doesn't crash, it's a Good Thing.
>>> out = pickle.dumps(Item.objects.all())
+We should also be able to pickle things that use select_related(). The only
+tricky thing here is to ensure that we do the related selections properly after
+unpickling.
+>>> qs = Item.objects.select_related()
+>>> query = qs.query.as_sql()[0]
+>>> query2 = pickle.loads(pickle.dumps(qs.query))
+>>> query2.as_sql()[0] == query
+True
+
Bug #7277
>>> ann1 = Annotation.objects.create(name='a1', tag=t1)
>>> ann1.notes.add(n1)
@@ -822,6 +867,26 @@ Bug #7759 -- count should work with a partially read result set.
... break
True
+Bug #7791 -- there were "issues" when ordering and distinct-ing on fields
+related via ForeignKeys.
+>>> len(Note.objects.order_by('extrainfo__info').distinct())
+3
+
+Bug #7778 - Model subclasses could not be deleted if a nullable foreign key
+relates to a model that relates back.
+
+>>> num_celebs = Celebrity.objects.count()
+>>> tvc = TvChef.objects.create(name="Huey")
+>>> Celebrity.objects.count() == num_celebs + 1
+True
+>>> f1 = Fan.objects.create(fan_of=tvc)
+>>> f2 = Fan.objects.create(fan_of=tvc)
+>>> tvc.delete()
+
+# The parent object should have been deleted as well.
+>>> Celebrity.objects.count() == num_celebs
+True
+
"""}
# In Python 2.3, exceptions raised in __len__ are swallowed (Python issue
diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
index aaaef1d8b0..a091113515 100644
--- a/tests/regressiontests/requests/tests.py
+++ b/tests/regressiontests/requests/tests.py
@@ -20,8 +20,9 @@ META:{...}>
... def __init__(self, *args, **kwargs):
... super(FakeModPythonRequest, self).__init__(*args, **kwargs)
... self._get = self._post = self._meta = self._cookies = {}
->>> class Dummy: pass
-...
+>>> class Dummy:
+... def get_options(self):
+... return {}
>>> req = Dummy()
>>> req.uri = 'bogus'
>>> print repr(FakeModPythonRequest(req))
diff --git a/tests/regressiontests/reverse_single_related/__init__.py b/tests/regressiontests/reverse_single_related/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/reverse_single_related/__init__.py
diff --git a/tests/regressiontests/reverse_single_related/models.py b/tests/regressiontests/reverse_single_related/models.py
new file mode 100644
index 0000000000..b2b75392aa
--- /dev/null
+++ b/tests/regressiontests/reverse_single_related/models.py
@@ -0,0 +1,54 @@
+"""
+Regression tests for an object that cannot access a single related object due
+to a restrictive default manager.
+"""
+
+from django.db import models
+
+
+class SourceManager(models.Manager):
+ def get_query_set(self):
+ return super(SourceManager, self).get_query_set().filter(is_public=True)
+
+class Source(models.Model):
+ is_public = models.BooleanField()
+ objects = SourceManager()
+
+class Item(models.Model):
+ source = models.ForeignKey(Source)
+
+
+__test__ = {'API_TESTS':"""
+
+>>> public_source = Source.objects.create(is_public=True)
+>>> public_item = Item.objects.create(source=public_source)
+
+>>> private_source = Source.objects.create(is_public=False)
+>>> private_item = Item.objects.create(source=private_source)
+
+# Only one source is available via all() due to the custom default manager.
+
+>>> Source.objects.all()
+[<Source: Source object>]
+
+>>> public_item.source
+<Source: Source object>
+
+# Make sure that an item can still access its related source even if the default
+# manager doesn't normally allow it.
+
+>>> private_item.source
+<Source: Source object>
+
+# If the manager is marked "use_for_related_fields", it'll get used instead
+# of the "bare" queryset. Usually you'd define this as a property on the class,
+# but this approximates that in a way that's easier in tests.
+
+>>> Source.objects.use_for_related_fields = True
+>>> private_item = Item.objects.get(pk=private_item.pk)
+>>> private_item.source
+Traceback (most recent call last):
+ ...
+DoesNotExist: Source matching query does not exist.
+
+"""}
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index 9bc5eec1eb..f990d57a17 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -72,13 +72,13 @@ def inherited_create(pk, klass, data):
# 1) we're testing inheritance, not field behaviour, so none
# of the field values need to be protected.
# 2) saving the child class and having the parent created
- # automatically is easier than manually creating both.
+ # automatically is easier than manually creating both.
models.Model.save(instance)
created = [instance]
for klass,field in instance._meta.parents.items():
created.append(klass.objects.get(id=pk))
return created
-
+
# A set of functions that can be used to compare
# test data objects of various kinds
def data_compare(testcase, pk, klass, data):
@@ -111,7 +111,7 @@ def inherited_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
for key,value in data.items():
testcase.assertEqual(value, getattr(instance,key))
-
+
# Define some data types. Each data type is
# actually a pair of functions; one to create
# and one to compare objects of that type
@@ -274,7 +274,7 @@ The end."""),
(data_obj, 800, AutoNowDateTimeData, datetime.datetime(2006,6,16,10,42,37)),
(data_obj, 810, ModifyingSaveData, 42),
-
+
(inherited_obj, 900, InheritAbstractModel, {'child_data':37,'parent_data':42}),
(inherited_obj, 910, ExplicitInheritBaseModel, {'child_data':37,'parent_data':42}),
(inherited_obj, 920, InheritBaseModel, {'child_data':37,'parent_data':42}),
@@ -302,17 +302,19 @@ def serializerTest(format, self):
objects = []
instance_count = {}
transaction.enter_transaction_management()
- transaction.managed(True)
- for (func, pk, klass, datum) in test_data:
- objects.extend(func[0](pk, klass, datum))
- instance_count[klass] = 0
- transaction.commit()
- transaction.leave_transaction_management()
+ try:
+ transaction.managed(True)
+ for (func, pk, klass, datum) in test_data:
+ objects.extend(func[0](pk, klass, datum))
+ instance_count[klass] = 0
+ transaction.commit()
+ finally:
+ transaction.leave_transaction_management()
# Get a count of the number of objects created for each class
for klass in instance_count:
instance_count[klass] = klass.objects.count()
-
+
# Add the generic tagged objects to the object list
objects.extend(Tag.objects.all())
@@ -322,11 +324,13 @@ def serializerTest(format, self):
# Flush the database and recreate from the serialized data
management.call_command('flush', verbosity=0, interactive=False)
transaction.enter_transaction_management()
- transaction.managed(True)
- for obj in serializers.deserialize(format, serialized_data):
- obj.save()
- transaction.commit()
- transaction.leave_transaction_management()
+ try:
+ transaction.managed(True)
+ for obj in serializers.deserialize(format, serialized_data):
+ obj.save()
+ transaction.commit()
+ finally:
+ transaction.leave_transaction_management()
# Assert that the deserialized data is the same
# as the original source
diff --git a/tests/regressiontests/templates/loaders.py b/tests/regressiontests/templates/loaders.py
index db37116b94..fdaf9ac83f 100644
--- a/tests/regressiontests/templates/loaders.py
+++ b/tests/regressiontests/templates/loaders.py
@@ -14,6 +14,7 @@ import sys
import pkg_resources
import imp
import StringIO
+import os.path
from django.template import TemplateDoesNotExist
from django.template.loaders.eggs import load_template_source as lts_egg
@@ -57,8 +58,8 @@ class EggLoader(unittest.TestCase):
self.empty_egg = create_egg("egg_empty", {})
self.egg_1 = create_egg("egg_1", {
- 'templates/y.html' : StringIO.StringIO("y"),
- 'templates/x.txt' : StringIO.StringIO("x"),
+ os.path.normcase('templates/y.html') : StringIO.StringIO("y"),
+ os.path.normcase('templates/x.txt') : StringIO.StringIO("x"),
})
self._old_installed_apps = settings.INSTALLED_APPS
settings.INSTALLED_APPS = []
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 186b8aacb5..13b8c6b488 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -11,6 +11,7 @@ import unittest
from datetime import datetime, timedelta
from django import template
+from django.core import urlresolvers
from django.template import loader
from django.template.loaders import app_directories, filesystem
from django.utils.translation import activate, deactivate, ugettext as _
@@ -565,6 +566,14 @@ class Templates(unittest.TestCase):
# ifchanged for the day.
'ifchanged-param04': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
+ # Test the else clause of ifchanged.
+ 'ifchanged-else01': ('{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-first,1-other,2-first,2-other,2-other,3-first,'),
+
+ 'ifchanged-else02': ('{% for id in ids %}{{ id }}-{% ifchanged id %}{% cycle red,blue %}{% else %}grey{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1-grey,2-blue,2-grey,2-grey,3-red,'),
+ 'ifchanged-else03': ('{% for id in ids %}{{ id }}{% ifchanged id %}-{% cycle red,blue %}{% else %}{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-red,1,2-blue,2,2,3-red,'),
+
+ 'ifchanged-else04': ('{% for id in ids %}{% ifchanged %}***{{ id }}*{% else %}...{% endifchanged %}{{ forloop.counter }}{% endfor %}', {'ids': [1,1,2,2,2,3,4]}, '***1*1...2***2*3...4...5***3*6***4*7'),
+
### IFEQUAL TAG ###########################################################
'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),
'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"),
@@ -712,7 +721,7 @@ class Templates(unittest.TestCase):
# Inheritance from a template that doesn't have any blocks
'inheritance27': ("{% extends 'inheritance26' %}", {}, 'no tags'),
-
+
### I18N ##################################################################
# {% spaceless %} tag
@@ -880,8 +889,8 @@ class Templates(unittest.TestCase):
# Failures
'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
- 'url-fail02': ('{% url no_such_view %}', {}, ''),
- 'url-fail03': ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''),
+ 'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
+ 'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
### CACHE TAG ######################################################
'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
@@ -893,16 +902,16 @@ class Templates(unittest.TestCase):
'cache07': ('{% load cache %}{% cache 2 test foo %}cache07{% endcache %}', {'foo': 1}, 'cache05'),
# Allow first argument to be a variable.
- 'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'),
- 'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'),
- 'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'),
+ 'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'),
+ 'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'),
+ 'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'),
# Raise exception if we don't have at least 2 args, first one integer.
'cache11': ('{% load cache %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError),
'cache12': ('{% load cache %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError),
'cache13': ('{% load cache %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError),
- 'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError),
- 'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError),
+ 'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError),
+ 'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError),
### AUTOESCAPE TAG ##############################################
'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
index 1eb55e312e..3518df3b9f 100644
--- a/tests/regressiontests/test_client_regress/models.py
+++ b/tests/regressiontests/test_client_regress/models.py
@@ -1,12 +1,10 @@
"""
Regression tests for the Test Client, especially the customized assertions.
-
"""
+
from django.test import Client, TestCase
from django.core.urlresolvers import reverse
from django.core.exceptions import SuspiciousOperation
-import os
-import sha
class AssertContainsTests(TestCase):
def test_contains(self):
@@ -24,7 +22,7 @@ class AssertContainsTests(TestCase):
self.assertNotContains(response, 'once')
except AssertionError, e:
self.assertEquals(str(e), "Response should not contain 'once'")
-
+
try:
self.assertContains(response, 'never', 1)
except AssertionError, e:
@@ -287,7 +285,7 @@ class URLEscapingTests(TestCase):
class ExceptionTests(TestCase):
fixtures = ['testdata.json']
-
+
def test_exception_cleared(self):
"#5836 - A stale user exception isn't re-raised by the test client."
@@ -300,7 +298,7 @@ class ExceptionTests(TestCase):
pass
# At this point, an exception has been raised, and should be cleared.
-
+
# This next operation should be successful; if it isn't we have a problem.
login = self.client.login(username='staff', password='password')
self.failUnless(login, 'Could not log in')
@@ -309,7 +307,7 @@ class ExceptionTests(TestCase):
except SuspiciousOperation:
self.fail("Staff should be able to visit this page")
-# We need two different tests to check URLconf subsitution - one to check
+# We need two different tests to check URLconf substitution - one to check
# it was changed, and another one (without self.urls) to check it was reverted on
# teardown. This pair of tests relies upon the alphabetical ordering of test execution.
class UrlconfSubstitutionTests(TestCase):
diff --git a/tests/regressiontests/test_utils/__init__.py b/tests/regressiontests/test_utils/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/test_utils/__init__.py
diff --git a/tests/regressiontests/test_utils/models.py b/tests/regressiontests/test_utils/models.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/test_utils/models.py
diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py
new file mode 100644
index 0000000000..a2539bf8c6
--- /dev/null
+++ b/tests/regressiontests/test_utils/tests.py
@@ -0,0 +1,72 @@
+r"""
+# Some checks of the doctest output normalizer.
+# Standard doctests do fairly
+>>> from django.utils import simplejson
+>>> from django.utils.xmlutils import SimplerXMLGenerator
+>>> from StringIO import StringIO
+
+>>> def produce_long():
+... return 42L
+
+>>> def produce_int():
+... return 42
+
+>>> def produce_json():
+... return simplejson.dumps(['foo', {'bar': ('baz', None, 1.0, 2), 'whiz': 42}])
+
+>>> def produce_xml():
+... stream = StringIO()
+... xml = SimplerXMLGenerator(stream, encoding='utf-8')
+... xml.startDocument()
+... xml.startElement("foo", {"aaa" : "1.0", "bbb": "2.0"})
+... xml.startElement("bar", {"ccc" : "3.0"})
+... xml.characters("Hello")
+... xml.endElement("bar")
+... xml.startElement("whiz", {})
+... xml.characters("Goodbye")
+... xml.endElement("whiz")
+... xml.endElement("foo")
+... xml.endDocument()
+... return stream.getvalue()
+
+>>> def produce_xml_fragment():
+... stream = StringIO()
+... xml = SimplerXMLGenerator(stream, encoding='utf-8')
+... xml.startElement("foo", {"aaa": "1.0", "bbb": "2.0"})
+... xml.characters("Hello")
+... xml.endElement("foo")
+... xml.startElement("bar", {"ccc": "3.0", "ddd": "4.0"})
+... xml.endElement("bar")
+... return stream.getvalue()
+
+# Long values are normalized and are comparable to normal integers ...
+>>> produce_long()
+42
+
+# ... and vice versa
+>>> produce_int()
+42L
+
+# JSON output is normalized for field order, so it doesn't matter
+# which order json dictionary attributes are listed in output
+>>> produce_json()
+'["foo", {"bar": ["baz", null, 1.0, 2], "whiz": 42}]'
+
+>>> produce_json()
+'["foo", {"whiz": 42, "bar": ["baz", null, 1.0, 2]}]'
+
+# XML output is normalized for attribute order, so it doesn't matter
+# which order XML element attributes are listed in output
+>>> produce_xml()
+'<?xml version="1.0" encoding="UTF-8"?>\n<foo aaa="1.0" bbb="2.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>'
+
+>>> produce_xml()
+'<?xml version="1.0" encoding="UTF-8"?>\n<foo bbb="2.0" aaa="1.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>'
+
+>>> produce_xml_fragment()
+'<foo aaa="1.0" bbb="2.0">Hello</foo><bar ccc="3.0" ddd="4.0"></bar>'
+
+>>> produce_xml_fragment()
+'<foo bbb="2.0" aaa="1.0">Hello</foo><bar ddd="4.0" ccc="3.0"></bar>'
+
+""" \ No newline at end of file
diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py
index 5d31d21318..8ac6b9ec7e 100644
--- a/tests/regressiontests/utils/datastructures.py
+++ b/tests/regressiontests/utils/datastructures.py
@@ -50,9 +50,3 @@
['second-two', 'one']
"""
-# Python 2.3 doesn't have sorted()
-try:
- sorted
-except NameError:
- from django.utils.itercompat import sorted
- \ No newline at end of file
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
index cd4762e02f..485c5faa75 100644
--- a/tests/regressiontests/utils/tests.py
+++ b/tests/regressiontests/utils/tests.py
@@ -11,6 +11,13 @@ import datastructures
import itercompat
from decorators import DecoratorFromMiddlewareTests
+# We need this because "datastructures" uses sorted() and the tests are run in
+# the scope of this module.
+try:
+ sorted
+except NameError:
+ from django.utils.itercompat import sorted # For Python 2.3
+
# Extra tests
__test__ = {
'timesince': timesince,