1
0
mirror of https://github.com/django/django.git synced 2025-07-03 17:29:12 +00:00

newforms-admin: Merged from trunk up to [7917].

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7922 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Brian Rosner 2008-07-14 05:04:57 +00:00
parent f3cda0b77a
commit 2624f4ea56
34 changed files with 503 additions and 240 deletions

View File

@ -52,7 +52,7 @@ answer newbie questions, and generally made Django that much better:
andy@jadedplanet.net andy@jadedplanet.net
Fabrice Aneche <akh@nobugware.com> Fabrice Aneche <akh@nobugware.com>
ant9000@netwise.it ant9000@netwise.it
Florian Apolloner Florian Apolloner <florian@apolloner.eu>
arien <regexbot@gmail.com> arien <regexbot@gmail.com>
David Ascher <http://ascher.ca/> David Ascher <http://ascher.ca/>
Jökull Sólberg Auðunsson <jokullsolberg@gmail.com> Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>

View File

@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Django vSVN\n" "Project-Id-Version: Django vSVN\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-02 18:40+0200\n" "POT-Creation-Date: 2008-07-12 20:30+0200\n"
"PO-Revision-Date: 2008-05-18 19:13+0200\n" "PO-Revision-Date: 2008-07-12 20:45+0200\n"
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n" "Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
"Language-Team: Italiano\n" "Language-Team: Italiano\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -16,191 +16,199 @@ msgstr ""
"X-Generator: KBabel 1.11.4\n" "X-Generator: KBabel 1.11.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: conf/global_settings.py:43 #: conf/global_settings.py:44
msgid "Arabic" msgid "Arabic"
msgstr "Arabo" msgstr "Arabo"
#: conf/global_settings.py:44 #: conf/global_settings.py:45
msgid "Bengali" msgid "Bengali"
msgstr "Bengali" msgstr "Bengali"
#: conf/global_settings.py:45 #: conf/global_settings.py:46
msgid "Bulgarian" msgid "Bulgarian"
msgstr "Bulgaro" msgstr "Bulgaro"
#: conf/global_settings.py:46 #: conf/global_settings.py:47
msgid "Catalan" msgid "Catalan"
msgstr "Catalano" msgstr "Catalano"
#: conf/global_settings.py:47 #: conf/global_settings.py:48
msgid "Czech" msgid "Czech"
msgstr "Ceco" msgstr "Ceco"
#: conf/global_settings.py:48 #: conf/global_settings.py:49
msgid "Welsh" msgid "Welsh"
msgstr "Gallese" msgstr "Gallese"
#: conf/global_settings.py:49 #: conf/global_settings.py:50
msgid "Danish" msgid "Danish"
msgstr "Danese" msgstr "Danese"
#: conf/global_settings.py:50 #: conf/global_settings.py:51
msgid "German" msgid "German"
msgstr "Tedesco" msgstr "Tedesco"
#: conf/global_settings.py:51 #: conf/global_settings.py:52
msgid "Greek" msgid "Greek"
msgstr "Greco" msgstr "Greco"
#: conf/global_settings.py:52 #: conf/global_settings.py:53
msgid "English" msgid "English"
msgstr "Inglese" msgstr "Inglese"
#: conf/global_settings.py:53 #: conf/global_settings.py:54
msgid "Spanish" msgid "Spanish"
msgstr "Spagnolo" msgstr "Spagnolo"
#: conf/global_settings.py:54 #: conf/global_settings.py:55
msgid "Estonian"
msgstr "Estone"
#: conf/global_settings.py:56
msgid "Argentinean Spanish" msgid "Argentinean Spanish"
msgstr "Spagnolo argentino" msgstr "Spagnolo argentino"
#: conf/global_settings.py:55 #: conf/global_settings.py:57
msgid "Basque" msgid "Basque"
msgstr "Basco" msgstr "Basco"
#: conf/global_settings.py:56 #: conf/global_settings.py:58
msgid "Persian" msgid "Persian"
msgstr "Persiano" msgstr "Persiano"
#: conf/global_settings.py:57 #: conf/global_settings.py:59
msgid "Finnish" msgid "Finnish"
msgstr "Finlandese" msgstr "Finlandese"
#: conf/global_settings.py:58 #: conf/global_settings.py:60
msgid "French" msgid "French"
msgstr "Francese" msgstr "Francese"
#: conf/global_settings.py:59 #: conf/global_settings.py:61
msgid "Irish" msgid "Irish"
msgstr "Irlandese" msgstr "Irlandese"
#: conf/global_settings.py:60 #: conf/global_settings.py:62
msgid "Galician" msgid "Galician"
msgstr "Galiziano" msgstr "Galiziano"
#: conf/global_settings.py:61 #: conf/global_settings.py:63
msgid "Hungarian" msgid "Hungarian"
msgstr "Ungherese" msgstr "Ungherese"
#: conf/global_settings.py:62 #: conf/global_settings.py:64
msgid "Hebrew" msgid "Hebrew"
msgstr "Ebraico" msgstr "Ebraico"
#: conf/global_settings.py:63 #: conf/global_settings.py:65
msgid "Croatian" msgid "Croatian"
msgstr "Croato" msgstr "Croato"
#: conf/global_settings.py:64 #: conf/global_settings.py:66
msgid "Icelandic" msgid "Icelandic"
msgstr "Islandese" msgstr "Islandese"
#: conf/global_settings.py:65 #: conf/global_settings.py:67
msgid "Italian" msgid "Italian"
msgstr "Italiano" msgstr "Italiano"
#: conf/global_settings.py:66 #: conf/global_settings.py:68
msgid "Japanese" msgid "Japanese"
msgstr "Giapponese" msgstr "Giapponese"
#: conf/global_settings.py:67 #: conf/global_settings.py:69
msgid "Georgian" msgid "Georgian"
msgstr "Georgiano" msgstr "Georgiano"
#: conf/global_settings.py:68 #: conf/global_settings.py:70
msgid "Korean" msgid "Korean"
msgstr "Coreano" msgstr "Coreano"
#: conf/global_settings.py:69 #: conf/global_settings.py:71
msgid "Khmer" msgid "Khmer"
msgstr "Khmer" msgstr "Khmer"
#: conf/global_settings.py:70 #: conf/global_settings.py:72
msgid "Kannada" msgid "Kannada"
msgstr "Kannada" msgstr "Kannada"
#: conf/global_settings.py:71 #: conf/global_settings.py:73
msgid "Latvian" msgid "Latvian"
msgstr "Lettone" msgstr "Lettone"
#: conf/global_settings.py:72 #: conf/global_settings.py:74
msgid "Lithuanian"
msgstr "Lituano"
#: conf/global_settings.py:75
msgid "Macedonian" msgid "Macedonian"
msgstr "Macedone" msgstr "Macedone"
#: conf/global_settings.py:73 #: conf/global_settings.py:76
msgid "Dutch" msgid "Dutch"
msgstr "Olandese" msgstr "Olandese"
#: conf/global_settings.py:74 #: conf/global_settings.py:77
msgid "Norwegian" msgid "Norwegian"
msgstr "Norvegese" msgstr "Norvegese"
#: conf/global_settings.py:75 #: conf/global_settings.py:78
msgid "Polish" msgid "Polish"
msgstr "Polacco" msgstr "Polacco"
#: conf/global_settings.py:76 #: conf/global_settings.py:79
msgid "Portugese" msgid "Portugese"
msgstr "Portoghese" msgstr "Portoghese"
#: conf/global_settings.py:77 #: conf/global_settings.py:80
msgid "Brazilian Portuguese" msgid "Brazilian Portuguese"
msgstr "Brasiliano Portoghese" msgstr "Brasiliano Portoghese"
#: conf/global_settings.py:78 #: conf/global_settings.py:81
msgid "Romanian" msgid "Romanian"
msgstr "Rumeno" msgstr "Rumeno"
#: conf/global_settings.py:79 #: conf/global_settings.py:82
msgid "Russian" msgid "Russian"
msgstr "Russo" msgstr "Russo"
#: conf/global_settings.py:80 #: conf/global_settings.py:83
msgid "Slovak" msgid "Slovak"
msgstr "Slovacco" msgstr "Slovacco"
#: conf/global_settings.py:81 #: conf/global_settings.py:84
msgid "Slovenian" msgid "Slovenian"
msgstr "Sloveno" msgstr "Sloveno"
#: conf/global_settings.py:82 #: conf/global_settings.py:85
msgid "Serbian" msgid "Serbian"
msgstr "Serbo" msgstr "Serbo"
#: conf/global_settings.py:83 #: conf/global_settings.py:86
msgid "Swedish" msgid "Swedish"
msgstr "Svedese" msgstr "Svedese"
#: conf/global_settings.py:84 #: conf/global_settings.py:87
msgid "Tamil" msgid "Tamil"
msgstr "Tamil" msgstr "Tamil"
#: conf/global_settings.py:85 #: conf/global_settings.py:88
msgid "Telugu" msgid "Telugu"
msgstr "Telugu" msgstr "Telugu"
#: conf/global_settings.py:86 #: conf/global_settings.py:89
msgid "Turkish" msgid "Turkish"
msgstr "Turco" msgstr "Turco"
#: conf/global_settings.py:87 #: conf/global_settings.py:90
msgid "Ukrainian" msgid "Ukrainian"
msgstr "Ucraino" msgstr "Ucraino"
#: conf/global_settings.py:88 #: conf/global_settings.py:91
msgid "Simplified Chinese" msgid "Simplified Chinese"
msgstr "Cinese semplificato" msgstr "Cinese semplificato"
#: conf/global_settings.py:89 #: conf/global_settings.py:92
msgid "Traditional Chinese" msgid "Traditional Chinese"
msgstr "Cinese tradizionale" msgstr "Cinese tradizionale"
@ -1133,15 +1141,15 @@ msgstr "permessi"
msgid "group" msgid "group"
msgstr "gruppo" msgstr "gruppo"
#: contrib/auth/models.py:98 contrib/auth/models.py:141 #: contrib/auth/models.py:98 contrib/auth/models.py:148
msgid "groups" msgid "groups"
msgstr "gruppi" msgstr "gruppi"
#: contrib/auth/models.py:131 #: contrib/auth/models.py:138
msgid "username" msgid "username"
msgstr "nome utente" msgstr "nome utente"
#: contrib/auth/models.py:131 #: contrib/auth/models.py:138
msgid "" msgid ""
"Required. 30 characters or fewer. Alphanumeric characters only (letters, " "Required. 30 characters or fewer. Alphanumeric characters only (letters, "
"digits and underscores)." "digits and underscores)."
@ -1149,23 +1157,23 @@ msgstr ""
"Obbligatorio. 30 caratteri o meno. Solo caratteri alfanumerici (lettere, " "Obbligatorio. 30 caratteri o meno. Solo caratteri alfanumerici (lettere, "
"cifre e sottolineati)." "cifre e sottolineati)."
#: contrib/auth/models.py:132 #: contrib/auth/models.py:139
msgid "first name" msgid "first name"
msgstr "nome" msgstr "nome"
#: contrib/auth/models.py:133 #: contrib/auth/models.py:140
msgid "last name" msgid "last name"
msgstr "cognome" msgstr "cognome"
#: contrib/auth/models.py:134 #: contrib/auth/models.py:141
msgid "e-mail address" msgid "e-mail address"
msgstr "indirizzo e-mail" msgstr "indirizzo e-mail"
#: contrib/auth/models.py:135 #: contrib/auth/models.py:142
msgid "password" msgid "password"
msgstr "password" msgstr "password"
#: contrib/auth/models.py:135 #: contrib/auth/models.py:142
msgid "" msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change " "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>." "password form</a>."
@ -1173,19 +1181,19 @@ msgstr ""
"Usare '[algo]$[salt]$[hexdigest]' oppure la <a href=\"password/\">maschera " "Usare '[algo]$[salt]$[hexdigest]' oppure la <a href=\"password/\">maschera "
"di cambio password</a>." "di cambio password</a>."
#: contrib/auth/models.py:136 #: contrib/auth/models.py:143
msgid "staff status" msgid "staff status"
msgstr "privilegi di staff" msgstr "privilegi di staff"
#: contrib/auth/models.py:136 #: contrib/auth/models.py:143
msgid "Designates whether the user can log into this admin site." msgid "Designates whether the user can log into this admin site."
msgstr "Indica se l'utente può accedere a questo sito di amministrazione." msgstr "Indica se l'utente può accedere a questo sito di amministrazione."
#: contrib/auth/models.py:137 #: contrib/auth/models.py:144
msgid "active" msgid "active"
msgstr "attivo" msgstr "attivo"
#: contrib/auth/models.py:137 #: contrib/auth/models.py:144
msgid "" msgid ""
"Designates whether this user should be treated as active. Unselect this " "Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts." "instead of deleting accounts."
@ -1193,11 +1201,11 @@ msgstr ""
"Indica se l'utente debba essere considerato attivo. Deselezionare " "Indica se l'utente debba essere considerato attivo. Deselezionare "
"qui, piuttosto che cancellare gli account." "qui, piuttosto che cancellare gli account."
#: contrib/auth/models.py:138 #: contrib/auth/models.py:145
msgid "superuser status" msgid "superuser status"
msgstr "privilegi di superutente" msgstr "privilegi di superutente"
#: contrib/auth/models.py:138 #: contrib/auth/models.py:145
msgid "" msgid ""
"Designates that this user has all permissions without explicitly assigning " "Designates that this user has all permissions without explicitly assigning "
"them." "them."
@ -1205,15 +1213,15 @@ msgstr ""
"Indica che l'utente ha tutti i privilegi, senza che siano stati assegnati " "Indica che l'utente ha tutti i privilegi, senza che siano stati assegnati "
"esplicitamente." "esplicitamente."
#: contrib/auth/models.py:139 #: contrib/auth/models.py:146
msgid "last login" msgid "last login"
msgstr "ultimo accesso" msgstr "ultimo accesso"
#: contrib/auth/models.py:140 #: contrib/auth/models.py:147
msgid "date joined" msgid "date joined"
msgstr "iscritto in data" msgstr "iscritto in data"
#: contrib/auth/models.py:142 #: contrib/auth/models.py:149
msgid "" msgid ""
"In addition to the permissions manually assigned, this user will also get " "In addition to the permissions manually assigned, this user will also get "
"all permissions granted to each group he/she is in." "all permissions granted to each group he/she is in."
@ -1221,39 +1229,39 @@ msgstr ""
"In aggiunta ai privilegi assegnati manualmente, l'utente riceverà anche " "In aggiunta ai privilegi assegnati manualmente, l'utente riceverà anche "
"tutti i privilegi assegnati ad ogni gruppo cui appartiene." "tutti i privilegi assegnati ad ogni gruppo cui appartiene."
#: contrib/auth/models.py:143 #: contrib/auth/models.py:150
msgid "user permissions" msgid "user permissions"
msgstr "privilegi utente" msgstr "privilegi utente"
#: contrib/auth/models.py:147 #: contrib/auth/models.py:154
msgid "user" msgid "user"
msgstr "utente" msgstr "utente"
#: contrib/auth/models.py:148 #: contrib/auth/models.py:155
msgid "users" msgid "users"
msgstr "utenti" msgstr "utenti"
#: contrib/auth/models.py:154 #: contrib/auth/models.py:160
msgid "Personal info" msgid "Personal info"
msgstr "Informazioni personali" msgstr "Informazioni personali"
#: contrib/auth/models.py:155 #: contrib/auth/models.py:161
msgid "Permissions" msgid "Permissions"
msgstr "Permessi" msgstr "Permessi"
#: contrib/auth/models.py:156 #: contrib/auth/models.py:162
msgid "Important dates" msgid "Important dates"
msgstr "Date importanti" msgstr "Date importanti"
#: contrib/auth/models.py:157 #: contrib/auth/models.py:163
msgid "Groups" msgid "Groups"
msgstr "Gruppi" msgstr "Gruppi"
#: contrib/auth/models.py:316 #: contrib/auth/models.py:323
msgid "message" msgid "message"
msgstr "messaggio" msgstr "messaggio"
#: contrib/auth/views.py:47 #: contrib/auth/views.py:49
msgid "Logged out" msgid "Logged out"
msgstr "Accesso annullato" msgstr "Accesso annullato"
@ -3523,23 +3531,23 @@ msgstr "redirezione"
msgid "redirects" msgid "redirects"
msgstr "redirezioni" msgstr "redirezioni"
#: contrib/sessions/models.py:41 #: contrib/sessions/models.py:45
msgid "session key" msgid "session key"
msgstr "chiave di sessione" msgstr "chiave di sessione"
#: contrib/sessions/models.py:42 #: contrib/sessions/models.py:47
msgid "session data" msgid "session data"
msgstr "dati di sessione" msgstr "dati di sessione"
#: contrib/sessions/models.py:43 #: contrib/sessions/models.py:48
msgid "expire date" msgid "expire date"
msgstr "data di scadenza" msgstr "data di scadenza"
#: contrib/sessions/models.py:48 #: contrib/sessions/models.py:53
msgid "session" msgid "session"
msgstr "sessione" msgstr "sessione"
#: contrib/sessions/models.py:49 #: contrib/sessions/models.py:54
msgid "sessions" msgid "sessions"
msgstr "sessioni" msgstr "sessioni"
@ -3607,7 +3615,7 @@ msgstr "Sono ammessi soltanto caratteri numerici."
msgid "This value can't be comprised solely of digits." msgid "This value can't be comprised solely of digits."
msgstr "Questo valore non può essere composto solo da cifre." msgstr "Questo valore non può essere composto solo da cifre."
#: core/validators.py:128 newforms/fields.py:152 #: core/validators.py:128 newforms/fields.py:157
msgid "Enter a whole number." msgid "Enter a whole number."
msgstr "Inserire un numero intero." msgstr "Inserire un numero intero."
@ -3624,7 +3632,7 @@ msgstr "L'anno deve essere 1900 o successivo."
msgid "Invalid date: %s" msgid "Invalid date: %s"
msgstr "Data non valida: %s" msgstr "Data non valida: %s"
#: core/validators.py:156 db/models/fields/__init__.py:548 #: core/validators.py:156 db/models/fields/__init__.py:554
msgid "Enter a valid date in YYYY-MM-DD format." msgid "Enter a valid date in YYYY-MM-DD format."
msgstr "Inserire una data valida in formato AAAA-MM-GG." msgstr "Inserire una data valida in formato AAAA-MM-GG."
@ -3632,20 +3640,19 @@ msgstr "Inserire una data valida in formato AAAA-MM-GG."
msgid "Enter a valid time in HH:MM format." msgid "Enter a valid time in HH:MM format."
msgstr "Inserire un ora valida in formato OO:MM." msgstr "Inserire un ora valida in formato OO:MM."
#: core/validators.py:165 db/models/fields/__init__.py:625 #: core/validators.py:165 db/models/fields/__init__.py:631
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
msgstr "Inserire una data/ora valida in formato AAAA-MM-GG OO:MM." msgstr "Inserire una data/ora valida in formato AAAA-MM-GG OO:MM."
#: core/validators.py:170 newforms/fields.py:403 #: core/validators.py:170 newforms/fields.py:408
msgid "Enter a valid e-mail address." msgid "Enter a valid e-mail address."
msgstr "Inserire un indirizzo e-mail valido." msgstr "Inserire un indirizzo e-mail valido."
#: core/validators.py:182 core/validators.py:474 newforms/fields.py:433 #: core/validators.py:182 core/validators.py:474 newforms/fields.py:426
#: oldforms/__init__.py:687
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 "Non è stato inviato alcun file. Verificare il tipo di codifica della form." msgstr "Non è stato inviato alcun file. Verificare il tipo di codifica della form."
#: core/validators.py:193 newforms/fields.py:459 #: core/validators.py:193 newforms/fields.py:468
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."
@ -3876,38 +3883,38 @@ msgstr ""
msgid "%(object)s with this %(type)s already exists for the given %(field)s." msgid "%(object)s with this %(type)s already exists for the given %(field)s."
msgstr "Un %(object)s·con questo·%(type)s·esiste già per questo·%(field)s." msgstr "Un %(object)s·con questo·%(type)s·esiste già per questo·%(field)s."
#: db/models/fields/__init__.py:54 #: db/models/fields/__init__.py:52
#, python-format #, python-format
msgid "%(optname)s with this %(fieldname)s already exists." msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "Un %(optname)s·con questo·%(fieldname)s·esiste già." msgstr "Un %(optname)s·con questo·%(fieldname)s·esiste già."
#: db/models/fields/__init__.py:179 db/models/fields/__init__.py:348 #: db/models/fields/__init__.py:182 db/models/fields/__init__.py:354
#: db/models/fields/__init__.py:780 db/models/fields/__init__.py:791 #: db/models/fields/__init__.py:788 db/models/fields/__init__.py:799
#: newforms/fields.py:46 oldforms/__init__.py:374 #: newforms/fields.py:51 oldforms/__init__.py:374
msgid "This field is required." msgid "This field is required."
msgstr "Questo campo è obbligatorio." msgstr "Questo campo è obbligatorio."
#: db/models/fields/__init__.py:448 #: db/models/fields/__init__.py:454
msgid "This value must be an integer." msgid "This value must be an integer."
msgstr "Questo valore deve essere un intero." msgstr "Questo valore deve essere un intero."
#: db/models/fields/__init__.py:487 #: db/models/fields/__init__.py:493
msgid "This value must be either True or False." msgid "This value must be either True or False."
msgstr "Questo valore deve essere True o False." msgstr "Questo valore deve essere True o False."
#: db/models/fields/__init__.py:511 #: db/models/fields/__init__.py:517
msgid "This field cannot be null." msgid "This field cannot be null."
msgstr "Questo campo non può essere nullo." msgstr "Questo campo non può essere nullo."
#: db/models/fields/__init__.py:689 #: db/models/fields/__init__.py:695
msgid "This value must be a decimal number." msgid "This value must be a decimal number."
msgstr "Questo valore deve essere un numero decimale." msgstr "Questo valore deve essere un numero decimale."
#: db/models/fields/__init__.py:800 #: db/models/fields/__init__.py:808
msgid "Enter a valid filename." msgid "Enter a valid filename."
msgstr "Inserire un nome di file valido." msgstr "Inserire un nome di file valido."
#: db/models/fields/__init__.py:981 #: db/models/fields/__init__.py:999
msgid "This value must be either None, True or False." msgid "This value must be either None, True or False."
msgstr "Questo valore deve essere None, True o False." msgstr "Questo valore deve essere None, True o False."
@ -3916,118 +3923,118 @@ msgstr "Questo valore deve essere None, True o False."
msgid "Please enter a valid %s." msgid "Please enter a valid %s."
msgstr "Inserire un %s valido." msgstr "Inserire un %s valido."
#: db/models/fields/related.py:721 #: db/models/fields/related.py:756
msgid "Separate multiple IDs with commas." msgid "Separate multiple IDs with commas."
msgstr "Separare gli ID multipli con virgole." msgstr "Separare gli ID multipli con virgole."
#: db/models/fields/related.py:723 #: db/models/fields/related.py:758
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
msgstr "" msgstr ""
"Tenere premuto \"Control\", o \"Command\" su Mac, per selezionarne più di " "Tenere premuto \"Control\", o \"Command\" su Mac, per selezionarne più di "
"uno." "uno."
#: db/models/fields/related.py:770 #: db/models/fields/related.py:805
#, 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 "Please enter valid %(self)s IDs. The values %(value)r are invalid." msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
msgstr[0] "Inserire un ID valido per %(self)s. Il valore %(value)r non è valido." msgstr[0] "Inserire un ID valido per %(self)s. Il valore %(value)r non è valido."
msgstr[1] "Inserire ID validi per %(self)s. I valori %(value)r non sono validi." msgstr[1] "Inserire ID validi per %(self)s. I valori %(value)r non sono validi."
#: newforms/fields.py:47 #: newforms/fields.py:52
msgid "Enter a valid value." msgid "Enter a valid value."
msgstr "Inserire un valore valido." msgstr "Inserire un valore valido."
#: newforms/fields.py:124 #: newforms/fields.py:129
#, python-format #, python-format
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
msgstr "" msgstr ""
"Assicurarsi che questo valore non contenga più di %(max)d caratteri (ne ha %" "Assicurarsi che questo valore non contenga più di %(max)d caratteri (ne ha %"
"(length)d)." "(length)d)."
#: newforms/fields.py:125 #: newforms/fields.py:130
#, python-format #, python-format
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
msgstr "" msgstr ""
"Assicurarsi che questo valore contenga almeno %(min)d caratteri (ne ha %" "Assicurarsi che questo valore contenga almeno %(min)d caratteri (ne ha %"
"(length)d)." "(length)d)."
#: newforms/fields.py:153 newforms/fields.py:182 newforms/fields.py:211 #: newforms/fields.py:158 newforms/fields.py:187 newforms/fields.py:216
#, python-format #, python-format
msgid "Ensure this value is less than or equal to %s." msgid "Ensure this value is less than or equal to %s."
msgstr "Assicurarsi che questo valore sia minore o uguale a %s." msgstr "Assicurarsi che questo valore sia minore o uguale a %s."
#: newforms/fields.py:154 newforms/fields.py:183 newforms/fields.py:212 #: newforms/fields.py:159 newforms/fields.py:188 newforms/fields.py:217
#, python-format #, python-format
msgid "Ensure this value is greater than or equal to %s." msgid "Ensure this value is greater than or equal to %s."
msgstr "Assicurarsi che questo valore sia maggiore o uguale a %s." msgstr "Assicurarsi che questo valore sia maggiore o uguale a %s."
#: newforms/fields.py:181 newforms/fields.py:210 #: newforms/fields.py:186 newforms/fields.py:215
msgid "Enter a number." msgid "Enter a number."
msgstr "Inserire un numero." msgstr "Inserire un numero."
#: newforms/fields.py:213 #: newforms/fields.py:218
#, 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 "Assicurarsi che non vi siano più di %s cifre in totale." msgstr "Assicurarsi che non vi siano più di %s cifre in totale."
#: newforms/fields.py:214 #: newforms/fields.py:219
#, 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 "Assicurarsi che non vi siano più di %s cifre decimali." msgstr "Assicurarsi che non vi siano più di %s cifre decimali."
#: newforms/fields.py:215 #: newforms/fields.py:220
#, 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 "Assicurarsi che non vi siano più di %s cifre prima della virgola." msgstr "Assicurarsi che non vi siano più di %s cifre prima della virgola."
#: newforms/fields.py:263 newforms/fields.py:751 #: newforms/fields.py:268 newforms/fields.py:779
msgid "Enter a valid date." msgid "Enter a valid date."
msgstr "Inserire una data valida." msgstr "Inserire una data valida."
#: newforms/fields.py:296 newforms/fields.py:752 #: newforms/fields.py:301 newforms/fields.py:780
msgid "Enter a valid time." msgid "Enter a valid time."
msgstr "Inserire un ora valida." msgstr "Inserire un ora valida."
#: newforms/fields.py:335 #: newforms/fields.py:340
msgid "Enter a valid date/time." msgid "Enter a valid date/time."
msgstr "Inserire una coppia data/ora valida." msgstr "Inserire una coppia data/ora valida."
#: newforms/fields.py:434 #: newforms/fields.py:427
msgid "No file was submitted." msgid "No file was submitted."
msgstr "Nessun file è stato inviato." msgstr "Nessun file è stato inviato."
#: newforms/fields.py:435 oldforms/__init__.py:689 #: newforms/fields.py:428 oldforms/__init__.py:693
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "Il file inviato è vuoto." msgstr "Il file inviato è vuoto."
#: newforms/fields.py:497 #: newforms/fields.py:522
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "Inserire una URL valida." msgstr "Inserire una URL valida."
#: newforms/fields.py:498 #: newforms/fields.py:523
msgid "This URL appears to be a broken link." msgid "This URL appears to be a broken link."
msgstr "Questa URL non sembra funzionare." msgstr "Questa URL non sembra funzionare."
#: newforms/fields.py:560 newforms/models.py:299 #: newforms/fields.py:588 newforms/models.py:306
msgid "Select a valid choice. That choice is not one of the available choices." msgid "Select a valid choice. That choice is not one of the available choices."
msgstr "" msgstr ""
"Scegliere un'opzione valida. La scelta effettuata non compare tra quelle " "Scegliere un'opzione valida. La scelta effettuata non compare tra quelle "
"disponibili." "disponibili."
#: newforms/fields.py:599 #: newforms/fields.py:627
#, 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 "Scegliere un'opzione valida. '%(value)s non compare tra quelle disponibili." msgstr "Scegliere un'opzione valida. '%(value)s non compare tra quelle disponibili."
#: newforms/fields.py:600 newforms/fields.py:662 newforms/models.py:371 #: newforms/fields.py:628 newforms/fields.py:690 newforms/models.py:373
msgid "Enter a list of values." msgid "Enter a list of values."
msgstr "Inserire una lista di valori." msgstr "Inserire una lista di valori."
#: newforms/fields.py:780 #: newforms/fields.py:808
msgid "Enter a valid IPv4 address." msgid "Enter a valid IPv4 address."
msgstr "Inserire un indirizzo IPv4 valido." msgstr "Inserire un indirizzo IPv4 valido."
#: newforms/models.py:372 #: newforms/models.py:374
#, python-format #, python-format
msgid "Select a valid choice. %s is not one of the available choices." msgid "Select a valid choice. %s is not one of the available choices."
msgstr "Scegliere un'opzione valida. '%s non compare tra quelle disponibili." msgstr "Scegliere un'opzione valida. '%s non compare tra quelle disponibili."
@ -4048,15 +4055,15 @@ msgstr "Non sono ammessi a capo manuali qui."
msgid "Select a valid choice; '%(data)s' is not in %(choices)s." msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Scegliere un'opzione valida; '%(data)s' non presente in %(choices)s." msgstr "Scegliere un'opzione valida; '%(data)s' non presente in %(choices)s."
#: oldforms/__init__.py:745 #: oldforms/__init__.py:754
msgid "Enter a whole number between -32,768 and 32,767." msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Inserire un numero intero compreso tra -32.768 e 32.767 ." msgstr "Inserire un numero intero compreso tra -32.768 e 32.767 ."
#: oldforms/__init__.py:755 #: oldforms/__init__.py:764
msgid "Enter a positive number." msgid "Enter a positive number."
msgstr "Inserire un numero positivo." msgstr "Inserire un numero positivo."
#: oldforms/__init__.py:765 #: oldforms/__init__.py:774
msgid "Enter a whole number between 0 and 32,767." msgid "Enter a whole number between 0 and 32,767."
msgstr "Inserire un numero intero compreso tra 0 e 32.767 ." msgstr "Inserire un numero intero compreso tra 0 e 32.767 ."
@ -4290,7 +4297,7 @@ msgstr "Nov."
msgid "Dec." msgid "Dec."
msgstr "Dic." msgstr "Dic."
#: utils/text.py:127 #: utils/text.py:128
msgid "or" msgid "or"
msgstr "o" msgstr "o"
@ -4344,23 +4351,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:403 #: utils/translation/trans_real.py:412
msgid "DATE_FORMAT" msgid "DATE_FORMAT"
msgstr "j F Y" msgstr "j F Y"
#: utils/translation/trans_real.py:404 #: utils/translation/trans_real.py:413
msgid "DATETIME_FORMAT" msgid "DATETIME_FORMAT"
msgstr "j F Y, H:i" msgstr "j F Y, H:i"
#: utils/translation/trans_real.py:405 #: utils/translation/trans_real.py:414
msgid "TIME_FORMAT" msgid "TIME_FORMAT"
msgstr "H:i" msgstr "H:i"
#: utils/translation/trans_real.py:421 #: utils/translation/trans_real.py:430
msgid "YEAR_MONTH_FORMAT" msgid "YEAR_MONTH_FORMAT"
msgstr "Y F" msgstr "Y F"
#: utils/translation/trans_real.py:422 #: utils/translation/trans_real.py:431
msgid "MONTH_DAY_FORMAT" msgid "MONTH_DAY_FORMAT"
msgstr "F j" msgstr "F j"

