1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

[soc2010/test-refactor] Merged back up to trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/test-refactor@13566 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Paul McMillan 2010-08-09 22:11:28 +00:00
parent 6c7baa96d8
commit a2e30a41dd
108 changed files with 8165 additions and 1669 deletions

View File

@ -184,11 +184,13 @@ answer newbie questions, and generally made Django that much better:
Idan Gazit Idan Gazit
geber@datacollect.com geber@datacollect.com
Baishampayan Ghose Baishampayan Ghose
Joshua Ginsberg <jag@flowtheory.net>
Dimitris Glezos <dimitris@glezos.com> Dimitris Glezos <dimitris@glezos.com>
glin@seznam.cz glin@seznam.cz
martin.glueck@gmail.com martin.glueck@gmail.com
Artyom Gnilov <boobsd@gmail.com> Artyom Gnilov <boobsd@gmail.com>
Ben Godfrey <http://aftnn.org> Ben Godfrey <http://aftnn.org>
Andrew Godwin <andrew@aeracode.org>
GomoX <gomo@datafull.com> GomoX <gomo@datafull.com>
Guilherme Mesquita Gondim <semente@taurinus.org> Guilherme Mesquita Gondim <semente@taurinus.org>
Mario Gonzalez <gonzalemario@gmail.com> Mario Gonzalez <gonzalemario@gmail.com>
@ -337,6 +339,7 @@ answer newbie questions, and generally made Django that much better:
Aljosa Mohorovic <aljosa.mohorovic@gmail.com> Aljosa Mohorovic <aljosa.mohorovic@gmail.com>
Ramiro Morales <rm0@gmx.net> Ramiro Morales <rm0@gmx.net>
Eric Moritz <http://eric.themoritzfamily.com/> Eric Moritz <http://eric.themoritzfamily.com/>
Gregor Müllegger <gregor@muellegger.de>
Robin Munn <http://www.geekforgod.com/> Robin Munn <http://www.geekforgod.com/>
James Murty James Murty
msundstr msundstr

View File