View File

@ -193,7 +193,7 @@ class TemporaryUploadedFile(UploadedFile):
""" """
Returns the full path of this file. Returns the full path of this file.
""" """
return self.name return self._file.name
# Most methods on this object get proxied to NamedTemporaryFile. # Most methods on this object get proxied to NamedTemporaryFile.
# We can't directly subclass because NamedTemporaryFile is actually a # We can't directly subclass because NamedTemporaryFile is actually a

View File

@ -134,6 +134,35 @@ class LaxOptionParser(OptionParser):
""" """
def error(self, msg): def error(self, msg):
pass pass
def _process_args(self, largs, rargs, values):
"""
Overrides OptionParser._process_args to exclusively handle default
options and ignore args and other options.
This overrides the behavior of the super class, which stop parsing
at the first unrecognized option.
"""
while rargs:
arg = rargs[0]
try:
if arg[0:2] == "--" and len(arg) > 2:
# process a single long option (possibly with value(s))
# the superclass code pops the arg off rargs
self._process_long_opt(rargs, values)
elif arg[:1] == "-" and len(arg) > 1:
# process a cluster of short options (possibly with
# value(s) for the last one only)
# the superclass code pops the arg off rargs
self._process_short_opts(rargs, values)
else:
# it's either a non-default option or an arg
# either way, add it to the args list so we can keep
# dealing with options
del rargs[0]
raise error
except:
largs.append(arg)
class ManagementUtility(object): class ManagementUtility(object):
""" """