@ -54,7 +54,7 @@ LANGUAGES = (
('en', gettext_noop('English')), ('en', gettext_noop('English')),
('en-gb', gettext_noop('British English')), ('en-gb', gettext_noop('British English')),
('es', gettext_noop('Spanish')), ('es', gettext_noop('Spanish')),
('es-ar', gettext_noop('Argentinean Spanish')), ('es-ar', gettext_noop('Argentinian Spanish')),
('et', gettext_noop('Estonian')), ('et', gettext_noop('Estonian')),
('eu', gettext_noop('Basque')), ('eu', gettext_noop('Basque')),
('fa', gettext_noop('Persian')), ('fa', gettext_noop('Persian')),
@ -78,6 +78,7 @@ LANGUAGES = (
('lt', gettext_noop('Lithuanian')), ('lt', gettext_noop('Lithuanian')),
('lv', gettext_noop('Latvian')), ('lv', gettext_noop('Latvian')),
('mk', gettext_noop('Macedonian')), ('mk', gettext_noop('Macedonian')),
('ml', gettext_noop('Malayalam')),
('mn', gettext_noop('Mongolian')), ('mn', gettext_noop('Mongolian')),
('nl', gettext_noop('Dutch')), ('nl', gettext_noop('Dutch')),
('no', gettext_noop('Norwegian')), ('no', gettext_noop('Norwegian')),

View File

@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-09 14:26+0200\n" "POT-Creation-Date: 2010-08-06 18:35+0200\n"
"PO-Revision-Date: 2010-05-09 14:09+0100\n" "PO-Revision-Date: 2010-08-06 18:33+0100\n"
"Last-Translator: Vlada Macek <macek@sandbox.cz>\n" "Last-Translator: Vlada Macek <macek@sandbox.cz>\n"
"Language-Team: Czech\n" "Language-Team: Czech\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -70,7 +70,7 @@ msgid "Spanish"
msgstr "španělsky" msgstr "španělsky"
#: conf/global_settings.py:57 #: conf/global_settings.py:57
msgid "Argentinean Spanish" msgid "Argentinian Spanish"
msgstr "španělsky (Argentina)" msgstr "španělsky (Argentina)"
#: conf/global_settings.py:58 #: conf/global_settings.py:58
@ -122,138 +122,146 @@ msgid "Hungarian"
msgstr "maďarsky" msgstr "maďarsky"
#: conf/global_settings.py:70 #: conf/global_settings.py:70
msgid "Indonesian"
msgstr "indonésky"
#: conf/global_settings.py:71
msgid "Icelandic" msgid "Icelandic"
msgstr "islandsky" msgstr "islandsky"
#: conf/global_settings.py:71 #: conf/global_settings.py:72
msgid "Italian" msgid "Italian"
msgstr "italsky" msgstr "italsky"
#: conf/global_settings.py:72 #: conf/global_settings.py:73
msgid "Japanese" msgid "Japanese"
msgstr "japonsky" msgstr "japonsky"
#: conf/global_settings.py:73 #: conf/global_settings.py:74
msgid "Georgian" msgid "Georgian"
msgstr "gruzínsky" msgstr "gruzínsky"
#: conf/global_settings.py:74 #: conf/global_settings.py:75
msgid "Khmer" msgid "Khmer"
msgstr "khmersky" msgstr "khmersky"
#: conf/global_settings.py:75 #: conf/global_settings.py:76
msgid "Kannada" msgid "Kannada"
msgstr "kannadsky" msgstr "kannadsky"
#: conf/global_settings.py:76 #: conf/global_settings.py:77
msgid "Korean" msgid "Korean"
msgstr "korejsky" msgstr "korejsky"
#: conf/global_settings.py:77 #: conf/global_settings.py:78
msgid "Lithuanian" msgid "Lithuanian"
msgstr "litevsky" msgstr "litevsky"
#: conf/global_settings.py:78 #: conf/global_settings.py:79
msgid "Latvian" msgid "Latvian"
msgstr "lotyšsky" msgstr "lotyšsky"
#: conf/global_settings.py:79 #: conf/global_settings.py:80
msgid "Macedonian" msgid "Macedonian"
msgstr "makedonsky" msgstr "makedonsky"
#: conf/global_settings.py:80 #: conf/global_settings.py:81
msgid "Malayalam"
msgstr "malajálamsky"
#: conf/global_settings.py:82
msgid "Mongolian" msgid "Mongolian"
msgstr "mongolsky" msgstr "mongolsky"
#: conf/global_settings.py:81 #: conf/global_settings.py:83
msgid "Dutch" msgid "Dutch"
msgstr "holandsky" msgstr "holandsky"
#: conf/global_settings.py:82 #: conf/global_settings.py:84
msgid "Norwegian" msgid "Norwegian"
msgstr "norsky" msgstr "norsky"
#: conf/global_settings.py:83 #: conf/global_settings.py:85
msgid "Norwegian Bokmal" msgid "Norwegian Bokmal"
msgstr "norsky (Bokmål)" msgstr "norsky (Bokmål)"
#: conf/global_settings.py:84 #: conf/global_settings.py:86
msgid "Norwegian Nynorsk" msgid "Norwegian Nynorsk"
msgstr "norsky (Nynorsk)" msgstr "norsky (Nynorsk)"
#: conf/global_settings.py:85 #: conf/global_settings.py:87
msgid "Polish" msgid "Polish"
msgstr "polsky" msgstr "polsky"
#: conf/global_settings.py:86 #: conf/global_settings.py:88
msgid "Portuguese" msgid "Portuguese"
msgstr "portugalsky" msgstr "portugalsky"
#: conf/global_settings.py:87 #: conf/global_settings.py:89
msgid "Brazilian Portuguese" msgid "Brazilian Portuguese"
msgstr "portugalsky (Brazílie)" msgstr "portugalsky (Brazílie)"
#: conf/global_settings.py:88 #: conf/global_settings.py:90
msgid "Romanian" msgid "Romanian"
msgstr "rumunsky" msgstr "rumunsky"
#: conf/global_settings.py:89 #: conf/global_settings.py:91
msgid "Russian" msgid "Russian"
msgstr "rusky" msgstr "rusky"
#: conf/global_settings.py:90 #: conf/global_settings.py:92
msgid "Slovak" msgid "Slovak"
msgstr "slovensky" msgstr "slovensky"
#: conf/global_settings.py:91 #: conf/global_settings.py:93
msgid "Slovenian" msgid "Slovenian"
msgstr "slovinsky" msgstr "slovinsky"
#: conf/global_settings.py:92 #: conf/global_settings.py:94
msgid "Albanian" msgid "Albanian"
msgstr "albánsky" msgstr "albánsky"
#: conf/global_settings.py:93 #: conf/global_settings.py:95
msgid "Serbian" msgid "Serbian"
msgstr "srbsky" msgstr "srbsky"
#: conf/global_settings.py:94 #: conf/global_settings.py:96
msgid "Serbian Latin" msgid "Serbian Latin"
msgstr "srbsky (latinkou)" msgstr "srbsky (latinkou)"
#: conf/global_settings.py:95 #: conf/global_settings.py:97
msgid "Swedish" msgid "Swedish"
msgstr "švédsky" msgstr "švédsky"
#: conf/global_settings.py:96 #: conf/global_settings.py:98
msgid "Tamil" msgid "Tamil"
msgstr "tamilsky" msgstr "tamilsky"
#: conf/global_settings.py:97 #: conf/global_settings.py:99
msgid "Telugu" msgid "Telugu"
msgstr "telužsky" msgstr "telužsky"
#: conf/global_settings.py:98 #: conf/global_settings.py:100
msgid "Thai" msgid "Thai"
msgstr "thajsky" msgstr "thajsky"
#: conf/global_settings.py:99 #: conf/global_settings.py:101
msgid "Turkish" msgid "Turkish"
msgstr "turecky" msgstr "turecky"
#: conf/global_settings.py:100 #: conf/global_settings.py:102
msgid "Ukrainian" msgid "Ukrainian"
msgstr "ukrajinsky" msgstr "ukrajinsky"
#: conf/global_settings.py:101 #: conf/global_settings.py:103
msgid "Vietnamese" msgid "Vietnamese"
msgstr "vietnamsky" msgstr "vietnamsky"
#: conf/global_settings.py:102 #: conf/global_settings.py:104
msgid "Simplified Chinese" msgid "Simplified Chinese"
msgstr "čínsky (zjednodušeně)" msgstr "čínsky (zjednodušeně)"
#: conf/global_settings.py:103 #: conf/global_settings.py:105
msgid "Traditional Chinese" msgid "Traditional Chinese"
msgstr "čínsky (tradičně)" msgstr "čínsky (tradičně)"
@ -305,15 +313,15 @@ msgstr "Tento měsíc"
msgid "This year" msgid "This year"
msgstr "Tento rok" msgstr "Tento rok"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "Yes" msgid "Yes"
msgstr "Ano" msgstr "Ano"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "No" msgid "No"
msgstr "Ne" msgstr "Ne"
#: contrib/admin/filterspecs.py:154 forms/widgets.py:469 #: contrib/admin/filterspecs.py:154 forms/widgets.py:478
msgid "Unknown" msgid "Unknown"
msgstr "Neznámé" msgstr "Neznámé"
@ -359,7 +367,7 @@ msgid "Changed %s."
msgstr "Změněno: %s" msgstr "Změněno: %s"
#: contrib/admin/options.py:559 contrib/admin/options.py:569 #: contrib/admin/options.py:559 contrib/admin/options.py:569
#: contrib/comments/templates/comments/preview.html:16 db/models/base.py:844 #: contrib/comments/templates/comments/preview.html:16 db/models/base.py:845
#: forms/models.py:568 #: forms/models.py:568
msgid "and" msgid "and"
msgstr "a" msgstr "a"
@ -853,7 +861,7 @@ msgstr "Uložit a přidat další položku"
msgid "Save and continue editing" msgid "Save and continue editing"
msgstr "Uložit a pokračovat v úpravách" msgstr "Uložit a pokračovat v úpravách"
#: contrib/admin/templates/admin/auth/user/add_form.html:5 #: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid "" msgid ""
"First, enter a username and password. Then, you'll be able to edit more user " "First, enter a username and password. Then, you'll be able to edit more user "
"options." "options."
@ -861,6 +869,10 @@ msgstr ""
"Nejdříve vložte uživatelské jméno a heslo. Poté budete moci upravovat více " "Nejdříve vložte uživatelské jméno a heslo. Poté budete moci upravovat více "
"uživatelských nastavení." "uživatelských nastavení."
#: contrib/admin/templates/admin/auth/user/add_form.html:8
msgid "Enter a username and password."
msgstr "Vložte uživatelské jméno a heslo."
#: contrib/admin/templates/admin/auth/user/change_password.html:28 #: contrib/admin/templates/admin/auth/user/change_password.html:28
#, python-format #, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>." msgid "Enter a new password for the user <strong>%(username)s</strong>."
@ -1418,8 +1430,8 @@ msgstr "zpráva"
msgid "Logged out" msgid "Logged out"
msgstr "Odhlášeno" msgstr "Odhlášeno"
#: contrib/auth/management/commands/createsuperuser.py:23 #: contrib/auth/management/commands/createsuperuser.py:24
#: core/validators.py:120 forms/fields.py:428 #: core/validators.py:120 forms/fields.py:427
msgid "Enter a valid e-mail address." msgid "Enter a valid e-mail address."
msgstr "Vložte platnou e-mailovou adresu." msgstr "Vložte platnou e-mailovou adresu."
@ -1491,7 +1503,7 @@ msgid "Email address"
msgstr "E-mailová adresa" msgstr "E-mailová adresa"
#: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8 #: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8
#: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1109
msgid "URL" msgid "URL"
msgstr "URL" msgstr "URL"
@ -1541,7 +1553,7 @@ msgstr "komentář"
msgid "date/time submitted" msgid "date/time submitted"
msgstr "datum a čas byly zaslané" msgstr "datum a čas byly zaslané"
#: contrib/comments/models.py:60 db/models/fields/__init__.py:896 #: contrib/comments/models.py:60 db/models/fields/__init__.py:904
msgid "IP address" msgid "IP address"
msgstr "Adresa IP" msgstr "Adresa IP"
@ -4473,22 +4485,22 @@ msgstr "weby"
msgid "Enter a valid value." msgid "Enter a valid value."
msgstr "Vložte platnou hodnotu." msgstr "Vložte platnou hodnotu."
#: core/validators.py:87 forms/fields.py:529 #: core/validators.py:87 forms/fields.py:528
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "Vložte platnou adresu URL." msgstr "Vložte platnou adresu URL."
#: core/validators.py:89 forms/fields.py:530 #: core/validators.py:89 forms/fields.py:529
msgid "This URL appears to be a broken link." msgid "This URL appears to be a broken link."
msgstr "Tato adresa URL je zřejmě neplatný odkaz." msgstr "Tato adresa URL je zřejmě neplatný odkaz."
#: core/validators.py:123 forms/fields.py:873 #: core/validators.py:123 forms/fields.py:877
msgid "" msgid ""
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "" msgstr ""
"Vložte platný identifikátor složený pouze z písmen, čísel, podtržítek a " "Vložte platný identifikátor složený pouze z písmen, čísel, podtržítek a "
"pomlček." "pomlček."
#: core/validators.py:126 forms/fields.py:866 #: core/validators.py:126 forms/fields.py:870
msgid "Enter a valid IPv4 address." msgid "Enter a valid IPv4 address."
msgstr "Vložte platnou adresu typu IPv4." msgstr "Vložte platnou adresu typu IPv4."
@ -4501,12 +4513,12 @@ msgstr "Vložte pouze číslice oddělené čárkami."
msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)."
msgstr "Hodnota musí být %(limit_value)s (nyní je %(show_value)s)." msgstr "Hodnota musí být %(limit_value)s (nyní je %(show_value)s)."
#: core/validators.py:153 forms/fields.py:205 forms/fields.py:257 #: core/validators.py:153 forms/fields.py:204 forms/fields.py:256
#, python-format #, python-format
msgid "Ensure this value is less than or equal to %(limit_value)s." msgid "Ensure this value is less than or equal to %(limit_value)s."
msgstr "Hodnota musí být menší nebo rovna %(limit_value)s." msgstr "Hodnota musí být menší nebo rovna %(limit_value)s."
#: core/validators.py:158 forms/fields.py:206 forms/fields.py:258 #: core/validators.py:158 forms/fields.py:205 forms/fields.py:257
#, python-format #, python-format
msgid "Ensure this value is greater than or equal to %(limit_value)s." msgid "Ensure this value is greater than or equal to %(limit_value)s."
msgstr "Hodnota musí být větší nebo rovna %(limit_value)s." msgstr "Hodnota musí být větší nebo rovna %(limit_value)s."
@ -4529,13 +4541,13 @@ msgstr ""
"Hodnota smí mít nejvýše %(limit_value)d znaků, ale nyní jich má %(show_value)" "Hodnota smí mít nejvýše %(limit_value)d znaků, ale nyní jich má %(show_value)"
"d." "d."
#: db/models/base.py:822 #: db/models/base.py:823
#, python-format #, python-format
msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s." msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s."
msgstr "" msgstr ""
"Pole %(field_name)s musí být unikátní testem %(lookup)s pole %(date_field)s." "Pole %(field_name)s musí být unikátní testem %(lookup)s pole %(date_field)s."
#: db/models/base.py:837 db/models/base.py:845 #: db/models/base.py:838 db/models/base.py:846
#, python-format #, python-format
msgid "%(model_name)s with this %(field_label)s already exists." msgid "%(model_name)s with this %(field_label)s already exists."
msgstr "" msgstr ""
@ -4559,13 +4571,13 @@ msgstr "Pole nemůže být prázdné."
msgid "Field of type: %(field_type)s" msgid "Field of type: %(field_type)s"
msgstr "Pole typu: %(field_type)s" msgstr "Pole typu: %(field_type)s"
#: db/models/fields/__init__.py:451 db/models/fields/__init__.py:852 #: db/models/fields/__init__.py:451 db/models/fields/__init__.py:860
#: db/models/fields/__init__.py:961 db/models/fields/__init__.py:972 #: db/models/fields/__init__.py:969 db/models/fields/__init__.py:980
#: db/models/fields/__init__.py:999 #: db/models/fields/__init__.py:1007
msgid "Integer" msgid "Integer"
msgstr "Celé číslo" msgstr "Celé číslo"
#: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850 #: db/models/fields/__init__.py:455 db/models/fields/__init__.py:858
msgid "This value must be an integer." msgid "This value must be an integer."
msgstr "Hodnota musí být celé číslo." msgstr "Hodnota musí být celé číslo."
@ -4577,7 +4589,7 @@ msgstr "Hodnota musí být buď Ano (True) nebo Ne (False)."
msgid "Boolean (Either True or False)" msgid "Boolean (Either True or False)"
msgstr "Pravdivost (buď Ano (True), nebo Ne (False))" msgstr "Pravdivost (buď Ano (True), nebo Ne (False))"
#: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982 #: db/models/fields/__init__.py:539 db/models/fields/__init__.py:990
#, python-format #, python-format
msgid "String (up to %(max_length)s)" msgid "String (up to %(max_length)s)"
msgstr "Řetězec (max. %(max_length)s znaků)" msgstr "Řetězec (max. %(max_length)s znaků)"
@ -4619,44 +4631,44 @@ msgstr "Desetinné číslo"
msgid "E-mail address" msgid "E-mail address"
msgstr "E-mailová adresa" msgstr "E-mailová adresa"
#: db/models/fields/__init__.py:799 db/models/fields/files.py:220 #: db/models/fields/__init__.py:807 db/models/fields/files.py:220
#: db/models/fields/files.py:331 #: db/models/fields/files.py:331
msgid "File path" msgid "File path"
msgstr "Cesta k souboru" msgstr "Cesta k souboru"
#: db/models/fields/__init__.py:822 #: db/models/fields/__init__.py:830
msgid "This value must be a float." msgid "This value must be a float."
msgstr "Hodnota musí být desetinné číslo." msgstr "Hodnota musí být desetinné číslo."
#: db/models/fields/__init__.py:824 #: db/models/fields/__init__.py:832
msgid "Floating point number" msgid "Floating point number"
msgstr "Číslo s pohyblivou řádovou čárkou" msgstr "Číslo s pohyblivou řádovou čárkou"
#: db/models/fields/__init__.py:883 #: db/models/fields/__init__.py:891
msgid "Big (8 byte) integer" msgid "Big (8 byte) integer"
msgstr "Velké číslo (8 bajtů)" msgstr "Velké číslo (8 bajtů)"
#: db/models/fields/__init__.py:912 #: db/models/fields/__init__.py:920
msgid "This value must be either None, True or False." msgid "This value must be either None, True or False."
msgstr "Hodnota musí být buď Nic (None), Ano (True) nebo Ne (False)." msgstr "Hodnota musí být buď Nic (None), Ano (True) nebo Ne (False)."
#: db/models/fields/__init__.py:914 #: db/models/fields/__init__.py:922
msgid "Boolean (Either True, False or None)" msgid "Boolean (Either True, False or None)"
msgstr "Pravdivost (buď Ano (True), Ne (False) nebo Nic (None))" msgstr "Pravdivost (buď Ano (True), Ne (False) nebo Nic (None))"
#: db/models/fields/__init__.py:1005 #: db/models/fields/__init__.py:1013
msgid "Text" msgid "Text"
msgstr "Text" msgstr "Text"
#: db/models/fields/__init__.py:1021 #: db/models/fields/__init__.py:1029
msgid "Time" msgid "Time"
msgstr "Čas" msgstr "Čas"
#: db/models/fields/__init__.py:1025 #: db/models/fields/__init__.py:1033
msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format." msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
msgstr "Vložte platný čas ve tvaru HH:MM[:ss[.uuuuuu]]" msgstr "Vložte platný čas ve tvaru HH:MM[:ss[.uuuuuu]]"
#: db/models/fields/__init__.py:1109 #: db/models/fields/__init__.py:1125
msgid "XML text" msgid "XML text"
msgstr "XML text" msgstr "XML text"
@ -4669,22 +4681,22 @@ msgstr "Položka typu %(model)s s primárním klíčem %(pk)r neexistuje."
msgid "Foreign Key (type determined by related field)" msgid "Foreign Key (type determined by related field)"
msgstr "Cizí klíč (typ určen pomocí souvisejícího pole)" msgstr "Cizí klíč (typ určen pomocí souvisejícího pole)"
#: db/models/fields/related.py:918 #: db/models/fields/related.py:919
msgid "One-to-one relationship" msgid "One-to-one relationship"
msgstr "Vazba jedna-jedna" msgstr "Vazba jedna-jedna"
#: db/models/fields/related.py:980 #: db/models/fields/related.py:981
msgid "Many-to-many relationship" msgid "Many-to-many relationship"
msgstr "Vazba mnoho-mnoho" msgstr "Vazba mnoho-mnoho"
#: db/models/fields/related.py:1000 #: db/models/fields/related.py:1001
msgid "" msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "" msgstr ""
"Výběr více než jedné položky je možný přidržením klávesy \"Control\" (nebo " "Výběr více než jedné položky je možný přidržením klávesy \"Control\" (nebo "
"\"Command\" na Macu)." "\"Command\" na Macu)."
#: db/models/fields/related.py:1061 #: db/models/fields/related.py:1062
#, python-format #, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural "" msgid_plural ""
@ -4697,74 +4709,74 @@ msgstr[2] "Vložte platné ID položky %(self)s. Hodnoty %(value)r jsou neplatn
msgid "This field is required." msgid "This field is required."
msgstr "Pole je povinné." msgstr "Pole je povinné."
#: forms/fields.py:204 #: forms/fields.py:203
msgid "Enter a whole number." msgid "Enter a whole number."
msgstr "Vložte celé číslo." msgstr "Vložte celé číslo."
#: forms/fields.py:235 forms/fields.py:256 #: forms/fields.py:234 forms/fields.py:255
msgid "Enter a number." msgid "Enter a number."
msgstr "Vložte číslo." msgstr "Vložte číslo."
#: forms/fields.py:259 #: forms/fields.py:258
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits in total." msgid "Ensure that there are no more than %s digits in total."
msgstr "Hodnota nesmí celkem mít více než %s cifer." msgstr "Hodnota nesmí celkem mít více než %s cifer."
#: forms/fields.py:260 #: forms/fields.py:259
#, python-format #, python-format
msgid "Ensure that there are no more than %s decimal places." msgid "Ensure that there are no more than %s decimal places."
msgstr "Hodnota nesmí mít za desetinnou čárkou více než %s cifer." msgstr "Hodnota nesmí mít za desetinnou čárkou více než %s cifer."
#: forms/fields.py:261 #: forms/fields.py:260
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits before the decimal point." msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Hodnota nesmí mít před desetinnou čárkou více než %s cifer." msgstr "Hodnota nesmí mít před desetinnou čárkou více než %s cifer."
#: forms/fields.py:323 forms/fields.py:838 #: forms/fields.py:322 forms/fields.py:837
msgid "Enter a valid date." msgid "Enter a valid date."
msgstr "Vložte platné datum." msgstr "Vložte platné datum."
#: forms/fields.py:351 forms/fields.py:839 #: forms/fields.py:350 forms/fields.py:838
msgid "Enter a valid time." msgid "Enter a valid time."
msgstr "Vložte platný čas." msgstr "Vložte platný čas."
#: forms/fields.py:377 #: forms/fields.py:376
msgid "Enter a valid date/time." msgid "Enter a valid date/time."
msgstr "Vložte platné datum a čas." msgstr "Vložte platné datum a čas."
#: forms/fields.py:435 #: forms/fields.py:434
msgid "No file was submitted. Check the encoding type on the form." msgid "No file was submitted. Check the encoding type on the form."
msgstr "" msgstr ""
"Soubor nebyl odeslán. Zkontrolujte parametr \"encoding type\" formuláře." "Soubor nebyl odeslán. Zkontrolujte parametr \"encoding type\" formuláře."
#: forms/fields.py:436 #: forms/fields.py:435
msgid "No file was submitted." msgid "No file was submitted."
msgstr "Žádný soubor nebyl odeslán." msgstr "Žádný soubor nebyl odeslán."
#: forms/fields.py:437 #: forms/fields.py:436
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "Odeslaný soubor je prázdný." msgstr "Odeslaný soubor je prázdný."
#: forms/fields.py:438 #: forms/fields.py:437
#, python-format #, python-format
msgid "" msgid ""
"Ensure this filename has at most %(max)d characters (it has %(length)d)." "Ensure this filename has at most %(max)d characters (it has %(length)d)."
msgstr "" msgstr ""
"Délka názvu souboru má být nejvýše %(max)d znaků, ale nyní je %(length)d." "Délka názvu souboru má být nejvýše %(max)d znaků, ale nyní je %(length)d."
#: forms/fields.py:473 #: forms/fields.py:472
msgid "" msgid ""
"Upload a valid image. The file you uploaded was either not an image or a " "Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image." "corrupted image."
msgstr "" msgstr ""
"Nahrajte platný obrázek. Odeslaný soubor buď nebyl obrázek nebo byl poškozen." "Nahrajte platný obrázek. Odeslaný soubor buď nebyl obrázek nebo byl poškozen."
#: forms/fields.py:596 forms/fields.py:671 #: forms/fields.py:595 forms/fields.py:670
#, python-format #, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices." msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "Vyberte platnou možnost, \"%(value)s\" není k dispozici." msgstr "Vyberte platnou možnost, \"%(value)s\" není k dispozici."
#: forms/fields.py:672 forms/fields.py:734 forms/models.py:1002 #: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002
msgid "Enter a list of values." msgid "Enter a list of values."
msgstr "Vložte seznam hodnot." msgstr "Vložte seznam hodnot."

View File

@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-09 14:30+0200\n" "POT-Creation-Date: 2010-08-06 18:35+0200\n"
"PO-Revision-Date: 2010-05-09 14:04+0100\n" "PO-Revision-Date: 2010-08-06 18:34+0100\n"
"Last-Translator: Vlada Macek <macek@sandbox.cz>\n" "Last-Translator: Vlada Macek <macek@sandbox.cz>\n"
"Language-Team: Czech\n" "Language-Team: Czech\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@ -6,9 +6,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-04-26 15:49+0200\n" "POT-Creation-Date: 2010-08-07 11:57+0200\n"
"PO-Revision-Date: 2008-08-13 22:00+0200\n" "PO-Revision-Date: 2010-08-07 22:00+0200\n"
"Last-Translator: Finn Gruwier Larsen<finn@gruwier.dk>\n" "Last-Translator: Finn Gruwier Larsen<finngruwierlarsen@gmail.com>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -44,13 +44,42 @@ msgstr "Foretag dit/dine valg og klik "
msgid "Clear all" msgid "Clear all"
msgstr "Fravælg alle" msgstr "Fravælg alle"
#: contrib/admin/media/js/actions.js:17 #: contrib/admin/media/js/actions.js:18
#: contrib/admin/media/js/actions.min.js:1 #: contrib/admin/media/js/actions.min.js:1
msgid "%(sel)s of %(cnt)s selected" msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected" msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s af %(cnt)s valgt" msgstr[0] "%(sel)s af %(cnt)s valgt"
msgstr[1] "%(sel)s af %(cnt)s valgt" msgstr[1] "%(sel)s af %(cnt)s valgt"
#: contrib/admin/media/js/actions.js:109
#: contrib/admin/media/js/actions.min.js:5
msgid ""
"You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost."
msgstr ""
"Du har ugemte ændringer af et eller flere redigerbare felter. Hvis du "
"udfører en handling fra drop-down-menuen, vil du miste disse ændringer."
#: contrib/admin/media/js/actions.js:121
#: contrib/admin/media/js/actions.min.js:6
msgid ""
"You have selected an action, but you haven't saved your changes to "
"individual fields yet. Please click OK to save. You'll need to re-run the "
"action."
msgstr ""
"Du har valgt en handling, men du har ikke gemt dine ændringer til et eller "
"flere felter. Klik venligst OK for at gemme og vælg dernæst handlingen igen."
#: contrib/admin/media/js/actions.js:123
#: contrib/admin/media/js/actions.min.js:6
msgid ""
"You have selected an action, and you haven't made any changes on individual "
"fields. You're probably looking for the Go button rather than the Save "
"button."
msgstr ""
"Du har valgt en handling, og du har ikke udført nogen ændringer på felter. "
"Det, du søger er formentlig Udfør-knappen i stedet for Gem-knappen."
#: contrib/admin/media/js/calendar.js:24 #: contrib/admin/media/js/calendar.js:24
#: contrib/admin/media/js/dateparse.js:32 #: contrib/admin/media/js/dateparse.js:32
msgid "" msgid ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-13 15:30+0200\n" "POT-Creation-Date: 2010-08-06 18:53+0200\n"
"PO-Revision-Date: 2010-04-26 13:53+0100\n" "PO-Revision-Date: 2010-04-26 13:53+0100\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n" "Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"Language-Team: \n" "Language-Team: \n"
@ -72,7 +72,7 @@ msgid "Spanish"
msgstr "Spanisch" msgstr "Spanisch"
#: conf/global_settings.py:57 #: conf/global_settings.py:57
msgid "Argentinean Spanish" msgid "Argentinian Spanish"
msgstr "Argentinisches Spanisch" msgstr "Argentinisches Spanisch"
#: conf/global_settings.py:58 #: conf/global_settings.py:58
@ -168,98 +168,102 @@ msgid "Macedonian"
msgstr "Mazedonisch" msgstr "Mazedonisch"
#: conf/global_settings.py:81 #: conf/global_settings.py:81
msgid "Malayalam"
msgstr "Malayalam"
#: conf/global_settings.py:82
msgid "Mongolian" msgid "Mongolian"
msgstr "Mongolisch" msgstr "Mongolisch"
#: conf/global_settings.py:82 #: conf/global_settings.py:83
msgid "Dutch" msgid "Dutch"
msgstr "Holländisch" msgstr "Holländisch"
#: conf/global_settings.py:83 #: conf/global_settings.py:84
msgid "Norwegian" msgid "Norwegian"
msgstr "Norwegisch" msgstr "Norwegisch"
#: conf/global_settings.py:84 #: conf/global_settings.py:85
msgid "Norwegian Bokmal" msgid "Norwegian Bokmal"
msgstr "Norwegisch (Bokmål)" msgstr "Norwegisch (Bokmål)"
#: conf/global_settings.py:85 #: conf/global_settings.py:86
msgid "Norwegian Nynorsk" msgid "Norwegian Nynorsk"
msgstr "Norwegisch (Nynorsk)" msgstr "Norwegisch (Nynorsk)"
#: conf/global_settings.py:86 #: conf/global_settings.py:87
msgid "Polish" msgid "Polish"
msgstr "Polnisch" msgstr "Polnisch"
#: conf/global_settings.py:87 #: conf/global_settings.py:88
msgid "Portuguese" msgid "Portuguese"
msgstr "Portugiesisch" msgstr "Portugiesisch"
#: conf/global_settings.py:88 #: conf/global_settings.py:89
msgid "Brazilian Portuguese" msgid "Brazilian Portuguese"
msgstr "Brasilianisches Portugiesisch" msgstr "Brasilianisches Portugiesisch"
#: conf/global_settings.py:89 #: conf/global_settings.py:90
msgid "Romanian" msgid "Romanian"
msgstr "Rumänisch" msgstr "Rumänisch"
#: conf/global_settings.py:90 #: conf/global_settings.py:91
msgid "Russian" msgid "Russian"
msgstr "Russisch" msgstr "Russisch"
#: conf/global_settings.py:91 #: conf/global_settings.py:92
msgid "Slovak" msgid "Slovak"
msgstr "Slowakisch" msgstr "Slowakisch"
#: conf/global_settings.py:92 #: conf/global_settings.py:93
msgid "Slovenian" msgid "Slovenian"
msgstr "Slowenisch" msgstr "Slowenisch"
#: conf/global_settings.py:93 #: conf/global_settings.py:94
msgid "Albanian" msgid "Albanian"
msgstr "Albanisch" msgstr "Albanisch"
#: conf/global_settings.py:94 #: conf/global_settings.py:95
msgid "Serbian" msgid "Serbian"
msgstr "Serbisch" msgstr "Serbisch"
#: conf/global_settings.py:95 #: conf/global_settings.py:96
msgid "Serbian Latin" msgid "Serbian Latin"
msgstr "Serbisch (Latein)" msgstr "Serbisch (Latein)"
#: conf/global_settings.py:96 #: conf/global_settings.py:97
msgid "Swedish" msgid "Swedish"
msgstr "Schwedisch" msgstr "Schwedisch"
#: conf/global_settings.py:97 #: conf/global_settings.py:98
msgid "Tamil" msgid "Tamil"
msgstr "Tamilisch" msgstr "Tamilisch"
#: conf/global_settings.py:98 #: conf/global_settings.py:99
msgid "Telugu" msgid "Telugu"
msgstr "Telugisch" msgstr "Telugisch"
#: conf/global_settings.py:99 #: conf/global_settings.py:100
msgid "Thai" msgid "Thai"
msgstr "Thailändisch" msgstr "Thailändisch"
#: conf/global_settings.py:100 #: conf/global_settings.py:101
msgid "Turkish" msgid "Turkish"
msgstr "Türkisch" msgstr "Türkisch"
#: conf/global_settings.py:101 #: conf/global_settings.py:102
msgid "Ukrainian" msgid "Ukrainian"
msgstr "Ukrainisch" msgstr "Ukrainisch"
#: conf/global_settings.py:102 #: conf/global_settings.py:103
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamesisch" msgstr "Vietnamesisch"
#: conf/global_settings.py:103 #: conf/global_settings.py:104
msgid "Simplified Chinese" msgid "Simplified Chinese"
msgstr "Vereinfachtes Chinesisch" msgstr "Vereinfachtes Chinesisch"
#: conf/global_settings.py:104 #: conf/global_settings.py:105
msgid "Traditional Chinese" msgid "Traditional Chinese"
msgstr "Traditionelles Chinesisch" msgstr "Traditionelles Chinesisch"
@ -311,15 +315,15 @@ msgstr "Diesen Monat"
msgid "This year" msgid "This year"
msgstr "Dieses Jahr" msgstr "Dieses Jahr"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "Yes" msgid "Yes"
msgstr "Ja" msgstr "Ja"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "No" msgid "No"
msgstr "Nein" msgstr "Nein"
#: contrib/admin/filterspecs.py:154 forms/widgets.py:469 #: contrib/admin/filterspecs.py:154 forms/widgets.py:478
msgid "Unknown" msgid "Unknown"
msgstr "Unbekannt" msgstr "Unbekannt"
@ -696,7 +700,7 @@ msgid "Filter"
msgstr "Filter" msgstr "Filter"
#: contrib/admin/templates/admin/delete_confirmation.html:10 #: contrib/admin/templates/admin/delete_confirmation.html:10
#: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:302 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:300
msgid "Delete" msgid "Delete"
msgstr "Löschen" msgstr "Löschen"
@ -859,7 +863,7 @@ msgstr "Sichern und neu hinzufügen"
msgid "Save and continue editing" msgid "Save and continue editing"
msgstr "Sichern und weiter bearbeiten" msgstr "Sichern und weiter bearbeiten"
#: contrib/admin/templates/admin/auth/user/add_form.html:5 #: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid "" msgid ""
"First, enter a username and password. Then, you'll be able to edit more user " "First, enter a username and password. Then, you'll be able to edit more user "
"options." "options."
@ -867,6 +871,10 @@ msgstr ""
"Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere " "Zuerst einen Benutzer und ein Passwort eingeben. Danach können weitere "
"Optionen für den Benutzer geändert werden." "Optionen für den Benutzer geändert werden."
#: contrib/admin/templates/admin/auth/user/add_form.html:8
msgid "Enter a username and password."
msgstr "Bitte einen Benutzernamen und ein Passwort eingeben."
#: contrib/admin/templates/admin/auth/user/change_password.html:28 #: contrib/admin/templates/admin/auth/user/change_password.html:28
#, python-format #, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>." msgid "Enter a new password for the user <strong>%(username)s</strong>."
@ -1437,8 +1445,8 @@ msgstr "Mitteilung"
msgid "Logged out" msgid "Logged out"
msgstr "Abgemeldet" msgstr "Abgemeldet"
#: contrib/auth/management/commands/createsuperuser.py:23 #: contrib/auth/management/commands/createsuperuser.py:24
#: core/validators.py:120 forms/fields.py:428 #: core/validators.py:120 forms/fields.py:427
msgid "Enter a valid e-mail address." msgid "Enter a valid e-mail address."
msgstr "Bitte eine gültige E-Mail-Adresse eingeben." msgstr "Bitte eine gültige E-Mail-Adresse eingeben."
@ -1506,7 +1514,7 @@ msgid "Email address"
msgstr "E-Mail-Adresse" msgstr "E-Mail-Adresse"
#: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8 #: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8
#: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1109
msgid "URL" msgid "URL"
msgstr "Adresse (URL)" msgstr "Adresse (URL)"
@ -1557,7 +1565,7 @@ msgstr "Kommentar"
msgid "date/time submitted" msgid "date/time submitted"
msgstr "Datum/Zeit Erstellung" msgstr "Datum/Zeit Erstellung"
#: contrib/comments/models.py:60 db/models/fields/__init__.py:896 #: contrib/comments/models.py:60 db/models/fields/__init__.py:904
msgid "IP address" msgid "IP address"
msgstr "IP-Adresse" msgstr "IP-Adresse"
@ -4509,22 +4517,22 @@ msgstr "Sites"
msgid "Enter a valid value." msgid "Enter a valid value."
msgstr "Bitte einen gültigen Wert eingeben." msgstr "Bitte einen gültigen Wert eingeben."
#: core/validators.py:87 forms/fields.py:529 #: core/validators.py:87 forms/fields.py:528
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "Bitte eine gültige Adresse eingeben." msgstr "Bitte eine gültige Adresse eingeben."
#: core/validators.py:89 forms/fields.py:530 #: core/validators.py:89 forms/fields.py:529
msgid "This URL appears to be a broken link." msgid "This URL appears to be a broken link."
msgstr "Diese Adresse scheint nicht gültig zu sein." msgstr "Diese Adresse scheint nicht gültig zu sein."
#: core/validators.py:123 forms/fields.py:873 #: core/validators.py:123 forms/fields.py:877
msgid "" msgid ""
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "" msgstr ""
"Bitte ein gültiges Kürzel, bestehend aus Buchstaben, Ziffern, Unterstrichen " "Bitte ein gültiges Kürzel, bestehend aus Buchstaben, Ziffern, Unterstrichen "
"und Bindestrichen, eingeben." "und Bindestrichen, eingeben."
#: core/validators.py:126 forms/fields.py:866 #: core/validators.py:126 forms/fields.py:870
msgid "Enter a valid IPv4 address." msgid "Enter a valid IPv4 address."
msgstr "Bitte eine gültige IPv4-Adresse eingeben." msgstr "Bitte eine gültige IPv4-Adresse eingeben."
@ -4539,12 +4547,12 @@ msgstr ""
"Bitte sicherstellen, dass der Wert %(limit_value)s ist. (Er ist %(show_value)" "Bitte sicherstellen, dass der Wert %(limit_value)s ist. (Er ist %(show_value)"
"s)" "s)"
#: core/validators.py:153 forms/fields.py:205 forms/fields.py:257 #: core/validators.py:153 forms/fields.py:204 forms/fields.py:256
#, python-format #, python-format
msgid "Ensure this value is less than or equal to %(limit_value)s." msgid "Ensure this value is less than or equal to %(limit_value)s."
msgstr "Dieser Wert muss kleiner oder gleich %(limit_value)s sein." msgstr "Dieser Wert muss kleiner oder gleich %(limit_value)s sein."
#: core/validators.py:158 forms/fields.py:206 forms/fields.py:258 #: core/validators.py:158 forms/fields.py:205 forms/fields.py:257
#, python-format #, python-format
msgid "Ensure this value is greater than or equal to %(limit_value)s." msgid "Ensure this value is greater than or equal to %(limit_value)s."
msgstr "Dieser Wert muss größer oder gleich %(limit_value)s sein." msgstr "Dieser Wert muss größer oder gleich %(limit_value)s sein."
@ -4595,13 +4603,13 @@ msgstr "Dieses Feld darf nicht leer sein."
msgid "Field of type: %(field_type)s" msgid "Field of type: %(field_type)s"
msgstr "Feldtyp: %(field_type)s" msgstr "Feldtyp: %(field_type)s"
#: db/models/fields/__init__.py:451 db/models/fields/__init__.py:852 #: db/models/fields/__init__.py:451 db/models/fields/__init__.py:860
#: db/models/fields/__init__.py:961 db/models/fields/__init__.py:972 #: db/models/fields/__init__.py:969 db/models/fields/__init__.py:980
#: db/models/fields/__init__.py:999 #: db/models/fields/__init__.py:1007
msgid "Integer" msgid "Integer"
msgstr "Ganzzahl" msgstr "Ganzzahl"
#: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850 #: db/models/fields/__init__.py:455 db/models/fields/__init__.py:858
msgid "This value must be an integer." msgid "This value must be an integer."
msgstr "Dieser Wert muss eine Ganzzahl sein." msgstr "Dieser Wert muss eine Ganzzahl sein."
@ -4613,7 +4621,7 @@ msgstr "Dieser Wert muss True oder False sein."
msgid "Boolean (Either True or False)" msgid "Boolean (Either True or False)"
msgstr "Boolescher Wert (True oder False)" msgstr "Boolescher Wert (True oder False)"
#: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982 #: db/models/fields/__init__.py:539 db/models/fields/__init__.py:990
#, python-format #, python-format
msgid "String (up to %(max_length)s)" msgid "String (up to %(max_length)s)"
msgstr "Zeichenkette (bis zu %(max_length)s Zeichen)" msgstr "Zeichenkette (bis zu %(max_length)s Zeichen)"
@ -4657,44 +4665,44 @@ msgstr "Dezimalzahl"
msgid "E-mail address" msgid "E-mail address"
msgstr "E-Mail-Adresse" msgstr "E-Mail-Adresse"
#: db/models/fields/__init__.py:799 db/models/fields/files.py:220 #: db/models/fields/__init__.py:807 db/models/fields/files.py:220
#: db/models/fields/files.py:331 #: db/models/fields/files.py:331
msgid "File path" msgid "File path"
msgstr "Dateipfad" msgstr "Dateipfad"
#: db/models/fields/__init__.py:822 #: db/models/fields/__init__.py:830
msgid "This value must be a float." msgid "This value must be a float."
msgstr "Dieser Wert muss eine Gleitkommazahl sein." msgstr "Dieser Wert muss eine Gleitkommazahl sein."
#: db/models/fields/__init__.py:824 #: db/models/fields/__init__.py:832
msgid "Floating point number" msgid "Floating point number"
msgstr "Gleitkommazahl" msgstr "Gleitkommazahl"
#: db/models/fields/__init__.py:883 #: db/models/fields/__init__.py:891
msgid "Big (8 byte) integer" msgid "Big (8 byte) integer"
msgstr "Große Ganzzahl (8 Byte)" msgstr "Große Ganzzahl (8 Byte)"
#: db/models/fields/__init__.py:912 #: db/models/fields/__init__.py:920
msgid "This value must be either None, True or False." msgid "This value must be either None, True or False."
msgstr "Dieser Wert muss None, True oder False sein." msgstr "Dieser Wert muss None, True oder False sein."
#: db/models/fields/__init__.py:914 #: db/models/fields/__init__.py:922
msgid "Boolean (Either True, False or None)" msgid "Boolean (Either True, False or None)"
msgstr "Boolescher Wert (True, False oder None)" msgstr "Boolescher Wert (True, False oder None)"
#: db/models/fields/__init__.py:1005 #: db/models/fields/__init__.py:1013
msgid "Text" msgid "Text"
msgstr "Text" msgstr "Text"
#: db/models/fields/__init__.py:1021 #: db/models/fields/__init__.py:1029
msgid "Time" msgid "Time"
msgstr "Zeit" msgstr "Zeit"
#: db/models/fields/__init__.py:1025 #: db/models/fields/__init__.py:1033
msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format." msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
msgstr "Bitte eine gültige Zeit im Format HH:MM[:ss[.uuuuuu]] eingeben." msgstr "Bitte eine gültige Zeit im Format HH:MM[:ss[.uuuuuu]] eingeben."
#: db/models/fields/__init__.py:1109 #: db/models/fields/__init__.py:1125
msgid "XML text" msgid "XML text"
msgstr "XML-Text" msgstr "XML-Text"
@ -4707,22 +4715,22 @@ msgstr "Modell %(model)s mit dem Primärschlüssel %(pk)r ist nicht vorhanden."
msgid "Foreign Key (type determined by related field)" msgid "Foreign Key (type determined by related field)"
msgstr "Fremdschlüssel (Typ definiert durch verknüpftes Feld)" msgstr "Fremdschlüssel (Typ definiert durch verknüpftes Feld)"
#: db/models/fields/related.py:918 #: db/models/fields/related.py:919
msgid "One-to-one relationship" msgid "One-to-one relationship"
msgstr "One-to-one-Beziehung" msgstr "One-to-one-Beziehung"
#: db/models/fields/related.py:980 #: db/models/fields/related.py:981
msgid "Many-to-many relationship" msgid "Many-to-many relationship"
msgstr "Many-to-many-Beziehung" msgstr "Many-to-many-Beziehung"
#: db/models/fields/related.py:1000 #: db/models/fields/related.py:1001
msgid "" msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "" msgstr ""
"Halten Sie die Strg-Taste (⌘ für Mac) während des Klickens gedrückt, um " "Halten Sie die Strg-Taste (⌘ für Mac) während des Klickens gedrückt, um "
"mehrere Einträge auszuwählen." "mehrere Einträge auszuwählen."
#: db/models/fields/related.py:1061 #: db/models/fields/related.py:1062
#, python-format #, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural "" msgid_plural ""
@ -4736,55 +4744,55 @@ msgstr[1] ""
msgid "This field is required." msgid "This field is required."
msgstr "Dieses Feld ist zwingend erforderlich." msgstr "Dieses Feld ist zwingend erforderlich."
#: forms/fields.py:204 #: forms/fields.py:203
msgid "Enter a whole number." msgid "Enter a whole number."
msgstr "Bitte eine ganze Zahl eingeben." msgstr "Bitte eine ganze Zahl eingeben."
#: forms/fields.py:235 forms/fields.py:256 #: forms/fields.py:234 forms/fields.py:255
msgid "Enter a number." msgid "Enter a number."
msgstr "Bitte eine Zahl eingeben." msgstr "Bitte eine Zahl eingeben."
#: forms/fields.py:259 #: forms/fields.py:258
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits in total." msgid "Ensure that there are no more than %s digits in total."
msgstr "Bitte geben Sie nicht mehr als insgesamt %s Ziffern ein." msgstr "Bitte geben Sie nicht mehr als insgesamt %s Ziffern ein."
#: forms/fields.py:260 #: forms/fields.py:259
#, python-format #, python-format
msgid "Ensure that there are no more than %s decimal places." msgid "Ensure that there are no more than %s decimal places."
msgstr "Bitte geben Sie nicht mehr als %s Dezimalstellen ein." msgstr "Bitte geben Sie nicht mehr als %s Dezimalstellen ein."
#: forms/fields.py:261 #: forms/fields.py:260
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits before the decimal point." 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." msgstr "Bitte geben Sie nicht mehr als %s Ziffern vor dem Komma ein."
#: forms/fields.py:323 forms/fields.py:838 #: forms/fields.py:322 forms/fields.py:837
msgid "Enter a valid date." msgid "Enter a valid date."
msgstr "Bitte ein gültiges Datum eingeben." msgstr "Bitte ein gültiges Datum eingeben."
#: forms/fields.py:351 forms/fields.py:839 #: forms/fields.py:350 forms/fields.py:838
msgid "Enter a valid time." msgid "Enter a valid time."
msgstr "Bitte eine gültige Uhrzeit eingeben." msgstr "Bitte eine gültige Uhrzeit eingeben."
#: forms/fields.py:377 #: forms/fields.py:376
msgid "Enter a valid date/time." msgid "Enter a valid date/time."
msgstr "Bitte ein gültiges Datum und Uhrzeit eingeben." msgstr "Bitte ein gültiges Datum und Uhrzeit eingeben."
#: forms/fields.py:435 #: forms/fields.py:434
msgid "No file was submitted. Check the encoding type on the form." msgid "No file was submitted. Check the encoding type on the form."
msgstr "" msgstr ""
"Es wurde keine Datei übermittelt. Überprüfen Sie das Encoding des Formulars." "Es wurde keine Datei übermittelt. Überprüfen Sie das Encoding des Formulars."
#: forms/fields.py:436 #: forms/fields.py:435
msgid "No file was submitted." msgid "No file was submitted."
msgstr "Es wurde keine Datei übertragen." msgstr "Es wurde keine Datei übertragen."
#: forms/fields.py:437 #: forms/fields.py:436
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "Die ausgewählte Datei ist leer." msgstr "Die ausgewählte Datei ist leer."
#: forms/fields.py:438 #: forms/fields.py:437
#, python-format #, python-format
msgid "" msgid ""
"Ensure this filename has at most %(max)d characters (it has %(length)d)." "Ensure this filename has at most %(max)d characters (it has %(length)d)."
@ -4792,7 +4800,7 @@ msgstr ""
"Bitte sicherstellen, dass der Dateiname maximal %(max)d Zeichen hat. (Er hat " "Bitte sicherstellen, dass der Dateiname maximal %(max)d Zeichen hat. (Er hat "
"%(length)d)." "%(length)d)."
#: forms/fields.py:473 #: forms/fields.py:472
msgid "" msgid ""
"Upload a valid image. The file you uploaded was either not an image or a " "Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image." "corrupted image."
@ -4800,17 +4808,17 @@ msgstr ""
"Bitte ein Bild hochladen. Die hochgeladene Datei ist kein Bild oder ist " "Bitte ein Bild hochladen. Die hochgeladene Datei ist kein Bild oder ist "
"defekt." "defekt."
#: forms/fields.py:596 forms/fields.py:671 #: forms/fields.py:595 forms/fields.py:670
#, python-format #, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices." msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "" msgstr ""
"Bitte eine gültige Auswahl treffen. %(value)s ist keine gültige Auswahl." "Bitte eine gültige Auswahl treffen. %(value)s ist keine gültige Auswahl."
#: forms/fields.py:672 forms/fields.py:734 forms/models.py:1002 #: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002
msgid "Enter a list of values." msgid "Enter a list of values."
msgstr "Bitte eine Liste mit Werten eingeben." msgstr "Bitte eine Liste mit Werten eingeben."
#: forms/formsets.py:298 forms/formsets.py:300 #: forms/formsets.py:296 forms/formsets.py:298
msgid "Order" msgid "Order"
msgstr "Reihenfolge" msgstr "Reihenfolge"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-11 08:35-0300\n" "POT-Creation-Date: 2010-08-06 15:38-0300\n"
"PO-Revision-Date: 2010-05-17 10:52-0300\n" "PO-Revision-Date: 2010-08-06 16:02-0300\n"
"Last-Translator: Ramiro <rm0@gmx.net>\n" "Last-Translator: Ramiro <rm0@gmx.net>\n"
"Language-Team: Django-I18N <django-i18n@googlegroups.com>\n" "Language-Team: Django-I18N <django-i18n@googlegroups.com>\n"
"Language: es_AR\n" "Language: es_AR\n"
@ -70,7 +70,7 @@ msgid "Spanish"
msgstr "español" msgstr "español"
#: conf/global_settings.py:57 #: conf/global_settings.py:57
msgid "Argentinean Spanish" msgid "Argentinian Spanish"
msgstr "español de Argentina" msgstr "español de Argentina"
#: conf/global_settings.py:58 #: conf/global_settings.py:58
@ -166,98 +166,102 @@ msgid "Macedonian"
msgstr "macedonio" msgstr "macedonio"
#: conf/global_settings.py:81 #: conf/global_settings.py:81
msgid "Malayalam"
msgstr "Malayalam"
#: conf/global_settings.py:82
msgid "Mongolian" msgid "Mongolian"
msgstr "mongol" msgstr "mongol"
#: conf/global_settings.py:82 #: conf/global_settings.py:83
msgid "Dutch" msgid "Dutch"
msgstr "holandés" msgstr "holandés"
#: conf/global_settings.py:83 #: conf/global_settings.py:84
msgid "Norwegian" msgid "Norwegian"
msgstr "noruego" msgstr "noruego"
#: conf/global_settings.py:84 #: conf/global_settings.py:85
msgid "Norwegian Bokmal" msgid "Norwegian Bokmal"
msgstr "bokmål" msgstr "bokmål"
#: conf/global_settings.py:85 #: conf/global_settings.py:86
msgid "Norwegian Nynorsk" msgid "Norwegian Nynorsk"
msgstr "nynorsk" msgstr "nynorsk"
#: conf/global_settings.py:86 #: conf/global_settings.py:87
msgid "Polish" msgid "Polish"
msgstr "polaco" msgstr "polaco"
#: conf/global_settings.py:87 #: conf/global_settings.py:88
msgid "Portuguese" msgid "Portuguese"
msgstr "portugués" msgstr "portugués"
#: conf/global_settings.py:88 #: conf/global_settings.py:89
msgid "Brazilian Portuguese" msgid "Brazilian Portuguese"
msgstr "portugués de Brasil" msgstr "portugués de Brasil"
#: conf/global_settings.py:89 #: conf/global_settings.py:90
msgid "Romanian" msgid "Romanian"
msgstr "rumano" msgstr "rumano"
#: conf/global_settings.py:90 #: conf/global_settings.py:91
msgid "Russian" msgid "Russian"
msgstr "ruso" msgstr "ruso"
#: conf/global_settings.py:91 #: conf/global_settings.py:92
msgid "Slovak" msgid "Slovak"
msgstr "eslovaco" msgstr "eslovaco"
#: conf/global_settings.py:92 #: conf/global_settings.py:93
msgid "Slovenian" msgid "Slovenian"
msgstr "esloveno" msgstr "esloveno"
#: conf/global_settings.py:93 #: conf/global_settings.py:94
msgid "Albanian" msgid "Albanian"
msgstr "albanés" msgstr "albanés"
#: conf/global_settings.py:94 #: conf/global_settings.py:95
msgid "Serbian" msgid "Serbian"
msgstr "serbio" msgstr "serbio"
#: conf/global_settings.py:95 #: conf/global_settings.py:96
msgid "Serbian Latin" msgid "Serbian Latin"
msgstr "Latín de Serbia" msgstr "Latín de Serbia"
#: conf/global_settings.py:96 #: conf/global_settings.py:97
msgid "Swedish" msgid "Swedish"
msgstr "sueco" msgstr "sueco"
#: conf/global_settings.py:97 #: conf/global_settings.py:98
msgid "Tamil" msgid "Tamil"
msgstr "tamil" msgstr "tamil"
#: conf/global_settings.py:98 #: conf/global_settings.py:99
msgid "Telugu" msgid "Telugu"
msgstr "telugu" msgstr "telugu"
#: conf/global_settings.py:99 #: conf/global_settings.py:100
msgid "Thai" msgid "Thai"
msgstr "tailandés" msgstr "tailandés"
#: conf/global_settings.py:100 #: conf/global_settings.py:101
msgid "Turkish" msgid "Turkish"
msgstr "turco" msgstr "turco"
#: conf/global_settings.py:101 #: conf/global_settings.py:102
msgid "Ukrainian" msgid "Ukrainian"
msgstr "ucraniano" msgstr "ucraniano"
#: conf/global_settings.py:102 #: conf/global_settings.py:103
msgid "Vietnamese" msgid "Vietnamese"
msgstr "vietnamita" msgstr "vietnamita"
#: conf/global_settings.py:103 #: conf/global_settings.py:104
msgid "Simplified Chinese" msgid "Simplified Chinese"
msgstr "chino simplificado" msgstr "chino simplificado"
#: conf/global_settings.py:104 #: conf/global_settings.py:105
msgid "Traditional Chinese" msgid "Traditional Chinese"
msgstr "chino tradicional" msgstr "chino tradicional"
@ -309,15 +313,15 @@ msgstr "Este mes"
msgid "This year" msgid "This year"
msgstr "Este año" msgstr "Este año"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "Yes" msgid "Yes"
msgstr "Sí" msgstr "Sí"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "No" msgid "No"
msgstr "No" msgstr "No"
#: contrib/admin/filterspecs.py:154 forms/widgets.py:469 #: contrib/admin/filterspecs.py:154 forms/widgets.py:478
msgid "Unknown" msgid "Unknown"
msgstr "Desconocido" msgstr "Desconocido"
@ -363,7 +367,7 @@ msgid "Changed %s."
msgstr "Modifica %s." msgstr "Modifica %s."
#: contrib/admin/options.py:559 contrib/admin/options.py:569 #: contrib/admin/options.py:559 contrib/admin/options.py:569
#: contrib/comments/templates/comments/preview.html:16 db/models/base.py:844 #: contrib/comments/templates/comments/preview.html:16 db/models/base.py:845
#: forms/models.py:568 #: forms/models.py:568
msgid "and" msgid "and"
msgstr "y" msgstr "y"
@ -692,7 +696,7 @@ msgid "Filter"
msgstr "Filtrar" msgstr "Filtrar"
#: contrib/admin/templates/admin/delete_confirmation.html:10 #: contrib/admin/templates/admin/delete_confirmation.html:10
#: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:302 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:300
msgid "Delete" msgid "Delete"
msgstr "Eliminar" msgstr "Eliminar"
@ -855,13 +859,17 @@ msgstr "Guardar y agregar otro"
msgid "Save and continue editing" msgid "Save and continue editing"
msgstr "Guardar y continuar editando" msgstr "Guardar y continuar editando"
#: contrib/admin/templates/admin/auth/user/add_form.html:5 #: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid "" msgid ""
"First, enter a username and password. Then, you'll be able to edit more user " "First, enter a username and password. Then, you'll be able to edit more user "
"options." "options."
msgstr "" msgstr ""
"Primero, introduzca un nombre de usuario y una contraseña. Luego podrá " "Primero introduzca un nombre de usuario y una contraseña. Luego podrá "
"configurar opciones adicionales." "configurar opciones adicionales acerca del usuario."
#: contrib/admin/templates/admin/auth/user/add_form.html:8
msgid "Enter a username and password."
msgstr "Introduzca un nombre de usuario y una contraseña."
#: contrib/admin/templates/admin/auth/user/change_password.html:28 #: contrib/admin/templates/admin/auth/user/change_password.html:28
#, python-format #, python-format
@ -1435,8 +1443,8 @@ msgstr "mensaje"
msgid "Logged out" msgid "Logged out"
msgstr "Sesión cerrada" msgstr "Sesión cerrada"
#: contrib/auth/management/commands/createsuperuser.py:23 #: contrib/auth/management/commands/createsuperuser.py:24
#: core/validators.py:120 forms/fields.py:428 #: core/validators.py:120 forms/fields.py:427
msgid "Enter a valid e-mail address." msgid "Enter a valid e-mail address."
msgstr "Introduzca una dirección de correo electrónico válida" msgstr "Introduzca una dirección de correo electrónico válida"
@ -1504,7 +1512,7 @@ msgid "Email address"
msgstr "Dirección de correo electrónico" msgstr "Dirección de correo electrónico"
#: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8 #: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8
#: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1109
msgid "URL" msgid "URL"
msgstr "URL" msgstr "URL"
@ -1553,7 +1561,7 @@ msgstr "comentario"
msgid "date/time submitted" msgid "date/time submitted"
msgstr "fecha/hora de envío" msgstr "fecha/hora de envío"
#: contrib/comments/models.py:60 db/models/fields/__init__.py:896 #: contrib/comments/models.py:60 db/models/fields/__init__.py:904
msgid "IP address" msgid "IP address"
msgstr "Dirección IP" msgstr "Dirección IP"
@ -4503,20 +4511,20 @@ msgstr "sitios"
msgid "Enter a valid value." msgid "Enter a valid value."
msgstr "Introduzca un valor válido." msgstr "Introduzca un valor válido."
#: core/validators.py:87 forms/fields.py:529 #: core/validators.py:87 forms/fields.py:528
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "Introduzca una URL válida." msgstr "Introduzca una URL válida."
#: core/validators.py:89 forms/fields.py:530 #: core/validators.py:89 forms/fields.py:529
msgid "This URL appears to be a broken link." msgid "This URL appears to be a broken link."
msgstr "La URL parece ser un enlace roto." msgstr "La URL parece ser un enlace roto."
#: core/validators.py:123 forms/fields.py:873 #: core/validators.py:123 forms/fields.py:877
msgid "" msgid ""
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "Introduzca un 'slug' válido consistente de letras, números o guiones." msgstr "Introduzca un 'slug' válido consistente de letras, números o guiones."
#: core/validators.py:126 forms/fields.py:866 #: core/validators.py:126 forms/fields.py:870
msgid "Enter a valid IPv4 address." msgid "Enter a valid IPv4 address."
msgstr "Introduzca una dirección IPv4 válida" msgstr "Introduzca una dirección IPv4 válida"
@ -4528,15 +4536,15 @@ msgstr "Introduzca sólo dígitos separados por comas."
#, python-format #, python-format
msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)."
msgstr "" msgstr ""
"Asegúrese de que este valor sea %(limit_value)s (actualmente es %(show_value)" "Asegúrese de que este valor sea %(limit_value)s (actualmente es "
"s)." "%(show_value)s)."
#: core/validators.py:153 forms/fields.py:205 forms/fields.py:257 #: core/validators.py:153 forms/fields.py:204 forms/fields.py:256
#, python-format #, python-format
msgid "Ensure this value is less than or equal to %(limit_value)s." msgid "Ensure this value is less than or equal to %(limit_value)s."
msgstr "Asegúrese de que este valor sea menor o igual a %(limit_value)s." msgstr "Asegúrese de que este valor sea menor o igual a %(limit_value)s."
#: core/validators.py:158 forms/fields.py:206 forms/fields.py:258 #: core/validators.py:158 forms/fields.py:205 forms/fields.py:257
#, python-format #, python-format
msgid "Ensure this value is greater than or equal to %(limit_value)s." msgid "Ensure this value is greater than or equal to %(limit_value)s."
msgstr "Asegúrese de que este valor sea mayor o igual a %(limit_value)s." msgstr "Asegúrese de que este valor sea mayor o igual a %(limit_value)s."
@ -4544,8 +4552,8 @@ msgstr "Asegúrese de que este valor sea mayor o igual a %(limit_value)s."
#: core/validators.py:164 #: core/validators.py:164
#, python-format #, python-format
msgid "" msgid ""
"Ensure this value has at least %(limit_value)d characters (it has %" "Ensure this value has at least %(limit_value)d characters (it has "
"(show_value)d)." "%(show_value)d)."
msgstr "" msgstr ""
"Asegúrese de que este valor tenga al menos %(limit_value)d caracteres (tiene " "Asegúrese de que este valor tenga al menos %(limit_value)d caracteres (tiene "
"%(show_value)d)." "%(show_value)d)."
@ -4553,20 +4561,20 @@ msgstr ""
#: core/validators.py:170 #: core/validators.py:170
#, python-format #, python-format
msgid "" msgid ""
"Ensure this value has at most %(limit_value)d characters (it has %" "Ensure this value has at most %(limit_value)d characters (it has "
"(show_value)d)." "%(show_value)d)."
msgstr "" msgstr ""
"Asegúrese de que este valor tenga como máximo %(limit_value)d caracteres " "Asegúrese de que este valor tenga como máximo %(limit_value)d caracteres "
"(tiene %(show_value)d)." "(tiene %(show_value)d)."
#: db/models/base.py:822 #: db/models/base.py:823
#, python-format #, python-format
msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s." msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s."
msgstr "" msgstr ""
"%(field_name)s debe ser único/a para un %(lookup)s %(date_field)s " "%(field_name)s debe ser único/a para un %(lookup)s %(date_field)s "
"determinado." "determinado."
#: db/models/base.py:837 db/models/base.py:845 #: db/models/base.py:838 db/models/base.py:846
#, python-format #, python-format
msgid "%(model_name)s with this %(field_label)s already exists." msgid "%(model_name)s with this %(field_label)s already exists."
msgstr "Ya existe un/a %(model_name)s con este/a %(field_label)s." msgstr "Ya existe un/a %(model_name)s con este/a %(field_label)s."
@ -4589,13 +4597,13 @@ msgstr "Este campo no puede estar en blanco."
msgid "Field of type: %(field_type)s" msgid "Field of type: %(field_type)s"
msgstr "Campo tipo: %(field_type)s" msgstr "Campo tipo: %(field_type)s"
#: db/models/fields/__init__.py:451 db/models/fields/__init__.py:852 #: db/models/fields/__init__.py:451 db/models/fields/__init__.py:860
#: db/models/fields/__init__.py:961 db/models/fields/__init__.py:972 #: db/models/fields/__init__.py:969 db/models/fields/__init__.py:980
#: db/models/fields/__init__.py:999 #: db/models/fields/__init__.py:1007
msgid "Integer" msgid "Integer"
msgstr "Entero" msgstr "Entero"
#: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850 #: db/models/fields/__init__.py:455 db/models/fields/__init__.py:858
msgid "This value must be an integer." msgid "This value must be an integer."
msgstr "Este valor debe ser un número entero." msgstr "Este valor debe ser un número entero."
@ -4607,7 +4615,7 @@ msgstr "Este valor debe ser True o False."
msgid "Boolean (Either True or False)" msgid "Boolean (Either True or False)"
msgstr "Booleano (Verdadero o Falso)" msgstr "Booleano (Verdadero o Falso)"
#: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982 #: db/models/fields/__init__.py:539 db/models/fields/__init__.py:990
#, python-format #, python-format
msgid "String (up to %(max_length)s)" msgid "String (up to %(max_length)s)"
msgstr "Cadena (máximo %(max_length)s)" msgstr "Cadena (máximo %(max_length)s)"
@ -4651,44 +4659,44 @@ msgstr "Número decimal"
msgid "E-mail address" msgid "E-mail address"
msgstr "Dirección de correo electrónico" msgstr "Dirección de correo electrónico"
#: db/models/fields/__init__.py:799 db/models/fields/files.py:220 #: db/models/fields/__init__.py:807 db/models/fields/files.py:220
#: db/models/fields/files.py:331 #: db/models/fields/files.py:331
msgid "File path" msgid "File path"
msgstr "Ruta de archivo" msgstr "Ruta de archivo"
#: db/models/fields/__init__.py:822 #: db/models/fields/__init__.py:830
msgid "This value must be a float." msgid "This value must be a float."
msgstr "Este valor debe ser un valor en representación de punto flotante." msgstr "Este valor debe ser un valor en representación de punto flotante."
#: db/models/fields/__init__.py:824 #: db/models/fields/__init__.py:832
msgid "Floating point number" msgid "Floating point number"
msgstr "Número de punto flotante" msgstr "Número de punto flotante"
#: db/models/fields/__init__.py:883 #: db/models/fields/__init__.py:891
msgid "Big (8 byte) integer" msgid "Big (8 byte) integer"
msgstr "Entero grande (8 bytes)" msgstr "Entero grande (8 bytes)"
#: db/models/fields/__init__.py:912 #: db/models/fields/__init__.py:920
msgid "This value must be either None, True or False." msgid "This value must be either None, True or False."
msgstr "Este valor debe ser None, True o False." msgstr "Este valor debe ser None, True o False."
#: db/models/fields/__init__.py:914 #: db/models/fields/__init__.py:922
msgid "Boolean (Either True, False or None)" msgid "Boolean (Either True, False or None)"
msgstr "Booleano (Verdadero, Falso o Nulo)" msgstr "Booleano (Verdadero, Falso o Nulo)"
#: db/models/fields/__init__.py:1005 #: db/models/fields/__init__.py:1013
msgid "Text" msgid "Text"
msgstr "Texto" msgstr "Texto"
#: db/models/fields/__init__.py:1021 #: db/models/fields/__init__.py:1029
msgid "Time" msgid "Time"
msgstr "Hora" msgstr "Hora"
#: db/models/fields/__init__.py:1025 #: db/models/fields/__init__.py:1033
msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format." msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
msgstr "Introduzca un valor de hora válido en formato HH:MM[:ss[.uuuuuu]]." msgstr "Introduzca un valor de hora válido en formato HH:MM[:ss[.uuuuuu]]."
#: db/models/fields/__init__.py:1109 #: db/models/fields/__init__.py:1125
msgid "XML text" msgid "XML text"
msgstr "Texto XML" msgstr "Texto XML"
@ -4701,22 +4709,22 @@ msgstr "No existe un modelo %(model)s con una clave primaria %(pk)r."
msgid "Foreign Key (type determined by related field)" msgid "Foreign Key (type determined by related field)"
msgstr "Clave foránea (el tipo está determinado por el campo relacionado)" msgstr "Clave foránea (el tipo está determinado por el campo relacionado)"
#: db/models/fields/related.py:918 #: db/models/fields/related.py:919
msgid "One-to-one relationship" msgid "One-to-one relationship"
msgstr "Relación uno-a-uno" msgstr "Relación uno-a-uno"
#: db/models/fields/related.py:980 #: db/models/fields/related.py:981
msgid "Many-to-many relationship" msgid "Many-to-many relationship"
msgstr "Relación muchos-a-muchos" msgstr "Relación muchos-a-muchos"
#: db/models/fields/related.py:1000 #: db/models/fields/related.py:1001
msgid "" msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "" msgstr ""
"Mantenga presionada \"Control\" (\"Command\" en una Mac) para seleccionar " "Mantenga presionada \"Control\" (\"Command\" en una Mac) para seleccionar "
"más de uno." "más de uno."
#: db/models/fields/related.py:1061 #: db/models/fields/related.py:1062
#, python-format #, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural "" msgid_plural ""
@ -4732,55 +4740,55 @@ msgstr[1] ""
msgid "This field is required." msgid "This field is required."
msgstr "Este campo es obligatorio." msgstr "Este campo es obligatorio."
#: forms/fields.py:204 #: forms/fields.py:203
msgid "Enter a whole number." msgid "Enter a whole number."
msgstr "Introduzca un número entero." msgstr "Introduzca un número entero."
#: forms/fields.py:235 forms/fields.py:256 #: forms/fields.py:234 forms/fields.py:255
msgid "Enter a number." msgid "Enter a number."
msgstr "Introduzca un número." msgstr "Introduzca un número."
#: forms/fields.py:259 #: forms/fields.py:258
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits in total." 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." msgstr "Asegúrese de que no existan en total mas de %s dígitos."
#: forms/fields.py:260 #: forms/fields.py:259
#, python-format #, python-format
msgid "Ensure that there are no more than %s decimal places." msgid "Ensure that there are no more than %s decimal places."
msgstr "Asegúrese de que no existan mas de %s lugares decimales." msgstr "Asegúrese de que no existan mas de %s lugares decimales."
#: forms/fields.py:261 #: forms/fields.py:260
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits before the decimal point." 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." msgstr "Asegúrese de que no existan mas de %s dígitos antes del punto decimal."
#: forms/fields.py:323 forms/fields.py:838 #: forms/fields.py:322 forms/fields.py:837
msgid "Enter a valid date." msgid "Enter a valid date."
msgstr "Introduzca una fecha válida." msgstr "Introduzca una fecha válida."
#: forms/fields.py:351 forms/fields.py:839 #: forms/fields.py:350 forms/fields.py:838
msgid "Enter a valid time." msgid "Enter a valid time."
msgstr "Introduzca un valor de hora válido." msgstr "Introduzca un valor de hora válido."
#: forms/fields.py:377 #: forms/fields.py:376
msgid "Enter a valid date/time." msgid "Enter a valid date/time."
msgstr "Introduzca un valor de fecha/hora válido." msgstr "Introduzca un valor de fecha/hora válido."
#: forms/fields.py:435 #: forms/fields.py:434
msgid "No file was submitted. Check the encoding type on the form." msgid "No file was submitted. Check the encoding type on the form."
msgstr "" msgstr ""
"No se envió un archivo. Verifique el tipo de codificación en el formulario." "No se envió un archivo. Verifique el tipo de codificación en el formulario."
#: forms/fields.py:436 #: forms/fields.py:435
msgid "No file was submitted." msgid "No file was submitted."
msgstr "No se envió ningún archivo." msgstr "No se envió ningún archivo."
#: forms/fields.py:437 #: forms/fields.py:436
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "El archivo enviado está vacío." msgstr "El archivo enviado está vacío."
#: forms/fields.py:438 #: forms/fields.py:437
#, python-format #, python-format
msgid "" msgid ""
"Ensure this filename has at most %(max)d characters (it has %(length)d)." "Ensure this filename has at most %(max)d characters (it has %(length)d)."
@ -4788,7 +4796,7 @@ msgstr ""
"Asegúrese de que este nombre de archivo tenga como máximo %(max)d caracteres " "Asegúrese de que este nombre de archivo tenga como máximo %(max)d caracteres "
"(tiene %(length)d)." "(tiene %(length)d)."
#: forms/fields.py:473 #: forms/fields.py:472
msgid "" msgid ""
"Upload a valid image. The file you uploaded was either not an image or a " "Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image." "corrupted image."
@ -4796,18 +4804,18 @@ msgstr ""
"Seleccione una imagen válida. El archivo que ha seleccionado no es una " "Seleccione una imagen válida. El archivo que ha seleccionado no es una "
"imagen o es un un archivo de imagen corrupto." "imagen o es un un archivo de imagen corrupto."
#: forms/fields.py:596 forms/fields.py:671 #: forms/fields.py:595 forms/fields.py:670
#, python-format #, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices." msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "" msgstr ""
"Seleccione una opción válida. %(value)s no es una de las opciones " "Seleccione una opción válida. %(value)s no es una de las opciones "
"disponibles." "disponibles."
#: forms/fields.py:672 forms/fields.py:734 forms/models.py:1002 #: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002
msgid "Enter a list of values." msgid "Enter a list of values."
msgstr "Introduzca una lista de valores." msgstr "Introduzca una lista de valores."
#: forms/formsets.py:298 forms/formsets.py:300 #: forms/formsets.py:296 forms/formsets.py:298
msgid "Order" msgid "Order"
msgstr "Ordenar" msgstr "Ordenar"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-04 22:01-0300\n" "POT-Creation-Date: 2010-08-06 15:47-0300\n"
"PO-Revision-Date: 2010-05-04 22:10-0300\n" "PO-Revision-Date: 2010-08-06 15:52-0300\n"
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n" "Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
"Language-Team: Django-I18N <django-i18n@googlegroups.com>\n" "Language-Team: Django-I18N <django-i18n@googlegroups.com>\n"
"Language: es_AR\n" "Language: es_AR\n"
@ -17,45 +17,17 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.1\n" "X-Generator: Pootle 2.0.1\n"
#: contrib/admin/media/js/SelectFilter2.js:37
#, perl-format
msgid "Available %s"
msgstr "%s disponibles"
#: contrib/admin/media/js/SelectFilter2.js:45
msgid "Choose all"
msgstr "Seleccionar todos"
#: contrib/admin/media/js/SelectFilter2.js:50
msgid "Add"
msgstr "Agregar"
#: contrib/admin/media/js/SelectFilter2.js:52
msgid "Remove"
msgstr "Eliminar"
#: contrib/admin/media/js/SelectFilter2.js:57
#, perl-format
msgid "Chosen %s"
msgstr "%s elegidos"
#: contrib/admin/media/js/SelectFilter2.js:58
msgid "Select your choice(s) and click "
msgstr "Seleccione los items a agregar y haga click en "
#: contrib/admin/media/js/SelectFilter2.js:63 #: contrib/admin/media/js/SelectFilter2.js:63
msgid "Clear all" msgid "Clear all"
msgstr "Eliminar todos" msgstr "Eliminar todos"
#: contrib/admin/media/js/actions.js:18 #: contrib/admin/media/js/actions.js:18
#: contrib/admin/media/js/actions.min.js:1
msgid "%(sel)s of %(cnt)s selected" msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected" msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s de %(cnt)s seleccionado/a" msgstr[0] "%(sel)s de %(cnt)s seleccionado/a"
msgstr[1] "%(sel)s de %(cnt)s seleccionados/as" msgstr[1] "%(sel)s de %(cnt)s seleccionados/as"
#: contrib/admin/media/js/actions.js:109 #: contrib/admin/media/js/actions.js:109
#: contrib/admin/media/js/actions.min.js:5
msgid "" msgid ""
"You have unsaved changes on individual editable fields. If you run an " "You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost." "action, your unsaved changes will be lost."

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,156 @@
# Translation of Django Js files to malayalam.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Rajeesh Nair <rajeeshrnair@gmail.com>, 2010.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Django SVN\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-28 15:32+0530\n"
"PO-Revision-Date: 2010-05-28 15:45+0530\n"
"Last-Translator: Rajeesh Nair <rajeeshrnair@gmail.com>\n"
"Language-Team: Malayalam <ml@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Malayalam\n"
"X-Poedit-Country: INDIA\n"
#: contrib/admin/media/js/SelectFilter2.js:37
#, perl-format
msgid "Available %s"
msgstr "ലഭ്യമായ %s"
#: contrib/admin/media/js/SelectFilter2.js:45
msgid "Choose all"
msgstr "എല്ലാം തെരഞ്ഞെടുക്കുക"
#: contrib/admin/media/js/SelectFilter2.js:50
msgid "Add"
msgstr "പുതിയത് ചേര്‍ക്കൂ"
#: contrib/admin/media/js/SelectFilter2.js:52
msgid "Remove"
msgstr "നീക്കം ചെയ്യൂ"
#: contrib/admin/media/js/SelectFilter2.js:57
#, perl-format
msgid "Chosen %s"
msgstr "തെരഞ്ഞെടുത്ത %s"
#: contrib/admin/media/js/SelectFilter2.js:58
msgid "Select your choice(s) and click "
msgstr "ഉചിതമായത് തെരഞ്ഞെടുത്ത ശേഷം ക്ളിക് ചെയ്യൂ"
#: contrib/admin/media/js/SelectFilter2.js:63
msgid "Clear all"
msgstr "എല്ലാം ക്ളിയര്‍ ചെയ്യൂ"
#: contrib/admin/media/js/actions.js:18
#: contrib/admin/media/js/actions.min.js:1
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(cnt)sല് %(sel)s തെരഞ്ഞെടുത്തു"
msgstr[1] "%(cnt)sല് %(sel)s എണ്ണം തെരഞ്ഞെടുത്തു"
#: contrib/admin/media/js/actions.js:109
#: contrib/admin/media/js/actions.min.js:5
msgid ""
"You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost."
msgstr "വരുത്തിയ മാറ്റങ്ങള്‍ സേവ് ചെയ്തിട്ടില്ല. ഒരു ആക്ഷന്‍ പ്രയോഗിച്ചാല്‍ സേവ് ചെയ്യാത്ത "
"മാറ്റങ്ങളെല്ലാം നഷ്ടപ്പെടും."
#: contrib/admin/media/js/actions.js:121
#: contrib/admin/media/js/actions.min.js:6
msgid ""
"You have selected an action, but you haven't saved your changes to "
"individual fields yet. Please click OK to save. You'll need to re-run the "
"action."
msgstr ""
"നിങ്ങള്‍ ഒരു ആക്ഷന്‍ തെരഞ്ഞെടുത്തിട്ടുണ്ട്. പക്ഷേ, കളങ്ങളിലെ മാറ്റങ്ങള്‍ ഇനിയും സേവ് ചെയ്യാനുണ്ട്. ആദ്യം സേവ്"
"ചെയ്യാനായി OK ക്ലിക് ചെയ്യുക. അതിനു ശേഷം ആക്ഷന്‍ ഒന്നു കൂടി പ്രയോഗിക്കേണ്ടി വരും."
#: contrib/admin/media/js/actions.js:123
#: contrib/admin/media/js/actions.min.js:6
msgid ""
"You have selected an action, and you haven't made any changes on individual "
"fields. You're probably looking for the Go button rather than the Save "
"button."
msgstr ""
"നിങ്ങള്‍ ഒരു ആക്ഷന്‍ തെരഞ്ഞെടുത്തിട്ടുണ്ട്. കളങ്ങളില്‍ സേവ് ചെയ്യാത്ത മാറ്റങ്ങള്‍ ഇല്ല. നിങ്ങള്‍"
"സേവ് ബട്ടണ്‍ തന്നെയാണോ അതോ ഗോ ബട്ടണാണോ ഉദ്ദേശിച്ചത്."
#: 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 "ജനുവരി ഫെബൃവരി മാര്‍ച്ച് ഏപ്രില്‍ മെയ് ജൂണ്‍ ജൂലൈ ആഗസ്ത് സെപ്തംബര്‍ ഒക്ടോബര്‍ നവംബര്‍ ഡിസംബര്‍"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "ഞാ തി ചൊ ബു വ്യാ വെ ശ"
#: contrib/admin/media/js/collapse.js:9 contrib/admin/media/js/collapse.js:21
#: contrib/admin/media/js/collapse.min.js:1
msgid "Show"
msgstr "കാണട്ടെ"
#: contrib/admin/media/js/collapse.js:16
#: contrib/admin/media/js/collapse.min.js:1
msgid "Hide"
msgstr "മറയട്ടെ"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "ഞായര്‍ തിങ്കള്‍ ചൊവ്വ ബുധന്‍ വ്യാഴം വെള്ളി ശനി"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "Now"
msgstr "ഇപ്പോള്‍"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:52
msgid "Clock"
msgstr "ഘടികാരം (ക്ലോക്ക്)"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:79
msgid "Choose a time"
msgstr "സമയം തെരഞ്ഞെടുക്കൂ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Midnight"
msgstr "അര്‍ധരാത്രി"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:85
msgid "6 a.m."
msgstr "6 a.m."
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:86
msgid "Noon"
msgstr "ഉച്ച"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:90
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:187
msgid "Cancel"
msgstr "റദ്ദാക്കൂ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:181
msgid "Today"
msgstr "ഇന്ന്"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:136
msgid "Calendar"
msgstr "കലണ്ടര്‍"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Yesterday"
msgstr "ഇന്നലെ"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Tomorrow"
msgstr "നാളെ"