View File

@ -41,10 +41,11 @@ class Command(NoArgsCommand):
# but raises an ImportError for some reason. The only way we # but raises an ImportError for some reason. The only way we
# can do this is to check the text of the exception. Note that # can do this is to check the text of the exception. Note that
# we're a bit broad in how we check the text, because different # we're a bit broad in how we check the text, because different
# Python implementations may not use the same text. CPython # Python implementations may not use the same text.
# uses the text "No module named management". # CPython uses the text "No module named management"
# PyPy uses "No module named myproject.myapp.management"
msg = exc.args[0] msg = exc.args[0]
if not msg.startswith('No module named management') or 'management' not in msg: if not msg.startswith('No module named') or 'management' not in msg:
raise raise
cursor = connection.cursor() cursor = connection.cursor()
@ -105,7 +106,10 @@ class Command(NoArgsCommand):
# Send the post_syncdb signal, so individual apps can do whatever they need # Send the post_syncdb signal, so individual apps can do whatever they need
# to do at this point. # to do at this point.
emit_post_sync_signal(created_models, verbosity, interactive) emit_post_sync_signal(created_models, verbosity, interactive)
# The connection may have been closed by a syncdb handler.
cursor = connection.cursor()
# 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)
for app in models.get_apps(): for app in models.get_apps():
@ -144,7 +148,7 @@ class Command(NoArgsCommand):
for sql in index_sql: for sql in index_sql:
cursor.execute(sql) cursor.execute(sql)
except Exception, e: except Exception, e:
sys.stderr.write("Failed to install index for %s.%s model: %s" % \ sys.stderr.write("Failed to install index for %s.%s model: %s\n" % \
(app_name, model._meta.object_name, e)) (app_name, model._meta.object_name, e))
transaction.rollback_unless_managed() transaction.rollback_unless_managed()
else: else:

View File

@ -314,7 +314,7 @@ class Field(object):
params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month))) params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
if self.unique_for_year: if self.unique_for_year:
params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year))) params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
if self.unique or (self.primary_key and not rel): if self.unique and not rel:
params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator)) params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
# Only add is_required=True if the field cannot be blank. Primary keys # Only add is_required=True if the field cannot be blank. Primary keys
@ -539,7 +539,7 @@ class DateField(Field):
raise validators.ValidationError, _('Enter a valid date in YYYY-MM-DD format.') raise validators.ValidationError, _('Enter a valid date in YYYY-MM-DD format.')
def get_db_prep_lookup(self, lookup_type, value): def get_db_prep_lookup(self, lookup_type, value):
if lookup_type == 'range': if lookup_type in ('range', 'in'):
value = [smart_unicode(v) for v in value] value = [smart_unicode(v) for v in value]
elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'): elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'):
value = value.strftime('%Y-%m-%d') value = value.strftime('%Y-%m-%d')
@ -626,7 +626,7 @@ class DateTimeField(DateField):
return Field.get_db_prep_save(self, value) return Field.get_db_prep_save(self, value)
def get_db_prep_lookup(self, lookup_type, value): def get_db_prep_lookup(self, lookup_type, value):
if lookup_type == 'range': if lookup_type in ('range', 'in'):
value = [smart_unicode(v) for v in value] value = [smart_unicode(v) for v in value]
else: else:
value = smart_unicode(value) value = smart_unicode(value)
@ -705,7 +705,7 @@ class DecimalField(Field):
return super(DecimalField, self).get_db_prep_save(value) return super(DecimalField, self).get_db_prep_save(value)
def get_db_prep_lookup(self, lookup_type, value): def get_db_prep_lookup(self, lookup_type, value):
if lookup_type == 'range': if lookup_type in ('range', 'in'):
value = [self._format(v) for v in value] value = [self._format(v) for v in value]
else: else:
value = self._format(value) value = self._format(value)
@ -820,12 +820,14 @@ class FileField(Field):
def save_file(self, new_data, new_object, original_object, change, rel, save=True): def save_file(self, new_data, new_object, original_object, change, rel, save=True):
upload_field_name = self.get_manipulator_field_names('')[0] upload_field_name = self.get_manipulator_field_names('')[0]
if new_data.get(upload_field_name, False): if new_data.get(upload_field_name, False):
func = getattr(new_object, 'save_%s_file' % self.name)
if rel: if rel:
file = new_data[upload_field_name][0] file = new_data[upload_field_name][0]
else: else:
file = new_data[upload_field_name] file = new_data[upload_field_name]
if not file:
return
# Backwards-compatible support for files-as-dictionaries. # Backwards-compatible support for files-as-dictionaries.
# We don't need to raise a warning because Model._save_FIELD_file will # We don't need to raise a warning because Model._save_FIELD_file will
# do so for us. # do so for us.
@ -834,6 +836,7 @@ class FileField(Field):
except AttributeError: except AttributeError:
file_name = file['filename'] file_name = file['filename']
func = getattr(new_object, 'save_%s_file' % self.name)
func(file_name, file, save) func(file_name, file, save)
def get_directory_name(self): def get_directory_name(self):
@ -1086,7 +1089,7 @@ class TimeField(Field):
return smart_unicode(value) return smart_unicode(value)
else: else:
prep = smart_unicode prep = smart_unicode
if lookup_type == 'range': if lookup_type in ('range', 'in'):
value = [prep(v) for v in value] value = [prep(v) for v in value]
else: else:
value = prep(value) value = prep(value)