View File

View File

@ -0,0 +1,38 @@
# -*- encoding: utf-8 -*-
# This file is distributed under the same license as the Django package.
#
DATE_FORMAT = 'N j, Y'
TIME_FORMAT = 'P'
DATETIME_FORMAT = 'N j, Y, P'
YEAR_MONTH_FORMAT = 'F Y'
MONTH_DAY_FORMAT = 'F j'
SHORT_DATE_FORMAT = 'm/d/Y'
SHORT_DATETIME_FORMAT = 'm/d/Y P'
FIRST_DAY_OF_WEEK = 0 # Sunday
DATE_INPUT_FORMATS = (
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
# '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
# '%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'
)
TIME_INPUT_FORMATS = (
'%H:%M:%S', # '14:30:59'
'%H:%M', # '14:30'
)
DATETIME_INPUT_FORMATS = (
'%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'
)
DECIMAL_SEPARATOR = '.'
THOUSAND_SEPARATOR = ','
NUMBER_GROUPING = 3

View File

@ -4,17 +4,18 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-07 20:44+0200\n" "POT-Creation-Date: 2010-08-06 19:53+0200\n"
"PO-Revision-Date: 2010-03-23 23:39+0100\n" "PO-Revision-Date: 2010-08-06 19:47+0100\n"
"Last-Translator: Janos Guljas <janos@janos.in.rs>\n" "Last-Translator: Janos Guljas <janos@janos.in.rs>\n"
"Language-Team: Branko Vukelic <bg.branko@gmail.com> & Janos Guljas " "Language-Team: Branko Vukelic <bg.branko@gmail.com> & Janos Guljas "
"<janos@janos.in.rs> & Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail." "<janos@janos.in.rs> & Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail."
"com>\n" "com>\n"
"Language: \n"
"MIME-Version: 1.0\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" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: conf/global_settings.py:44 #: conf/global_settings.py:44
msgid "Arabic" msgid "Arabic"
@ -69,7 +70,7 @@ msgid "Spanish"
msgstr "шпански" msgstr "шпански"
#: conf/global_settings.py:57 #: conf/global_settings.py:57
msgid "Argentinean Spanish" msgid "Argentinian Spanish"
msgstr "аргентински шпански" msgstr "аргентински шпански"
#: conf/global_settings.py:58 #: conf/global_settings.py:58
@ -121,138 +122,146 @@ msgid "Hungarian"
msgstr "мађарски" msgstr "мађарски"
#: conf/global_settings.py:70 #: conf/global_settings.py:70
msgid "Indonesian"
msgstr "индонежански"
#: conf/global_settings.py:71
msgid "Icelandic" msgid "Icelandic"
msgstr "исландски" msgstr "исландски"
#: conf/global_settings.py:71 #: conf/global_settings.py:72
msgid "Italian" msgid "Italian"
msgstr "италијански" msgstr "италијански"
#: conf/global_settings.py:72 #: conf/global_settings.py:73
msgid "Japanese" msgid "Japanese"
msgstr "јапански" msgstr "јапански"
#: conf/global_settings.py:73 #: conf/global_settings.py:74
msgid "Georgian" msgid "Georgian"
msgstr "грузијски" msgstr "грузијски"
#: conf/global_settings.py:74 #: conf/global_settings.py:75
msgid "Khmer" msgid "Khmer"
msgstr "камбодијски" msgstr "камбодијски"
#: conf/global_settings.py:75 #: conf/global_settings.py:76
msgid "Kannada" msgid "Kannada"
msgstr "канада" msgstr "канада"
#: conf/global_settings.py:76 #: conf/global_settings.py:77
msgid "Korean" msgid "Korean"
msgstr "корејски" msgstr "корејски"
#: conf/global_settings.py:77 #: conf/global_settings.py:78
msgid "Lithuanian" msgid "Lithuanian"
msgstr "литвански" msgstr "литвански"
#: conf/global_settings.py:78 #: conf/global_settings.py:79
msgid "Latvian" msgid "Latvian"
msgstr "латвијски" msgstr "латвијски"
#: conf/global_settings.py:79 #: conf/global_settings.py:80
msgid "Macedonian" msgid "Macedonian"
msgstr "македонски" msgstr "македонски"
#: conf/global_settings.py:80 #: conf/global_settings.py:81
msgid "Malayalam"
msgstr "малајаламски"
#: conf/global_settings.py:82
msgid "Mongolian" msgid "Mongolian"
msgstr "монголски" msgstr "монголски"
#: conf/global_settings.py:81 #: conf/global_settings.py:83
msgid "Dutch" msgid "Dutch"
msgstr "холандски" msgstr "холандски"
#: conf/global_settings.py:82 #: conf/global_settings.py:84
msgid "Norwegian" msgid "Norwegian"
msgstr "норвешки" msgstr "норвешки"
#: conf/global_settings.py:83 #: conf/global_settings.py:85
msgid "Norwegian Bokmal" msgid "Norwegian Bokmal"
msgstr "норвешки кнјжевни" msgstr "норвешки кнјжевни"
#: conf/global_settings.py:84 #: conf/global_settings.py:86
msgid "Norwegian Nynorsk" msgid "Norwegian Nynorsk"
msgstr "норвешки нови" msgstr "норвешки нови"
#: conf/global_settings.py:85 #: conf/global_settings.py:87
msgid "Polish" msgid "Polish"
msgstr "пољски" msgstr "пољски"
#: conf/global_settings.py:86 #: conf/global_settings.py:88
msgid "Portuguese" msgid "Portuguese"
msgstr "португалски" msgstr "португалски"
#: conf/global_settings.py:87 #: conf/global_settings.py:89
msgid "Brazilian Portuguese" msgid "Brazilian Portuguese"
msgstr "бразилски португалски" msgstr "бразилски португалски"
#: conf/global_settings.py:88 #: conf/global_settings.py:90
msgid "Romanian" msgid "Romanian"
msgstr "румунски" msgstr "румунски"
#: conf/global_settings.py:89 #: conf/global_settings.py:91
msgid "Russian" msgid "Russian"
msgstr "руски" msgstr "руски"
#: conf/global_settings.py:90 #: conf/global_settings.py:92
msgid "Slovak" msgid "Slovak"
msgstr "словачки" msgstr "словачки"
#: conf/global_settings.py:91 #: conf/global_settings.py:93
msgid "Slovenian" msgid "Slovenian"
msgstr "словеначки" msgstr "словеначки"
#: conf/global_settings.py:92 #: conf/global_settings.py:94
msgid "Albanian" msgid "Albanian"
msgstr "албански" msgstr "албански"
#: conf/global_settings.py:93 #: conf/global_settings.py:95
msgid "Serbian" msgid "Serbian"
msgstr "српски" msgstr "српски"
#: conf/global_settings.py:94 #: conf/global_settings.py:96
msgid "Serbian Latin" msgid "Serbian Latin"
msgstr "српски (латиница)" msgstr "српски (латиница)"
#: conf/global_settings.py:95 #: conf/global_settings.py:97
msgid "Swedish" msgid "Swedish"
msgstr "шведски" msgstr "шведски"
#: conf/global_settings.py:96 #: conf/global_settings.py:98
msgid "Tamil" msgid "Tamil"
msgstr "тамилски" msgstr "тамилски"
#: conf/global_settings.py:97 #: conf/global_settings.py:99
msgid "Telugu" msgid "Telugu"
msgstr "телугу" msgstr "телугу"
#: conf/global_settings.py:98 #: conf/global_settings.py:100
msgid "Thai" msgid "Thai"
msgstr "тајландски" msgstr "тајландски"
#: conf/global_settings.py:99 #: conf/global_settings.py:101
msgid "Turkish" msgid "Turkish"
msgstr "турски" msgstr "турски"
#: conf/global_settings.py:100 #: conf/global_settings.py:102
msgid "Ukrainian" msgid "Ukrainian"
msgstr "украјински" msgstr "украјински"
#: conf/global_settings.py:101 #: conf/global_settings.py:103
msgid "Vietnamese" msgid "Vietnamese"
msgstr "вијетнамски" msgstr "вијетнамски"
#: conf/global_settings.py:102 #: conf/global_settings.py:104
msgid "Simplified Chinese" msgid "Simplified Chinese"
msgstr "новокинески" msgstr "новокинески"
#: conf/global_settings.py:103 #: conf/global_settings.py:105
msgid "Traditional Chinese" msgid "Traditional Chinese"
msgstr "старокинески" msgstr "старокинески"
@ -304,15 +313,15 @@ msgstr "Овај месец"
msgid "This year" msgid "This year"
msgstr "Ова година" msgstr "Ова година"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "Yes" msgid "Yes"
msgstr "Да" msgstr "Да"
#: contrib/admin/filterspecs.py:147 forms/widgets.py:469 #: contrib/admin/filterspecs.py:147 forms/widgets.py:478
msgid "No" msgid "No"
msgstr "Не" msgstr "Не"
#: contrib/admin/filterspecs.py:154 forms/widgets.py:469 #: contrib/admin/filterspecs.py:154 forms/widgets.py:478
msgid "Unknown" msgid "Unknown"
msgstr "Непознато" msgstr "Непознато"
@ -358,7 +367,7 @@ msgid "Changed %s."
msgstr "Измењена поља %s" msgstr "Измењена поља %s"
#: contrib/admin/options.py:559 contrib/admin/options.py:569 #: contrib/admin/options.py:559 contrib/admin/options.py:569
#: contrib/comments/templates/comments/preview.html:16 db/models/base.py:844 #: contrib/comments/templates/comments/preview.html:16 db/models/base.py:845
#: forms/models.py:568 #: forms/models.py:568
msgid "and" msgid "and"
msgstr "и" msgstr "и"
@ -457,9 +466,9 @@ msgstr[1] "%(total_count)s изабрано"
msgstr[2] "%(total_count)s изабраних" msgstr[2] "%(total_count)s изабраних"
#: contrib/admin/options.py:1071 #: contrib/admin/options.py:1071
#, fuzzy, python-format #, python-format
msgid "0 of %(cnt)s selected" msgid "0 of %(cnt)s selected"
msgstr "0 од %(cnt)d изабрано" msgstr "0 од %(cnt)s изабрано"
#: contrib/admin/options.py:1118 #: contrib/admin/options.py:1118
#, python-format #, python-format
@ -687,7 +696,7 @@ msgid "Filter"
msgstr "Филтер" msgstr "Филтер"
#: contrib/admin/templates/admin/delete_confirmation.html:10 #: contrib/admin/templates/admin/delete_confirmation.html:10
#: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:302 #: contrib/admin/templates/admin/submit_line.html:4 forms/formsets.py:300
msgid "Delete" msgid "Delete"
msgstr "Обриши" msgstr "Обриши"
@ -849,7 +858,7 @@ msgstr "Сачувај и додај следећи"
msgid "Save and continue editing" msgid "Save and continue editing"
msgstr "Сачувај и настави са изменама" msgstr "Сачувај и настави са изменама"
#: contrib/admin/templates/admin/auth/user/add_form.html:5 #: contrib/admin/templates/admin/auth/user/add_form.html:6
msgid "" msgid ""
"First, enter a username and password. Then, you'll be able to edit more user " "First, enter a username and password. Then, you'll be able to edit more user "
"options." "options."
@ -857,6 +866,10 @@ msgstr ""
"Прво унесите корисничко име и лозинку. Потом ћете моћи да мењате још " "Прво унесите корисничко име и лозинку. Потом ћете моћи да мењате још "
"корисничких подешавања." "корисничких подешавања."
#: contrib/admin/templates/admin/auth/user/add_form.html:8
msgid "Enter a username and password."
msgstr "Унесите корисничко име и лозинку"
#: contrib/admin/templates/admin/auth/user/change_password.html:28 #: contrib/admin/templates/admin/auth/user/change_password.html:28
#, python-format #, python-format
msgid "Enter a new password for the user <strong>%(username)s</strong>." msgid "Enter a new password for the user <strong>%(username)s</strong>."
@ -1050,7 +1063,7 @@ msgstr "Имејл адреса:"
msgid "Reset my password" msgid "Reset my password"
msgstr "Ресетуј моју лозинку" msgstr "Ресетуј моју лозинку"
#: contrib/admin/templatetags/admin_list.py:239 #: contrib/admin/templatetags/admin_list.py:257
msgid "All dates" msgid "All dates"
msgstr "Сви датуми" msgstr "Сви датуми"
@ -1424,8 +1437,8 @@ msgstr "порука"
msgid "Logged out" msgid "Logged out"
msgstr "Одјављен" msgstr "Одјављен"
#: contrib/auth/management/commands/createsuperuser.py:23 #: contrib/auth/management/commands/createsuperuser.py:24
#: core/validators.py:120 forms/fields.py:428 #: core/validators.py:120 forms/fields.py:427
msgid "Enter a valid e-mail address." msgid "Enter a valid e-mail address."
msgstr "Унесите важећу имејл адресу." msgstr "Унесите важећу имејл адресу."
@ -1497,7 +1510,7 @@ msgid "Email address"
msgstr "Имејл адреса" msgstr "Имејл адреса"
#: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8 #: contrib/comments/forms.py:95 contrib/flatpages/admin.py:8
#: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1101 #: contrib/flatpages/models.py:7 db/models/fields/__init__.py:1109
msgid "URL" msgid "URL"
msgstr "URL" msgstr "URL"
@ -1547,7 +1560,7 @@ msgstr "коментар"
msgid "date/time submitted" msgid "date/time submitted"
msgstr "датум/време постављања" msgstr "датум/време постављања"
#: contrib/comments/models.py:60 db/models/fields/__init__.py:896 #: contrib/comments/models.py:60 db/models/fields/__init__.py:904
msgid "IP address" msgid "IP address"
msgstr "IP адреса" msgstr "IP адреса"
@ -4471,22 +4484,22 @@ msgstr "сајтови"
msgid "Enter a valid value." msgid "Enter a valid value."
msgstr "Унесите исправну вредност." msgstr "Унесите исправну вредност."
#: core/validators.py:87 forms/fields.py:529 #: core/validators.py:87 forms/fields.py:528
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "Унесите исправан URL." msgstr "Унесите исправан URL."
#: core/validators.py:89 forms/fields.py:530 #: core/validators.py:89 forms/fields.py:529
msgid "This URL appears to be a broken link." msgid "This URL appears to be a broken link."
msgstr "Овај URL изгледа не води никуда." msgstr "Овај URL изгледа не води никуда."
#: core/validators.py:123 forms/fields.py:873 #: core/validators.py:123 forms/fields.py:877
msgid "" msgid ""
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens." "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "" msgstr ""
"Унесите исрпаван „слаг“, који се састоји од слова, бројки, доњих црта или " "Унесите исрпаван „слаг“, који се састоји од слова, бројки, доњих црта или "
"циртица." "циртица."
#: core/validators.py:126 forms/fields.py:866 #: core/validators.py:126 forms/fields.py:870
msgid "Enter a valid IPv4 address." msgid "Enter a valid IPv4 address."
msgstr "Унесите исправну IPv4 адресу." msgstr "Унесите исправну IPv4 адресу."
@ -4499,12 +4512,12 @@ msgstr "Унесите само бројке раздвојене запетам
msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)."
msgstr "Ово поље мора да буде %(limit_value)s (тренутно има %(show_value)s)." msgstr "Ово поље мора да буде %(limit_value)s (тренутно има %(show_value)s)."
#: core/validators.py:153 forms/fields.py:205 forms/fields.py:257 #: core/validators.py:153 forms/fields.py:204 forms/fields.py:256
#, python-format #, python-format
msgid "Ensure this value is less than or equal to %(limit_value)s." msgid "Ensure this value is less than or equal to %(limit_value)s."
msgstr "Ова вредност мора да буде мања од %(limit_value)s. или тачно толико." msgstr "Ова вредност мора да буде мања од %(limit_value)s. или тачно толико."
#: core/validators.py:158 forms/fields.py:206 forms/fields.py:258 #: core/validators.py:158 forms/fields.py:205 forms/fields.py:257
#, python-format #, python-format
msgid "Ensure this value is greater than or equal to %(limit_value)s." msgid "Ensure this value is greater than or equal to %(limit_value)s."
msgstr "Ова вредност мора бити већа од %(limit_value)s или тачно толико." msgstr "Ова вредност мора бити већа од %(limit_value)s или тачно толико."
@ -4512,27 +4525,27 @@ msgstr "Ова вредност мора бити већа од %(limit_value)s
#: core/validators.py:164 #: core/validators.py:164
#, python-format #, python-format
msgid "" msgid ""
"Ensure this value has at least %(limit_value)d characters (it has %" "Ensure this value has at least %(limit_value)d characters (it has "
"(show_value)d)." "%(show_value)d)."
msgstr "" msgstr ""
"Ово поље мора да садржи најмање %(limit_value)d словних места (тренутно има %" "Ово поље мора да садржи најмање %(limit_value)d словних места (тренутно има "
"(show_value)d)." "%(show_value)d)."
#: core/validators.py:170 #: core/validators.py:170
#, python-format #, python-format
msgid "" msgid ""
"Ensure this value has at most %(limit_value)d characters (it has %" "Ensure this value has at most %(limit_value)d characters (it has "
"(show_value)d)." "%(show_value)d)."
msgstr "" msgstr ""
"Ово поље мора да садржи највише %(limit_value)d словних места (тренутно има %" "Ово поље мора да садржи највише %(limit_value)d словних места (тренутно има "
"(show_value)d)." "%(show_value)d)."
#: db/models/base.py:822 #: db/models/base.py:823
#, python-format #, python-format
msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s." msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s."
msgstr "%(field_name)s мора да буде јединствен за %(date_field)s %(lookup)s." msgstr "%(field_name)s мора да буде јединствен за %(date_field)s %(lookup)s."
#: db/models/base.py:837 db/models/base.py:845 #: db/models/base.py:838 db/models/base.py:846
#, python-format #, python-format
msgid "%(model_name)s with this %(field_label)s already exists." msgid "%(model_name)s with this %(field_label)s already exists."
msgstr "%(model_name)s са овом вредношћу %(field_label)s већ постоји." msgstr "%(model_name)s са овом вредношћу %(field_label)s већ постоји."
@ -4555,13 +4568,13 @@ msgstr "Ово поље не може да остане празно."
msgid "Field of type: %(field_type)s" msgid "Field of type: %(field_type)s"
msgstr "Поње типа: %(field_type)s" msgstr "Поње типа: %(field_type)s"
#: db/models/fields/__init__.py:451 db/models/fields/__init__.py:852 #: db/models/fields/__init__.py:451 db/models/fields/__init__.py:860
#: db/models/fields/__init__.py:961 db/models/fields/__init__.py:972 #: db/models/fields/__init__.py:969 db/models/fields/__init__.py:980
#: db/models/fields/__init__.py:999 #: db/models/fields/__init__.py:1007
msgid "Integer" msgid "Integer"
msgstr "Цео број" msgstr "Цео број"
#: db/models/fields/__init__.py:455 db/models/fields/__init__.py:850 #: db/models/fields/__init__.py:455 db/models/fields/__init__.py:858
msgid "This value must be an integer." msgid "This value must be an integer."
msgstr "Ова вредност мора бити целобројна." msgstr "Ова вредност мора бити целобројна."
@ -4573,7 +4586,7 @@ msgstr "Ова вредност мора бити True или False."
msgid "Boolean (Either True or False)" msgid "Boolean (Either True or False)"
msgstr "Булова вредност (True или False)" msgstr "Булова вредност (True или False)"
#: db/models/fields/__init__.py:539 db/models/fields/__init__.py:982 #: db/models/fields/__init__.py:539 db/models/fields/__init__.py:990
#, python-format #, python-format
msgid "String (up to %(max_length)s)" msgid "String (up to %(max_length)s)"
msgstr "Стринг (највише %(max_length)s знакова)" msgstr "Стринг (највише %(max_length)s знакова)"
@ -4615,44 +4628,44 @@ msgstr "Децимални број"
msgid "E-mail address" msgid "E-mail address"
msgstr "Имејл адреса" msgstr "Имејл адреса"
#: db/models/fields/__init__.py:799 db/models/fields/files.py:220 #: db/models/fields/__init__.py:807 db/models/fields/files.py:220
#: db/models/fields/files.py:331 #: db/models/fields/files.py:331
msgid "File path" msgid "File path"
msgstr "Путања фајла" msgstr "Путања фајла"
#: db/models/fields/__init__.py:822 #: db/models/fields/__init__.py:830
msgid "This value must be a float." msgid "This value must be a float."
msgstr "Ова вредност мора бити број са клизећом запетом" msgstr "Ова вредност мора бити број са клизећом запетом"
#: db/models/fields/__init__.py:824 #: db/models/fields/__init__.py:832
msgid "Floating point number" msgid "Floating point number"
msgstr "Број са покреном запетом" msgstr "Број са покреном запетом"
#: db/models/fields/__init__.py:883 #: db/models/fields/__init__.py:891
msgid "Big (8 byte) integer" msgid "Big (8 byte) integer"
msgstr "Велики цео број" msgstr "Велики цео број"
#: db/models/fields/__init__.py:912 #: db/models/fields/__init__.py:920
msgid "This value must be either None, True or False." msgid "This value must be either None, True or False."
msgstr "Ова вредност мора бити или None, или True, или False." msgstr "Ова вредност мора бити или None, или True, или False."
#: db/models/fields/__init__.py:914 #: db/models/fields/__init__.py:922
msgid "Boolean (Either True, False or None)" msgid "Boolean (Either True, False or None)"
msgstr "Булова вредност (True, False или None)" msgstr "Булова вредност (True, False или None)"
#: db/models/fields/__init__.py:1005 #: db/models/fields/__init__.py:1013
msgid "Text" msgid "Text"
msgstr "Текст" msgstr "Текст"
#: db/models/fields/__init__.py:1021 #: db/models/fields/__init__.py:1029
msgid "Time" msgid "Time"
msgstr "Време" msgstr "Време"
#: db/models/fields/__init__.py:1025 #: db/models/fields/__init__.py:1033
msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format." msgid "Enter a valid time in HH:MM[:ss[.uuuuuu]] format."
msgstr "Унесите исправно време у формату ЧЧ:ММ[:сс[.уууууу]]." msgstr "Унесите исправно време у формату ЧЧ:ММ[:сс[.уууууу]]."
#: db/models/fields/__init__.py:1109 #: db/models/fields/__init__.py:1125
msgid "XML text" msgid "XML text"
msgstr "XML текст" msgstr "XML текст"
@ -4665,22 +4678,22 @@ msgstr "Објекат класе %(model)s са примарним кључем
msgid "Foreign Key (type determined by related field)" msgid "Foreign Key (type determined by related field)"
msgstr "Страни кључ (тип одређује референтно поље)" msgstr "Страни кључ (тип одређује референтно поље)"
#: db/models/fields/related.py:918 #: db/models/fields/related.py:919
msgid "One-to-one relationship" msgid "One-to-one relationship"
msgstr "Релација један на један" msgstr "Релација један на један"
#: db/models/fields/related.py:980 #: db/models/fields/related.py:981
msgid "Many-to-many relationship" msgid "Many-to-many relationship"
msgstr "Релација више на више" msgstr "Релација више на више"
#: db/models/fields/related.py:1000 #: db/models/fields/related.py:1001
msgid "" msgid ""
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one." "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "" msgstr ""
"Држите „Control“, или „Command“ на Mac-у да бисте обележили више од једне " "Држите „Control“, или „Command“ на Mac-у да бисте обележили више од једне "
"ставке." "ставке."
#: db/models/fields/related.py:1061 #: db/models/fields/related.py:1062
#, python-format #, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid." msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
msgid_plural "" msgid_plural ""
@ -4693,62 +4706,62 @@ msgstr[2] "Унесите исправан %(self)s IDs. Вредности %(va
msgid "This field is required." msgid "This field is required."
msgstr "Ово поље се мора попунити." msgstr "Ово поље се мора попунити."
#: forms/fields.py:204 #: forms/fields.py:203
msgid "Enter a whole number." msgid "Enter a whole number."
msgstr "Унесите цео број." msgstr "Унесите цео број."
#: forms/fields.py:235 forms/fields.py:256 #: forms/fields.py:234 forms/fields.py:255
msgid "Enter a number." msgid "Enter a number."
msgstr "Унесите број." msgstr "Унесите број."
#: forms/fields.py:259 #: forms/fields.py:258
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits in total." msgid "Ensure that there are no more than %s digits in total."
msgstr "Не сме бити укупно више од %s цифара. Проверите." msgstr "Не сме бити укупно више од %s цифара. Проверите."
#: forms/fields.py:260 #: forms/fields.py:259
#, python-format #, python-format
msgid "Ensure that there are no more than %s decimal places." msgid "Ensure that there are no more than %s decimal places."
msgstr "Не сме бити укупно више од %s децималних места. Проверите." msgstr "Не сме бити укупно више од %s децималних места. Проверите."
#: forms/fields.py:261 #: forms/fields.py:260
#, python-format #, python-format
msgid "Ensure that there are no more than %s digits before the decimal point." msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr "Не сме бити укупно више од %s цифара пре запете. Проверите." msgstr "Не сме бити укупно више од %s цифара пре запете. Проверите."
#: forms/fields.py:323 forms/fields.py:838 #: forms/fields.py:322 forms/fields.py:837
msgid "Enter a valid date." msgid "Enter a valid date."
msgstr "Унесите исправан датум." msgstr "Унесите исправан датум."
#: forms/fields.py:351 forms/fields.py:839 #: forms/fields.py:350 forms/fields.py:838
msgid "Enter a valid time." msgid "Enter a valid time."
msgstr "Унесите исправно време" msgstr "Унесите исправно време"
#: forms/fields.py:377 #: forms/fields.py:376
msgid "Enter a valid date/time." msgid "Enter a valid date/time."
msgstr "Унесите исправан датум/време." msgstr "Унесите исправан датум/време."
#: forms/fields.py:435 #: forms/fields.py:434
msgid "No file was submitted. Check the encoding type on the form." msgid "No file was submitted. Check the encoding type on the form."
msgstr "Фајл није пребачен. Проверите тип енкодирања формулара." msgstr "Фајл није пребачен. Проверите тип енкодирања формулара."
#: forms/fields.py:436 #: forms/fields.py:435
msgid "No file was submitted." msgid "No file was submitted."
msgstr "Фајл није пребачен." msgstr "Фајл није пребачен."
#: forms/fields.py:437 #: forms/fields.py:436
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "Пребачен фајл је празан." msgstr "Пребачен фајл је празан."
#: forms/fields.py:438 #: forms/fields.py:437
#, python-format #, python-format
msgid "" msgid ""
"Ensure this filename has at most %(max)d characters (it has %(length)d)." "Ensure this filename has at most %(max)d characters (it has %(length)d)."
msgstr "" msgstr ""
"Назив фајла мора да садржи бар %(max)d словних места (тренутно има %(length)" "Назив фајла мора да садржи бар %(max)d словних места (тренутно има "
"d)." "%(length)d)."
#: forms/fields.py:473 #: forms/fields.py:472
msgid "" msgid ""
"Upload a valid image. The file you uploaded was either not an image or a " "Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image." "corrupted image."
@ -4756,17 +4769,17 @@ msgstr ""
"Пребаците исправан фајл. Фајл који је пребачен или није слика, или је " "Пребаците исправан фајл. Фајл који је пребачен или није слика, или је "
"оштећен." "оштећен."
#: forms/fields.py:596 forms/fields.py:671 #: forms/fields.py:595 forms/fields.py:670
#, python-format #, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices." msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "" msgstr ""
"%(value)s није међу понуђеним вредностима. Одаберите једну од понуђених." "%(value)s није међу понуђеним вредностима. Одаберите једну од понуђених."
#: forms/fields.py:672 forms/fields.py:734 forms/models.py:1002 #: forms/fields.py:671 forms/fields.py:733 forms/models.py:1002
msgid "Enter a list of values." msgid "Enter a list of values."
msgstr "Унесите листу вредности." msgstr "Унесите листу вредности."
#: forms/formsets.py:298 forms/formsets.py:300 #: forms/formsets.py:296 forms/formsets.py:298
msgid "Order" msgid "Order"
msgstr "Редослед" msgstr "Редослед"
@ -5103,23 +5116,23 @@ msgstr "%(number)d %(type)s"
msgid ", %(number)d %(type)s" msgid ", %(number)d %(type)s"
msgstr ", %(number)d %(type)s" msgstr ", %(number)d %(type)s"
#: utils/translation/trans_real.py:518 #: utils/translation/trans_real.py:519
msgid "DATE_FORMAT" msgid "DATE_FORMAT"
msgstr "j. F Y." msgstr "j. F Y."
#: utils/translation/trans_real.py:519 #: utils/translation/trans_real.py:520
msgid "DATETIME_FORMAT" msgid "DATETIME_FORMAT"
msgstr "j. F Y. H:i Т" msgstr "j. F Y. H:i Т"
#: utils/translation/trans_real.py:520 #: utils/translation/trans_real.py:521
msgid "TIME_FORMAT" msgid "TIME_FORMAT"
msgstr "G:i" msgstr "G:i"
#: utils/translation/trans_real.py:541 #: utils/translation/trans_real.py:542
msgid "YEAR_MONTH_FORMAT" msgid "YEAR_MONTH_FORMAT"
msgstr "F Y." msgstr "F Y."
#: utils/translation/trans_real.py:542 #: utils/translation/trans_real.py:543
msgid "MONTH_DAY_FORMAT" msgid "MONTH_DAY_FORMAT"
msgstr "j. F" msgstr "j. F"