View File

@ -1,13 +1,17 @@
import warnings import warnings
try:
set
except NameError:
from sets import Set as set # Python 2.3 fallback
from django.conf import settings
from django.db import connection, transaction, IntegrityError from django.db import connection, transaction, IntegrityError
from django.db.models.fields import DateField, FieldDoesNotExist from django.db.models.fields import DateField
from django.db.models.query_utils import Q, select_related_descend from django.db.models.query_utils import Q, select_related_descend
from django.db.models import signals, sql from django.db.models import signals, sql
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
# Used to control how many objects are worked with at once in some cases (e.g. # Used to control how many objects are worked with at once in some cases (e.g.
# when deleting objects). # when deleting objects).
CHUNK_SIZE = 100 CHUNK_SIZE = 100
@ -16,7 +20,12 @@ ITER_CHUNK_SIZE = CHUNK_SIZE
# Pull into this namespace for backwards compatibility. # Pull into this namespace for backwards compatibility.
EmptyResultSet = sql.EmptyResultSet EmptyResultSet = sql.EmptyResultSet
class CyclicDependency(Exception): class CyclicDependency(Exception):
"""
An error when dealing with a collection of objects that have a cyclic
dependency, i.e. when deleting multiple objects.
"""
pass pass

View File

@ -283,12 +283,11 @@ class Query(object):
if ordering: if ordering:
result.append('ORDER BY %s' % ', '.join(ordering)) result.append('ORDER BY %s' % ', '.join(ordering))
# FIXME: Pull this out to make life easier for Oracle et al.
if with_limits: if with_limits:
if self.high_mark: if self.high_mark is not None:
result.append('LIMIT %d' % (self.high_mark - self.low_mark)) result.append('LIMIT %d' % (self.high_mark - self.low_mark))
if self.low_mark: if self.low_mark:
if not self.high_mark: if self.high_mark is None:
val = self.connection.ops.no_limit_value() val = self.connection.ops.no_limit_value()
if val: if val:
result.append('LIMIT %d' % val) result.append('LIMIT %d' % val)
@ -1381,12 +1380,12 @@ class Query(object):
constraints. So low is added to the current low value and both will be constraints. So low is added to the current low value and both will be
clamped to any existing high value. clamped to any existing high value.
""" """
if high: if high is not None:
if self.high_mark: if self.high_mark:
self.high_mark = min(self.high_mark, self.low_mark + high) self.high_mark = min(self.high_mark, self.low_mark + high)
else: else:
self.high_mark = self.low_mark + high self.high_mark = self.low_mark + high
if low: if low is not None:
if self.high_mark: if self.high_mark:
self.low_mark = min(self.high_mark, self.low_mark + low) self.low_mark = min(self.high_mark, self.low_mark + low)
else: else:

View File

@ -270,24 +270,9 @@ class LazyStream(object):
self._empty = False self._empty = False
self._leftover = '' self._leftover = ''
self.length = length self.length = length
self._position = 0 self.position = 0
self._remaining = length self._remaining = length
self._unget_history = []
# These fields are to do sanity checking to make sure we don't
# have infinite loops getting/ungetting from the stream. The
# purpose overall is to raise an exception if we perform lots
# of stream get/unget gymnastics without getting
# anywhere. Naturally this is not sound, but most probably
# would indicate a bug if the exception is raised.
# largest position tell us how far this lazystream has ever
# been advanced
self._largest_position = 0
# "modifications since" will start at zero and increment every
# time the position is modified but a new largest position is
# not achieved.
self._modifications_since = 0
def tell(self): def tell(self):
return self.position return self.position
@ -329,6 +314,7 @@ class LazyStream(object):
self._leftover = '' self._leftover = ''
else: else:
output = self._producer.next() output = self._producer.next()
self._unget_history = []
self.position += len(output) self.position += len(output)
return output return output
@ -351,25 +337,30 @@ class LazyStream(object):
Future calls to read() will return those bytes first. The Future calls to read() will return those bytes first. The
stream position and thus tell() will be rewound. stream position and thus tell() will be rewound.
""" """
if not bytes:
return
self._update_unget_history(len(bytes))
self.position -= len(bytes) self.position -= len(bytes)
self._leftover = ''.join([bytes, self._leftover]) self._leftover = ''.join([bytes, self._leftover])
def _set_position(self, value): def _update_unget_history(self, num_bytes):
if value > self._largest_position: """
self._modifications_since = 0 Updates the unget history as a sanity check to see if we've pushed
self._largest_position = value back the same number of bytes in one chunk. If we keep ungetting the
else: same number of bytes many times (here, 50), we're mostly likely in an
self._modifications_since += 1 infinite loop of some sort. This is usually caused by a
if self._modifications_since > 500: maliciously-malformed MIME request.
raise SuspiciousOperation( """
"The multipart parser got stuck, which shouldn't happen with" self._unget_history = [num_bytes] + self._unget_history[:49]
" normal uploaded files. Check for malicious upload activity;" number_equal = len([current_number for current_number in self._unget_history
" if there is none, report this to the Django developers." if current_number == num_bytes])
)
self._position = value if number_equal > 40:
raise SuspiciousOperation(
position = property(lambda self: self._position, _set_position) "The multipart parser got stuck, which shouldn't happen with"
" normal uploaded files. Check for malicious upload activity;"
" if there is none, report this to the Django developers."
)
class ChunkIter(object): class ChunkIter(object):
""" """

View File

@ -507,6 +507,8 @@ class ImageField(FileField):
trial_image.verify() trial_image.verify()
except Exception: # Python Imaging Library doesn't recognize it as an image except Exception: # Python Imaging Library doesn't recognize it as an image
raise ValidationError(self.error_messages['invalid_image']) raise ValidationError(self.error_messages['invalid_image'])
if hasattr(f, 'seek') and callable(f.seek):
f.seek(0)
return f return f
url_re = re.compile( url_re = re.compile(

View File

@ -67,3 +67,8 @@ def is_iterable(x):
else: else:
return True return True
def sorted(in_value):
"A naive implementation of sorted"
out_value = in_value[:]
out_value.sort()
return out_value

View File

@ -738,6 +738,11 @@ If you're using another backend:
deleted when the tests are finished. This means your user account needs deleted when the tests are finished. This means your user account needs
permission to execute ``CREATE DATABASE``. permission to execute ``CREATE DATABASE``.
You will also need to ensure that your database uses UTF-8 as the default
character set. If your database server doesn't use UTF-8 as a default charset,
you will need to include a value for ``TEST_DATABASE_CHARSET`` in your settings
file.
If you want to run the full suite of tests, you'll need to install a number of If you want to run the full suite of tests, you'll need to install a number of
dependencies: dependencies:

View File

@ -2212,6 +2212,18 @@ updated is that it can only access one database table, the model's main
table. So don't try to filter based on related fields or anything like that; table. So don't try to filter based on related fields or anything like that;
it won't work. it won't work.
Be aware that the ``update()`` method is converted directly to an SQL
statement. It is a bulk operation for direct updates. It doesn't run any
``save()`` methods on your models, or emit the ``pre_save`` or ``post_save``
signals (which are a consequence of calling ``save()``). If you want to save
every item in a ``QuerySet`` and make sure that the ``save()`` method is
called on each instance, you don't need any special function to handle that.
Just loop over them and call ``save()``:
for item in my_queryset:
item.save()
Extra instance methods Extra instance methods
====================== ======================

View File

@ -89,7 +89,7 @@ read Python's official documentation for the details.
For example, this function has a docstring that describes what it does:: For example, this function has a docstring that describes what it does::
def add_two(num): def add_two(num):
"Adds 2 to the given number and returns the result." "Return the result of adding two to the provided number."
return num + 2 return num + 2
Because tests often make great documentation, putting tests directly in Because tests often make great documentation, putting tests directly in
@ -600,8 +600,6 @@ Specifically, a ``Response`` object has the following attributes:
``context`` will be a list of ``Context`` ``context`` will be a list of ``Context``
objects, in the order in which they were rendered. objects, in the order in which they were rendered.
``headers`` The HTTP headers of the response. This is a dictionary.
``request`` The request data that stimulated the response. ``request`` The request data that stimulated the response.
``status_code`` The HTTP status of the response, as an integer. See ``status_code`` The HTTP status of the response, as an integer. See
@ -619,6 +617,10 @@ Specifically, a ``Response`` object has the following attributes:
which they were rendered. which they were rendered.
=============== ========================================================== =============== ==========================================================
You can also use dictionary syntax on the response object to query the value
of any settings in the HTTP headers. For example, you could determine the
content type of a response using ``response['Content-Type']``.
.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
.. _template inheritance: ../templates/#template-inheritance .. _template inheritance: ../templates/#template-inheritance

View File

@ -146,7 +146,7 @@ database's connection parameters:
* ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or 'sqlite3'. * ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or 'sqlite3'.
Other backends are `also available`_. Other backends are `also available`_.
* ``DATABASE_NAME`` -- The name of your database, or the full (absolute) * ``DATABASE_NAME`` -- The name of your database, or the full (absolute)
path to the database file if you're using SQLite. path to the database file if you're using SQLite.
* ``DATABASE_USER`` -- Your database username (not used for SQLite). * ``DATABASE_USER`` -- Your database username (not used for SQLite).
* ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite). * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite).
* ``DATABASE_HOST`` -- The host your database is on. Leave this as an * ``DATABASE_HOST`` -- The host your database is on. Leave this as an
@ -161,6 +161,9 @@ database's connection parameters:
this point. Do that with "``CREATE DATABASE database_name;``" within your this point. Do that with "``CREATE DATABASE database_name;``" within your
database's interactive prompt. database's interactive prompt.
If you're using SQLite, you don't need to create anything beforehand - the
database file will be created automatically when it is needed.
While you're editing ``settings.py``, take note of the ``INSTALLED_APPS`` While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
setting towards the bottom of the file. That variable holds the names of all setting towards the bottom of the file. That variable holds the names of all
Django applications that are activated in this Django instance. Apps can be Django applications that are activated in this Django instance. Apps can be

View File

@ -4,12 +4,18 @@
This is a basic model with only two non-primary-key fields. This is a basic model with only two non-primary-key fields.
""" """
# Python 2.3 doesn't have set as a builtin
try: try:
set set
except NameError: except NameError:
from sets import Set as set from sets import Set as set
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
from django.db import models from django.db import models
class Article(models.Model): class Article(models.Model):

View File

@ -900,7 +900,7 @@ u'...test3.txt'
... class Meta: ... class Meta:
... model = ImageFile ... model = ImageFile
>>> image_data = open(os.path.join(os.path.dirname(__file__), "test.png")).read() >>> image_data = open(os.path.join(os.path.dirname(__file__), "test.png"), 'rb').read()
>>> f = ImageFileForm(data={'description': u'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)}) >>> f = ImageFileForm(data={'description': u'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)})
>>> f.is_valid() >>> f.is_valid()

View File

@ -8,6 +8,11 @@ Alternatively, use positional arguments, and pass one or more expressions of
clauses using the variable ``django.db.models.Q`` (or any object with an clauses using the variable ``django.db.models.Q`` (or any object with an
add_to_query method). add_to_query method).
""" """
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
from django.db import models from django.db import models

View File

@ -70,7 +70,13 @@ class ClientTest(TestCase):
self.assertEqual(response.context['data'], '37') self.assertEqual(response.context['data'], '37')
self.assertEqual(response.template.name, 'POST Template') self.assertEqual(response.template.name, 'POST Template')
self.failUnless('Data received' in response.content) self.failUnless('Data received' in response.content)
def test_response_headers(self):
"Check the value of HTTP headers returned in a response"
response = self.client.get("/test_client/header_view/")
self.assertEquals(response['X-DJANGO-TEST'], 'Slartibartfast')
def test_raw_post(self): def test_raw_post(self):
"POST raw data (with a content type) to a view" "POST raw data (with a content type) to a view"
test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>""" test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>"""

View File