View File

@ -4,50 +4,24 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-05-07 20:46+0200\n" "POT-Creation-Date: 2010-08-06 19:53+0200\n"
"PO-Revision-Date: 2009-03-30 14:04+0200\n" "PO-Revision-Date: 2009-03-30 14:04+0200\n"
"Last-Translator: Janos Guljas <janos@janos.in.rs>\n" "Last-Translator: Janos Guljas <janos@janos.in.rs>\n"
"Language-Team: Branko Vukelic <bg.branko@gmail.com> & Janos Guljas " "Language-Team: Branko Vukelic <bg.branko@gmail.com> & Janos Guljas "
"<janos@janos.in.rs> & Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail." "<janos@janos.in.rs> & Nesh <djnesh@gmail.com> & Petar <petar.maric@gmail."
"com>\n" "com>\n"
"Language: \n"
"MIME-Version: 1.0\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" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: contrib/admin/media/js/SelectFilter2.js:37
#, perl-format
msgid "Available %s"
msgstr "Доступни %s"
#: contrib/admin/media/js/SelectFilter2.js:45
msgid "Choose all"
msgstr "Додај све"
#: contrib/admin/media/js/SelectFilter2.js:50
msgid "Add"
msgstr "Додај"
#: contrib/admin/media/js/SelectFilter2.js:52
msgid "Remove"
msgstr "Уклони"
#: contrib/admin/media/js/SelectFilter2.js:57
#, perl-format
msgid "Chosen %s"
msgstr "Одабрани %s"
#: contrib/admin/media/js/SelectFilter2.js:58
msgid "Select your choice(s) and click "
msgstr "Направите избор и кликните "
#: contrib/admin/media/js/SelectFilter2.js:63 #: contrib/admin/media/js/SelectFilter2.js:63
msgid "Clear all" msgid "Clear all"
msgstr "Врати све" msgstr "Врати све"
#: contrib/admin/media/js/actions.js:18 #: contrib/admin/media/js/actions.js:18
#: contrib/admin/media/js/actions.min.js:1
msgid "%(sel)s of %(cnt)s selected" msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected" msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s од %(cnt)s изабран" msgstr[0] "%(sel)s од %(cnt)s изабран"
@ -55,7 +29,6 @@ msgstr[1] "%(sel)s од %(cnt)s изабрано"
msgstr[2] "%(sel)s од %(cnt)s изабраних" msgstr[2] "%(sel)s од %(cnt)s изабраних"
#: contrib/admin/media/js/actions.js:109 #: contrib/admin/media/js/actions.js:109
#: contrib/admin/media/js/actions.min.js:5
msgid "" msgid ""
"You have unsaved changes on individual editable fields. If you run an " "You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost." "action, your unsaved changes will be lost."
@ -151,3 +124,21 @@ msgstr "Јуче"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:184 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:184
msgid "Tomorrow" msgid "Tomorrow"
msgstr "Сутра" msgstr "Сутра"
#~ msgid "Available %s"
#~ msgstr "Доступни %s"
#~ msgid "Choose all"
#~ msgstr "Додај све"
#~ msgid "Add"
#~ msgstr "Додај"
#~ msgid "Remove"
#~ msgstr "Уклони"
#~ msgid "Chosen %s"
#~ msgstr "Одабрани %s"
#~ msgid "Select your choice(s) and click "
#~ msgstr "Направите избор и кликните "

View File

@ -11,9 +11,9 @@ SHORT_DATE_FORMAT = 'j.m.Y.'
SHORT_DATETIME_FORMAT = 'j.m.Y. H:i' SHORT_DATETIME_FORMAT = 'j.m.Y. H:i'
FIRST_DAY_OF_WEEK = 1 FIRST_DAY_OF_WEEK = 1
DATE_INPUT_FORMATS = ( DATE_INPUT_FORMATS = (
'%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.'
'%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.'
'%Y-%m-%d', # '2006-10-25' '%Y-%m-%d', # '2006-10-25'
'%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.'
'%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.'
# '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.' # '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.'
# '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.' # '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.'
# '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.' # '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.'
@ -23,22 +23,22 @@ TIME_INPUT_FORMATS = (
'%H:%M', # '14:30' '%H:%M', # '14:30'
) )
DATETIME_INPUT_FORMATS = ( DATETIME_INPUT_FORMATS = (
'%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59'
'%d.%m.%Y. %H:%M', # '25.10.2006. 14:30'
'%d.%m.%Y.', # '25.10.2006.'
'%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59'
'%d.%m.%y. %H:%M', # '25.10.06. 14:30'
'%d.%m.%y.', # '25.10.06.'
'%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59'
'%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30'
'%d. %m. %Y.', # '25. 10. 2006.'
'%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59'
'%d. %m. %y. %H:%M', # '25. 10. 06. 14:30'
'%d. %m. %y.', # '25. 10. 06.'
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' '%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 %H:%M', # '2006-10-25 14:30'
'%Y-%m-%d', # '2006-10-25' '%Y-%m-%d', # '2006-10-25'
'%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59'
'%d.%m.%Y. %H:%M', # '25.10.2006. 14:30'
'%d.%m.%Y.', # '25.10.2006.'
'%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59'
'%d.%m.%y. %H:%M', # '25.10.06. 14:30'
'%d.%m.%y.', # '25.10.06.'
'%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59'
'%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30'
'%d. %m. %Y.', # '25. 10. 2006.'
'%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59'
'%d. %m. %y. %H:%M', # '25. 10. 06. 14:30'
'%d. %m. %y.', # '25. 10. 06.'
) )
DECIMAL_SEPARATOR = '.' DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = ',' THOUSAND_SEPARATOR = '.'
NUMBER_GROUPING = 3 NUMBER_GROUPING = 3

File diff suppressed because it is too large Load Diff

View File

@ -11,9 +11,9 @@ SHORT_DATE_FORMAT = 'j.m.Y.'
SHORT_DATETIME_FORMAT = 'j.m.Y. H:i' SHORT_DATETIME_FORMAT = 'j.m.Y. H:i'
FIRST_DAY_OF_WEEK = 1 FIRST_DAY_OF_WEEK = 1
DATE_INPUT_FORMATS = ( DATE_INPUT_FORMATS = (
'%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.'
'%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.'
'%Y-%m-%d', # '2006-10-25' '%Y-%m-%d', # '2006-10-25'
'%d.%m.%Y.', '%d.%m.%y.', # '25.10.2006.', '25.10.06.'
'%d. %m. %Y.', '%d. %m. %y.', # '25. 10. 2006.', '25. 10. 06.'
# '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.' # '%d. %b %y.', '%d. %B %y.', # '25. Oct 06.', '25. October 06.'
# '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.' # '%d. %b \'%y.', '%d. %B \'%y.', # '25. Oct '06.', '25. October '06.'
# '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.' # '%d. %b %Y.', '%d. %B %Y.', # '25. Oct 2006.', '25. October 2006.'
@ -23,22 +23,22 @@ TIME_INPUT_FORMATS = (
'%H:%M', # '14:30' '%H:%M', # '14:30'
) )
DATETIME_INPUT_FORMATS = ( DATETIME_INPUT_FORMATS = (
'%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59'
'%d.%m.%Y. %H:%M', # '25.10.2006. 14:30'
'%d.%m.%Y.', # '25.10.2006.'
'%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59'
'%d.%m.%y. %H:%M', # '25.10.06. 14:30'
'%d.%m.%y.', # '25.10.06.'
'%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59'
'%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30'
'%d. %m. %Y.', # '25. 10. 2006.'
'%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59'
'%d. %m. %y. %H:%M', # '25. 10. 06. 14:30'
'%d. %m. %y.', # '25. 10. 06.'
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' '%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 %H:%M', # '2006-10-25 14:30'
'%Y-%m-%d', # '2006-10-25' '%Y-%m-%d', # '2006-10-25'
'%d.%m.%Y. %H:%M:%S', # '25.10.2006. 14:30:59'
'%d.%m.%Y. %H:%M', # '25.10.2006. 14:30'
'%d.%m.%Y.', # '25.10.2006.'
'%d.%m.%y. %H:%M:%S', # '25.10.06. 14:30:59'
'%d.%m.%y. %H:%M', # '25.10.06. 14:30'
'%d.%m.%y.', # '25.10.06.'
'%d. %m. %Y. %H:%M:%S', # '25. 10. 2006. 14:30:59'
'%d. %m. %Y. %H:%M', # '25. 10. 2006. 14:30'
'%d. %m. %Y.', # '25. 10. 2006.'
'%d. %m. %y. %H:%M:%S', # '25. 10. 06. 14:30:59'
'%d. %m. %y. %H:%M', # '25. 10. 06. 14:30'
'%d. %m. %y.', # '25. 10. 06.'
) )
DECIMAL_SEPARATOR = '.' DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = ',' THOUSAND_SEPARATOR = '.'
NUMBER_GROUPING = 3 NUMBER_GROUPING = 3

View File

@ -501,7 +501,7 @@ class ModelAdmin(BaseModelAdmin):
# Convert the actions into a SortedDict keyed by name # Convert the actions into a SortedDict keyed by name
# and sorted by description. # and sorted by description.
actions.sort(lambda a,b: cmp(a[2].lower(), b[2].lower())) actions.sort(key=lambda k: k[2].lower())
actions = SortedDict([ actions = SortedDict([
(name, (func, name, desc)) (name, (func, name, desc))
for func, name, desc in actions for func, name, desc in actions

View File

@ -379,11 +379,11 @@ class AdminSite(object):
# Sort the apps alphabetically. # Sort the apps alphabetically.
app_list = app_dict.values() app_list = app_dict.values()
app_list.sort(lambda x, y: cmp(x['name'], y['name'])) app_list.sort(key=lambda x: x['name'])
# Sort the models alphabetically within each app. # Sort the models alphabetically within each app.
for app in app_list: for app in app_list:
app['models'].sort(lambda x, y: cmp(x['name'], y['name'])) app['models'].sort(key=lambda x: x['name'])
context = { context = {
'title': _('Site administration'), 'title': _('Site administration'),
@ -443,7 +443,7 @@ class AdminSite(object):
if not app_dict: if not app_dict:
raise http.Http404('The requested admin page does not exist.') raise http.Http404('The requested admin page does not exist.')
# Sort the models alphabetically within each app. # Sort the models alphabetically within each app.
app_dict['models'].sort(lambda x, y: cmp(x['name'], y['name'])) app_dict['models'].sort(key=lambda x: x['name'])
context = { context = {
'title': _('%s administration') % capfirst(app_label), 'title': _('%s administration') % capfirst(app_label),
'app_list': [app_dict], 'app_list': [app_dict],

View File

@ -2,8 +2,11 @@
{% load i18n %} {% load i18n %}
{% block form_top %} {% block form_top %}
{% if not is_popup %}
<p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p> <p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p>
<input type="hidden" name="_continue" value="1" /> {% else %}
<p>{% trans "Enter a username and password." %}</p>
{% endif %}
{% endblock %} {% endblock %}
{% block after_field_sets %} {% block after_field_sets %}

View File

@ -60,7 +60,7 @@ class CalendarPlugin(DatabrowsePlugin):
def homepage_view(self, request): def homepage_view(self, request):
easy_model = EasyModel(self.site, self.model) easy_model = EasyModel(self.site, self.model)
field_list = self.fields.values() field_list = self.fields.values()
field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name)) field_list.sort(key=lambda k:k.verbose_name)
return render_to_response('databrowse/calendar_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list}) return render_to_response('databrowse/calendar_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
def calendar_view(self, request, field, year=None, month=None, day=None): def calendar_view(self, request, field, year=None, month=None, day=None):

View File

@ -61,7 +61,7 @@ class FieldChoicePlugin(DatabrowsePlugin):
def homepage_view(self, request): def homepage_view(self, request):
easy_model = EasyModel(self.site, self.model) easy_model = EasyModel(self.site, self.model)
field_list = self.fields.values() field_list = self.fields.values()
field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name)) field_list.sort(key=lambda k: k.verbose_name)
return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list}) return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
def field_view(self, request, field, value=None): def field_view(self, request, field, value=None):

View File

@ -58,7 +58,7 @@ class SessionStore(SessionBase):
finally: finally:
session_file.close() session_file.close()
except IOError: except IOError:
pass self.create()
return session_data return session_data
def create(self): def create(self):

View File

@ -1,388 +1,273 @@
r""" from datetime import datetime, timedelta
from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
from django.contrib.sessions.backends.cache import SessionStore as CacheSession
from django.contrib.sessions.backends.cached_db import SessionStore as CacheDBSession
from django.contrib.sessions.backends.file import SessionStore as FileSession
from django.contrib.sessions.backends.base import SessionBase
from django.contrib.sessions.models import Session
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
import shutil
import tempfile
import unittest
>>> from django.conf import settings
>>> from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
>>> from django.contrib.sessions.backends.cache import SessionStore as CacheSession
>>> from django.contrib.sessions.backends.cached_db import SessionStore as CacheDBSession
>>> from django.contrib.sessions.backends.file import SessionStore as FileSession
>>> from django.contrib.sessions.backends.base import SessionBase
>>> from django.contrib.sessions.models import Session
>>> db_session = DatabaseSession() class SessionTestsMixin(object):
>>> db_session.modified # This does not inherit from TestCase to avoid any tests being run with this
False # class, which wouldn't work, and to allow different TestCase subclasses to
>>> db_session.get('cat') # be used.
>>> db_session['cat'] = "dog"
>>> db_session.modified
True
>>> db_session.pop('cat')
'dog'
>>> db_session.pop('some key', 'does not exist')
'does not exist'
>>> db_session.save()
>>> db_session.exists(db_session.session_key)
True
>>> db_session.delete(db_session.session_key)
>>> db_session.exists(db_session.session_key)
False
>>> db_session['foo'] = 'bar' backend = None # subclasses must specify
>>> db_session.save()
>>> db_session.exists(db_session.session_key)
True
>>> prev_key = db_session.session_key
>>> db_session.flush()
>>> db_session.exists(prev_key)
False
>>> db_session.session_key == prev_key
False
>>> db_session.modified, db_session.accessed
(True, True)
>>> db_session['a'], db_session['b'] = 'c', 'd'
>>> db_session.save()
>>> prev_key = db_session.session_key
>>> prev_data = db_session.items()
>>> db_session.cycle_key()
>>> db_session.session_key == prev_key
False
>>> db_session.items() == prev_data
True
def setUp(self):
self.session = self.backend()
def tearDown(self):
# NB: be careful to delete any sessions created; stale sessions fill up
# the /tmp (with some backends) and eventually overwhelm it after lots
# of runs (think buildbots)
self.session.delete()
def test_new_session(self):
self.assertFalse(self.session.modified)
self.assertFalse(self.session.accessed)
def test_get_empty(self):
self.assertEqual(self.session.get('cat'), None)
def test_store(self):
self.session['cat'] = "dog"
self.assertTrue(self.session.modified)
self.assertEqual(self.session.pop('cat'), 'dog')
def test_pop(self):
self.session['some key'] = 'exists'
# Need to reset these to pretend we haven't accessed it:
self.accessed = False
self.modified = False
self.assertEqual(self.session.pop('some key'), 'exists')
self.assertTrue(self.session.accessed)
self.assertTrue(self.session.modified)
self.assertEqual(self.session.get('some key'), None)
def test_pop_default(self):
self.assertEqual(self.session.pop('some key', 'does not exist'),
'does not exist')
self.assertTrue(self.session.accessed)
self.assertFalse(self.session.modified)
def test_setdefault(self):
self.assertEqual(self.session.setdefault('foo', 'bar'), 'bar')
self.assertEqual(self.session.setdefault('foo', 'baz'), 'bar')
self.assertTrue(self.session.accessed)
self.assertTrue(self.session.modified)
def test_update(self):
self.session.update({'update key': 1})
self.assertTrue(self.session.accessed)
self.assertTrue(self.session.modified)
self.assertEqual(self.session.get('update key', None), 1)
def test_has_key(self):
self.session['some key'] = 1
self.session.modified = False
self.session.accessed = False
self.assertTrue(self.session.has_key('some key'))
self.assertTrue(self.session.accessed)
self.assertFalse(self.session.modified)
def test_values(self):
self.assertEqual(self.session.values(), [])
self.assertTrue(self.session.accessed)
self.session['some key'] = 1
self.assertEqual(self.session.values(), [1])
def test_iterkeys(self):
self.session['x'] = 1
self.session.modified = False
self.session.accessed = False
i = self.session.iterkeys()
self.assertTrue(hasattr(i, '__iter__'))
self.assertTrue(self.session.accessed)
self.assertFalse(self.session.modified)
self.assertEqual(list(i), ['x'])
def test_iterkeys(self):
self.session['x'] = 1
self.session.modified = False
self.session.accessed = False
i = self.session.itervalues()
self.assertTrue(hasattr(i, '__iter__'))
self.assertTrue(self.session.accessed)
self.assertFalse(self.session.modified)
self.assertEqual(list(i), [1])
def test_iteritems(self):
self.session['x'] = 1
self.session.modified = False
self.session.accessed = False
i = self.session.iteritems()
self.assertTrue(hasattr(i, '__iter__'))
self.assertTrue(self.session.accessed)
self.assertFalse(self.session.modified)
self.assertEqual(list(i), [('x',1)])
def test_clear(self):
self.session['x'] = 1
self.session.modified = False
self.session.accessed = False
self.assertEqual(self.session.items(), [('x',1)])
self.session.clear()
self.assertEqual(self.session.items(), [])
self.assertTrue(self.session.accessed)
self.assertTrue(self.session.modified)
def test_save(self):
self.session.save()
self.assertTrue(self.session.exists(self.session.session_key))
def test_delete(self):
self.session.delete(self.session.session_key)
self.assertFalse(self.session.exists(self.session.session_key))
def test_flush(self):
self.session['foo'] = 'bar'
self.session.save()
prev_key = self.session.session_key
self.session.flush()
self.assertFalse(self.session.exists(prev_key))
self.assertNotEqual(self.session.session_key, prev_key)
self.assertTrue(self.session.modified)
self.assertTrue(self.session.accessed)
def test_cycle(self):
self.session['a'], self.session['b'] = 'c', 'd'
self.session.save()
prev_key = self.session.session_key
prev_data = self.session.items()
self.session.cycle_key()
self.assertNotEqual(self.session.session_key, prev_key)
self.assertEqual(self.session.items(), prev_data)
def test_invalid_key(self):
# Submitting an invalid session key (either by guessing, or if the db has # Submitting an invalid session key (either by guessing, or if the db has
# removed the key) results in a new key being generated. # removed the key) results in a new key being generated.
>>> Session.objects.filter(pk=db_session.session_key).delete() session = self.backend('1')
>>> db_session = DatabaseSession(db_session.session_key) session.save()
>>> db_session.save() self.assertNotEqual(session.session_key, '1')
>>> DatabaseSession('1').get('cat') self.assertEqual(session.get('cat'), None)
session.delete()
#
# Cached DB session tests
#
>>> cdb_session = CacheDBSession()
>>> cdb_session.modified
False
>>> cdb_session['cat'] = "dog"
>>> cdb_session.modified
True
>>> cdb_session.pop('cat')
'dog'
>>> cdb_session.pop('some key', 'does not exist')
'does not exist'
>>> cdb_session.save()
>>> cdb_session.exists(cdb_session.session_key)
True
>>> cdb_session.delete(cdb_session.session_key)
>>> cdb_session.exists(cdb_session.session_key)
False
#
# File session tests.
#
# Do file session tests in an isolated directory, and kill it after we're done.
>>> original_session_file_path = settings.SESSION_FILE_PATH
>>> import tempfile
>>> temp_session_store = settings.SESSION_FILE_PATH = tempfile.mkdtemp()
>>> file_session = FileSession()
>>> file_session.modified
False
>>> file_session['cat'] = "dog"
>>> file_session.modified
True
>>> file_session.pop('cat')
'dog'
>>> file_session.pop('some key', 'does not exist')
'does not exist'
>>> file_session.save()
>>> file_session.exists(file_session.session_key)
True
>>> file_session.delete(file_session.session_key)
>>> file_session.exists(file_session.session_key)
False
>>> FileSession('1').get('cat')
>>> file_session['foo'] = 'bar'
>>> file_session.save()
>>> file_session.exists(file_session.session_key)
True
>>> prev_key = file_session.session_key
>>> file_session.flush()
>>> file_session.exists(prev_key)
False
>>> file_session.session_key == prev_key
False
>>> file_session.modified, file_session.accessed
(True, True)
>>> file_session['a'], file_session['b'] = 'c', 'd'
>>> file_session.save()
>>> prev_key = file_session.session_key
>>> prev_data = file_session.items()
>>> file_session.cycle_key()
>>> file_session.session_key == prev_key
False
>>> file_session.items() == prev_data
True
>>> Session.objects.filter(pk=file_session.session_key).delete()
>>> file_session = FileSession(file_session.session_key)
>>> file_session.save()
# Make sure the file backend checks for a good storage dir
>>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer"
>>> FileSession()
Traceback (innermost last):
...
ImproperlyConfigured: The session storage path '/if/this/directory/exists/you/have/a/weird/computer' doesn't exist. Please set your SESSION_FILE_PATH setting to an existing directory in which Django can store session data.
# Clean up after the file tests
>>> settings.SESSION_FILE_PATH = original_session_file_path
>>> import shutil
>>> shutil.rmtree(temp_session_store)
#
# Cache-based tests
# NB: be careful to delete any sessions created; stale sessions fill up the
# /tmp and eventually overwhelm it after lots of runs (think buildbots)
#
>>> cache_session = CacheSession()
>>> cache_session.modified
False
>>> cache_session['cat'] = "dog"
>>> cache_session.modified
True
>>> cache_session.pop('cat')
'dog'
>>> cache_session.pop('some key', 'does not exist')
'does not exist'
>>> cache_session.save()
>>> cache_session.delete(cache_session.session_key)
>>> cache_session.exists(cache_session.session_key)
False
>>> cache_session['foo'] = 'bar'
>>> cache_session.save()
>>> cache_session.exists(cache_session.session_key)
True
>>> prev_key = cache_session.session_key
>>> cache_session.flush()
>>> cache_session.exists(prev_key)
False
>>> cache_session.session_key == prev_key
False
>>> cache_session.modified, cache_session.accessed
(True, True)
>>> cache_session['a'], cache_session['b'] = 'c', 'd'
>>> cache_session.save()
>>> prev_key = cache_session.session_key
>>> prev_data = cache_session.items()
>>> cache_session.cycle_key()
>>> cache_session.session_key == prev_key
False
>>> cache_session.items() == prev_data
True
>>> cache_session = CacheSession()
>>> cache_session.save()
>>> key = cache_session.session_key
>>> cache_session.exists(key)
True
>>> Session.objects.filter(pk=cache_session.session_key).delete()
>>> cache_session = CacheSession(cache_session.session_key)
>>> cache_session.save()
>>> cache_session.delete(cache_session.session_key)
>>> s = SessionBase()
>>> s._session['some key'] = 'exists' # Pre-populate the session with some data
>>> s.accessed = False # Reset to pretend this wasn't accessed previously
>>> s.accessed, s.modified
(False, False)
>>> s.pop('non existant key', 'does not exist')
'does not exist'
>>> s.accessed, s.modified
(True, False)
>>> s.setdefault('foo', 'bar')
'bar'
>>> s.setdefault('foo', 'baz')
'bar'
>>> s.accessed = False # Reset the accessed flag
>>> s.pop('some key')
'exists'
>>> s.accessed, s.modified
(True, True)
>>> s.pop('some key', 'does not exist')
'does not exist'
>>> s.get('update key', None)
# test .update()
>>> s.modified = s.accessed = False # Reset to pretend this wasn't accessed previously
>>> s.update({'update key':1})
>>> s.accessed, s.modified
(True, True)
>>> s.get('update key', None)
1
# test .has_key()
>>> s.modified = s.accessed = False # Reset to pretend this wasn't accessed previously
>>> s.has_key('update key')
True
>>> s.accessed, s.modified
(True, False)
# test .values()
>>> s = SessionBase()
>>> s.values()
[]
>>> s.accessed
True
>>> s['x'] = 1
>>> s.values()
[1]
# test .iterkeys()
>>> s.accessed = False
>>> i = s.iterkeys()
>>> hasattr(i,'__iter__')
True
>>> s.accessed
True
>>> list(i)
['x']
# test .itervalues()
>>> s.accessed = False
>>> i = s.itervalues()
>>> hasattr(i,'__iter__')
True
>>> s.accessed
True
>>> list(i)
[1]
# test .iteritems()
>>> s.accessed = False
>>> i = s.iteritems()
>>> hasattr(i,'__iter__')
True
>>> s.accessed
True
>>> list(i)
[('x', 1)]
# test .clear()
>>> s.modified = s.accessed = False
>>> s.items()
[('x', 1)]
>>> s.clear()
>>> s.items()
[]
>>> s.accessed, s.modified
(True, True)
#########################
# Custom session expiry #
#########################
>>> from django.conf import settings
>>> from datetime import datetime, timedelta
>>> td10 = timedelta(seconds=10)
# Custom session expiry
def test_default_expiry(self):
# A normal session has a max age equal to settings # A normal session has a max age equal to settings
>>> s.get_expiry_age() == settings.SESSION_COOKIE_AGE self.assertEqual(self.session.get_expiry_age(), settings.SESSION_COOKIE_AGE)
True
# So does a custom session with an idle expiration time of 0 (but it'll expire # So does a custom session with an idle expiration time of 0 (but it'll
# at browser close) # expire at browser close)
>>> s.set_expiry(0) self.session.set_expiry(0)
>>> s.get_expiry_age() == settings.SESSION_COOKIE_AGE self.assertEqual(self.session.get_expiry_age(), settings.SESSION_COOKIE_AGE)
True
# Custom session idle expiration time def test_custom_expiry_seconds(self):
>>> s.set_expiry(10) # Using seconds
>>> delta = s.get_expiry_date() - datetime.now() self.session.set_expiry(10)
>>> delta.seconds in (9, 10) delta = self.session.get_expiry_date() - datetime.now()
True self.assertTrue(delta.seconds in (9, 10))
>>> age = s.get_expiry_age()
>>> age in (9, 10)
True
# Custom session fixed expiry date (timedelta) age = self.session.get_expiry_age()
>>> s.set_expiry(td10) self.assertTrue(age in (9, 10))
>>> delta = s.get_expiry_date() - datetime.now()
>>> delta.seconds in (9, 10)
True
>>> age = s.get_expiry_age()
>>> age in (9, 10)
True
# Custom session fixed expiry date (fixed datetime) def test_custom_expiry_timedelta(self):
>>> s.set_expiry(datetime.now() + td10) # Using timedelta
>>> delta = s.get_expiry_date() - datetime.now() self.session.set_expiry(timedelta(seconds=10))
>>> delta.seconds in (9, 10) delta = self.session.get_expiry_date() - datetime.now()
True self.assertTrue(delta.seconds in (9, 10))
>>> age = s.get_expiry_age()
>>> age in (9, 10)
True
# Set back to default session age age = self.session.get_expiry_age()
>>> s.set_expiry(None) self.assertTrue(age in (9, 10))
>>> s.get_expiry_age() == settings.SESSION_COOKIE_AGE
True
# Allow to set back to default session age even if no alternate has been set def test_custom_expiry_timedelta(self):
>>> s.set_expiry(None) # Using timedelta
self.session.set_expiry(datetime.now() + timedelta(seconds=10))
delta = self.session.get_expiry_date() - datetime.now()
self.assertTrue(delta.seconds in (9, 10))
age = self.session.get_expiry_age()
self.assertTrue(age in (9, 10))
def test_custom_expiry_reset(self):
self.session.set_expiry(None)
self.session.set_expiry(10)
self.session.set_expiry(None)
self.assertEqual(self.session.get_expiry_age(), settings.SESSION_COOKIE_AGE)
def test_get_expire_at_browser_close(self):
# Tests get_expire_at_browser_close with different settings and different
# set_expiry calls
try:
original_expire_at_browser_close = settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = False
self.session.set_expiry(10)
self.assertFalse(self.session.get_expire_at_browser_close())
self.session.set_expiry(0)
self.assertTrue(self.session.get_expire_at_browser_close())
self.session.set_expiry(None)
self.assertFalse(self.session.get_expire_at_browser_close())
settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = True
self.session.set_expiry(10)
self.assertFalse(self.session.get_expire_at_browser_close())
self.session.set_expiry(0)
self.assertTrue(self.session.get_expire_at_browser_close())
self.session.set_expiry(None)
self.assertTrue(self.session.get_expire_at_browser_close())
except:
raise
finally:
settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = original_expire_at_browser_close
# We're changing the setting then reverting back to the original setting at the class DatabaseSessionTests(SessionTestsMixin, TestCase):
# end of these tests.
>>> original_expire_at_browser_close = settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# Custom session age backend = DatabaseSession
>>> s.set_expiry(10)
>>> s.get_expire_at_browser_close()
False
# Custom expire-at-browser-close
>>> s.set_expiry(0)
>>> s.get_expire_at_browser_close()
True
# Default session age class CacheDBSessionTests(SessionTestsMixin, TestCase):
>>> s.set_expiry(None)
>>> s.get_expire_at_browser_close()
False
>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = True backend = CacheDBSession
# Custom session age # Don't need DB flushing for these tests, so can use unittest.TestCase as base class
>>> s.set_expiry(10) class FileSessionTests(SessionTestsMixin, unittest.TestCase):
>>> s.get_expire_at_browser_close()
False
# Custom expire-at-browser-close backend = FileSession
>>> s.set_expiry(0)
>>> s.get_expire_at_browser_close()
True
# Default session age def setUp(self):
>>> s.set_expiry(None) super(FileSessionTests, self).setUp()
>>> s.get_expire_at_browser_close() # Do file session tests in an isolated directory, and kill it after we're done.
True self.original_session_file_path = settings.SESSION_FILE_PATH
self.temp_session_store = settings.SESSION_FILE_PATH = tempfile.mkdtemp()
>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = original_expire_at_browser_close def tearDown(self):
""" settings.SESSION_FILE_PATH = self.original_session_file_path
shutil.rmtree(self.temp_session_store)
super(FileSessionTests, self).tearDown()
if __name__ == '__main__': def test_configuration_check(self):
import doctest # Make sure the file backend checks for a good storage dir
doctest.testmod() settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer"
self.assertRaises(ImproperlyConfigured, self.backend)
class CacheSessionTests(SessionTestsMixin, unittest.TestCase):
backend = CacheSession

View File

@ -250,15 +250,15 @@ class ManagementUtility(object):
""" """
try: try:
app_name = get_commands()[subcommand] app_name = get_commands()[subcommand]
except KeyError:
sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \
(subcommand, self.prog_name))
sys.exit(1)
if isinstance(app_name, BaseCommand): if isinstance(app_name, BaseCommand):
# If the command is already loaded, use it directly. # If the command is already loaded, use it directly.
klass = app_name klass = app_name
else: else:
klass = load_command_class(app_name, subcommand) klass = load_command_class(app_name, subcommand)
except KeyError:
sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \
(subcommand, self.prog_name))
sys.exit(1)
return klass return klass
def autocomplete(self): def autocomplete(self):

View File

@ -118,7 +118,7 @@ class BaseCommand(object):
# Metadata about this command. # Metadata about this command.
option_list = ( option_list = (
make_option('-v', '--verbosity', action='store', dest='verbosity', default='1', make_option('-v', '--verbosity', action='store', dest='verbosity', default='1',
type='choice', choices=['0', '1', '2'], type='choice', choices=['0', '1', '2', '3'],
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
make_option('--settings', make_option('--settings',
help='The Python path to a settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.'), help='The Python path to a settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.'),

View File

@ -16,7 +16,7 @@ class Command(BaseCommand):
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load ' default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
'fixtures into. Defaults to the "default" database.'), 'fixtures into. Defaults to the "default" database.'),
make_option('-e', '--exclude', dest='exclude',action='append', default=[], make_option('-e', '--exclude', dest='exclude',action='append', default=[],
help='App to exclude (use multiple --exclude to exclude multiple apps).'), help='An appname or appname.ModelName to exclude (use multiple --exclude to exclude multiple apps/models).'),
make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False, make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False,
help='Use natural keys if they are available.'), help='Use natural keys if they are available.'),
) )
@ -31,11 +31,25 @@ class Command(BaseCommand):
indent = options.get('indent',None) indent = options.get('indent',None)
using = options.get('database', DEFAULT_DB_ALIAS) using = options.get('database', DEFAULT_DB_ALIAS)
connection = connections[using] connection = connections[using]
exclude = options.get('exclude',[]) excludes = options.get('exclude',[])
show_traceback = options.get('traceback', False) show_traceback = options.get('traceback', False)
use_natural_keys = options.get('use_natural_keys', False) use_natural_keys = options.get('use_natural_keys', False)
excluded_apps = set(get_app(app_label) for app_label in exclude) excluded_apps = set()
excluded_models = set()
for exclude in excludes:
if '.' in exclude:
app_label, model_name = exclude.split('.', 1)
model_obj = get_model(app_label, model_name)
if not model_obj:
raise CommandError('Unknown model in excludes: %s' % exclude)
excluded_models.add(model_obj)
else:
try:
app_obj = get_app(exclude)
excluded_apps.add(app_obj)
except ImproperlyConfigured:
raise CommandError('Unknown app in excludes: %s' % exclude)
if len(app_labels) == 0: if len(app_labels) == 0:
app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps) app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
@ -48,7 +62,8 @@ class Command(BaseCommand):
app = get_app(app_label) app = get_app(app_label)
except ImproperlyConfigured: except ImproperlyConfigured:
raise CommandError("Unknown application: %s" % app_label) raise CommandError("Unknown application: %s" % app_label)
if app in excluded_apps:
continue
model = get_model(app_label, model_label) model = get_model(app_label, model_label)
if model is None: if model is None:
raise CommandError("Unknown model: %s.%s" % (app_label, model_label)) raise CommandError("Unknown model: %s.%s" % (app_label, model_label))
@ -65,6 +80,8 @@ class Command(BaseCommand):
app = get_app(app_label) app = get_app(app_label)
except ImproperlyConfigured: except ImproperlyConfigured:
raise CommandError("Unknown application: %s" % app_label) raise CommandError("Unknown application: %s" % app_label)
if app in excluded_apps:
continue
app_list[app] = None app_list[app] = None
# Check that the serialization format exists; this is a shortcut to # Check that the serialization format exists; this is a shortcut to
@ -80,6 +97,8 @@ class Command(BaseCommand):
# Now collate the objects to be serialized. # Now collate the objects to be serialized.
objects = [] objects = []
for model in sort_dependencies(app_list.items()): for model in sort_dependencies(app_list.items()):
if model in excluded_models:
continue
if not model._meta.proxy and router.allow_syncdb(using, model): if not model._meta.proxy and router.allow_syncdb(using, model):
objects.extend(model._default_manager.using(using).all()) objects.extend(model._default_manager.using(using).all())

View File

@ -111,7 +111,7 @@ class Command(BaseCommand):
formats = [] formats = []
if formats: if formats:
if verbosity > 1: if verbosity >= 2:
self.stdout.write("Loading '%s' fixtures...\n" % fixture_name) self.stdout.write("Loading '%s' fixtures...\n" % fixture_name)
else: else:
sys.stderr.write( sys.stderr.write(
@ -127,7 +127,7 @@ class Command(BaseCommand):
fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + [''] fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + ['']
for fixture_dir in fixture_dirs: for fixture_dir in fixture_dirs:
if verbosity > 1: if verbosity >= 2:
self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir)) self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir))
label_found = False label_found = False
@ -140,7 +140,7 @@ class Command(BaseCommand):
if p if p
) )
if verbosity > 1: if verbosity >= 3:
self.stdout.write("Trying %s for %s fixture '%s'...\n" % \ self.stdout.write("Trying %s for %s fixture '%s'...\n" % \
(humanize(fixture_dir), file_name, fixture_name)) (humanize(fixture_dir), file_name, fixture_name))
full_path = os.path.join(fixture_dir, file_name) full_path = os.path.join(fixture_dir, file_name)
@ -157,7 +157,7 @@ class Command(BaseCommand):
else: else:
fixture_count += 1 fixture_count += 1
objects_in_fixture = 0 objects_in_fixture = 0
if verbosity > 0: if verbosity >= 2:
self.stdout.write("Installing %s fixture '%s' from %s.\n" % \ self.stdout.write("Installing %s fixture '%s' from %s.\n" % \
(format, fixture_name, humanize(fixture_dir))) (format, fixture_name, humanize(fixture_dir)))
try: try:
@ -197,7 +197,7 @@ class Command(BaseCommand):
return return
except Exception, e: except Exception, e:
if verbosity > 1: if verbosity >= 2:
self.stdout.write("No %s fixture '%s' in %s.\n" % \ self.stdout.write("No %s fixture '%s' in %s.\n" % \
(format, fixture_name, humanize(fixture_dir))) (format, fixture_name, humanize(fixture_dir)))
@ -206,7 +206,7 @@ class Command(BaseCommand):
if object_count > 0: if object_count > 0:
sequence_sql = connection.ops.sequence_reset_sql(self.style, models) sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
if sequence_sql: if sequence_sql:
if verbosity > 1: if verbosity >= 2:
self.stdout.write("Resetting sequences\n") self.stdout.write("Resetting sequences\n")
for line in sequence_sql: for line in sequence_sql:
cursor.execute(line) cursor.execute(line)
@ -216,10 +216,10 @@ class Command(BaseCommand):
transaction.leave_transaction_management(using=using) transaction.leave_transaction_management(using=using)
if object_count == 0: if object_count == 0:
if verbosity > 0: if verbosity >= 1:
self.stdout.write("No fixtures found.\n") self.stdout.write("No fixtures found.\n")
else: else:
if verbosity > 0: if verbosity >= 1:
self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % (object_count, fixture_count)) self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % (object_count, fixture_count))
# Close the DB connection. This is required as a workaround for an # Close the DB connection. This is required as a workaround for an

View File