@ -5,6 +5,7 @@ import views
urlpatterns = patterns('', urlpatterns = patterns('',
(r'^get_view/$', views.get_view), (r'^get_view/$', views.get_view),
(r'^post_view/$', views.post_view), (r'^post_view/$', views.post_view),
(r'^header_view/$', views.view_with_header),
(r'^raw_post_view/$', views.raw_post_view), (r'^raw_post_view/$', views.raw_post_view),
(r'^redirect_view/$', views.redirect_view), (r'^redirect_view/$', views.redirect_view),
(r'^permanent_redirect_view/$', redirect_to, { 'url': '/test_client/get_view/' }), (r'^permanent_redirect_view/$', redirect_to, { 'url': '/test_client/get_view/' }),

View File

@ -32,6 +32,12 @@ def post_view(request):
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
def view_with_header(request):
"A view that has a custom header"
response = HttpResponse()
response['X-DJANGO-TEST'] = 'Slartibartfast'
return response
def raw_post_view(request): def raw_post_view(request):
"""A view which expects raw XML to be posted and returns content extracted """A view which expects raw XML to be posted and returns content extracted
from the XML""" from the XML"""

View File

@ -1,4 +1,9 @@
from django.core.management.base import AppCommand from django.core.management.base import AppCommand
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Command(AppCommand): class Command(AppCommand):
help = 'Test Application-based commands' help = 'Test Application-based commands'

View File

@ -1,6 +1,17 @@
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from optparse import make_option
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Command(BaseCommand): class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option('--option_a','-a', action='store', dest='option_a', default='1'),
make_option('--option_b','-b', action='store', dest='option_b', default='2'),
make_option('--option_c','-c', action='store', dest='option_c', default='3'),
)
help = 'Test basic commands' help = 'Test basic commands'
requires_model_validation = False requires_model_validation = False
args = '[labels ...]' args = '[labels ...]'

View File

@ -1,4 +1,9 @@
from django.core.management.base import LabelCommand from django.core.management.base import LabelCommand
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Command(LabelCommand): class Command(LabelCommand):
help = "Test Label-based commands" help = "Test Label-based commands"

View File

@ -1,4 +1,9 @@
from django.core.management.base import NoArgsCommand from django.core.management.base import NoArgsCommand
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "Test No-args commands" help = "Test No-args commands"

View File

@ -7,7 +7,7 @@ import os
import unittest import unittest
import shutil import shutil
from django import conf, bin from django import conf, bin, get_version
from django.conf import settings from django.conf import settings
class AdminScriptTestCase(unittest.TestCase): class AdminScriptTestCase(unittest.TestCase):
@ -29,7 +29,7 @@ class AdminScriptTestCase(unittest.TestCase):
settings_file.write("%s = '%s'\n" % (s, str(getattr(settings,s)))) settings_file.write("%s = '%s'\n" % (s, str(getattr(settings,s))))
if apps is None: if apps is None:
apps = ['django.contrib.auth', 'django.contrib.contenttypes', 'regressiontests.admin_scripts'] apps = ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts']
if apps: if apps:
settings_file.write("INSTALLED_APPS = %s\n" % apps) settings_file.write("INSTALLED_APPS = %s\n" % apps)
@ -53,7 +53,7 @@ class AdminScriptTestCase(unittest.TestCase):
# Build the command line # Build the command line
cmd = 'python "%s"' % script cmd = 'python "%s"' % script
cmd += ''.join(' %s' % arg for arg in args) cmd += ''.join([' %s' % arg for arg in args])
# Remember the old environment # Remember the old environment
old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None) old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None)
@ -66,8 +66,8 @@ class AdminScriptTestCase(unittest.TestCase):
elif 'DJANGO_SETTINGS_MODULE' in os.environ: elif 'DJANGO_SETTINGS_MODULE' in os.environ:
del os.environ['DJANGO_SETTINGS_MODULE'] del os.environ['DJANGO_SETTINGS_MODULE']
os.environ['PYTHONPATH'] = os.pathsep.join([project_dir,base_dir]) os.environ['PYTHONPATH'] = os.pathsep.join([test_dir,base_dir])
# Move to the test directory and run # Move to the test directory and run
os.chdir(test_dir) os.chdir(test_dir)
stdin, stdout, stderr = os.popen3(cmd) stdin, stdout, stderr = os.popen3(cmd)
@ -129,17 +129,17 @@ class DjangoAdminNoSettings(AdminScriptTestCase):
def test_builtin_with_bad_settings(self): def test_builtin_with_bad_settings(self):
"no settings: django-admin builtin commands fail if settings file (from argument) doesn't exist" "no settings: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=regressiontests.bad_settings', 'admin_scripts'] args = ['sqlall','--settings=bad_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_builtin_with_bad_environment(self): def test_builtin_with_bad_environment(self):
"no settings: django-admin builtin commands fail if settings file (from environment) doesn't exist" "no settings: django-admin builtin commands fail if settings file (from environment) doesn't exist"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.bad_settings') out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
class DjangoAdminDefaultSettings(AdminScriptTestCase): class DjangoAdminDefaultSettings(AdminScriptTestCase):
@ -161,7 +161,7 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
def test_builtin_with_settings(self): def test_builtin_with_settings(self):
"default: django-admin builtin commands succeed if settings are provided as argument" "default: django-admin builtin commands succeed if settings are provided as argument"
args = ['sqlall','--settings=regressiontests.settings', 'admin_scripts'] args = ['sqlall','--settings=settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
@ -169,23 +169,23 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
def test_builtin_with_environment(self): def test_builtin_with_environment(self):
"default: django-admin builtin commands succeed if settings are provided in the environment" "default: django-admin builtin commands succeed if settings are provided in the environment"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.settings') out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
def test_builtin_with_bad_settings(self): def test_builtin_with_bad_settings(self):
"default: django-admin builtin commands fail if settings file (from argument) doesn't exist" "default: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=regressiontests.bad_settings', 'admin_scripts'] args = ['sqlall','--settings=bad_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_builtin_with_bad_environment(self): def test_builtin_with_bad_environment(self):
"default: django-admin builtin commands fail if settings file (from environment) doesn't exist" "default: django-admin builtin commands fail if settings file (from environment) doesn't exist"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.bad_settings') out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self): def test_custom_command(self):
"default: django-admin can't execute user commands" "default: django-admin can't execute user commands"
@ -196,7 +196,7 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
def test_custom_command_with_settings(self): def test_custom_command_with_settings(self):
"default: django-admin can't execute user commands, even if settings are provided as argument" "default: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=regressiontests.settings'] args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -204,7 +204,7 @@ class DjangoAdminDefaultSettings(AdminScriptTestCase):
def test_custom_command_with_environment(self): def test_custom_command_with_environment(self):
"default: django-admin can't execute user commands, even if settings are provided in environment" "default: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command'] args = ['noargs_command']
out, err = self.run_django_admin(args,'regressiontests.settings') out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -227,7 +227,7 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
def test_builtin_with_settings(self): def test_builtin_with_settings(self):
"minimal: django-admin builtin commands fail if settings are provided as argument" "minimal: django-admin builtin commands fail if settings are provided as argument"
args = ['sqlall','--settings=regressiontests.settings', 'admin_scripts'] args = ['sqlall','--settings=settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, 'App with label admin_scripts could not be found') self.assertOutput(err, 'App with label admin_scripts could not be found')
@ -235,23 +235,23 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
def test_builtin_with_environment(self): def test_builtin_with_environment(self):
"minimal: django-admin builtin commands fail if settings are provided in the environment" "minimal: django-admin builtin commands fail if settings are provided in the environment"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.settings') out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, 'App with label admin_scripts could not be found') self.assertOutput(err, 'App with label admin_scripts could not be found')
def test_builtin_with_bad_settings(self): def test_builtin_with_bad_settings(self):
"minimal: django-admin builtin commands fail if settings file (from argument) doesn't exist" "minimal: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=regressiontests.bad_settings', 'admin_scripts'] args = ['sqlall','--settings=bad_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_builtin_with_bad_environment(self): def test_builtin_with_bad_environment(self):
"minimal: django-admin builtin commands fail if settings file (from environment) doesn't exist" "minimal: django-admin builtin commands fail if settings file (from environment) doesn't exist"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.bad_settings') out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self): def test_custom_command(self):
"minimal: django-admin can't execute user commands" "minimal: django-admin can't execute user commands"
@ -262,7 +262,7 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
def test_custom_command_with_settings(self): def test_custom_command_with_settings(self):
"minimal: django-admin can't execute user commands, even if settings are provided as argument" "minimal: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=regressiontests.settings'] args = ['noargs_command', '--settings=settings']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -270,7 +270,7 @@ class DjangoAdminMinimalSettings(AdminScriptTestCase):
def test_custom_command_with_environment(self): def test_custom_command_with_environment(self):
"minimal: django-admin can't execute user commands, even if settings are provided in environment" "minimal: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command'] args = ['noargs_command']
out, err = self.run_django_admin(args,'regressiontests.settings') out, err = self.run_django_admin(args,'settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -293,7 +293,7 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
def test_builtin_with_settings(self): def test_builtin_with_settings(self):
"alternate: django-admin builtin commands succeed if settings are provided as argument" "alternate: django-admin builtin commands succeed if settings are provided as argument"
args = ['sqlall','--settings=regressiontests.alternate_settings', 'admin_scripts'] args = ['sqlall','--settings=alternate_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
@ -301,23 +301,23 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
def test_builtin_with_environment(self): def test_builtin_with_environment(self):
"alternate: django-admin builtin commands succeed if settings are provided in the environment" "alternate: django-admin builtin commands succeed if settings are provided in the environment"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.alternate_settings') out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
def test_builtin_with_bad_settings(self): def test_builtin_with_bad_settings(self):
"alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist" "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=regressiontests.bad_settings', 'admin_scripts'] args = ['sqlall','--settings=bad_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_builtin_with_bad_environment(self): def test_builtin_with_bad_environment(self):
"alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist" "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.bad_settings') out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self): def test_custom_command(self):
"alternate: django-admin can't execute user commands" "alternate: django-admin can't execute user commands"
@ -328,7 +328,7 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
def test_custom_command_with_settings(self): def test_custom_command_with_settings(self):
"alternate: django-admin can't execute user commands, even if settings are provided as argument" "alternate: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=regressiontests.alternate_settings'] args = ['noargs_command', '--settings=alternate_settings']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -336,7 +336,7 @@ class DjangoAdminAlternateSettings(AdminScriptTestCase):
def test_custom_command_with_environment(self): def test_custom_command_with_environment(self):
"alternate: django-admin can't execute user commands, even if settings are provided in environment" "alternate: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command'] args = ['noargs_command']
out, err = self.run_django_admin(args,'regressiontests.alternate_settings') out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -364,7 +364,7 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
def test_builtin_with_settings(self): def test_builtin_with_settings(self):
"alternate: django-admin builtin commands succeed if settings are provided as argument" "alternate: django-admin builtin commands succeed if settings are provided as argument"
args = ['sqlall','--settings=regressiontests.alternate_settings', 'admin_scripts'] args = ['sqlall','--settings=alternate_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
@ -372,22 +372,22 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
def test_builtin_with_environment(self): def test_builtin_with_environment(self):
"alternate: django-admin builtin commands succeed if settings are provided in the environment" "alternate: django-admin builtin commands succeed if settings are provided in the environment"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.alternate_settings') out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, 'CREATE TABLE') self.assertOutput(out, 'CREATE TABLE')
def test_builtin_with_bad_settings(self): def test_builtin_with_bad_settings(self):
"alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist" "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist"
args = ['sqlall','--settings=regressiontests.bad_settings', 'admin_scripts'] args = ['sqlall','--settings=bad_settings', 'admin_scripts']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_builtin_with_bad_environment(self): def test_builtin_with_bad_environment(self):
"alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist" "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist"
args = ['sqlall','admin_scripts'] args = ['sqlall','admin_scripts']
out, err = self.run_django_admin(args,'regressiontests.bad_settings') out, err = self.run_django_admin(args,'bad_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Could not import settings 'regressiontests.bad_settings'") self.assertOutput(err, "Could not import settings 'bad_settings'")
def test_custom_command(self): def test_custom_command(self):
"alternate: django-admin can't execute user commands" "alternate: django-admin can't execute user commands"
@ -398,7 +398,7 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
def test_custom_command_with_settings(self): def test_custom_command_with_settings(self):
"alternate: django-admin can't execute user commands, even if settings are provided as argument" "alternate: django-admin can't execute user commands, even if settings are provided as argument"
args = ['noargs_command', '--settings=regressiontests.alternate_settings'] args = ['noargs_command', '--settings=alternate_settings']
out, err = self.run_django_admin(args) out, err = self.run_django_admin(args)
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -406,7 +406,7 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
def test_custom_command_with_environment(self): def test_custom_command_with_environment(self):
"alternate: django-admin can't execute user commands, even if settings are provided in environment" "alternate: django-admin can't execute user commands, even if settings are provided in environment"
args = ['noargs_command'] args = ['noargs_command']
out, err = self.run_django_admin(args,'regressiontests.alternate_settings') out, err = self.run_django_admin(args,'alternate_settings')
self.assertNoOutput(out) self.assertNoOutput(out)
self.assertOutput(err, "Unknown command: 'noargs_command'") self.assertOutput(err, "Unknown command: 'noargs_command'")
@ -725,26 +725,62 @@ class CommandTypes(AdminScriptTestCase):
def tearDown(self): def tearDown(self):
self.remove_settings('settings.py') self.remove_settings('settings.py')
def test_version(self):
"--version is handled as a special case"
args = ['--version']
out, err = self.run_manage(args)
self.assertNoOutput(err)
# Only check the first part of the version number
self.assertOutput(out, get_version().split('-')[0])
def test_help(self):
"--help is handled as a special case"
args = ['--help']
out, err = self.run_manage(args)
self.assertOutput(out, "Usage: manage.py [options]")
self.assertOutput(err, "Type 'manage.py help <subcommand>' for help on a specific subcommand.")
def test_specific_help(self):
"--help can be used on a specific command"
args = ['sqlall','--help']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).")
def test_base_command(self): def test_base_command(self):
"User BaseCommands can execute when a label is provided" "User BaseCommands can execute when a label is provided"
args = ['base_command','testlabel'] args = ['base_command','testlabel']
out, err = self.run_manage(args) out, err = self.run_manage(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_base_command_no_label(self): def test_base_command_no_label(self):
"User BaseCommands can execute when no labels are provided" "User BaseCommands can execute when no labels are provided"
args = ['base_command'] args = ['base_command']
out, err = self.run_manage(args) out, err = self.run_manage(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_base_command_multiple_label(self): def test_base_command_multiple_label(self):
"User BaseCommands can execute when no labels are provided" "User BaseCommands can execute when no labels are provided"
args = ['base_command','testlabel','anotherlabel'] args = ['base_command','testlabel','anotherlabel']
out, err = self.run_manage(args) out, err = self.run_manage(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_base_command_with_option(self):
"User BaseCommands can execute with options when a label is provided"
args = ['base_command','testlabel','--option_a=x']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_base_command_with_options(self):
"User BaseCommands can execute with multiple options when a label is provided"
args = ['base_command','testlabel','-a','x','--option_b=y']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_noargs(self): def test_noargs(self):
"NoArg Commands can be executed" "NoArg Commands can be executed"
@ -765,8 +801,9 @@ class CommandTypes(AdminScriptTestCase):
out, err = self.run_manage(args) out, err = self.run_manage(args)
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'") self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
self.assertOutput(out, os.sep.join(['django','contrib','auth','models.pyc']) + "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, os.sep.join(['django','contrib','auth','models.py']))
self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_app_command_no_apps(self): def test_app_command_no_apps(self):
"User AppCommands raise an error when no app name is provided" "User AppCommands raise an error when no app name is provided"
args = ['app_command'] args = ['app_command']
@ -781,7 +818,8 @@ class CommandTypes(AdminScriptTestCase):
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'") self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
self.assertOutput(out, os.sep.join(['django','contrib','auth','models.pyc']) + "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, os.sep.join(['django','contrib','auth','models.pyc']) + "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'") self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
self.assertOutput(out, os.sep.join(['django','contrib','contenttypes','models.pyc']) + "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, os.sep.join(['django','contrib','contenttypes','models.py']))
self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
def test_app_command_invalid_appname(self): def test_app_command_invalid_appname(self):
"User AppCommands can execute when a single app name is provided" "User AppCommands can execute when a single app name is provided"
@ -815,3 +853,56 @@ class CommandTypes(AdminScriptTestCase):
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None)]") self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None)]")
class ArgumentOrder(AdminScriptTestCase):
"""Tests for 2-stage argument parsing scheme.
django-admin command arguments are parsed in 2 parts; the core arguments
(--settings, --traceback and --pythonpath) are parsed using a Lax parser.
This Lax parser ignores any unknown options. Then the full settings are
passed to the command parser, which extracts commands of interest to the
individual command.
"""
def setUp(self):
self.write_settings('settings.py', apps=['django.contrib.auth','django.contrib.contenttypes'])
self.write_settings('alternate_settings.py')
def tearDown(self):
self.remove_settings('settings.py')
self.remove_settings('alternate_settings.py')
def test_setting_then_option(self):
"Options passed after settings are correctly handled"
args = ['base_command','testlabel','--settings=alternate_settings','--option_a=x']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None)]")
def test_setting_then_short_option(self):
"Short options passed after settings are correctly handled"
args = ['base_command','testlabel','--settings=alternate_settings','--option_a=x']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None)]")
def test_option_then_setting(self):
"Options passed before settings are correctly handled"
args = ['base_command','testlabel','--option_a=x','--settings=alternate_settings']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None)]")
def test_short_option_then_setting(self):
"Short options passed before settings are correctly handled"
args = ['base_command','testlabel','-a','x','--settings=alternate_settings']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None)]")
def test_option_then_setting_then_option(self):
"Options are correctly handled when they are passed before and after a setting"
args = ['base_command','testlabel','--option_a=x','--settings=alternate_settings','--option_b=y']
out, err = self.run_manage(args)
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None)]")

View File

@ -537,6 +537,12 @@ u'123'
from django.template.defaultfilters import * from django.template.defaultfilters import *
import datetime import datetime
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
if __name__ == '__main__': if __name__ == '__main__':
import doctest import doctest
doctest.testmod() doctest.testmod()

View File

@ -25,7 +25,7 @@ class FileUploadTests(TestCase):
file2.seek(0) file2.seek(0)
# This file contains chinese symbols for a name. # This file contains chinese symbols for a name.
file3 = open(os.path.join(tdir, u'test_&#20013;&#25991;_Orl\u00e9ans.jpg'), 'w+b') file3 = open(os.path.join(tdir, u'test_&#20013;&#25991;_Orl\u00e9ans.jpg'.encode('utf-8')), 'w+b')
file3.write('b' * (2 ** 10)) file3.write('b' * (2 ** 10))
file3.seek(0) file3.seek(0)

View File

@ -6,6 +6,12 @@ import datetime
from django.db import models from django.db import models
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Place(models.Model): class Place(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
address = models.CharField(max_length=80) address = models.CharField(max_length=80)

View File

@ -8,6 +8,12 @@ import pickle
from django.db import models from django.db import models
from django.db.models.query import Q from django.db.models.query import Q
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted
class Tag(models.Model): class Tag(models.Model):
name = models.CharField(max_length=10) name = models.CharField(max_length=10)
parent = models.ForeignKey('self', blank=True, null=True, parent = models.ForeignKey('self', blank=True, null=True,
@ -805,5 +811,14 @@ Bug #7371
>>> Related.objects.order_by('custom') >>> Related.objects.order_by('custom')
[] []
Bug #7448, #7707 -- Complex objects should be converted to strings before being
used in lookups.
>>> Item.objects.filter(created__in=[time1, time2])
[<Item: one>, <Item: two>]
Bug #7698 -- People like to slice with '0' as the high-water mark.
>>> Item.objects.all()[0:0]
[]
"""} """}

View File

@ -44,8 +44,15 @@
>>> d.keys() >>> d.keys()
[2, 1] [2, 1]
>>> real_dict = dict(tuples) >>> real_dict = dict(tuples)
>>> real_dict.values() >>> sorted(real_dict.values())
['one', 'second-two'] ['one', 'second-two']
>>> d.values() >>> d.values() # Here the order of SortedDict values *is* what we are testing
['second-two', 'one'] ['second-two', 'one']
""" """
# Python 2.3 doesn't have sorted()
try:
sorted
except NameError:
from django.utils.itercompat import sorted

View File

@ -0,0 +1,15 @@
"""
# Tests of the utils itercompat library.
>>> from django.utils.itercompat import sorted as compat_sorted
# Check the replacement version of sorted
>>> x = [5,1,4,2,3]
>>> y = compat_sorted(x)
>>> print y
[1, 2, 3, 4, 5]
>>> print x
[5, 1, 4, 2, 3]
"""

View File

@ -8,12 +8,14 @@ from django.utils import html, checksums
import timesince import timesince
import datastructures import datastructures
import itercompat
from decorators import DecoratorFromMiddlewareTests from decorators import DecoratorFromMiddlewareTests
# Extra tests # Extra tests
__test__ = { __test__ = {
'timesince': timesince, 'timesince': timesince,
'datastructures': datastructures, 'datastructures': datastructures,
'itercompat': itercompat,
} }
class TestUtilsHtml(TestCase): class TestUtilsHtml(TestCase):