@ -76,10 +76,12 @@ class Command(NoArgsCommand):
) )
# Create the tables for each model # Create the tables for each model
if verbosity >= 1:
print "Creating tables ..."
for app_name, model_list in manifest.items(): for app_name, model_list in manifest.items():
for model in model_list: for model in model_list:
# Create the model's database table, if it doesn't already exist. # Create the model's database table, if it doesn't already exist.
if verbosity >= 2: if verbosity >= 3:
print "Processing %s.%s model" % (app_name, model._meta.object_name) print "Processing %s.%s model" % (app_name, model._meta.object_name)
sql, references = connection.creation.sql_create_model(model, self.style, seen_models) sql, references = connection.creation.sql_create_model(model, self.style, seen_models)
seen_models.add(model) seen_models.add(model)
@ -107,12 +109,14 @@ class Command(NoArgsCommand):
# Install custom SQL for the app (but only if this # Install custom SQL for the app (but only if this
# is a model we've just created) # is a model we've just created)
if verbosity >= 1:
print "Installing custom SQL ..."
for app_name, model_list in manifest.items(): for app_name, model_list in manifest.items():
for model in model_list: for model in model_list:
if model in created_models: if model in created_models:
custom_sql = custom_sql_for_model(model, self.style, connection) custom_sql = custom_sql_for_model(model, self.style, connection)
if custom_sql: if custom_sql:
if verbosity >= 1: if verbosity >= 2:
print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name) print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name)
try: try:
for sql in custom_sql: for sql in custom_sql:
@ -127,16 +131,18 @@ class Command(NoArgsCommand):
else: else:
transaction.commit_unless_managed(using=db) transaction.commit_unless_managed(using=db)
else: else:
if verbosity >= 2: if verbosity >= 3:
print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name) print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name)
if verbosity >= 1:
print "Installing indexes ..."
# Install SQL indicies for all newly created models # Install SQL indicies for all newly created models
for app_name, model_list in manifest.items(): for app_name, model_list in manifest.items():
for model in model_list: for model in model_list:
if model in created_models: if model in created_models:
index_sql = connection.creation.sql_indexes_for_model(model, self.style) index_sql = connection.creation.sql_indexes_for_model(model, self.style)
if index_sql: if index_sql:
if verbosity >= 1: if verbosity >= 2:
print "Installing index for %s.%s model" % (app_name, model._meta.object_name) print "Installing index for %s.%s model" % (app_name, model._meta.object_name)
try: try:
for sql in index_sql: for sql in index_sql:

View File

@ -30,6 +30,40 @@ _prefixes = {}
# Overridden URLconfs for each thread are stored here. # Overridden URLconfs for each thread are stored here.
_urlconfs = {} _urlconfs = {}
class ResolverMatch(object):
def __init__(self, func, args, kwargs, url_name=None, app_name=None, namespaces=None):
self.func = func
self.args = args
self.kwargs = kwargs
self.app_name = app_name
if namespaces:
self.namespaces = [x for x in namespaces if x]
else:
self.namespaces = []
if not url_name:
if not hasattr(func, '__name__'):
# An instance of a callable class
url_name = '.'.join([func.__class__.__module__, func.__class__.__name__])
else:
# A function
url_name = '.'.join([func.__module__, func.__name__])
self.url_name = url_name
def namespace(self):
return ':'.join(self.namespaces)
namespace = property(namespace)
def view_name(self):
return ':'.join([ x for x in [ self.namespace, self.url_name ] if x ])
view_name = property(view_name)
def __getitem__(self, index):
return (self.func, self.args, self.kwargs)[index]
def __repr__(self):
return "ResolverMatch(func=%s, args=%s, kwargs=%s, url_name='%s', app_name='%s', namespace='%s')" % (
self.func, self.args, self.kwargs, self.url_name, self.app_name, self.namespace)
class Resolver404(Http404): class Resolver404(Http404):
pass pass
@ -120,7 +154,7 @@ class RegexURLPattern(object):
# In both cases, pass any extra_kwargs as **kwargs. # In both cases, pass any extra_kwargs as **kwargs.
kwargs.update(self.default_args) kwargs.update(self.default_args)
return self.callback, args, kwargs return ResolverMatch(self.callback, args, kwargs, self.name)
def _get_callback(self): def _get_callback(self):
if self._callback is not None: if self._callback is not None:
@ -183,6 +217,7 @@ class RegexURLResolver(object):
else: else:
bits = normalize(p_pattern) bits = normalize(p_pattern)
lookups.appendlist(pattern.callback, (bits, p_pattern)) lookups.appendlist(pattern.callback, (bits, p_pattern))
if pattern.name is not None:
lookups.appendlist(pattern.name, (bits, p_pattern)) lookups.appendlist(pattern.name, (bits, p_pattern))
self._reverse_dict = lookups self._reverse_dict = lookups
self._namespace_dict = namespaces self._namespace_dict = namespaces
@ -224,9 +259,9 @@ class RegexURLResolver(object):
if sub_match: if sub_match:
sub_match_dict = dict([(smart_str(k), v) for k, v in match.groupdict().items()]) sub_match_dict = dict([(smart_str(k), v) for k, v in match.groupdict().items()])
sub_match_dict.update(self.default_kwargs) sub_match_dict.update(self.default_kwargs)
for k, v in sub_match[2].iteritems(): for k, v in sub_match.kwargs.iteritems():
sub_match_dict[smart_str(k)] = v sub_match_dict[smart_str(k)] = v
return sub_match[0], sub_match[1], sub_match_dict return ResolverMatch(sub_match.func, sub_match.args, sub_match_dict, sub_match.url_name, self.app_name or sub_match.app_name, [self.namespace] + sub_match.namespaces)
tried.append(pattern.regex.pattern) tried.append(pattern.regex.pattern)
raise Resolver404({'tried': tried, 'path': new_path}) raise Resolver404({'tried': tried, 'path': new_path})
raise Resolver404({'path' : path}) raise Resolver404({'path' : path})

View File

@ -35,6 +35,8 @@ if DEFAULT_DB_ALIAS not in settings.DATABASES:
raise ImproperlyConfigured("You must default a '%s' database" % DEFAULT_DB_ALIAS) raise ImproperlyConfigured("You must default a '%s' database" % DEFAULT_DB_ALIAS)
for alias, database in settings.DATABASES.items(): for alias, database in settings.DATABASES.items():
if 'ENGINE' not in database:
raise ImproperlyConfigured("You must specify a 'ENGINE' for database '%s'" % alias)
if database['ENGINE'] in ("postgresql", "postgresql_psycopg2", "sqlite3", "mysql", "oracle"): if database['ENGINE'] in ("postgresql", "postgresql_psycopg2", "sqlite3", "mysql", "oracle"):
import warnings import warnings
if 'django.contrib.gis' in settings.INSTALLED_APPS: if 'django.contrib.gis' in settings.INSTALLED_APPS:

View File

@ -350,7 +350,10 @@ class BaseDatabaseCreation(object):
can_rollback = self._rollback_works() can_rollback = self._rollback_works()
self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback
call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias) # Report syncdb messages at one level lower than that requested.
# This ensures we don't get flooded with messages during testing
# (unless you really ask to be flooded)
call_command('syncdb', verbosity=max(verbosity - 1, 0), interactive=False, database=self.connection.alias)
if settings.CACHE_BACKEND.startswith('db://'): if settings.CACHE_BACKEND.startswith('db://'):
from django.core.cache import parse_backend_uri, cache from django.core.cache import parse_backend_uri, cache
@ -390,10 +393,8 @@ class BaseDatabaseCreation(object):
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
print "Destroying old test database..." print "Destroying old test database '%s'..." % self.connection.alias
cursor.execute("DROP DATABASE %s" % qn(test_database_name)) cursor.execute("DROP DATABASE %s" % qn(test_database_name))
if verbosity >= 1:
print "Creating test database..."
cursor.execute("CREATE DATABASE %s %s" % (qn(test_database_name), suffix)) cursor.execute("CREATE DATABASE %s %s" % (qn(test_database_name), suffix))
except Exception, e: except Exception, e:
sys.stderr.write("Got an error recreating the test database: %s\n" % e) sys.stderr.write("Got an error recreating the test database: %s\n" % e)

View File

@ -61,8 +61,6 @@ class DatabaseCreation(BaseDatabaseCreation):
cursor = self.connection.cursor() cursor = self.connection.cursor()
if self._test_database_create(): if self._test_database_create():
if verbosity >= 1:
print 'Creating test database...'
try: try:
self._execute_test_db_creation(cursor, parameters, verbosity) self._execute_test_db_creation(cursor, parameters, verbosity)
except Exception, e: except Exception, e:
@ -72,10 +70,8 @@ class DatabaseCreation(BaseDatabaseCreation):
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1: if verbosity >= 1:
print "Destroying old test database..." print "Destroying old test database '%s'..." % self.connection.alias
self._execute_test_db_destruction(cursor, parameters, verbosity) self._execute_test_db_destruction(cursor, parameters, verbosity)
if verbosity >= 1:
print "Creating test database..."
self._execute_test_db_creation(cursor, parameters, verbosity) self._execute_test_db_creation(cursor, parameters, verbosity)
except Exception, e: except Exception, e:
sys.stderr.write("Got an error recreating the test database: %s\n" % e) sys.stderr.write("Got an error recreating the test database: %s\n" % e)

View File

@ -43,14 +43,12 @@ class DatabaseCreation(BaseDatabaseCreation):
if test_database_name and test_database_name != ":memory:": if test_database_name and test_database_name != ":memory:":
# Erase the old test database # Erase the old test database
if verbosity >= 1: if verbosity >= 1:
print "Destroying old test database..." print "Destroying old test database '%s'..." % self.connection.alias
if os.access(test_database_name, os.F_OK): if os.access(test_database_name, os.F_OK):
if not autoclobber: if not autoclobber:
confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name) confirm = raw_input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
if autoclobber or confirm == 'yes': if autoclobber or confirm == 'yes':
try: try:
if verbosity >= 1:
print "Destroying old test database..."
os.remove(test_database_name) os.remove(test_database_name)
except Exception, e: except Exception, e:
sys.stderr.write("Got an error deleting the old test database: %s\n" % e) sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
@ -58,8 +56,6 @@ class DatabaseCreation(BaseDatabaseCreation):
else: else:
print "Tests cancelled." print "Tests cancelled."
sys.exit(1) sys.exit(1)
if verbosity >= 1:
print "Creating test database..."
else: else:
test_database_name = ":memory:" test_database_name = ":memory:"
return test_database_name return test_database_name

View File

@ -456,7 +456,7 @@ class Model(object):
meta = cls._meta meta = cls._meta
if origin and not meta.auto_created: if origin and not meta.auto_created:
signals.pre_save.send(sender=origin, instance=self, raw=raw) signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using)
# If we are in a raw save, save the object exactly as presented. # If we are in a raw save, save the object exactly as presented.
# That means that we don't try to be smart about saving attributes # That means that we don't try to be smart about saving attributes
@ -540,7 +540,7 @@ class Model(object):
# Signal that the save is complete # Signal that the save is complete
if origin and not meta.auto_created: if origin and not meta.auto_created:
signals.post_save.send(sender=origin, instance=self, signals.post_save.send(sender=origin, instance=self,
created=(not record_exists), raw=raw) created=(not record_exists), raw=raw, using=using)
save_base.alters_data = True save_base.alters_data = True

View File

@ -459,6 +459,9 @@ class AutoField(Field):
kwargs['blank'] = True kwargs['blank'] = True
Field.__init__(self, *args, **kwargs) Field.__init__(self, *args, **kwargs)
def get_internal_type(self):
return "AutoField"
def to_python(self, value): def to_python(self, value):
if value is None: if value is None:
return value return value

View File

@ -566,7 +566,7 @@ def create_many_related_manager(superclass, rel=False):
# duplicate data row for symmetrical reverse entries. # duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action='pre_add', signals.m2m_changed.send(sender=rel.through, action='pre_add',
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=new_ids) model=self.model, pk_set=new_ids, using=db)
# Add the ones that aren't there already # Add the ones that aren't there already
for obj_id in new_ids: for obj_id in new_ids:
self.through._default_manager.using(db).create(**{ self.through._default_manager.using(db).create(**{
@ -578,7 +578,7 @@ def create_many_related_manager(superclass, rel=False):
# duplicate data row for symmetrical reverse entries. # duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action='post_add', signals.m2m_changed.send(sender=rel.through, action='post_add',
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=new_ids) model=self.model, pk_set=new_ids, using=db)
def _remove_items(self, source_field_name, target_field_name, *objs): def _remove_items(self, source_field_name, target_field_name, *objs):
# source_col_name: the PK colname in join_table for the source object # source_col_name: the PK colname in join_table for the source object
@ -594,14 +594,16 @@ def create_many_related_manager(superclass, rel=False):
old_ids.add(obj.pk) old_ids.add(obj.pk)
else: else:
old_ids.add(obj) old_ids.add(obj)
# Work out what DB we're operating on
db = router.db_for_write(self.through.__class__, instance=self.instance)
# Send a signal to the other end if need be.
if self.reverse or source_field_name == self.source_field_name: if self.reverse or source_field_name == self.source_field_name:
# Don't send the signal when we are deleting the # Don't send the signal when we are deleting the
# duplicate data row for symmetrical reverse entries. # duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="pre_remove", signals.m2m_changed.send(sender=rel.through, action="pre_remove",
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=old_ids) model=self.model, pk_set=old_ids, using=db)
# Remove the specified objects from the join table # Remove the specified objects from the join table
db = router.db_for_write(self.through.__class__, instance=self.instance)
self.through._default_manager.using(db).filter(**{ self.through._default_manager.using(db).filter(**{
source_field_name: self._pk_val, source_field_name: self._pk_val,
'%s__in' % target_field_name: old_ids '%s__in' % target_field_name: old_ids
@ -611,17 +613,17 @@ def create_many_related_manager(superclass, rel=False):
# duplicate data row for symmetrical reverse entries. # duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="post_remove", signals.m2m_changed.send(sender=rel.through, action="post_remove",
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=old_ids) model=self.model, pk_set=old_ids, using=db)
def _clear_items(self, source_field_name): def _clear_items(self, source_field_name):
db = router.db_for_write(self.through.__class__, instance=self.instance)
# source_col_name: the PK colname in join_table for the source object # source_col_name: the PK colname in join_table for the source object
if self.reverse or source_field_name == self.source_field_name: if self.reverse or source_field_name == self.source_field_name:
# Don't send the signal when we are clearing the # Don't send the signal when we are clearing the
# duplicate data rows for symmetrical reverse entries. # duplicate data rows for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="pre_clear", signals.m2m_changed.send(sender=rel.through, action="pre_clear",
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=None) model=self.model, pk_set=None, using=db)
db = router.db_for_write(self.through.__class__, instance=self.instance)
self.through._default_manager.using(db).filter(**{ self.through._default_manager.using(db).filter(**{
source_field_name: self._pk_val source_field_name: self._pk_val
}).delete() }).delete()
@ -630,7 +632,7 @@ def create_many_related_manager(superclass, rel=False):
# duplicate data rows for symmetrical reverse entries. # duplicate data rows for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="post_clear", signals.m2m_changed.send(sender=rel.through, action="post_clear",
instance=self.instance, reverse=self.reverse, instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=None) model=self.model, pk_set=None, using=db)
return ManyRelatedManager return ManyRelatedManager

View File

@ -1311,7 +1311,8 @@ def delete_objects(seen_objs, using):
# Pre-notify all instances to be deleted. # Pre-notify all instances to be deleted.
for pk_val, instance in items: for pk_val, instance in items:
if not cls._meta.auto_created: if not cls._meta.auto_created:
signals.pre_delete.send(sender=cls, instance=instance) signals.pre_delete.send(sender=cls, instance=instance,
using=using)
pk_list = [pk for pk,instance in items] pk_list = [pk for pk,instance in items]
@ -1343,7 +1344,7 @@ def delete_objects(seen_objs, using):
setattr(instance, field.attname, None) setattr(instance, field.attname, None)
if not cls._meta.auto_created: if not cls._meta.auto_created:
signals.post_delete.send(sender=cls, instance=instance) signals.post_delete.send(sender=cls, instance=instance, using=using)
setattr(instance, cls._meta.pk.attname, None) setattr(instance, cls._meta.pk.attname, None)
if forced_managed: if forced_managed:

View File

@ -5,12 +5,12 @@ class_prepared = Signal(providing_args=["class"])
pre_init = Signal(providing_args=["instance", "args", "kwargs"]) pre_init = Signal(providing_args=["instance", "args", "kwargs"])
post_init = Signal(providing_args=["instance"]) post_init = Signal(providing_args=["instance"])
pre_save = Signal(providing_args=["instance", "raw"]) pre_save = Signal(providing_args=["instance", "raw", "using"])
post_save = Signal(providing_args=["instance", "raw", "created"]) post_save = Signal(providing_args=["instance", "raw", "created", "using"])
pre_delete = Signal(providing_args=["instance"]) pre_delete = Signal(providing_args=["instance", "using"])
post_delete = Signal(providing_args=["instance"]) post_delete = Signal(providing_args=["instance", "using"])
post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive"]) post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive"])
m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set"]) m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set", "using"])

View File

@ -35,7 +35,7 @@ def get_declared_fields(bases, attrs, with_base_fields=True):
Also integrates any additional media definitions Also integrates any additional media definitions
""" """
fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) fields.sort(key=lambda x: x[1].creation_counter)
# If this class is subclassing another Form, add that Form's fields. # If this class is subclassing another Form, add that Form's fields.
# Note that we loop over the bases in *reverse*. This is necessary in # Note that we loop over the bases in *reverse*. This is necessary in
@ -213,7 +213,7 @@ class BaseForm(StrAndUnicode):
normal_row = u'<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', normal_row = u'<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>',
error_row = u'<tr><td colspan="2">%s</td></tr>', error_row = u'<tr><td colspan="2">%s</td></tr>',
row_ender = u'</td></tr>', row_ender = u'</td></tr>',
help_text_html = u'<br />%s', help_text_html = u'<br /><span class="helptext">%s</span>',
errors_on_separate_row = False) errors_on_separate_row = False)
def as_ul(self): def as_ul(self):
@ -222,7 +222,7 @@ class BaseForm(StrAndUnicode):
normal_row = u'<li%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</li>', normal_row = u'<li%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</li>',
error_row = u'<li>%s</li>', error_row = u'<li>%s</li>',
row_ender = '</li>', row_ender = '</li>',
help_text_html = u' %s', help_text_html = u' <span class="helptext">%s</span>',
errors_on_separate_row = False) errors_on_separate_row = False)
def as_p(self): def as_p(self):
@ -231,7 +231,7 @@ class BaseForm(StrAndUnicode):
normal_row = u'<p%(html_class_attr)s>%(label)s %(field)s%(help_text)s</p>', normal_row = u'<p%(html_class_attr)s>%(label)s %(field)s%(help_text)s</p>',
error_row = u'%s', error_row = u'%s',
row_ender = '</p>', row_ender = '</p>',
help_text_html = u' %s', help_text_html = u' <span class="helptext">%s</span>',
errors_on_separate_row = True) errors_on_separate_row = True)
def non_field_errors(self): def non_field_errors(self):

View File

@ -199,14 +199,12 @@ class BaseFormSet(StrAndUnicode):
# A sort function to order things numerically ascending, but # A sort function to order things numerically ascending, but
# None should be sorted below anything else. Allowing None as # None should be sorted below anything else. Allowing None as
# a comparison value makes it so we can leave ordering fields # a comparison value makes it so we can leave ordering fields
# blamk. # blank.
def compare_ordering_values(x, y): def compare_ordering_key(k):
if x[1] is None: if k[1] is None:
return 1 return (1, 0) # +infinity, larger than any number
if y[1] is None: return (0, k[1])
return -1 self._ordering.sort(key=compare_ordering_key)
return x[1] - y[1]
self._ordering.sort(compare_ordering_values)
# Return a list of form.cleaned_data dicts in the order spcified by # Return a list of form.cleaned_data dicts in the order spcified by
# the form data. # the form data.
return [self.forms[i[0]] for i in self._ordering] return [self.forms[i[0]] for i in self._ordering]

View File

@ -229,7 +229,7 @@ class TextInput(Input):
class PasswordInput(Input): class PasswordInput(Input):
input_type = 'password' input_type = 'password'
def __init__(self, attrs=None, render_value=True): def __init__(self, attrs=None, render_value=False):
super(PasswordInput, self).__init__(attrs) super(PasswordInput, self).__init__(attrs)
self.render_value = render_value self.render_value = render_value
@ -308,9 +308,13 @@ class DateInput(Input):
super(DateInput, self).__init__(attrs) super(DateInput, self).__init__(attrs)
if format: if format:
self.format = format self.format = format
self.manual_format = True
else:
self.format = formats.get_format('DATE_INPUT_FORMATS')[0]
self.manual_format = False
def _format_value(self, value): def _format_value(self, value):
if self.is_localized: if self.is_localized and not self.manual_format:
return formats.localize_input(value) return formats.localize_input(value)
elif hasattr(value, 'strftime'): elif hasattr(value, 'strftime'):
value = datetime_safe.new_date(value) value = datetime_safe.new_date(value)
@ -336,9 +340,13 @@ class DateTimeInput(Input):
super(DateTimeInput, self).__init__(attrs) super(DateTimeInput, self).__init__(attrs)
if format: if format:
self.format = format self.format = format
self.manual_format = True
else:
self.format = formats.get_format('DATETIME_INPUT_FORMATS')[0]
self.manual_format = False
def _format_value(self, value): def _format_value(self, value):
if self.is_localized: if self.is_localized and not self.manual_format:
return formats.localize_input(value) return formats.localize_input(value)
elif hasattr(value, 'strftime'): elif hasattr(value, 'strftime'):
value = datetime_safe.new_datetime(value) value = datetime_safe.new_datetime(value)
@ -364,9 +372,13 @@ class TimeInput(Input):
super(TimeInput, self).__init__(attrs) super(TimeInput, self).__init__(attrs)
if format: if format:
self.format = format self.format = format
self.manual_format = True
else:
self.format = formats.get_format('TIME_INPUT_FORMATS')[0]
self.manual_format = False
def _format_value(self, value): def _format_value(self, value):
if self.is_localized: if self.is_localized and not self.manual_format:
return formats.localize_input(value) return formats.localize_input(value)
elif hasattr(value, 'strftime'): elif hasattr(value, 'strftime'):
return value.strftime(self.format) return value.strftime(self.format)
@ -751,12 +763,8 @@ class SplitDateTimeWidget(MultiWidget):
time_format = TimeInput.format time_format = TimeInput.format
def __init__(self, attrs=None, date_format=None, time_format=None): def __init__(self, attrs=None, date_format=None, time_format=None):
if date_format: widgets = (DateInput(attrs=attrs, format=date_format),
self.date_format = date_format TimeInput(attrs=attrs, format=time_format))
if time_format:
self.time_format = time_format
widgets = (DateInput(attrs=attrs, format=self.date_format),
TimeInput(attrs=attrs, format=self.time_format))
super(SplitDateTimeWidget, self).__init__(widgets, attrs) super(SplitDateTimeWidget, self).__init__(widgets, attrs)
def decompress(self, value): def decompress(self, value):

View File

@ -256,6 +256,8 @@ def truncatewords(value, arg):
Truncates a string after a certain number of words. Truncates a string after a certain number of words.
Argument: Number of words to truncate after. Argument: Number of words to truncate after.
Newlines within the string are removed.
""" """
from django.utils.text import truncate_words from django.utils.text import truncate_words
try: try:
@ -271,6 +273,8 @@ def truncatewords_html(value, arg):
Truncates HTML after a certain number of words. Truncates HTML after a certain number of words.
Argument: Number of words to truncate after. Argument: Number of words to truncate after.
Newlines in the HTML are preserved.
""" """
from django.utils.text import truncate_html_words from django.utils.text import truncate_html_words
try: try:

View File

@ -3,6 +3,7 @@ from urlparse import urlparse, urlunparse, urlsplit
import sys import sys
import os import os
import re import re
import mimetypes
try: try:
from cStringIO import StringIO from cStringIO import StringIO
except ImportError: except ImportError:
@ -138,11 +139,14 @@ def encode_multipart(boundary, data):
def encode_file(boundary, key, file): def encode_file(boundary, key, file):
to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET) to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
content_type = mimetypes.guess_type(file.name)[0]
if content_type is None:
content_type = 'application/octet-stream'
return [ return [
'--' + boundary, '--' + boundary,
'Content-Disposition: form-data; name="%s"; filename="%s"' \ 'Content-Disposition: form-data; name="%s"; filename="%s"' \
% (to_str(key), to_str(os.path.basename(file.name))), % (to_str(key), to_str(os.path.basename(file.name))),
'Content-Type: application/octet-stream', 'Content-Type: %s' % content_type,
'', '',
file.read() file.read()
] ]

View File

@ -346,7 +346,7 @@ class TransactionTestCase(unittest.TestCase):
def assertContains(self, response, text, count=None, status_code=200, def assertContains(self, response, text, count=None, status_code=200,
msg_prefix=''): msg_prefix=''):
""" """
Asserts that a response indicates that a page was retrieved Asserts that a response indicates that some content was retrieved
successfully, (i.e., the HTTP status code was as expected), and that successfully, (i.e., the HTTP status code was as expected), and that
``text`` occurs ``count`` times in the content of the response. ``text`` occurs ``count`` times in the content of the response.
If ``count`` is None, the count doesn't matter - the assertion is true If ``count`` is None, the count doesn't matter - the assertion is true
@ -356,7 +356,7 @@ class TransactionTestCase(unittest.TestCase):
msg_prefix += ": " msg_prefix += ": "
self.assertEqual(response.status_code, status_code, self.assertEqual(response.status_code, status_code,
msg_prefix + "Couldn't retrieve page: Response code was %d" msg_prefix + "Couldn't retrieve content: Response code was %d"
" (expected %d)" % (response.status_code, status_code)) " (expected %d)" % (response.status_code, status_code))
text = smart_str(text, response._charset) text = smart_str(text, response._charset)
real_count = response.content.count(text) real_count = response.content.count(text)
@ -371,7 +371,7 @@ class TransactionTestCase(unittest.TestCase):
def assertNotContains(self, response, text, status_code=200, def assertNotContains(self, response, text, status_code=200,
msg_prefix=''): msg_prefix=''):
""" """
Asserts that a response indicates that a page was retrieved Asserts that a response indicates that some content was retrieved
successfully, (i.e., the HTTP status code was as expected), and that successfully, (i.e., the HTTP status code was as expected), and that
``text`` doesn't occurs in the content of the response. ``text`` doesn't occurs in the content of the response.
""" """
@ -379,7 +379,7 @@ class TransactionTestCase(unittest.TestCase):
msg_prefix += ": " msg_prefix += ": "
self.assertEqual(response.status_code, status_code, self.assertEqual(response.status_code, status_code,
msg_prefix + "Couldn't retrieve page: Response code was %d" msg_prefix + "Couldn't retrieve content: Response code was %d"
" (expected %d)" % (response.status_code, status_code)) " (expected %d)" % (response.status_code, status_code))
text = smart_str(text, response._charset) text = smart_str(text, response._charset)
self.assertEqual(response.content.count(text), 0, self.assertEqual(response.content.count(text), 0,

View File

@ -21,6 +21,12 @@ class ContextList(list):
else: else:
return super(ContextList, self).__getitem__(key) return super(ContextList, self).__getitem__(key)
def __contains__(self, key):
try:
value = self[key]
except KeyError:
return False
return True
def instrumented_test_render(self, context): def instrumented_test_render(self, context):
""" """

View File

@ -39,7 +39,10 @@ wrap = allow_lazy(wrap, unicode)
def truncate_words(s, num, end_text='...'): def truncate_words(s, num, end_text='...'):
"""Truncates a string after a certain number of words. Takes an optional """Truncates a string after a certain number of words. Takes an optional
argument of what should be used to notify that the string has been argument of what should be used to notify that the string has been
truncated, defaults to ellipsis (...)""" truncated, defaulting to ellipsis (...)
Newlines in the string will be stripped.
"""
s = force_unicode(s) s = force_unicode(s)
length = int(num) length = int(num)
words = s.split() words = s.split()
@ -51,10 +54,13 @@ def truncate_words(s, num, end_text='...'):
truncate_words = allow_lazy(truncate_words, unicode) truncate_words = allow_lazy(truncate_words, unicode)
def truncate_html_words(s, num, end_text='...'): def truncate_html_words(s, num, end_text='...'):
"""Truncates html to a certain number of words (not counting tags and """Truncates HTML to a certain number of words (not counting tags and
comments). Closes opened tags if they were correctly closed in the given comments). Closes opened tags if they were correctly closed in the given
html. Takes an optional argument of what should be used to notify that the html. Takes an optional argument of what should be used to notify that the
string has been truncated, defaults to ellipsis (...).""" string has been truncated, defaulting to ellipsis (...).
Newlines in the HTML are preserved.
"""
s = force_unicode(s) s = force_unicode(s)
length = int(num) length = int(num)
if length <= 0: if length <= 0:

View File

@ -496,7 +496,7 @@ def parse_accept_lang_header(lang_string):
return [] return []
priority = priority and float(priority) or 1.0 priority = priority and float(priority) or 1.0
result.append((lang, priority)) result.append((lang, priority))
result.sort(lambda x, y: -cmp(x[1], y[1])) result.sort(key=lambda k: k[1], reverse=True)
return result return result
# get_date_formats and get_partial_date_formats aren't used anymore by Django # get_date_formats and get_partial_date_formats aren't used anymore by Django

View File

@ -19,7 +19,7 @@ What are Django's prerequisites?
-------------------------------- --------------------------------
Django requires Python_, specifically any version of Python from 2.4 Django requires Python_, specifically any version of Python from 2.4
through 2.6. No other Python libraries are required for basic Django through 2.7. No other Python libraries are required for basic Django
usage. usage.
For a development environment -- if you just want to experiment with Django -- For a development environment -- if you just want to experiment with Django --

View File

@ -145,7 +145,11 @@ and time availability), claim it by following these steps:
* Claim the ticket by clicking the radio button next to "Accept ticket" * Claim the ticket by clicking the radio button next to "Accept ticket"
near the bottom of the page, then clicking "Submit changes." near the bottom of the page, then clicking "Submit changes."
If you have an account but have forgotten your password, you can reset it
using the `password reset page`_.
.. _Create an account: http://www.djangoproject.com/accounts/register/ .. _Create an account: http://www.djangoproject.com/accounts/register/
.. _password reset page: http://www.djangoproject.com/accounts/password/reset/
Ticket claimers' responsibility Ticket claimers' responsibility
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -474,17 +474,16 @@ change list page. By default, this is set to ``100``.
.. attribute:: ModelAdmin.list_select_related .. attribute:: ModelAdmin.list_select_related
Set ``list_select_related`` to tell Django to use ``select_related()`` in Set ``list_select_related`` to tell Django to use
retrieving the list of objects on the admin change list page. This can save you :meth:`~django.db.models.QuerySet.select_related` in retrieving the list of
a bunch of database queries. objects on the admin change list page. This can save you a bunch of database
queries.
The value should be either ``True`` or ``False``. Default is ``False``. The value should be either ``True`` or ``False``. Default is ``False``.
Note that Django will use ``select_related()``, regardless of this setting, Note that Django will use :meth:`~django.db.models.QuerySet.select_related`,
if one of the ``list_display`` fields is a ``ForeignKey``. regardless of this setting, if one of the ``list_display`` fields is a
``ForeignKey``.
For more on ``select_related()``, see
:ref:`the select_related() docs <select-related>`.
.. attribute:: ModelAdmin.inlines .. attribute:: ModelAdmin.inlines
@ -595,11 +594,16 @@ This should be set to a list of field names that will be searched whenever
somebody submits a search query in that text box. somebody submits a search query in that text box.
These fields should be some kind of text field, such as ``CharField`` or These fields should be some kind of text field, such as ``CharField`` or
``TextField``. You can also perform a related lookup on a ``ForeignKey`` with ``TextField``. You can also perform a related lookup on a ``ForeignKey`` or
the lookup API "follow" notation:: ``ManyToManyField`` with the lookup API "follow" notation::
search_fields = ['foreign_key__related_fieldname'] search_fields = ['foreign_key__related_fieldname']
For example, if you have a blog entry with an author, the following definition
would enable search blog entries by the email address of the author::
search_fields = ['user__email']
When somebody does a search in the admin search box, Django splits the search When somebody does a search in the admin search box, Django splits the search
query into words and returns all objects that contain each of the words, case query into words and returns all objects that contain each of the words, case
insensitive, where each word must be in at least one of ``search_fields``. For insensitive, where each word must be in at least one of ``search_fields``. For
@ -865,11 +869,26 @@ return a subset of objects for this foreign key field based on the user::
def formfield_for_foreignkey(self, db_field, request, **kwargs): def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car": if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user) kwargs["queryset"] = Car.objects.filter(owner=request.user)
return db_field.formfield(**kwargs)
return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs) return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field This uses the ``HttpRequest`` instance to filter the ``Car`` foreign key field
to only the cars owned by the ``User`` instance. to only display the cars owned by the ``User`` instance.
.. method:: ModelAdmin.formfield_for_manytomany(self, db_field, request, **kwargs)
.. versionadded:: 1.1
Like the ``formfield_for_foreignkey`` method, the ``formfield_for_manytomany``
method can be overridden to change the default formfield for a many to many
field. For example, if an owner can own multiple cars and cars can belong
to multiple owners -- a many to many relationship -- you could filter the
``Car`` foreign key field to only display the cars owned by the ``User``::
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "cars":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
.. method:: ModelAdmin.queryset(self, request) .. method:: ModelAdmin.queryset(self, request)

View File

@ -324,15 +324,19 @@ same types of lookups manually::
... object_id=b.id) ... object_id=b.id)
[<TaggedItem: django>, <TaggedItem: python>] [<TaggedItem: django>, <TaggedItem: python>]
Note that if the model with a :class:`~django.contrib.contenttypes.generic.GenericForeignKey` Note that if the model in a
that you're referring to uses a non-default value for ``ct_field`` or ``fk_field`` :class:`~django.contrib.contenttypes.generic.GenericRelation` uses a
(e.g. the :mod:`django.contrib.comments` app uses ``ct_field="object_pk"``), non-default value for ``ct_field`` or ``fk_field`` in its
you'll need to pass ``content_type_field`` and ``object_id_field`` to :class:`~django.contrib.contenttypes.generic.GenericForeignKey` (e.g. the
:class:`~django.contrib.contenttypes.generic.GenericRelation`.:: :mod:`django.contrib.comments` app uses ``ct_field="object_pk"``),
you'll need to set ``content_type_field`` and/or ``object_id_field`` in
the :class:`~django.contrib.contenttypes.generic.GenericRelation` to
match the ``ct_field`` and ``fk_field``, respectively, in the
:class:`~django.contrib.contenttypes.generic.GenericForeignKey`::
comments = generic.GenericRelation(Comment, content_type_field="content_type", object_id_field="object_pk") comments = generic.GenericRelation(Comment, object_id_field="object_pk")
Note that if you delete an object that has a Note also, that if you delete an object that has a
:class:`~django.contrib.contenttypes.generic.GenericRelation`, any objects :class:`~django.contrib.contenttypes.generic.GenericRelation`, any objects
which have a :class:`~django.contrib.contenttypes.generic.GenericForeignKey` which have a :class:`~django.contrib.contenttypes.generic.GenericForeignKey`
pointing at it will be deleted as well. In the example above, this means that pointing at it will be deleted as well. In the example above, this means that

View File

@ -189,8 +189,10 @@ for the wizard to work properly.
Hooking the wizard into a URLconf Hooking the wizard into a URLconf
================================= =================================
Finally, give your new :class:`FormWizard` object a URL in ``urls.py``. The Finally, we need to specify which forms to use in the wizard, and then
wizard takes a list of your :class:`~django.forms.Form` objects as arguments:: deploy the new :class:`FormWizard` object a URL in ``urls.py``. The
wizard takes a list of your :class:`~django.forms.Form` objects as
arguments when you instantiate the Wizard::
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from mysite.testapp.forms import ContactForm1, ContactForm2, ContactWizard from mysite.testapp.forms import ContactForm1, ContactForm2, ContactWizard

View File

@ -227,6 +227,11 @@ pretty-print the output with a number of indentation spaces.
The :djadminopt:`--exclude` option may be provided to prevent specific The :djadminopt:`--exclude` option may be provided to prevent specific
applications from being dumped. applications from being dumped.
.. versionadded:: 1.3
The :djadminopt:`--exclude` option may also be provided to prevent specific
models (specified as in the form of ``appname.ModelName``) from being dumped.
.. versionadded:: 1.1 .. versionadded:: 1.1
In addition to specifying application names, you can provide a list of In addition to specifying application names, you can provide a list of
@ -957,6 +962,7 @@ that ``django-admin.py`` should print to the console.
* ``0`` means no output. * ``0`` means no output.
* ``1`` means normal output (default). * ``1`` means normal output (default).
* ``2`` means verbose output. * ``2`` means verbose output.
* ``3`` means *very* verbose output.
Common options Common options
============== ==============

View File

@ -29,7 +29,12 @@ commonly used groups of widgets:
.. attribute:: PasswordInput.render_value .. attribute:: PasswordInput.render_value
Determines whether the widget will have a value filled in when the Determines whether the widget will have a value filled in when the
form is re-displayed after a validation error (default is ``True``). form is re-displayed after a validation error (default is ``False``).
.. versionchanged:: 1.3
The default value for
:attr:`~PasswordInput.render_value` was
changed from ``True`` to ``False``
.. class:: HiddenInput .. class:: HiddenInput

View File

@ -332,8 +332,6 @@ a model which defines a default ordering, or when using
ordering was undefined prior to calling ``reverse()``, and will remain ordering was undefined prior to calling ``reverse()``, and will remain
undefined afterward). undefined afterward).
.. _queryset-distinct:
``distinct()`` ``distinct()``
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -367,9 +365,6 @@ query spans multiple tables, it's possible to get duplicate results when a
``values()`` together, be careful when ordering by fields not in the ``values()`` together, be careful when ordering by fields not in the
``values()`` call. ``values()`` call.
.. _queryset-values:
``values(*fields)`` ``values(*fields)``
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
@ -679,8 +674,6 @@ related object.
``OneToOneFields`` will not be traversed in the reverse direction if you ``OneToOneFields`` will not be traversed in the reverse direction if you
are performing a depth-based ``select_related``. are performing a depth-based ``select_related``.
.. _queryset-extra:
``extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)`` ``extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -843,8 +836,6 @@ of the arguments is required, but you should use at least one of them.
Entry.objects.extra(where=['headline=%s'], params=['Lennon']) Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
.. _queryset-defer:
``defer(*fields)`` ``defer(*fields)``
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -1143,8 +1134,6 @@ Example::
If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary. If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary.
.. _queryset-iterator:
``iterator()`` ``iterator()``
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

View File

@ -498,11 +498,11 @@ Methods
.. method:: HttpResponse.__delitem__(header) .. method:: HttpResponse.__delitem__(header)
Deletes the header with the given name. Fails silently if the header Deletes the header with the given name. Fails silently if the header
doesn't exist. Case-sensitive. doesn't exist. Case-insensitive.
.. method:: HttpResponse.__getitem__(header) .. method:: HttpResponse.__getitem__(header)
Returns the value for the given header name. Case-sensitive. Returns the value for the given header name. Case-insensitive.
.. method:: HttpResponse.has_header(header) .. method:: HttpResponse.has_header(header)

View File

@ -152,18 +152,6 @@ Default: ``600``
The default number of seconds to cache a page when the caching middleware or The default number of seconds to cache a page when the caching middleware or
``cache_page()`` decorator is used. ``cache_page()`` decorator is used.
.. setting:: CSRF_COOKIE_NAME
CSRF_COOKIE_NAME
----------------
.. versionadded:: 1.2
Default: ``'csrftoken'``
The name of the cookie to use for the CSRF authentication token. This can be whatever you
want. See :ref:`ref-contrib-csrf`.
.. setting:: CSRF_COOKIE_DOMAIN .. setting:: CSRF_COOKIE_DOMAIN
CSRF_COOKIE_DOMAIN CSRF_COOKIE_DOMAIN
@ -179,6 +167,18 @@ request forgery protection. It should be set to a string such as
``".lawrence.com"`` to allow a POST request from a form on one subdomain to be ``".lawrence.com"`` to allow a POST request from a form on one subdomain to be
accepted by accepted by a view served from another subdomain. accepted by accepted by a view served from another subdomain.
.. setting:: CSRF_COOKIE_NAME
CSRF_COOKIE_NAME
----------------
.. versionadded:: 1.2
Default: ``'csrftoken'``
The name of the cookie to use for the CSRF authentication token. This can be whatever you
want. See :ref:`ref-contrib-csrf`.
.. setting:: CSRF_FAILURE_VIEW .. setting:: CSRF_FAILURE_VIEW
CSRF_FAILURE_VIEW CSRF_FAILURE_VIEW
@ -573,18 +573,6 @@ Default: ``'webmaster@localhost'``
Default e-mail address to use for various automated correspondence from the Default e-mail address to use for various automated correspondence from the
site manager(s). site manager(s).
.. setting:: DEFAULT_TABLESPACE
DEFAULT_TABLESPACE
------------------
.. versionadded:: 1.0
Default: ``''`` (Empty string)
Default tablespace to use for models that don't specify one, if the
backend supports it.
.. setting:: DEFAULT_INDEX_TABLESPACE .. setting:: DEFAULT_INDEX_TABLESPACE
DEFAULT_INDEX_TABLESPACE DEFAULT_INDEX_TABLESPACE
@ -597,6 +585,18 @@ Default: ``''`` (Empty string)
Default tablespace to use for indexes on fields that don't specify Default tablespace to use for indexes on fields that don't specify
one, if the backend supports it. one, if the backend supports it.
.. setting:: DEFAULT_TABLESPACE
DEFAULT_TABLESPACE
------------------
.. versionadded:: 1.0
Default: ``''`` (Empty string)
Default tablespace to use for models that don't specify one, if the
backend supports it.
.. setting:: DISALLOWED_USER_AGENTS .. setting:: DISALLOWED_USER_AGENTS
DISALLOWED_USER_AGENTS DISALLOWED_USER_AGENTS
@ -738,21 +738,6 @@ Default: ``2621440`` (i.e. 2.5 MB).
The maximum size (in bytes) that an upload will be before it gets streamed to The maximum size (in bytes) that an upload will be before it gets streamed to
the file system. See :ref:`topics-files` for details. the file system. See :ref:`topics-files` for details.
.. setting:: FILE_UPLOAD_TEMP_DIR
FILE_UPLOAD_TEMP_DIR
--------------------
.. versionadded:: 1.0
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.
See :ref:`topics-files` for details.
.. setting:: FILE_UPLOAD_PERMISSIONS .. setting:: FILE_UPLOAD_PERMISSIONS
FILE_UPLOAD_PERMISSIONS FILE_UPLOAD_PERMISSIONS
@ -781,6 +766,21 @@ system's standard umask.
.. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod .. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod
.. setting:: FILE_UPLOAD_TEMP_DIR
FILE_UPLOAD_TEMP_DIR
--------------------
.. versionadded:: 1.0
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.
See :ref:`topics-files` for details.
.. setting:: FIRST_DAY_OF_WEEK .. setting:: FIRST_DAY_OF_WEEK
FIRST_DAY_OF_WEEK FIRST_DAY_OF_WEEK
@ -1227,27 +1227,6 @@ Default: ``'root@localhost'``
The e-mail address that error messages come from, such as those sent to The e-mail address that error messages come from, such as those sent to
``ADMINS`` and ``MANAGERS``. ``ADMINS`` and ``MANAGERS``.
.. setting:: SESSION_ENGINE
SESSION_ENGINE
--------------
.. versionadded:: 1.0
.. versionchanged:: 1.1
The ``cached_db`` backend was added
Default: ``django.contrib.sessions.backends.db``
Controls where Django stores session data. Valid values are:
* ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'``
See :ref:`topics-http-sessions`.
.. setting:: SESSION_COOKIE_AGE .. setting:: SESSION_COOKIE_AGE
SESSION_COOKIE_AGE SESSION_COOKIE_AGE
@ -1306,6 +1285,27 @@ Whether to use a secure cookie for the session cookie. If this is set to
ensure that the cookie is only sent under an HTTPS connection. ensure that the cookie is only sent under an HTTPS connection.
See the :ref:`topics-http-sessions`. See the :ref:`topics-http-sessions`.
.. setting:: SESSION_ENGINE
SESSION_ENGINE
--------------
.. versionadded:: 1.0
.. versionchanged:: 1.1
The ``cached_db`` backend was added
Default: ``django.contrib.sessions.backends.db``
Controls where Django stores session data. Valid values are:
* ``'django.contrib.sessions.backends.db'``
* ``'django.contrib.sessions.backends.file'``
* ``'django.contrib.sessions.backends.cache'``
* ``'django.contrib.sessions.backends.cached_db'``
See :ref:`topics-http-sessions`.
.. setting:: SESSION_EXPIRE_AT_BROWSER_CLOSE .. setting:: SESSION_EXPIRE_AT_BROWSER_CLOSE
SESSION_EXPIRE_AT_BROWSER_CLOSE SESSION_EXPIRE_AT_BROWSER_CLOSE
@ -1601,6 +1601,20 @@ A boolean that specifies whether to output the "Etag" header. This saves
bandwidth but slows down performance. This is only used if ``CommonMiddleware`` bandwidth but slows down performance. This is only used if ``CommonMiddleware``
is installed (see :ref:`topics-http-middleware`). is installed (see :ref:`topics-http-middleware`).
.. setting:: USE_I18N
USE_I18N
--------
Default: ``True``
A boolean that specifies whether Django's internationalization system should be
enabled. This provides an easy way to turn it off, for performance. If this is
set to ``False``, Django will make some optimizations so as not to load the
internationalization machinery.
See also ``USE_L10N``
.. setting:: USE_L10N .. setting:: USE_L10N
USE_L10N USE_L10N
@ -1616,20 +1630,6 @@ format of the current locale.
See also ``USE_I18N`` and ``LANGUAGE_CODE`` See also ``USE_I18N`` and ``LANGUAGE_CODE``
.. setting:: USE_I18N
USE_I18N
--------
Default: ``True``
A boolean that specifies whether Django's internationalization system should be
enabled. This provides an easy way to turn it off, for performance. If this is
set to ``False``, Django will make some optimizations so as not to load the
internationalization machinery.
See also ``USE_L10N``
.. setting:: USE_THOUSAND_SEPARATOR .. setting:: USE_THOUSAND_SEPARATOR
USE_THOUSAND_SEPARATOR USE_THOUSAND_SEPARATOR

View File

@ -113,6 +113,9 @@ Arguments sent with this signal:
``instance`` ``instance``
The actual instance being saved. The actual instance being saved.
``using``
The database alias being used.
post_save post_save
--------- ---------
@ -133,6 +136,9 @@ Arguments sent with this signal:
``created`` ``created``
A boolean; ``True`` if a new record was created. A boolean; ``True`` if a new record was created.
``using``
The database alias being used.
pre_delete pre_delete
---------- ----------
@ -150,6 +156,9 @@ Arguments sent with this signal:
``instance`` ``instance``
The actual instance being deleted. The actual instance being deleted.
``using``
The database alias being used.
post_delete post_delete
----------- -----------
@ -170,6 +179,9 @@ Arguments sent with this signal:
Note that the object will no longer be in the database, so be very Note that the object will no longer be in the database, so be very
careful what you do with this instance. careful what you do with this instance.
``using``
The database alias being used.
m2m_changed m2m_changed
----------- -----------
@ -228,6 +240,9 @@ Arguments sent with this signal:
For the ``"clear"`` action, this is ``None``. For the ``"clear"`` action, this is ``None``.
``using``
The database alias being used.
For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled
like this: like this:
@ -266,6 +281,8 @@ the arguments sent to a :data:`m2m_changed` handler would be:
``Pizza``) ``Pizza``)
``pk_set`` ``[t.id]`` (since only ``Topping t`` was added to the relation) ``pk_set`` ``[t.id]`` (since only ``Topping t`` was added to the relation)
``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================ ============== ============================================================
And if we would then do something like this: And if we would then do something like this:
@ -293,6 +310,8 @@ the arguments sent to a :data:`m2m_changed` handler would be:
``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the ``pk_set`` ``[p.id]`` (since only ``Pizza p`` was removed from the
relation) relation)
``using`` ``"default"`` (since the default router sends writes here)
============== ============================================================ ============== ============================================================
class_prepared class_prepared

View File

@ -1883,6 +1883,8 @@ For example::
If ``value`` is ``"Joel is a slug"``, the output will be ``"Joel is ..."``. If ``value`` is ``"Joel is a slug"``, the output will be ``"Joel is ..."``.
Newlines within the string will be removed.
.. templatefilter:: truncatewords_html .. templatefilter:: truncatewords_html
truncatewords_html truncatewords_html
@ -1902,6 +1904,8 @@ For example::
If ``value`` is ``"<p>Joel is a slug</p>"``, the output will be If ``value`` is ``"<p>Joel is a slug</p>"``, the output will be
``"<p>Joel is ...</p>"``. ``"<p>Joel is ...</p>"``.
Newlines in the HTML content will be preserved.
.. templatefilter:: unordered_list .. templatefilter:: unordered_list
unordered_list unordered_list

View File

@ -71,8 +71,9 @@ processing to convert them to Python objects. If you know you don't need those
particular fields, you can now tell Django not to retrieve them from the particular fields, you can now tell Django not to retrieve them from the
database. database.
You'll do this with the :ref:`new queryset methods <queryset-defer>` You'll do this with the new queryset methods
``defer()`` and ``only()``. :meth:`~django.db.models.QuerySet.defer` and
:meth:`~django.db.models.QuerySet.only`.
New admin features New admin features
------------------ ------------------

View File

@ -258,8 +258,9 @@ processing to convert them to Python objects. If you know you don't need those
particular fields, you can now tell Django not to retrieve them from the particular fields, you can now tell Django not to retrieve them from the
database. database.
You'll do this with the :ref:`new queryset methods <queryset-defer>` You'll do this with the new queryset methods
``defer()`` and ``only()``. :meth:`~django.db.models.QuerySet.defer` and
:meth:`~django.db.models.QuerySet.only`.
Testing improvements Testing improvements
-------------------- --------------------

View File

@ -18,6 +18,31 @@ fixes and an easy upgrade path from Django 1.2.
Backwards-incompatible changes in 1.3 Backwards-incompatible changes in 1.3
===================================== =====================================
PasswordInput default rendering behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prior to Django 1.3, a :class:`~django.forms.PasswordInput` would render
data values like any other form. If a form submission raised an error,
the password that was submitted would be reflected to the client as form
data populating the form for resubmission.
This had the potential to leak passwords, as any failed password
attempt would cause the password that was typed to be sent back to the
client.
In Django 1.3, the default behavior of
:class:`~django.forms.PasswordInput` is to suppress the display of
password values. This change doesn't alter the way form data is
validated or handled. It only affects the user experience with
passwords on a form when they make an error submitting form data (such
as on unsuccessful logins, or when completing a registration form).
If you want restore the pre-Django 1.3 behavior, you need to pass in a
custom widget to your form that sets the ``render_value`` argument::
class LoginForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.PasswordField(widget=forms.PasswordInput(render_value=True))
Features deprecated in 1.3 Features deprecated in 1.3

View File

@ -898,8 +898,9 @@ includes a few other useful built-in views located in
.. function:: views.password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect]) .. function:: views.password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect])
Allows a user to reset their password, and sends them the new password Allows a user to reset their password by generating a one-time use link
in an e-mail. that can be used to reset the password, and sending that link to the
user's registered e-mail address.
**Optional arguments:** **Optional arguments:**
@ -1005,8 +1006,8 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
.. class:: PasswordResetForm .. class:: PasswordResetForm
A form for resetting a user's password and e-mailing the new password to A form for generating and e-mailing a one-time use link to reset a
them. user's password.
.. class:: SetPasswordForm .. class:: SetPasswordForm

View File

@ -353,7 +353,7 @@ without any harmful effects, since that is already playing a role in the
query. query.
This behavior is the same as that noted in the queryset documentation for This behavior is the same as that noted in the queryset documentation for
:ref:`distinct() <queryset-distinct>` and the general rule is the same: :meth:`~django.db.models.QuerySet.distinct` and the general rule is the same:
normally you won't want extra columns playing a part in the result, so clear normally you won't want extra columns playing a part in the result, so clear
out the ordering, or at least make sure it's restricted only to those fields out the ordering, or at least make sure it's restricted only to those fields
you also select in a ``values()`` call. you also select in a ``values()`` call.

View File

@ -353,7 +353,7 @@ For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
As with :class:`~django.db.models.ForeignKey`, you can also create As with :class:`~django.db.models.ForeignKey`, you can also create
:ref:`recursive relationships <recursive-relationships>` (an object with a :ref:`recursive relationships <recursive-relationships>` (an object with a
many-to-one relationship to itself) and :ref:`relationships to models not yet many-to-many relationship to itself) and :ref:`relationships to models not yet
defined <lazy-relationships>`; see :ref:`the model field reference defined <lazy-relationships>`; see :ref:`the model field reference
<ref-manytomany>` for details. <ref-manytomany>` for details.

View File

@ -101,7 +101,7 @@ Use ``iterator()``
When you have a lot of objects, the caching behaviour of the ``QuerySet`` can When you have a lot of objects, the caching behaviour of the ``QuerySet`` can
cause a large amount of memory to be used. In this case, cause a large amount of memory to be used. In this case,
:ref:`QuerySet.iterator() <queryset-iterator>` may help. :meth:`~django.db.models.QuerySet.iterator()` may help.
Do database work in the database rather than in Python Do database work in the database rather than in Python
====================================================== ======================================================
@ -121,9 +121,9 @@ If these aren't enough to generate the SQL you need:
Use ``QuerySet.extra()`` Use ``QuerySet.extra()``
------------------------ ------------------------
A less portable but more powerful method is :ref:`QuerySet.extra() A less portable but more powerful method is
<queryset-extra>`, which allows some SQL to be explicitly added to the query. :meth:`~django.db.models.QuerySet.extra()`, which allows some SQL to be
If that still isn't powerful enough: explicitly added to the query. If that still isn't powerful enough:
Use raw SQL Use raw SQL
----------- -----------
@ -159,7 +159,7 @@ Use ``QuerySet.values()`` and ``values_list()``
----------------------------------------------- -----------------------------------------------
When you just want a dict/list of values, and don't need ORM model objects, make When you just want a dict/list of values, and don't need ORM model objects, make
appropriate usage of :ref:`QuerySet.values() <queryset-values>`. appropriate usage of :meth:`~django.db.models.QuerySet.values()`.
These can be useful for replacing model objects in template code - as long as These can be useful for replacing model objects in template code - as long as
the dicts you supply have the same attributes as those used in the template, you the dicts you supply have the same attributes as those used in the template, you
are fine. are fine.
@ -167,7 +167,8 @@ are fine.
Use ``QuerySet.defer()`` and ``only()`` Use ``QuerySet.defer()`` and ``only()``
--------------------------------------- ---------------------------------------
Use :ref:`defer() and only() <queryset-defer>` if there are database columns you Use :meth:`~django.db.models.QuerySet.defer()` and
:meth:`~django.db.models.QuerySet.only()` if there are database columns you
know that you won't need (or won't need in most cases) to avoid loading know that you won't need (or won't need in most cases) to avoid loading
them. Note that if you *do* use them, the ORM will have to go and get them in a them. Note that if you *do* use them, the ORM will have to go and get them in a
separate query, making this a pessimization if you use it inappropriately. separate query, making this a pessimization if you use it inappropriately.

View File

@ -116,9 +116,9 @@ Fields may also be left out::
>>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person') >>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person')
The ``Person`` objects returned by this query will be :ref:`deferred The ``Person`` objects returned by this query will be deferred model instances
<queryset-defer>` model instances. This means that the fields that are omitted (see :meth:`~django.db.models.QuerySet.defer()`). This means that the fields
from the query will be loaded on demand. For example:: that are omitted from the query will be loaded on demand. For example::
>>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'): >>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'):
... print p.first_name, # This will be retrieved by the original query ... print p.first_name, # This will be retrieved by the original query

View File

@ -501,7 +501,7 @@ convenience that can be used during development.
Defining a custom e-mail backend Defining a custom e-mail backend
-------------------------------- --------------------------------
If you need to change how e-mails are send you can write your own e-mail If you need to change how e-mails are sent you can write your own e-mail
backend. The ``EMAIL_BACKEND`` setting in your settings file is then the backend. The ``EMAIL_BACKEND`` setting in your settings file is then the
Python import path for your backend class. Python import path for your backend class.

View File

@ -595,8 +595,8 @@ Alternatively, you can create a subclass that sets ``self.queryset`` in
class BaseAuthorFormSet(BaseModelFormSet): class BaseAuthorFormSet(BaseModelFormSet):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.queryset = Author.objects.filter(name__startswith='O')
super(BaseAuthorFormSet, self).__init__(*args, **kwargs) super(BaseAuthorFormSet, self).__init__(*args, **kwargs)
self.queryset = Author.objects.filter(name__startswith='O')
Then, pass your ``BaseAuthorFormSet`` class to the factory function:: Then, pass your ``BaseAuthorFormSet`` class to the factory function::

View File

@ -827,17 +827,80 @@ namespaces into URLs on specific application instances, according to the
resolve() resolve()
--------- ---------
The :func:`django.core.urlresolvers.resolve` function can be used for resolving The :func:`django.core.urlresolvers.resolve` function can be used for
URL paths to the corresponding view functions. It has the following signature: resolving URL paths to the corresponding view functions. It has the
following signature:
.. function:: resolve(path, urlconf=None) .. function:: resolve(path, urlconf=None)
``path`` is the URL path you want to resolve. As with ``reverse()`` above, you ``path`` is the URL path you want to resolve. As with
don't need to worry about the ``urlconf`` parameter. The function returns the :func:`~django.core.urlresolvers.reverse`, you don't need to
triple (view function, arguments, keyword arguments). worry about the ``urlconf`` parameter. The function returns a
:class:`django.core.urlresolvers.ResolverMatch` object that allows you
to access various meta-data about the resolved URL.
For example, it can be used for testing if a view would raise a ``Http404`` .. class:: ResolverMatch()
error before redirecting to it::
.. attribute:: ResolverMatch.func
The view function that would be used to serve the URL
.. attribute:: ResolverMatch.args
The arguments that would be passed to the view function, as
parsed from the URL.
.. attribute:: ResolverMatch.kwargs
The keyword arguments that would be passed to the view
function, as parsed from the URL.
.. attribute:: ResolverMatch.url_name
The name of the URL pattern that matches the URL.
.. attribute:: ResolverMatch.app_name
The application namespace for the URL pattern that matches the
URL.
.. attribute:: ResolverMatch.namespace
The instance namespace for the URL pattern that matches the
URL.
.. attribute:: ResolverMatch.namespaces
The list of individual namespace components in the full
instance namespace for the URL pattern that matches the URL.
i.e., if the namespace is ``foo:bar``, then namespaces will be
``[`foo`, `bar`]``.
A :class:`~django.core.urlresolvers.ResolverMatch` object can then be
interrogated to provide information about the URL pattern that matches
a URL::
# Resolve a URL
match = resolve('/some/path/')
# Print the URL pattern that matches the URL
print match.url_name
A :class:`~django.core.urlresolvers.ResolverMatch` object can also be
assigned to a triple::
func, args, kwargs = resolve('/some/path/')
.. versionchanged:: 1.3
Triple-assignment exists for backwards-compatibility. Prior to
Django 1.3, :func:`~django.core.urlresolvers.resolve` returned a
triple containing (view function, arguments, keyword arguments);
the :class:`~django.core.urlresolvers.ResolverMatch` object (as
well as the namespace and pattern information it provides) is not
available in earlier Django releases.
One possible use of :func:`~django.core.urlresolvers.resolve` would be
to testing if a view would raise a ``Http404`` error before
redirecting to it::
from urlparse import urlparse from urlparse import urlparse
from django.core.urlresolvers import resolve from django.core.urlresolvers import resolve
@ -858,6 +921,7 @@ error before redirecting to it::
return HttpResponseRedirect('/') return HttpResponseRedirect('/')
return response return response
permalink() permalink()
----------- -----------

View File

@ -569,7 +569,7 @@ function supports both positional and named interpolation:
object or associative array. For example:: object or associative array. For example::
d = { d = {
count: 10 count: 10,
total: 50 total: 50
}; };

View File

@ -338,7 +338,7 @@ example, ``(first name, last name)``. Then, when you call
``serializers.serialize()``, you provide a ``use_natural_keys=True`` ``serializers.serialize()``, you provide a ``use_natural_keys=True``
argument:: argument::
>>> serializers.serialize([book1, book2], format='json', indent=2, use_natural_keys=True) >>> serializers.serialize('json', [book1, book2], indent=2, use_natural_keys=True)
When ``use_natural_keys=True`` is specified, Django will use the When ``use_natural_keys=True`` is specified, Django will use the
``natural_key()`` method to serialize any reference to objects of the ``natural_key()`` method to serialize any reference to objects of the

View File

@ -1,4 +1,4 @@
[bdist_rpm] [bdist_rpm]
doc_files = docs examples extras AUTHORS INSTALL LICENSE README doc_files = docs extras AUTHORS INSTALL LICENSE README
install-script = scripts/rpm-install.sh install-script = scripts/rpm-install.sh

View File

@ -21,9 +21,14 @@ class TestCaseFixtureLoadingTests(TestCase):
]) ])
class FixtureLoadingTests(TestCase): class FixtureLoadingTests(TestCase):
def _dumpdata_assert(self, args, output, format='json', natural_keys=False): def _dumpdata_assert(self, args, output, format='json', natural_keys=False,
exclude_list=[]):
new_io = StringIO.StringIO() new_io = StringIO.StringIO()
management.call_command('dumpdata', *args, **{'format':format, 'stdout':new_io, 'use_natural_keys':natural_keys}) management.call_command('dumpdata', *args, **{'format':format,
'stdout':new_io,
'stderr':new_io,
'use_natural_keys':natural_keys,
'exclude': exclude_list})
command_output = new_io.getvalue().strip() command_output = new_io.getvalue().strip()
self.assertEqual(command_output, output) self.assertEqual(command_output, output)
@ -148,6 +153,48 @@ class FixtureLoadingTests(TestCase):
self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?> self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Artist formerly known as "Prince"</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="1" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Django Reinhardt</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="2" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Stephane Grappelli</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="3" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Artist formerly known as "Prince"</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="1" model="fixtures.book"><field type="CharField" name="name">Music for all ages</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"><object><natural>Artist formerly known as "Prince"</natural></object><object><natural>Django Reinhardt</natural></object></field></object></django-objects>""", format='xml', natural_keys=True) <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Artist formerly known as "Prince"</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="1" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Django Reinhardt</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="2" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Stephane Grappelli</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="3" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Artist formerly known as "Prince"</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="1" model="fixtures.book"><field type="CharField" name="name">Music for all ages</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"><object><natural>Artist formerly known as "Prince"</natural></object><object><natural>Django Reinhardt</natural></object></field></object></django-objects>""", format='xml', natural_keys=True)
def test_dumpdata_with_excludes(self):
# Load fixture1 which has a site, two articles, and a category
management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False)
# Excluding fixtures app should only leave sites
self._dumpdata_assert(
['sites', 'fixtures'],
'[{"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}]',
exclude_list=['fixtures'])
# Excluding fixtures.Article should leave fixtures.Category
self._dumpdata_assert(
['sites', 'fixtures'],
'[{"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]',
exclude_list=['fixtures.Article'])
# Excluding fixtures and fixtures.Article should be a no-op
self._dumpdata_assert(
['sites', 'fixtures'],
'[{"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]',
exclude_list=['fixtures.Article'])
# Excluding sites and fixtures.Article should only leave fixtures.Category
self._dumpdata_assert(
['sites', 'fixtures'],
'[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]',
exclude_list=['fixtures.Article', 'sites'])
# Excluding a bogus app should throw an error
self.assertRaises(SystemExit,
self._dumpdata_assert,
['fixtures', 'sites'],
'',
exclude_list=['foo_app'])
# Excluding a bogus model should throw an error
self.assertRaises(SystemExit,
self._dumpdata_assert,
['fixtures', 'sites'],
'',
exclude_list=['fixtures.FooModel'])
def test_compress_format_loading(self): def test_compress_format_loading(self):
# Load fixture 4 (compressed), using format specification # Load fixture 4 (compressed), using format specification
management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False) management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False)

View File

@ -554,7 +554,7 @@ fields with the 'choices' attribute are represented by a ChoiceField.
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
<option value="3">Third test</option> <option value="3">Third test</option>
</select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr> </select><br /><span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></td></tr>
You can restrict a form to a subset of the complete list of fields You can restrict a form to a subset of the complete list of fields
by providing a 'fields' argument. If you try to save a by providing a 'fields' argument. If you try to save a
@ -579,7 +579,7 @@ inserted as 'initial' data in each Field.
... model = Writer ... model = Writer
>>> f = RoykoForm(auto_id=False, instance=w) >>> f = RoykoForm(auto_id=False, instance=w)
>>> print f >>> print f
<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br />Use both first and last names.</td></tr> <tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>
>>> art = Article(headline='Test article', slug='test-article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.') >>> art = Article(headline='Test article', slug='test-article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.')
>>> art.save() >>> art.save()
@ -609,7 +609,7 @@ inserted as 'initial' data in each Field.
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
<option value="3">Third test</option> <option value="3">Third test</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
>>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': unicode(w_royko.pk), 'article': 'Hello.'}, instance=art) >>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': unicode(w_royko.pk), 'article': 'Hello.'}, instance=art)
>>> f.errors >>> f.errors
{} {}
@ -672,7 +672,7 @@ Add some categories and test the many-to-many form output.
<option value="1" selected="selected">Entertainment</option> <option value="1" selected="selected">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
<option value="3">Third test</option> <option value="3">Third test</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
Initial values can be provided for model forms Initial values can be provided for model forms
>>> f = TestArticleForm(auto_id=False, initial={'headline': 'Your headline here', 'categories': ['1','2']}) >>> f = TestArticleForm(auto_id=False, initial={'headline': 'Your headline here', 'categories': ['1','2']})
@ -696,7 +696,7 @@ Initial values can be provided for model forms
<option value="1" selected="selected">Entertainment</option> <option value="1" selected="selected">Entertainment</option>
<option value="2" selected="selected">It&#39;s a test</option> <option value="2" selected="selected">It&#39;s a test</option>
<option value="3">Third test</option> <option value="3">Third test</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
>>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', >>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04',
... 'writer': unicode(w_royko.pk), 'article': u'Hello.', 'categories': [u'1', u'2']}, instance=new_art) ... 'writer': unicode(w_royko.pk), 'article': u'Hello.', 'categories': [u'1', u'2']}, instance=new_art)
@ -812,7 +812,7 @@ the data in the database when the form is instantiated.
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
<option value="3">Third</option> <option value="3">Third</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
>>> Category.objects.create(name='Fourth', url='4th') >>> Category.objects.create(name='Fourth', url='4th')
<Category: Fourth> <Category: Fourth>
>>> Writer.objects.create(name='Carl Bernstein') >>> Writer.objects.create(name='Carl Bernstein')
@ -839,7 +839,7 @@ the data in the database when the form is instantiated.
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
<option value="3">Third</option> <option value="3">Third</option>
<option value="4">Fourth</option> <option value="4">Fourth</option>
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> </select> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></li>
# ModelChoiceField ############################################################ # ModelChoiceField ############################################################

View File

@ -10,6 +10,7 @@ from django.core.mail import EmailMessage
from django.db import models from django.db import models
from django import forms from django import forms
from django.forms.models import BaseModelFormSet from django.forms.models import BaseModelFormSet
from django.contrib.auth.models import User
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -579,6 +580,10 @@ class Pizza(models.Model):
class PizzaAdmin(admin.ModelAdmin): class PizzaAdmin(admin.ModelAdmin):
readonly_fields = ('toppings',) readonly_fields = ('toppings',)
class Album(models.Model):
owner = models.ForeignKey(User)
title = models.CharField(max_length=30)
admin.site.register(Article, ArticleAdmin) admin.site.register(Article, ArticleAdmin)
admin.site.register(CustomArticle, CustomArticleAdmin) admin.site.register(CustomArticle, CustomArticleAdmin)
admin.site.register(Section, save_as=True, inlines=[ArticleInline]) admin.site.register(Section, save_as=True, inlines=[ArticleInline])
@ -625,3 +630,4 @@ admin.site.register(Promo)
admin.site.register(ChapterXtra1) admin.site.register(ChapterXtra1)
admin.site.register(Pizza, PizzaAdmin) admin.site.register(Pizza, PizzaAdmin)
admin.site.register(Topping) admin.site.register(Topping)
admin.site.register(Album)

View File

@ -2113,11 +2113,9 @@ class ReadonlyTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/pizza/add/') response = self.client.get('/test_admin/admin/admin_views/pizza/add/')
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
class IncompleteFormTest(TestCase): class UserAdminTest(TestCase):
""" """
Tests validation of a ModelForm that doesn't explicitly have all data Tests user CRUD functionality.
corresponding to model fields. Model validation shouldn't fail
such a forms.
""" """
fixtures = ['admin-views-users.xml'] fixtures = ['admin-views-users.xml']
@ -2128,6 +2126,7 @@ class IncompleteFormTest(TestCase):
self.client.logout() self.client.logout()
def test_user_creation(self): def test_user_creation(self):
user_count = User.objects.count()
response = self.client.post('/test_admin/admin/auth/user/add/', { response = self.client.post('/test_admin/admin/auth/user/add/', {
'username': 'newuser', 'username': 'newuser',
'password1': 'newpassword', 'password1': 'newpassword',
@ -2136,6 +2135,7 @@ class IncompleteFormTest(TestCase):
}) })
new_user = User.objects.order_by('-id')[0] new_user = User.objects.order_by('-id')[0]
self.assertRedirects(response, '/test_admin/admin/auth/user/%s/' % new_user.pk) self.assertRedirects(response, '/test_admin/admin/auth/user/%s/' % new_user.pk)
self.assertEquals(User.objects.count(), user_count + 1)
self.assertNotEquals(new_user.password, UNUSABLE_PASSWORD) self.assertNotEquals(new_user.password, UNUSABLE_PASSWORD)
def test_password_mismatch(self): def test_password_mismatch(self):
@ -2149,3 +2149,24 @@ class IncompleteFormTest(TestCase):
self.assert_('password' not in adminform.form.errors) self.assert_('password' not in adminform.form.errors)
self.assertEquals(adminform.form.errors['password2'], self.assertEquals(adminform.form.errors['password2'],
[u"The two password fields didn't match."]) [u"The two password fields didn't match."])
def test_user_fk_popup(self):
response = self.client.get('/test_admin/admin/admin_views/album/add/')
self.failUnlessEqual(response.status_code, 200)
self.assertContains(response, '/test_admin/admin/auth/user/add')
self.assertContains(response, 'class="add-another" id="add_id_owner" onclick="return showAddAnotherPopup(this);"')
response = self.client.get('/test_admin/admin/auth/user/add/?_popup=1')
self.assertNotContains(response, 'name="_continue"')
def test_user_add_another(self):
user_count = User.objects.count()
response = self.client.post('/test_admin/admin/auth/user/add/', {
'username': 'newuser',
'password1': 'newpassword',
'password2': 'newpassword',
'_addanother': '1',
})
new_user = User.objects.order_by('-id')[0]
self.assertRedirects(response, '/test_admin/admin/auth/user/add/')
self.assertEquals(User.objects.count(), user_count + 1)
self.assertNotEquals(new_user.password, UNUSABLE_PASSWORD)

View File

@ -705,13 +705,13 @@ Form.clean() is required to return a dictionary of all clean data.
>>> print f.as_table() >>> print f.as_table()
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr> <tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr> <tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr> <tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
>>> print f.as_ul() >>> print f.as_ul()
<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li> <li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li>
<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li> <li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
<li>Password1: <input type="password" name="password1" value="foo" /></li> <li>Password1: <input type="password" name="password1" /></li>
<li>Password2: <input type="password" name="password2" value="bar" /></li> <li>Password2: <input type="password" name="password2" /></li>
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
>>> f.errors >>> f.errors
{} {}
@ -1258,20 +1258,20 @@ to a Field class. This help text is displayed when a Form is rendered.
... password = CharField(widget=PasswordInput, help_text='Choose wisely.') ... password = CharField(widget=PasswordInput, help_text='Choose wisely.')
>>> p = UserRegistration(auto_id=False) >>> p = UserRegistration(auto_id=False)
>>> print p.as_ul() >>> print p.as_ul()
<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li> <li>Username: <input type="text" name="username" maxlength="10" /> <span class="helptext">e.g., user@example.com</span></li>
<li>Password: <input type="password" name="password" /> Choose wisely.</li> <li>Password: <input type="password" name="password" /> <span class="helptext">Choose wisely.</span></li>
>>> print p.as_p() >>> print p.as_p()
<p>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p> <p>Username: <input type="text" name="username" maxlength="10" /> <span class="helptext">e.g., user@example.com</span></p>
<p>Password: <input type="password" name="password" /> Choose wisely.</p> <p>Password: <input type="password" name="password" /> <span class="helptext">Choose wisely.</span></p>
>>> print p.as_table() >>> print p.as_table()
<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr> <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br /><span class="helptext">e.g., user@example.com</span></td></tr>
<tr><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr> <tr><th>Password:</th><td><input type="password" name="password" /><br /><span class="helptext">Choose wisely.</span></td></tr>
The help text is displayed whether or not data is provided for the form. The help text is displayed whether or not data is provided for the form.
>>> p = UserRegistration({'username': u'foo'}, auto_id=False) >>> p = UserRegistration({'username': u'foo'}, auto_id=False)
>>> print p.as_ul() >>> print p.as_ul()
<li>Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li> <li>Username: <input type="text" name="username" value="foo" maxlength="10" /> <span class="helptext">e.g., user@example.com</span></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li> <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> <span class="helptext">Choose wisely.</span></li>
help_text is not displayed for hidden fields. It can be used for documentation help_text is not displayed for hidden fields. It can be used for documentation
purposes, though. purposes, though.
@ -1281,7 +1281,7 @@ purposes, though.
... next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination') ... next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
>>> p = UserRegistration(auto_id=False) >>> p = UserRegistration(auto_id=False)
>>> print p.as_ul() >>> print p.as_ul()
<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li> <li>Username: <input type="text" name="username" maxlength="10" /> <span class="helptext">e.g., user@example.com</span></li>
<li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li> <li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>
Help text can include arbitrary Unicode characters. Help text can include arbitrary Unicode characters.
@ -1289,7 +1289,7 @@ Help text can include arbitrary Unicode characters.
... username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ') ... username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ')
>>> p = UserRegistration(auto_id=False) >>> p = UserRegistration(auto_id=False)
>>> p.as_ul() >>> p.as_ul()
u'<li>Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>' u'<li>Username: <input type="text" name="username" maxlength="10" /> <span class="helptext">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</span></li>'
# Subclassing forms ########################################################### # Subclassing forms ###########################################################
@ -1589,8 +1589,8 @@ Case 2: POST with erroneous data (a redisplayed form, with errors).
<table> <table>
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr> <tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters (it has 23).</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr> <tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr> <tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
</table> </table>
<input type="submit" /> <input type="submit" />
</form> </form>
@ -1719,8 +1719,8 @@ the list of errors is empty). You can also use it in {% if %} statements.
>>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)})) >>> print t.render(Context({'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)}))
<form action=""> <form action="">
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p> <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
<p><label>Password: <input type="password" name="password1" value="foo" /></label></p> <p><label>Password: <input type="password" name="password1" /></label></p>
<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p> <p><label>Password (again): <input type="password" name="password2" /></label></p>
<input type="submit" /> <input type="submit" />
</form> </form>
>>> t = Template('''<form action=""> >>> t = Template('''<form action="">
@ -1734,8 +1734,8 @@ the list of errors is empty). You can also use it in {% if %} statements.
<form action=""> <form action="">
<ul class="errorlist"><li>Please make sure your passwords match.</li></ul> <ul class="errorlist"><li>Please make sure your passwords match.</li></ul>
<p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p> <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" /></label></p>
<p><label>Password: <input type="password" name="password1" value="foo" /></label></p> <p><label>Password: <input type="password" name="password1" /></label></p>
<p><label>Password (again): <input type="password" name="password2" value="bar" /></label></p> <p><label>Password (again): <input type="password" name="password2" /></label></p>
<input type="submit" /> <input type="submit" />
</form> </form>

View File

@ -0,0 +1,894 @@
from datetime import time, date, datetime
from unittest import TestCase
from django import forms
from django.conf import settings
from django.utils.translation import activate, deactivate
class LocalizedTimeTests(TestCase):
def setUp(self):
self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
self.old_USE_L10N = settings.USE_L10N
settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
settings.USE_L10N = True
activate('de')
def tearDown(self):
settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
settings.USE_L10N = self.old_USE_L10N
deactivate()
def test_timeField(self):
"TimeFields can parse dates in the default format"
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30:05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '13:30:05')
# Parse a time in a valid, but non-default format, get a parsed result
result = f.clean('13:30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_localized_timeField(self):
"Localized TimeFields act as unlocalized widgets"
f = forms.TimeField(localize=True)
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30:05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_timeField_with_inputformat(self):
"TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30.05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_localized_timeField_with_inputformat(self):
"Localized TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30.05')
self.assertEqual(result, time(13,30,5))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
class CustomTimeInputFormatsTests(TestCase):
def setUp(self):
self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
def tearDown(self):
settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
def test_timeField(self):
"TimeFields can parse dates in the default format"
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30:05 PM')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '01:30:05 PM')
# Parse a time in a valid, but non-default format, get a parsed result
result = f.clean('1:30 PM')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM")
def test_localized_timeField(self):
"Localized TimeFields act as unlocalized widgets"
f = forms.TimeField(localize=True)
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30:05 PM')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '01:30:05 PM')
# Parse a time in a valid format, get a parsed result
result = f.clean('01:30 PM')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM")
def test_timeField_with_inputformat(self):
"TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30.05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM")
def test_localized_timeField_with_inputformat(self):
"Localized TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30.05')
self.assertEqual(result, time(13,30,5))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid format, get a parsed result
result = f.clean('13.30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM")
class SimpleTimeFormatTests(TestCase):
def test_timeField(self):
"TimeFields can parse dates in the default format"
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30:05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid, but non-default format, get a parsed result
result = f.clean('13:30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_localized_timeField(self):
"Localized TimeFields in a non-localized environment act as unlocalized widgets"
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM')
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30:05')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
result = f.clean('13:30')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_timeField_with_inputformat(self):
"TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"])
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30:05 PM')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30 PM')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
def test_localized_timeField_with_inputformat(self):
"Localized TimeFields with manually specified input formats can accept those formats"
f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"], localize=True)
# Parse a time in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05')
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30:05 PM')
self.assertEqual(result, time(13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
result = f.clean('1:30 PM')
self.assertEqual(result, time(13,30,0))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "13:30:00")
class LocalizedDateTests(TestCase):
def setUp(self):
self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
self.old_USE_L10N = settings.USE_L10N
settings.DATE_INPUT_FORMATS = ["%d/%m/%Y", "%d-%m-%Y"]
settings.USE_L10N = True
activate('de')
def tearDown(self):
settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
settings.USE_L10N = self.old_USE_L10N
deactivate()
def test_dateField(self):
"DateFields can parse dates in the default format"
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010')
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('21.12.10')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_localized_dateField(self):
"Localized DateFields act as unlocalized widgets"
f = forms.DateField(localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.10')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_dateField_with_inputformat(self):
"DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_localized_dateField_with_inputformat(self):
"Localized DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
self.assertRaises(forms.ValidationError, f.clean, '21/12/2010')
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010')
self.assertEqual(result, date(2010,12,21))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
class CustomDateInputFormatsTests(TestCase):
def setUp(self):
self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
settings.DATE_INPUT_FORMATS = ["%d.%m.%Y", "%d-%m-%Y"]
def tearDown(self):
settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
def test_dateField(self):
"DateFields can parse dates in the default format"
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010')
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('21-12-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_localized_dateField(self):
"Localized DateFields act as unlocalized widgets"
f = forms.DateField(localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21-12-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_dateField_with_inputformat(self):
"DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
def test_localized_dateField_with_inputformat(self):
"Localized DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010')
self.assertEqual(result, date(2010,12,21))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
class SimpleDateFormatTests(TestCase):
def test_dateField(self):
"DateFields can parse dates in the default format"
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('2010-12-21')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('12/21/2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
def test_localized_dateField(self):
"Localized DateFields in a non-localized environment act as unlocalized widgets"
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('2010-12-21')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
result = f.clean('12/21/2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
def test_dateField_with_inputformat(self):
"DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
result = f.clean('21-12-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
def test_localized_dateField_with_inputformat(self):
"Localized DateFields with manually specified input formats can accept those formats"
f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
result = f.clean('21-12-2010')
self.assertEqual(result, date(2010,12,21))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
class LocalizedDateTimeTests(TestCase):
def setUp(self):
self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
self.old_USE_L10N = settings.USE_L10N
settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
settings.USE_L10N = True
activate('de')
def tearDown(self):
settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
settings.USE_L10N = self.old_USE_L10N
deactivate()
def test_dateTimeField(self):
"DateTimeFields can parse dates in the default format"
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010 13:30:05')
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('21.12.2010 13:30')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:00")
def test_localized_dateTimeField(self):
"Localized DateTimeFields act as unlocalized widgets"
f = forms.DateTimeField(localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '21.12.2010 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('21.12.2010 13:30')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:00")
def test_dateTimeField_with_inputformat(self):
"DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05 13:30:05')
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('13.30.05 12.21.2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid format, get a parsed result
result = f.clean('13.30 12-21-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:00")
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
self.assertRaises(forms.ValidationError, f.clean, '1:30:05 PM 21/12/2010')
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('13.30.05 12.21.2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid format, get a parsed result
result = f.clean('13.30 12-21-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010 13:30:00")
class CustomDateTimeInputFormatsTests(TestCase):
def setUp(self):
self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
def tearDown(self):
settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
def test_dateTimeField(self):
"DateTimeFields can parse dates in the default format"
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30:05 PM 21/12/2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip
text = f.widget._format_value(result)
self.assertEqual(text, '01:30:05 PM 21/12/2010')
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('1:30 PM 21-12-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM 21/12/2010")
def test_localized_dateTimeField(self):
"Localized DateTimeFields act as unlocalized widgets"
f = forms.DateTimeField(localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30:05 PM 21/12/2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, '01:30:05 PM 21/12/2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30 PM 21-12-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM 21/12/2010")
def test_dateTimeField_with_inputformat(self):
"DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010 13:30')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM 21/12/2010")
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('12.21.2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# # Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
result = f.clean('12-21-2010 13:30')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "01:30:00 PM 21/12/2010")
class SimpleDateTimeFormatTests(TestCase):
def test_dateTimeField(self):
"DateTimeFields can parse dates in the default format"
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('2010-12-21 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid, but non-default format, get a parsed result
result = f.clean('12/21/2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
def test_localized_dateTimeField(self):
"Localized DateTimeFields in a non-localized environment act as unlocalized widgets"
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '13:30:05 21.12.2010')
# Parse a date in a valid format, get a parsed result
result = f.clean('2010-12-21 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
result = f.clean('12/21/2010 13:30:05')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
def test_dateTimeField_with_inputformat(self):
"DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"])
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30:05 PM 21.12.2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30 PM 21-12-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:00")
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
self.assertRaises(forms.ValidationError, f.clean, '2010-12-21 13:30:05')
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30:05 PM 21.12.2010')
self.assertEqual(result, datetime(2010,12,21,13,30,5))
# Check that the parsed result does a round trip to the same format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
result = f.clean('1:30 PM 21-12-2010')
self.assertEqual(result, datetime(2010,12,21,13,30))
# Check that the parsed result does a round trip to default format
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21 13:30:00")

View File

@ -50,7 +50,7 @@ u''
## AUPhoneNumberField ######################################################## ## AUPhoneNumberField ########################################################
A field that accepts a 10 digit Australian phone number. A field that accepts a 10 digit Australian phone number.
llows spaces and parentheses around area code. Allows spaces and parentheses around area code.
>>> from django.contrib.localflavor.au.forms import AUPhoneNumberField >>> from django.contrib.localflavor.au.forms import AUPhoneNumberField
>>> f = AUPhoneNumberField() >>> f = AUPhoneNumberField()

View File

@ -41,6 +41,8 @@ from fields import FieldsTests
from validators import TestFieldWithValidators from validators import TestFieldWithValidators
from widgets import WidgetTests from widgets import WidgetTests
from input_formats import *
__test__ = { __test__ = {
'extra_tests': extra_tests, 'extra_tests': extra_tests,
'form_tests': form_tests, 'form_tests': form_tests,

View File

@ -62,6 +62,17 @@ u'<input type="text" class="special" name="email" />'
u'<input type="password" name="email" />' u'<input type="password" name="email" />'
>>> w.render('email', None) >>> w.render('email', None)
u'<input type="password" name="email" />' u'<input type="password" name="email" />'
>>> w.render('email', 'secret')
u'<input type="password" name="email" />'
The render_value argument lets you specify whether the widget should render
its value. For security reasons, this is off by default.
>>> w = PasswordInput(render_value=True)
>>> w.render('email', '')
u'<input type="password" name="email" />'
>>> w.render('email', None)
u'<input type="password" name="email" />'
>>> w.render('email', 'test@example.com') >>> w.render('email', 'test@example.com')
u'<input type="password" name="email" value="test@example.com" />' u'<input type="password" name="email" value="test@example.com" />'
>>> w.render('email', 'some "quoted" & ampersanded value') >>> w.render('email', 'some "quoted" & ampersanded value')
@ -70,36 +81,20 @@ u'<input type="password" name="email" value="some &quot;quoted&quot; &amp; amper
u'<input type="password" name="email" value="test@example.com" class="fun" />' u'<input type="password" name="email" value="test@example.com" class="fun" />'
You can also pass 'attrs' to the constructor: You can also pass 'attrs' to the constructor:
>>> w = PasswordInput(attrs={'class': 'fun'}) >>> w = PasswordInput(attrs={'class': 'fun'}, render_value=True)
>>> w.render('email', '') >>> w.render('email', '')
u'<input type="password" class="fun" name="email" />' u'<input type="password" class="fun" name="email" />'
>>> w.render('email', 'foo@example.com') >>> w.render('email', 'foo@example.com')
u'<input type="password" class="fun" value="foo@example.com" name="email" />' u'<input type="password" class="fun" value="foo@example.com" name="email" />'
'attrs' passed to render() get precedence over those passed to the constructor: 'attrs' passed to render() get precedence over those passed to the constructor:
>>> w = PasswordInput(attrs={'class': 'pretty'}) >>> w = PasswordInput(attrs={'class': 'pretty'}, render_value=True)
>>> w.render('email', '', attrs={'class': 'special'}) >>> w.render('email', '', attrs={'class': 'special'})
u'<input type="password" class="special" name="email" />' u'<input type="password" class="special" name="email" />'
>>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}) >>> w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
u'<input type="password" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />' u'<input type="password" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" name="email" />'
The render_value argument lets you specify whether the widget should render
its value. You may want to do this for security reasons.
>>> w = PasswordInput(render_value=True)
>>> w.render('email', 'secret')
u'<input type="password" name="email" value="secret" />'
>>> w = PasswordInput(render_value=False)
>>> w.render('email', '')
u'<input type="password" name="email" />'
>>> w.render('email', None)
u'<input type="password" name="email" />'
>>> w.render('email', 'secret')
u'<input type="password" name="email" />'
>>> w = PasswordInput(attrs={'class': 'fun'}, render_value=False)
>>> w.render('email', 'secret')
u'<input type="password" class="fun" name="email" />'
# HiddenInput Widget ############################################################ # HiddenInput Widget ############################################################
>>> w = HiddenInput() >>> w = HiddenInput()

View File

@ -1,8 +0,0 @@
from django.db import models
from django.contrib.localflavor.us.models import USStateField
class Place(models.Model):
state = USStateField(blank=True)
state_req = USStateField()
state_default = USStateField(default="CA", blank=True)
name = models.CharField(max_length=20)

View File

@ -1,83 +1,5 @@
import unittest
from django.test import TestCase from django.test import TestCase
from models import Place
from forms import PlaceForm
class USLocalflavorTests(TestCase): # just import your tests here
def setUp(self): from us.tests import *
self.form = PlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})
def test_get_display_methods(self):
"""Test that the get_*_display() methods are added to the model instances."""
place = self.form.save()
self.assertEqual(place.get_state_display(), 'Georgia')
self.assertEqual(place.get_state_req_display(), 'North Carolina')
def test_required(self):
"""Test that required USStateFields throw appropriate errors."""
form = PlaceForm({'state':'GA', 'name':'Place in GA'})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['state_req'], [u'This field is required.'])
def test_field_blank_option(self):
"""Test that the empty option is there."""
state_select_html = """\
<select name="state" id="id_state">
<option value="">---------</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District of Columbia</option>
<option value="FL">Florida</option>
<option value="GA" selected="selected">Georgia</option>
<option value="GU">Guam</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="MP">Northern Mariana Islands</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="PR">Puerto Rico</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VI">Virgin Islands</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>"""
self.assertEqual(str(self.form['state']), state_select_html)

View File

@ -1,7 +1,7 @@
from django.forms import ModelForm from django.forms import ModelForm
from models import Place from models import USPlace
class PlaceForm(ModelForm): class USPlaceForm(ModelForm):
"""docstring for PlaceForm""" """docstring for PlaceForm"""
class Meta: class Meta:
model = Place model = USPlace

View File

@ -0,0 +1,13 @@
from django.db import models
from django.contrib.localflavor.us.models import USStateField
# When creating models you need to remember to add a app_label as
# 'localflavor', so your model can be found
class USPlace(models.Model):
state = USStateField(blank=True)
state_req = USStateField()
state_default = USStateField(default="CA", blank=True)
name = models.CharField(max_length=20)
class Meta:
app_label = 'localflavor'

View File

@ -0,0 +1,82 @@
from django.test import TestCase
from forms import USPlaceForm
class USLocalflavorTests(TestCase):
def setUp(self):
self.form = USPlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})
def test_get_display_methods(self):
"""Test that the get_*_display() methods are added to the model instances."""
place = self.form.save()
self.assertEqual(place.get_state_display(), 'Georgia')
self.assertEqual(place.get_state_req_display(), 'North Carolina')
def test_required(self):
"""Test that required USStateFields throw appropriate errors."""
form = USPlaceForm({'state':'GA', 'name':'Place in GA'})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['state_req'], [u'This field is required.'])
def test_field_blank_option(self):
"""Test that the empty option is there."""
state_select_html = """\
<select name="state" id="id_state">
<option value="">---------</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District of Columbia</option>
<option value="FL">Florida</option>
<option value="GA" selected="selected">Georgia</option>
<option value="GU">Guam</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="MP">Northern Mariana Islands</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="PR">Puerto Rico</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VI">Virgin Islands</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>"""
self.assertEqual(str(self.form['state']), state_select_html)

Some files were not shown because too many files have changed in this diff Show More