1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

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

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7022 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2008-01-17 18:12:24 +00:00
parent c080e441f3
commit daa467d79e
49 changed files with 5384 additions and 2865 deletions

View File

@ -70,6 +70,7 @@ answer newbie questions, and generally made Django that much better:
Andrew Brehaut <http://brehaut.net/blog>
brut.alll@gmail.com
Jonathan Buchanan <jonathan.buchanan@gmail.com>
Can Burak Çilingir <canburak@cs.bilgi.edu.tr>
Trevor Caira <trevor@caira.com>
Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
Graham Carlyle <graham.carlyle@maplecroft.net>
@ -175,6 +176,7 @@ answer newbie questions, and generally made Django that much better:
jpellerin@gmail.com
junzhang.jn@gmail.com
Antti Kaihola <http://akaihola.blogspot.com/>
Bahadır Kandemir <bahadir@pardus.org.tr>
Nagy Károly <charlie@rendszergazda.com>
Erik Karulf <erik@karulf.com>
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>

View File

@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-12-02 22:26+0100\n"
"PO-Revision-Date: 2007-12-02 22:32+0100\n"
"POT-Creation-Date: 2007-12-29 21:28+0100\n"
"PO-Revision-Date: 2007-12-30 11:38+0100\n"
"Last-Translator: Marc Fargas <telenieko@telenieko.com>\n"
"Language-Team: <es@li.org>\n"
"MIME-Version: 1.0\n"
@ -1691,41 +1691,42 @@ msgstr "demà"
msgid "yesterday"
msgstr "ahir"
#: contrib/localflavor/ar/forms.py:30 contrib/localflavor/ar/forms.py:38
#: contrib/localflavor/ar/forms.py:28
msgid "Enter a postal code in the format NNNN or ANNNNAAA."
msgstr "Introdueixi un codi postal en el format NNNN or ANNNNAAA."
msgstr "Introdueixi un codi postal en el format NNNN o ANNNNAAA."
#: contrib/localflavor/ar/forms.py:61 contrib/localflavor/br/forms.py:103
#: contrib/localflavor/pe/forms.py:34 contrib/localflavor/pe/forms.py:57
#: contrib/localflavor/ar/forms.py:50 contrib/localflavor/br/forms.py:96
#: contrib/localflavor/br/forms.py:135 contrib/localflavor/pe/forms.py:23
#: contrib/localflavor/pe/forms.py:51
msgid "This field requires only numbers."
msgstr "Aquest camps requereix només números."
#: contrib/localflavor/ar/forms.py:64
#: contrib/localflavor/ar/forms.py:51
msgid "This field requires 7 or 8 digits."
msgstr "Aquest camp requereix 7 o 8 dígits."
#: contrib/localflavor/ar/forms.py:75
#: contrib/localflavor/ar/forms.py:80
msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
msgstr ""
"Introdueixi un número CUIT vàlid en el format XX-XXXXXXXX-X o XXXXXXXXXXXX."
#: contrib/localflavor/ar/forms.py:88
#: contrib/localflavor/ar/forms.py:81
msgid "Invalid CUIT."
msgstr "Invàlid CUIT."
#: contrib/localflavor/au/forms.py:18
#: contrib/localflavor/au/forms.py:16
msgid "Enter a 4 digit post code."
msgstr "Introdueixi un codi postal de 4 dígits."
#: contrib/localflavor/br/forms.py:23
#: contrib/localflavor/br/forms.py:21
msgid "Enter a zip code in the format XXXXX-XXX."
msgstr "Introdueixi un codi zip en el format XXXXX-XXX."
#: contrib/localflavor/br/forms.py:35
#: contrib/localflavor/br/forms.py:30
msgid "Phone numbers must be in XX-XXXX-XXXX format."
msgstr "El número de telèfon ha de ser en el format XX-XXXX-XXXX."
#: contrib/localflavor/br/forms.py:68
#: contrib/localflavor/br/forms.py:58
msgid ""
"Select a valid brazilian state. That state is not one of the available "
"states."
@ -1733,30 +1734,30 @@ msgstr ""
"Seleccioni un estat brasiler vàlid. Aquest estat no és un dels estats "
"disponibles."
#: contrib/localflavor/br/forms.py:105
msgid "This field requires at most 11 digits or 14 characters."
msgstr "Aquest camp requereix com a màxim 11 dígits o 14 caracters."
#: contrib/localflavor/br/forms.py:115
#: contrib/localflavor/br/forms.py:94
msgid "Invalid CPF number."
msgstr "Número CPF invàlid."
#: contrib/localflavor/br/forms.py:137
msgid "This field requires at least 14 digits"
msgstr "Aquest camp requereix almenys 14 dígits."
#: contrib/localflavor/br/forms.py:95
msgid "This field requires at most 11 digits or 14 characters."
msgstr "Aquest camp requereix com a màxim 11 dígits o 14 caracters."
#: contrib/localflavor/br/forms.py:147
#: contrib/localflavor/br/forms.py:134
msgid "Invalid CNPJ number."
msgstr "Número CNPJ invàlid."
#: contrib/localflavor/ca/forms.py:19
#: contrib/localflavor/br/forms.py:136
msgid "This field requires at least 14 digits"
msgstr "Aquest camp requereix almenys 14 dígits."
#: contrib/localflavor/ca/forms.py:17
msgid "Enter a postal code in the format XXX XXX."
msgstr "Introdueixi un codi postal en el format XXX XXX."
#: contrib/localflavor/ca/forms.py:81
#: contrib/localflavor/ca/forms.py:88
msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format."
msgstr ""
"Introdueixi un número vàlid de la Seguretat Social de Canada en el format "
"Introdueixi un número vàlid de la Seguretat Social de Canadà en el format "
"XXX-XXX-XXXX."
#: contrib/localflavor/ch/ch_states.py:5
@ -1863,11 +1864,11 @@ msgstr "Zug"
msgid "Zurich"
msgstr "Zurich"
#: contrib/localflavor/ch/forms.py:18 contrib/localflavor/no/forms.py:14
#: contrib/localflavor/ch/forms.py:16 contrib/localflavor/no/forms.py:12
msgid "Enter a zip code in the format XXXX."
msgstr "Introdueixi un codi zip en el format XXXX."
#: contrib/localflavor/ch/forms.py:90
#: contrib/localflavor/ch/forms.py:64
msgid ""
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
"1234567890 format."
@ -1875,13 +1876,17 @@ msgstr ""
"Introdueixi un número de identificació o de passaport Suïssos en els formats "
"1234567890 o X1234567<0."
#: contrib/localflavor/cl/forms.py:32
msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
#: contrib/localflavor/cl/forms.py:29
msgid "Enter a valid Chilean RUT."
msgstr "Introdueixi un RUT Xilè vàlid."
#: contrib/localflavor/cl/forms.py:30
msgid "Enter a valid Chilean RUT. The format is XX.XXX.XXX-X."
msgstr "Introdueixi un RUT Xilè vàlid. El format és XX.XXX.XXX-X"
#: contrib/localflavor/cl/forms.py:37
msgid "Enter valid a Chilean RUT"
msgstr "Introdueixi un RUT Xilè vàlid."
#: contrib/localflavor/cl/forms.py:31
msgid "The Chilean RUT is not valid."
msgstr "El RUT Xilè no és vàlid."
#: contrib/localflavor/de/de_states.py:5
msgid "Baden-Wuerttemberg"
@ -1947,12 +1952,12 @@ msgstr "Schleswig-Holstein"
msgid "Thuringia"
msgstr "Thuringia"
#: contrib/localflavor/de/forms.py:16 contrib/localflavor/fi/forms.py:14
#: contrib/localflavor/fr/forms.py:17
#: contrib/localflavor/de/forms.py:14 contrib/localflavor/fi/forms.py:12
#: contrib/localflavor/fr/forms.py:15
msgid "Enter a zip code in the format XXXXX."
msgstr "Introdueixi un codi zip en el format XXXXX."
#: contrib/localflavor/de/forms.py:60
#: contrib/localflavor/de/forms.py:41
msgid ""
"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
"format."
@ -2227,7 +2232,7 @@ msgstr "Comunitat Foral de Navarra"
msgid "Valencian Community"
msgstr "Comunitat Valenciana"
#: contrib/localflavor/es/forms.py:22
#: contrib/localflavor/es/forms.py:19
msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
msgstr "Introdueixi un codi postal en rang i format 01XXX - 52XXX."
@ -2239,40 +2244,42 @@ msgstr ""
"Introdueixi un número de telèfon vàlid en un dels formats 6XXXXXXXX, "
"8XXXXXXXX o 9XXXXXXXX."
#: contrib/localflavor/es/forms.py:73 contrib/localflavor/es/forms.py:108
#: db/models/fields/related.py:55
#, python-format
msgid "Please enter a valid %s."
msgstr "Si us plau, introdueixi un %s vàlid."
#: contrib/localflavor/es/forms.py:66
msgid "Please enter a valid NIF, NIE, or CIF."
msgstr "Si us plau, introdueixi un NIF, NIE o CIF vàlid."
#: contrib/localflavor/es/forms.py:91
#: contrib/localflavor/es/forms.py:67
msgid "Please enter a valid NIF or NIE."
msgstr "Si us plau, introdueixi un NIF o NIE vàlid."
#: contrib/localflavor/es/forms.py:68
msgid "Invalid checksum for NIF."
msgstr "Validació invàlida del NIF."
#: contrib/localflavor/es/forms.py:97
#: contrib/localflavor/es/forms.py:69
msgid "Invalid checksum for NIE."
msgstr "Validació invàlida del NIE."
#: contrib/localflavor/es/forms.py:106
#: contrib/localflavor/es/forms.py:70
msgid "Invalid checksum for CIF."
msgstr "Validació invàlida del CIF."
#: contrib/localflavor/es/forms.py:136
#: contrib/localflavor/es/forms.py:142
msgid ""
"Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
msgstr ""
"Introdueixi un número de compte bancari vàlid en el format XXXX-XXXX-XX-"
"XXXXXXXXXX."
#: contrib/localflavor/es/forms.py:150
#: contrib/localflavor/es/forms.py:143
msgid "Invalid checksum for bank account number."
msgstr "Validació invàlida del número de compte bancari."
#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
#: contrib/localflavor/fi/forms.py:28
msgid "Enter a valid Finnish social security number."
msgstr "Introdueixi un número vàlid de la seguretat social finlandesa."
#: contrib/localflavor/in_/forms.py:16
#: contrib/localflavor/in_/forms.py:14
msgid "Enter a zip code in the format XXXXXXX."
msgstr "Introdueixi un codi zip en el format XXXXXXX."
@ -2282,15 +2289,15 @@ msgid ""
msgstr ""
"Introdueixi un número de identificació d'Islàndia. El format és XXXXXX-XXXX."
#: contrib/localflavor/is_/forms.py:31
#: contrib/localflavor/is_/forms.py:18
msgid "The Icelandic identification number is not valid."
msgstr "El número de identificació d'Islàndia no és vàlid."
#: contrib/localflavor/it/forms.py:16
#: contrib/localflavor/it/forms.py:14
msgid "Enter a valid zip code."
msgstr "Introdueixi un codi zip vàlid."
#: contrib/localflavor/it/forms.py:41
#: contrib/localflavor/it/forms.py:43
msgid "Enter a valid Social Security number."
msgstr "Introdueixi un número valid de la Seguretat Social."
@ -2298,7 +2305,7 @@ msgstr "Introdueixi un número valid de la Seguretat Social."
msgid "Enter a valid VAT number."
msgstr "Introdueixi un número de IVA (VAT) vàlid."
#: contrib/localflavor/jp/forms.py:21
#: contrib/localflavor/jp/forms.py:19
msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
msgstr "Introdueixi un codi postal en el format XXXXXXX o XX-XXXX."
@ -2490,15 +2497,143 @@ msgstr "Kagoshima"
msgid "Okinawa"
msgstr "Okinawa"
#: contrib/localflavor/nl/forms.py:25
#: contrib/localflavor/mx/mx_states.py:12
msgid "Aguascalientes"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:13
msgid "Baja California"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:14
msgid "Baja California Sur"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:15
msgid "Campeche"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:16
msgid "Chihuahua"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:17
msgid "Chiapas"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:18
msgid "Coahuila"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:19
msgid "Colima"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:20
msgid "Distrito Federal"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:21
msgid "Durango"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:22
msgid "Guerrero"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:23
msgid "Guanajuato"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:24
msgid "Hidalgo"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:25
msgid "Jalisco"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:26
msgid "Estado de México"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:27
msgid "Michoacán"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:28
msgid "Morelos"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:29
msgid "Nayarit"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:30
msgid "Nuevo León"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:31
msgid "Oaxaca"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:32
msgid "Puebla"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:33
msgid "Querétaro"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:34
msgid "Quintana Roo"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:35
msgid "Sinaloa"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:36
msgid "San Luis Potosí"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:37
msgid "Sonora"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:38
msgid "Tabasco"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:39
msgid "Tamaulipas"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:40
msgid "Tlaxcala"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:41
msgid "Veracruz"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:42
msgid "Yucatán"
msgstr ""
#: contrib/localflavor/mx/mx_states.py:43
msgid "Zacatecas"
msgstr ""
#: contrib/localflavor/nl/forms.py:21
msgid "Enter a valid postal code"
msgstr "Introdueixi un codi postal vàlid."
#: contrib/localflavor/nl/forms.py:53
#: contrib/localflavor/nl/forms.py:52
msgid "Enter a valid phone number"
msgstr "Introdueixi un número de telèfon vàlid."
#: contrib/localflavor/nl/forms.py:76
#: contrib/localflavor/nl/forms.py:78
msgid "Enter a valid SoFi number"
msgstr "Introdueixi un número SoFi vàlid."
@ -2550,23 +2685,23 @@ msgstr "Zeeland"
msgid "Zuid-Holland"
msgstr "Zuid-Holland"
#: contrib/localflavor/no/forms.py:35
#: contrib/localflavor/no/forms.py:33
msgid "Enter a valid Norwegian social security number."
msgstr "Introdueixi un número de la seguretat social Noruega vàlid."
#: contrib/localflavor/pe/forms.py:36
#: contrib/localflavor/pe/forms.py:24
msgid "This field requires 8 digits."
msgstr "Aquest camp requereix 8 dígits."
#: contrib/localflavor/pe/forms.py:59
#: contrib/localflavor/pe/forms.py:52
msgid "This field requires 11 digits."
msgstr "Aquest camp requereix 11 dígits."
#: contrib/localflavor/pl/forms.py:41
#: contrib/localflavor/pl/forms.py:39
msgid "National Identification Number consists of 11 digits."
msgstr "El número d'identidicació nacional està compost de 11 digits."
#: contrib/localflavor/pl/forms.py:47
#: contrib/localflavor/pl/forms.py:40
msgid "Wrong checksum for the National Identification Number."
msgstr "Validació invàlida del número d'identificació nacional."
@ -2575,11 +2710,11 @@ msgid ""
"Enter a tax number field (NIP) in the format XXX-XXX-XX-XX or XX-XX-XXX-XXX."
msgstr "Introdueixi un número NIP en el format XXX-XXX-XX-XX o XX-XX-XXX-XXX."
#: contrib/localflavor/pl/forms.py:78
#: contrib/localflavor/pl/forms.py:73
msgid "Wrong checksum for the Tax Number (NIP)."
msgstr "Validació invàlida del número tributari (NIP)."
#: contrib/localflavor/pl/forms.py:107
#: contrib/localflavor/pl/forms.py:112
msgid "National Business Register Number (REGON) consists of 7 or 9 digits."
msgstr ""
"El número nacional de registre de negocis (REGON) consisteix en 7 o 9 dígits."
@ -2588,7 +2723,7 @@ msgstr ""
msgid "Wrong checksum for the National Business Register Number (REGON)."
msgstr "Validació invàlida del número nacional de registre de negocis."
#: contrib/localflavor/pl/forms.py:148
#: contrib/localflavor/pl/forms.py:156
msgid "Enter a postal code in the format XX-XXX."
msgstr "Introdueixi un codi postal en el format XX-XXX."
@ -2656,7 +2791,7 @@ msgstr "Greater Poland"
msgid "West Pomerania"
msgstr "West Pomerania"
#: contrib/localflavor/sk/forms.py:32
#: contrib/localflavor/sk/forms.py:30
msgid "Enter a postal code in the format XXXXX or XXX XX."
msgstr "Introdueixi un codi postal en el format XXXXX or XXX XX."
@ -3008,27 +3143,302 @@ msgstr "Regió de Trnava"
msgid "Zilina region"
msgstr "Regió de Zilina"
#: contrib/localflavor/uk/forms.py:18
msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr ""
"Introdueixi un codi postal. És necessari un espai entre les dues parts del "
"codi postal."
#: contrib/localflavor/uk/forms.py:21
msgid "Enter a valid postcode."
msgstr "Introdueixi un codi postal vàlid."
#: contrib/localflavor/us/forms.py:18
#: contrib/localflavor/uk/uk_regions.py:11
msgid "Bedfordshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:12
msgid "Buckinghamshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:14
msgid "Cheshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:15
msgid "Cornwall and Isles of Scilly"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:16
msgid "Cumbria"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:17
msgid "Derbyshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:18
msgid "Devon"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:19
msgid "Dorset"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:20
msgid "Durham"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:21
msgid "East Sussex"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:22
msgid "Essex"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:23
msgid "Gloucestershire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:24
msgid "Greater London"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:25
msgid "Greater Manchester"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:26
msgid "Hampshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:27
msgid "Hertfordshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:28
msgid "Kent"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:29
msgid "Lancashire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:30
msgid "Leicestershire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:31
msgid "Lincolnshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:32
msgid "Merseyside"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:33
msgid "Norfolk"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:34
msgid "North Yorkshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:35
msgid "Northamptonshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:36
msgid "Northumberland"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:37
msgid "Nottinghamshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:38
msgid "Oxfordshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:39
msgid "Shropshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:40
msgid "Somerset"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:41
msgid "South Yorkshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:42
msgid "Staffordshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:43
msgid "Suffolk"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:44
msgid "Surrey"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:45
msgid "Tyne and Wear"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:46
msgid "Warwickshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:47
msgid "West Midlands"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:48
msgid "West Sussex"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:49
msgid "West Yorkshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:50
msgid "Wiltshire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:51
msgid "Worcestershire"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:55
msgid "County Antrim"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:56
msgid "County Armagh"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:57
#: contrib/localflavor/uk/uk_regions.py:58
msgid "County Down"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:59
msgid "County Londonderry"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:60
msgid "County Tyrone"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:64
msgid "Clwyd"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:65
msgid "Dyfed"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:66
msgid "Gwent"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:67
msgid "Gwynedd"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:68
msgid "Mid Glamorgan"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:69
msgid "Powys"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:70
msgid "South Glamorgan"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:71
msgid "West Glamorgan"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:75
msgid "Borders"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:76
msgid "Central Scotland"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:77
msgid "Dumfries and Galloway"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:78
msgid "Fife"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:79
msgid "Grampian"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:80
msgid "Highland"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:81
msgid "Lothian"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:82
msgid "Orkney Islands"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:83
msgid "Shetland Islands"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:84
msgid "Strathclyde"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:85
msgid "Tayside"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:86
msgid "Western Isles"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:90
msgid "England"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:91
msgid "Northern Ireland"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:92
msgid "Scotland"
msgstr ""
#: contrib/localflavor/uk/uk_regions.py:93
msgid "Wales"
msgstr ""
#: contrib/localflavor/us/forms.py:16
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
msgstr "Introdueixi un codi zip en el format XXXXX o XXXXX-XXXX."
#: contrib/localflavor/us/forms.py:51
#: contrib/localflavor/us/forms.py:54
msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
msgstr ""
"Introdueixi un número vàlid de la Seguretat Social dels E.U.A. en el format "
"XXX-XX-XXXX."
#: contrib/localflavor/za/forms.py:22
#: contrib/localflavor/za/forms.py:20
msgid "Enter a valid South African ID number"
msgstr "Introdueixi un número d'Identitat Sud Africà valid"
#: contrib/localflavor/za/forms.py:57
#: contrib/localflavor/za/forms.py:54
msgid "Enter a valid South African postal code"
msgstr "Introdueixi un codi postal Sud Africà vàlid."
@ -3503,6 +3913,11 @@ msgstr "Introdueixi un nom de fitxer vàlid."
msgid "This value must be either None, True or False."
msgstr "Aquest valor ha de ser None (Cap), True (Veritat) o False (Fals)"
#: db/models/fields/related.py:55
#, python-format
msgid "Please enter a valid %s."
msgstr "Si us plau, introdueixi un %s vàlid."
#: db/models/fields/related.py:658
msgid "Separate multiple IDs with commas."
msgstr "Separi múltiples IDs amb comes."
@ -3599,7 +4014,7 @@ msgstr "Introdueixi una URL vàlida."
msgid "This URL appears to be a broken link."
msgstr "Aquesta URL sembla ser un enllaç trencat."
#: newforms/fields.py:555 newforms/models.py:155
#: newforms/fields.py:555 newforms/models.py:317
msgid "Select a valid choice. That choice is not one of the available choices."
msgstr ""
"Esculli una opció vàlida; Aquesta opció no és una de les opcions disponibles."
@ -3609,7 +4024,7 @@ msgstr ""
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr "Esculli una opció vàlida. %(value)s no és una de les opcions vàlides."
#: newforms/fields.py:595 newforms/fields.py:657 newforms/models.py:215
#: newforms/fields.py:595 newforms/fields.py:657 newforms/models.py:377
msgid "Enter a list of values."
msgstr "Introdueixi una llista de valors."
@ -3617,7 +4032,7 @@ msgstr "Introdueixi una llista de valors."
msgid "Enter a valid IPv4 address."
msgstr "Introdueixi una adreça IPv4 vàlida."
#: newforms/models.py:216
#: newforms/models.py:378
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr "Esculli una opció vàlida; %s' no és una de les opcions vàlides."
@ -3650,28 +4065,28 @@ msgstr "Introdueixi un número positiu."
msgid "Enter a whole number between 0 and 32,767."
msgstr "Introdueixi un número entre 0 i 32,767."
#: template/defaultfilters.py:658
#: template/defaultfilters.py:683
msgid "yes,no,maybe"
msgstr "si,no,potser"
#: template/defaultfilters.py:689
#: template/defaultfilters.py:714
#, python-format
msgid "%(size)d byte"
msgid_plural "%(size)d bytes"
msgstr[0] "%(size)d byte"
msgstr[1] "%(size)d bytes"
#: template/defaultfilters.py:691
#: template/defaultfilters.py:716
#, python-format
msgid "%.1f KB"
msgstr "%.1f KB"
#: template/defaultfilters.py:693
#: template/defaultfilters.py:718
#, python-format
msgid "%.1f MB"
msgstr "%.1f MB"
#: template/defaultfilters.py:694
#: template/defaultfilters.py:719
#, python-format
msgid "%.1f GB"
msgstr "%.1f GB"
@ -3968,3 +4383,9 @@ msgstr "El/La %(verbose_name)s s'ha actualtzat amb èxit."
#, python-format
msgid "The %(verbose_name)s was deleted."
msgstr "El %(verbose_name)s s'ha eliminat."
#~ msgid ""
#~ "Enter a postcode. A space is required between the two postcode parts."
#~ msgstr ""
#~ "Introdueixi un codi postal. És necessari un espai entre les dues parts "
#~ "del codi postal."

File diff suppressed because it is too large Load Diff

View File

@ -1,118 +1,117 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# translation of djangojs.po to Hrvatski jezik
# This file is distributed under the same license as the Django package.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: djangojs\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-08-13 11:13+1000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"PO-Revision-Date: 2008-01-05 01:45+0100\n"
"Last-Translator: Aljosa Mohorovic <aljosa.mohorovic@gmail.com>\n"
"Language-Team: Hrvatski jezik\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.11.4\n"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr ""
msgstr "Dostupno %s"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr ""
msgstr "Odaberi sve"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr ""
msgstr "Dodaj"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr ""
msgstr "Ukloni"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr ""
msgstr "Odabrano %s"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr ""
msgstr "Odaberi iz izbora i klikni "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr ""
msgstr "Očisti sve"
#: contrib/admin/media/js/dateparse.js:32
#: contrib/admin/media/js/calendar.js:24
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
msgstr "Siječanj Veljača Ožujak Travanj Svibanj Lipanj Srpanj Kolovoz Rujan Listopad Studeni Prosinac"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr ""
msgstr "Nedjelja Ponedjeljak Utorak Srijeda Četvrtak Petak Subota"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr ""
msgstr "N P U S Č P S"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr ""
msgstr "Sada"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr ""
msgstr "Sat"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr ""
msgstr "Izaberite vrijeme"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr ""
msgstr "Ponoć"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr ""
msgstr "6 ujutro"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr ""
msgstr "Podne"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr ""
msgstr "Odustani"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr ""
msgstr "Danas"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr ""
msgstr "Kalendar"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr ""
msgstr "Jučer"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr ""
msgstr "Sutra"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
msgstr ""
msgstr "Prikaži"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
msgstr ""
msgstr "Sakri"

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,13 @@
# translation of django.po to Turkish
# Django 0.95
# Copyright (C) 2006 Django
# This file is distributed under the same license as the Django package.
#
# Can Burak Çilingir <canburak@cs.bilgi.edu.tr>, 2007. (Slight modifications)
# Bahadır Kandemir <bahadir@pardus.org.tr>, 2006.
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-03-14 01:38+0200\n"
"PO-Revision-Date: 2007-03-14 02:06+0200\n"
"Last-Translator: Bahadır Kandemir <bahadir@pardus.org.tr>\n"
"PO-Revision-Date: 2007-12-30 12:15+0200\n"
"Last-Translator: Can Burak Çilingir <canburak@cs.bilgi.edu.tr>\n"
"Language-Team: Turkish <bahadir@pardus.org.tr>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -157,7 +153,7 @@ msgstr "Bengali Dili"
#: conf/global_settings.py:41
msgid "Catalan"
msgstr ""
msgstr "Katalanca"
#: conf/global_settings.py:42
msgid "Czech"
@ -225,15 +221,15 @@ msgstr "Japonca"
#: conf/global_settings.py:58
msgid "Kannada"
msgstr ""
msgstr "Kannada Dili"
#: conf/global_settings.py:59
msgid "Latvian"
msgstr ""
msgstr "Leton Dili"
#: conf/global_settings.py:60
msgid "Macedonian"
msgstr ""
msgstr "Makedonca"
#: conf/global_settings.py:61
msgid "Dutch"
@ -245,7 +241,7 @@ msgstr "Norveç Dili"
#: conf/global_settings.py:63
msgid "Polish"
msgstr ""
msgstr "Lehçe"
#: conf/global_settings.py:64
msgid "Brazilian"
@ -281,7 +277,7 @@ msgstr "Tamilce"
#: conf/global_settings.py:72
msgid "Telugu"
msgstr ""
msgstr "Telugu Dili"
#: conf/global_settings.py:73
msgid "Turkish"
@ -615,7 +611,7 @@ msgstr "Geçerli bir seçimde bulunun; seçiminiz mevcut değerlerden birisi de
#: newforms/models.py:181 newforms/fields.py:378 newforms/fields.py:454
msgid "Enter a list of values."
msgstr ""
msgstr "Değer listesi giriniz."
#: newforms/models.py:187 newforms/fields.py:387
#, python-format
@ -648,11 +644,11 @@ msgstr "Geçerli bir tarih girin."
#: newforms/fields.py:190
msgid "Enter a valid time."
msgstr ""
msgstr "Geçerli bir zaman giriniz."
#: newforms/fields.py:226
msgid "Enter a valid date/time."
msgstr ""
msgstr "Geçerli bir tarih/zaman giriniz."
#: newforms/fields.py:240
msgid "Enter a valid value."
@ -668,40 +664,40 @@ msgstr "Bu URL kırık bir link gibi duruyor."
#: contrib/humanize/templatetags/humanize.py:17
msgid "th"
msgstr ""
msgstr "."
#: contrib/humanize/templatetags/humanize.py:17
msgid "st"
msgstr ""
msgstr "."
#: contrib/humanize/templatetags/humanize.py:17
msgid "nd"
msgstr ""
msgstr "."
#: contrib/humanize/templatetags/humanize.py:17
msgid "rd"
msgstr ""
msgstr "."
#: contrib/humanize/templatetags/humanize.py:47
#, python-format
msgid "%(value).1f million"
msgid_plural "%(value).1f million"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%(value).1f milyon"
msgstr[1] "%(value).1f milyon"
#: contrib/humanize/templatetags/humanize.py:50
#, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%(value).1f milyar"
msgstr[1] "%(value).1f milyar"
#: contrib/humanize/templatetags/humanize.py:53
#, python-format
msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%(value).1f trilyon"
msgstr[1] "%(value).1f trilyon"
#: contrib/humanize/templatetags/humanize.py:68
msgid "one"
@ -2029,6 +2025,8 @@ msgid ""
"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
"password form</a>."
msgstr ""
"'[algo]$[salt]$[hexdigest]' yazın ya da <a href=\"password/\">parola\n"
"değiştir formunu kullanın</a>."
#: contrib/auth/models.py:95
msgid "staff status"
@ -2152,7 +2150,7 @@ msgstr "Posta kodu girin. Posta kodunun iki kısmı arasında bir boşluk bırak
#: contrib/localflavor/usa/forms.py:17
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
msgstr ""
msgstr "XXXXX ya da XXXXX-XXXX biçiminde bir posta kodu yazın."
#: contrib/sessions/models.py:51
msgid "session key"
@ -2411,27 +2409,27 @@ msgstr[1] "dakika"
#: utils/dateformat.py:40
msgid "p.m."
msgstr ""
msgstr "ö.s."
#: utils/dateformat.py:41
msgid "a.m."
msgstr ""
msgstr "ö.ö."
#: utils/dateformat.py:46
msgid "PM"
msgstr ""
msgstr "ÖS"
#: utils/dateformat.py:47
msgid "AM"
msgstr ""
msgstr "ÖÖ"
#: utils/dateformat.py:95
msgid "midnight"
msgstr ""
msgstr "gece yarısı"
#: utils/dateformat.py:97
msgid "noon"
msgstr ""
msgstr "öğlen"
#: utils/translation/trans_real.py:362
msgid "DATE_FORMAT"

View File

@ -1,7 +1,4 @@
# Django 0.95
# Copyright (C) 2006 Django
# This file is distributed under the same license as the Django package.
# Bahadır Kandemir <bahadir@pardus.org.tr>, 2006.
#
msgid ""
msgstr ""

View File

@ -5,7 +5,7 @@ var LATIN_MAP = {
'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'o', 'ñ': 'n', 'ò': 'o', 'ó':
'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó':
'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u',
'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
}

View File

@ -10,6 +10,9 @@ from django.contrib.auth.models import User
import getpass
import os
import sys
import re
RE_VALID_USERNAME = re.compile('\w+$')
def createsuperuser(username=None, email=None, password=None):
"""
@ -43,7 +46,7 @@ def createsuperuser(username=None, email=None, password=None):
username = raw_input(input_msg + ': ')
if default_username and username == '':
username = default_username
if not username.isalnum():
if not RE_VALID_USERNAME.match(username):
sys.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.\n")
username = None
continue

View File

@ -80,12 +80,12 @@ class CASocialInsuranceNumberField(Field):
Checks the following rules to determine whether the number is valid:
* Conforms to the XXX-XXX-XXXX format.
* Conforms to the XXX-XXX-XXX format.
* Passes the check digit process "Luhn Algorithm"
See: http://en.wikipedia.org/wiki/Social_Insurance_Number
"""
default_error_messages = {
'invalid': ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.'),
'invalid': ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.'),
}
def clean(self, value):

View File

@ -85,7 +85,7 @@ PROVINCE_CHOICES = (
('RC', 'Reggio Calabria'),
('RE', 'Reggio Emilia'),
('RI', 'Rieti'),
('RN', 'Rimini')
('RN', 'Rimini'),
('RM', 'Roma'),
('RO', 'Rovigo'),
('SA', 'Salerno'),

View File

@ -26,6 +26,8 @@ class SessionStore(SessionBase):
# Save immediately to minimize collision
self.save()
# Ensure the user is notified via a new cookie.
self.modified = True
return {}
def exists(self, session_key):

View File

@ -46,6 +46,8 @@ class SessionStore(SessionBase):
self._session_key = self._get_new_session_key()
self._session_cache = {}
self.save()
# Ensure the user is notified via a new cookie.
self.modified = True
finally:
session_file.close()
except(IOError):

View File

@ -67,11 +67,10 @@ def make_msgid(idstring=None):
class BadHeaderError(ValueError):
pass
class SafeMIMEText(MIMEText):
def __setitem__(self, name, val):
def forbid_multi_line_headers(name, val):
"Forbids multi-line headers, to prevent header injection."
if '\n' in val or '\r' in val:
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
try:
val = force_unicode(val).encode('ascii')
except UnicodeEncodeError:
@ -84,25 +83,16 @@ class SafeMIMEText(MIMEText):
val = ', '.join(result)
else:
val = Header(force_unicode(val), settings.DEFAULT_CHARSET)
return name, val
class SafeMIMEText(MIMEText):
def __setitem__(self, name, val):
name, val = forbid_multi_line_headers(name, val)
MIMEText.__setitem__(self, name, val)
class SafeMIMEMultipart(MIMEMultipart):
def __setitem__(self, name, val):
"Forbids multi-line headers, to prevent header injection."
if '\n' in val or '\r' in val:
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
try:
val = force_unicode(val).encode('ascii')
except UnicodeEncodeError:
if name.lower() in ('to', 'from', 'cc'):
result = []
for item in val.split(', '):
nm, addr = parseaddr(item)
nm = str(Header(nm, settings.DEFAULT_CHARSET))
result.append(formataddr((nm, str(addr))))
val = ', '.join(result)
else:
val = Header(force_unicode(val), settings.DEFAULT_CHARSET)
name, val = forbid_multi_line_headers(name, val)
MIMEMultipart.__setitem__(self, name, val)
class SMTPConnection(object):
@ -209,8 +199,14 @@ class EmailMessage(object):
bytestrings). The SafeMIMEText class will handle any necessary encoding
conversions.
"""
self.to = to or []
self.bcc = bcc or []
if to:
self.to = list(to)
else:
self.to = []
if bcc:
self.bcc = list(bcc)
else:
self.bcc = []
self.from_email = from_email or settings.DEFAULT_FROM_EMAIL
self.subject = subject
self.body = body

View File

@ -293,7 +293,7 @@ def sql_model_create(model, style, known_models=set()):
style.SQL_KEYWORD('NULL'))
for field_constraints in opts.unique_together:
table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
", ".join([qn(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))
", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints]))
full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(qn(opts.db_table)) + ' (']
for i, line in enumerate(table_output): # Combine and add commas.

View File

@ -413,6 +413,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
return self.connection is not None
def _cursor(self, settings):
cursor = None
if not self._valid_connection():
if len(settings.DATABASE_HOST.strip()) == 0:
settings.DATABASE_HOST = 'localhost'
@ -422,16 +423,25 @@ class DatabaseWrapper(BaseDatabaseWrapper):
else:
conn_string = "%s/%s@%s" % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME)
self.connection = Database.connect(conn_string, **self.options)
cursor = FormatStylePlaceholderCursor(self.connection)
# Set oracle date to ansi date format. This only needs to execute
# once when we create a new connection.
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD' "
"NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'")
try:
self.oracle_version = int(self.connection.version.split('.')[0])
except ValueError:
pass
try:
self.connection.stmtcachesize = 20
except:
# Django docs specify cx_Oracle version 4.3.1 or higher, but
# stmtcachesize is available only in 4.3.2 and up.
pass
if not cursor:
cursor = FormatStylePlaceholderCursor(self.connection)
# Default arraysize of 1 is highly sub-optimal.
cursor.arraysize = 100
# Set oracle date to ansi date format.
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")
cursor.execute("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'")
return cursor
class FormatStylePlaceholderCursor(Database.Cursor):
@ -506,7 +516,10 @@ class FormatStylePlaceholderCursor(Database.Cursor):
return Database.Cursor.executemany(self, query, new_param_list)
def fetchone(self):
return to_unicode(Database.Cursor.fetchone(self))
row = Database.Cursor.fetchone(self)
if row is None:
return row
return tuple([to_unicode(e) for e in row])
def fetchmany(self, size=None):
if size is None:

View File

@ -795,13 +795,17 @@ class FileField(Field):
return os.path.normpath(f)
def save_form_data(self, instance, data):
if data:
from django.newforms.fields import UploadedFile
if data and isinstance(data, UploadedFile):
getattr(instance, "save_%s_file" % self.name)(data.filename, data.content, save=False)
def formfield(self, **kwargs):
defaults = {'form_class': forms.FileField}
# If a file has been provided previously, then the form doesn't require
# that a new file is provided this time.
# The code to mark the form field as not required is used by
# form_for_instance, but can probably be removed once form_for_instance
# is gone. ModelForm uses a different method to check for an existing file.
if 'initial' in kwargs:
defaults['required'] = False
defaults.update(kwargs)

View File

@ -437,10 +437,12 @@ class FileField(Field):
def __init__(self, *args, **kwargs):
super(FileField, self).__init__(*args, **kwargs)
def clean(self, data):
super(FileField, self).clean(data)
def clean(self, data, initial=None):
super(FileField, self).clean(initial or data)
if not self.required and data in EMPTY_VALUES:
return None
elif not data and initial:
return initial
try:
f = UploadedFile(data['filename'], data['content'])
except TypeError:
@ -456,12 +458,12 @@ class ImageField(FileField):
'invalid_image': _(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."),
}
def clean(self, data):
def clean(self, data, initial=None):
"""
Checks that the file-upload field data contains a valid image (GIF, JPG,
PNG, possibly others -- whatever the Python Imaging Library supports).
"""
f = super(ImageField, self).clean(data)
f = super(ImageField, self).clean(data, initial)
if f is None:
return None
from PIL import Image

View File

@ -9,7 +9,7 @@ from django.utils.html import escape
from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
from django.utils.safestring import mark_safe
from fields import Field
from fields import Field, FileField
from widgets import Media, media_property, TextInput, Textarea
from util import flatatt, ErrorDict, ErrorList, ValidationError
@ -205,6 +205,10 @@ class BaseForm(StrAndUnicode):
# widgets split data over several HTML fields.
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.initial.get(name, field.initial)
value = field.clean(value, initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):

View File

@ -154,15 +154,12 @@ class StringOrigin(Origin):
class Template(object):
def __init__(self, template_string, origin=None, name='<Unknown Template>'):
"Compilation stage"
try:
template_string = smart_unicode(template_string)
except UnicodeDecodeError:
raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.")
if settings.TEMPLATE_DEBUG and origin == None:
if settings.TEMPLATE_DEBUG and origin is None:
origin = StringOrigin(template_string)
# Could do some crazy stack-frame stuff to record where this string
# came from...
self.nodelist = compile_string(template_string, origin)
self.name = name
@ -177,13 +174,18 @@ class Template(object):
def compile_string(template_string, origin):
"Compiles template_string into NodeList ready for rendering"
lexer = lexer_factory(template_string, origin)
parser = parser_factory(lexer.tokenize())
if settings.TEMPLATE_DEBUG:
from debug import DebugLexer, DebugParser
lexer_class, parser_class = DebugLexer, DebugParser
else:
lexer_class, parser_class = Lexer, Parser
lexer = lexer_class(template_string, origin)
parser = parser_class(lexer.tokenize())
return parser.parse()
class Token(object):
def __init__(self, token_type, contents):
"The token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT"
# token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT.
self.token_type, self.contents = token_type, contents
def __str__(self):
@ -200,7 +202,7 @@ class Lexer(object):
self.origin = origin
def tokenize(self):
"Return a list of tokens from a given template_string"
"Return a list of tokens from a given template_string."
in_tag = False
result = []
for bit in tag_re.split(self.template_string):
@ -226,30 +228,6 @@ class Lexer(object):
token = Token(TOKEN_TEXT, token_string)
return token
class DebugLexer(Lexer):
def __init__(self, template_string, origin):
super(DebugLexer, self).__init__(template_string, origin)
def tokenize(self):
"Return a list of tokens from a given template_string"
result, upto = [], 0
for match in tag_re.finditer(self.template_string):
start, end = match.span()
if start > upto:
result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
upto = start
result.append(self.create_token(self.template_string[start:end], (start, end), True))
upto = end
last_bit = self.template_string[upto:]
if last_bit:
result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
return result
def create_token(self, token_string, source, in_tag):
token = super(DebugLexer, self).create_token(token_string, in_tag)
token.source = self.origin, source
return token
class Parser(object):
def __init__(self, tokens):
self.tokens = tokens
@ -319,17 +297,17 @@ class Parser(object):
def exit_command(self):
pass
def error(self, token, msg ):
def error(self, token, msg):
return TemplateSyntaxError(msg)
def empty_variable(self, token):
raise self.error( token, "Empty variable tag")
raise self.error(token, "Empty variable tag")
def empty_block_tag(self, token):
raise self.error( token, "Empty block tag")
raise self.error(token, "Empty block tag")
def invalid_block_tag(self, token, command):
raise self.error( token, "Invalid block tag: '%s'" % command)
raise self.error(token, "Invalid block tag: '%s'" % command)
def unclosed_block_tag(self, parse_until):
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
@ -358,57 +336,7 @@ class Parser(object):
if filter_name in self.filters:
return self.filters[filter_name]
else:
raise TemplateSyntaxError, "Invalid filter: '%s'" % filter_name
class DebugParser(Parser):
def __init__(self, lexer):
super(DebugParser, self).__init__(lexer)
self.command_stack = []
def enter_command(self, command, token):
self.command_stack.append( (command, token.source) )
def exit_command(self):
self.command_stack.pop()
def error(self, token, msg):
return self.source_error(token.source, msg)
def source_error(self, source,msg):
e = TemplateSyntaxError(msg)
e.source = source
return e
def create_nodelist(self):
return DebugNodeList()
def create_variable_node(self, contents):
return DebugVariableNode(contents)
def extend_nodelist(self, nodelist, node, token):
node.source = token.source
super(DebugParser, self).extend_nodelist(nodelist, node, token)
def unclosed_block_tag(self, parse_until):
command, source = self.command_stack.pop()
msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
raise self.source_error( source, msg)
def compile_function_error(self, token, e):
if not hasattr(e, 'source'):
e.source = token.source
def lexer_factory(*args, **kwargs):
if settings.TEMPLATE_DEBUG:
return DebugLexer(*args, **kwargs)
else:
return Lexer(*args, **kwargs)
def parser_factory(*args, **kwargs):
if settings.TEMPLATE_DEBUG:
return DebugParser(*args, **kwargs)
else:
return Parser(*args, **kwargs)
raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
class TokenParser(object):
"""
@ -426,7 +354,7 @@ class TokenParser(object):
def top(self):
"Overload this method to do the actual parsing and return the result."
raise NotImplemented
raise NotImplementedError()
def more(self):
"Returns True if there is more stuff in the tag."
@ -435,7 +363,7 @@ class TokenParser(object):
def back(self):
"Undoes the last microparser. Use this for lookahead and backtracking."
if not len(self.backout):
raise TemplateSyntaxError, "back called without some previous parsing"
raise TemplateSyntaxError("back called without some previous parsing")
self.pointer = self.backout.pop()
def tag(self):
@ -443,7 +371,7 @@ class TokenParser(object):
subject = self.subject
i = self.pointer
if i >= len(subject):
raise TemplateSyntaxError, "expected another tag, found end of string: %s" % subject
raise TemplateSyntaxError("expected another tag, found end of string: %s" % subject)
p = i
while i < len(subject) and subject[i] not in (' ', '\t'):
i += 1
@ -459,14 +387,14 @@ class TokenParser(object):
subject = self.subject
i = self.pointer
if i >= len(subject):
raise TemplateSyntaxError, "Searching for value. Expected another value but found end of string: %s" % subject
raise TemplateSyntaxError("Searching for value. Expected another value but found end of string: %s" % subject)
if subject[i] in ('"', "'"):
p = i
i += 1
while i < len(subject) and subject[i] != subject[p]:
i += 1
if i >= len(subject):
raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)
raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
i += 1
res = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
@ -483,7 +411,7 @@ class TokenParser(object):
while i < len(subject) and subject[i] != c:
i += 1
if i >= len(subject):
raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)
raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject))
i += 1
s = subject[p:i]
while i < len(subject) and subject[i] in (' ', '\t'):
@ -542,8 +470,8 @@ class FilterExpression(object):
for match in matches:
start = match.start()
if upto != start:
raise TemplateSyntaxError, "Could not parse some characters: %s|%s|%s" % \
(token[:upto], token[upto:start], token[start:])
raise TemplateSyntaxError("Could not parse some characters: %s|%s|%s" % \
(token[:upto], token[upto:start], token[start:]))
if var == None:
var, constant, i18n_constant = match.group("var", "constant", "i18n_constant")
if i18n_constant:
@ -552,9 +480,9 @@ class FilterExpression(object):
var = '"%s"' % constant.replace(r'\"', '"')
upto = match.end()
if var == None:
raise TemplateSyntaxError, "Could not find variable at start of %s" % token
raise TemplateSyntaxError("Could not find variable at start of %s" % token)
elif var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or var[0] == '_':
raise TemplateSyntaxError, "Variables and attributes may not begin with underscores: '%s'" % var
raise TemplateSyntaxError("Variables and attributes may not begin with underscores: '%s'" % var)
else:
filter_name = match.group("filter_name")
args = []
@ -570,7 +498,7 @@ class FilterExpression(object):
filters.append( (filter_func,args))
upto = match.end()
if upto != len(token):
raise TemplateSyntaxError, "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)
raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token))
self.filters = filters
self.var = Variable(var)
@ -627,7 +555,7 @@ class FilterExpression(object):
provided.pop(0)
except IndexError:
# Not enough
raise TemplateSyntaxError, "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)
raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen))
# Defaults can be overridden.
defaults = defaults and list(defaults) or []
@ -636,7 +564,7 @@ class FilterExpression(object):
defaults.pop(0)
except IndexError:
# Too many.
raise TemplateSyntaxError, "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)
raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen))
return True
args_check = staticmethod(args_check)
@ -816,22 +744,6 @@ class NodeList(list):
def render_node(self, node, context):
return node.render(context)
class DebugNodeList(NodeList):
def render_node(self, node, context):
try:
result = node.render(context)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = node.source
raise
except Exception, e:
from sys import exc_info
wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
wrapped.source = node.source
wrapped.exc_info = exc_info()
raise wrapped
return result
class TextNode(Node):
def __init__(self, s):
self.s = s
@ -861,21 +773,6 @@ class VariableNode(Node):
else:
return force_unicode(output)
class DebugVariableNode(VariableNode):
def render(self, context):
try:
output = force_unicode(self.filter_expression.resolve(context))
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = self.source
raise
except UnicodeDecodeError:
return ''
if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
return escape(output)
else:
return output
def generic_tag_compiler(params, defaults, name, node_class, parser, token):
"Returns a template.Node subclass."
bits = token.split_contents()[1:]
@ -887,7 +784,7 @@ def generic_tag_compiler(params, defaults, name, node_class, parser, token):
message = "%s takes %s arguments" % (name, bmin)
else:
message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
raise TemplateSyntaxError, message
raise TemplateSyntaxError(message)
return node_class(bits)
class Library(object):
@ -913,7 +810,7 @@ class Library(object):
self.tags[name] = compile_function
return compile_function
else:
raise InvalidTemplateLibrary, "Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function)
raise InvalidTemplateLibrary("Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function))
def tag_function(self,func):
self.tags[getattr(func, "_decorated_function", func).__name__] = func
@ -937,7 +834,7 @@ class Library(object):
self.filters[name] = filter_func
return filter_func
else:
raise InvalidTemplateLibrary, "Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func)
raise InvalidTemplateLibrary("Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func))
def filter_function(self, func):
self.filters[getattr(func, "_decorated_function", func).__name__] = func
@ -966,7 +863,7 @@ class Library(object):
if params[0] == 'context':
params = params[1:]
else:
raise TemplateSyntaxError, "Any tag function decorated with takes_context=True must have a first argument of 'context'"
raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
class InclusionNode(Node):
def __init__(self, vars_to_resolve):
@ -1003,12 +900,12 @@ def get_library(module_name):
try:
mod = __import__(module_name, {}, {}, [''])
except ImportError, e:
raise InvalidTemplateLibrary, "Could not load template library from %s, %s" % (module_name, e)
raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e))
try:
lib = mod.register
libraries[module_name] = lib
except AttributeError:
raise InvalidTemplateLibrary, "Template library %s does not have a variable named 'register'" % module_name
raise InvalidTemplateLibrary("Template library %s does not have a variable named 'register'" % module_name)
return lib
def add_to_builtins(module_name):

View File

@ -9,7 +9,6 @@ class ContextPopException(Exception):
class Context(object):
"A stack container for variable context"
def __init__(self, dict_=None, autoescape=True):
dict_ = dict_ or {}
self.dicts = [dict_]
@ -78,11 +77,11 @@ def get_standard_processors():
try:
mod = __import__(module, {}, {}, [attr])
except ImportError, e:
raise ImproperlyConfigured, 'Error importing request processor module %s: "%s"' % (module, e)
raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
try:
func = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured, 'Module "%s" does not define a "%s" callable request processor' % (module, attr)
raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr))
processors.append(func)
_standard_context_processors = tuple(processors)
return _standard_context_processors
@ -102,4 +101,3 @@ class RequestContext(Context):
processors = tuple(processors)
for processor in get_standard_processors() + processors:
self.update(processor(request))

97
django/template/debug.py Normal file
View File

@ -0,0 +1,97 @@
from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
from django.utils.encoding import force_unicode
from django.utils.html import escape
from django.utils.safestring import SafeData, EscapeData
class DebugLexer(Lexer):
def __init__(self, template_string, origin):
super(DebugLexer, self).__init__(template_string, origin)
def tokenize(self):
"Return a list of tokens from a given template_string"
result, upto = [], 0
for match in tag_re.finditer(self.template_string):
start, end = match.span()
if start > upto:
result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
upto = start
result.append(self.create_token(self.template_string[start:end], (start, end), True))
upto = end
last_bit = self.template_string[upto:]
if last_bit:
result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
return result
def create_token(self, token_string, source, in_tag):
token = super(DebugLexer, self).create_token(token_string, in_tag)
token.source = self.origin, source
return token
class DebugParser(Parser):
def __init__(self, lexer):
super(DebugParser, self).__init__(lexer)
self.command_stack = []
def enter_command(self, command, token):
self.command_stack.append( (command, token.source) )
def exit_command(self):
self.command_stack.pop()
def error(self, token, msg):
return self.source_error(token.source, msg)
def source_error(self, source,msg):
e = TemplateSyntaxError(msg)
e.source = source
return e
def create_nodelist(self):
return DebugNodeList()
def create_variable_node(self, contents):
return DebugVariableNode(contents)
def extend_nodelist(self, nodelist, node, token):
node.source = token.source
super(DebugParser, self).extend_nodelist(nodelist, node, token)
def unclosed_block_tag(self, parse_until):
command, source = self.command_stack.pop()
msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
raise self.source_error(source, msg)
def compile_function_error(self, token, e):
if not hasattr(e, 'source'):
e.source = token.source
class DebugNodeList(NodeList):
def render_node(self, node, context):
try:
result = node.render(context)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = node.source
raise
except Exception, e:
from sys import exc_info
wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
wrapped.source = node.source
wrapped.exc_info = exc_info()
raise wrapped
return result
class DebugVariableNode(VariableNode):
def render(self, context):
try:
output = force_unicode(self.filter_expression.resolve(context))
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = self.source
raise
except UnicodeDecodeError:
return ''
if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
return escape(output)
else:
return output

View File

@ -433,7 +433,7 @@ def first(value):
return value[0]
except IndexError:
return u''
first.is_safe = True
first.is_safe = False
def join(value, arg):
"""Joins a list with a string, like Python's ``str.join(list)``."""
@ -449,6 +449,14 @@ def join(value, arg):
return data
join.is_safe = True
def last(value):
"Returns the last item in a list"
try:
return value[-1]
except IndexError:
return u''
last.is_safe = True
def length(value):
"""Returns the length of the value - useful for lists."""
return len(value)
@ -800,6 +808,7 @@ register.filter(force_escape)
register.filter(get_digit)
register.filter(iriencode)
register.filter(join)
register.filter(last)
register.filter(length)
register.filter(length_is)
register.filter(linebreaks)

View File

@ -84,19 +84,16 @@ class FirstOfNode(Node):
return u''
class ForNode(Node):
def __init__(self, loopvars, sequence, reversed, nodelist_loop):
def __init__(self, loopvars, sequence, is_reversed, nodelist_loop):
self.loopvars, self.sequence = loopvars, sequence
self.reversed = reversed
self.is_reversed = is_reversed
self.nodelist_loop = nodelist_loop
def __repr__(self):
if self.reversed:
reversed = ' reversed'
else:
reversed = ''
reversed_text = self.is_reversed and ' reversed' or ''
return "<For Node: for %s in %s, tail_len: %d%s>" % \
(', '.join(self.loopvars), self.sequence, len(self.nodelist_loop),
reversed)
reversed_text)
def __iter__(self):
for node in self.nodelist_loop:
@ -125,22 +122,23 @@ class ForNode(Node):
if not hasattr(values, '__len__'):
values = list(values)
len_values = len(values)
if self.reversed:
if self.is_reversed:
values = reversed(values)
unpack = len(self.loopvars) > 1
# Create a forloop value in the context. We'll update counters on each
# iteration just below.
loop_dict = context['forloop'] = {'parentloop': parentloop}
for i, item in enumerate(values):
context['forloop'] = {
# Shortcuts for current loop iteration number.
'counter0': i,
'counter': i+1,
loop_dict['counter0'] = i
loop_dict['counter'] = i+1
# Reverse counter iteration numbers.
'revcounter': len_values - i,
'revcounter0': len_values - i - 1,
loop_dict['revcounter'] = len_values - i
loop_dict['revcounter0'] = len_values - i - 1
# Boolean values designating first and last times through loop.
'first': (i == 0),
'last': (i == len_values - 1),
'parentloop': parentloop,
}
loop_dict['first'] = (i == 0)
loop_dict['last'] = (i == len_values - 1)
if unpack:
# If there are multiple loop variables, unpack the item into
# them.
@ -619,8 +617,8 @@ def do_for(parser, token):
raise TemplateSyntaxError("'for' statements should have at least four"
" words: %s" % token.contents)
reversed = bits[-1] == 'reversed'
in_index = reversed and -3 or -2
is_reversed = bits[-1] == 'reversed'
in_index = is_reversed and -3 or -2
if bits[in_index] != 'in':
raise TemplateSyntaxError("'for' statements should use the format"
" 'for x in y': %s" % token.contents)
@ -634,7 +632,7 @@ def do_for(parser, token):
sequence = parser.compile_filter(bits[in_index+1])
nodelist_loop = parser.parse(('endfor',))
parser.delete_first_token()
return ForNode(loopvars, sequence, reversed, nodelist_loop)
return ForNode(loopvars, sequence, is_reversed, nodelist_loop)
do_for = register.tag("for", do_for)
def do_ifequal(parser, token, negate):

View File

@ -507,7 +507,7 @@ Exception Type: {{ exception_type|escape }} at {{ request.path|escape }}
Exception Value: {{ exception_value|escape }}
</textarea>
<br><br>
<input type="submit" value="Share this traceback on public Web site">
<input type="submit" value="Share this traceback on a public Web site">
</div>
</form>
</div>

View File

@ -57,7 +57,7 @@ worth using only if it creates a huge convenience unattainable in other ways,
and it isn't implemented in a way that confuses developers who are trying to
learn how to use the feature.
.. _`core Python principle`: http://www.python.org/doc/Humor.html#zen
.. _`core Python principle`: http://www.python.org/dev/peps/pep-0020/
Consistency
-----------

View File

@ -60,22 +60,22 @@ point to find their preferred version.
Gentoo
------
A Django build is available for `Gentoo Linux`_, and is based on Django 0.96.
The `current Gentoo build`_ can be installed by typing ``emerge django``.
A Django package is available for `Gentoo Linux`_, and is based on Django 0.96.1.
The `current Gentoo package`_ can be installed by typing ``emerge django``.
.. _Gentoo Linux: http://www.gentoo.org/
.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django
.. _current Gentoo package: http://packages.gentoo.org/package/django
Ubuntu
------
The Debian ``python-django`` package is also available for `Ubuntu Linux`_, in
the "universe" repository for Ubuntu 7.04 ("Feisty Fawn"). The `current Ubuntu
package`_ is also based on Django 0.95.1 and can be installed in the same
fashion as for Debian.
the "universe" repository for Ubuntu 7.10 ("Gutsy Gibbon"). The `current Ubuntu
package`_ is based on Django 0.96.1 and can be installed in the same fashion as
for Debian.
.. _Ubuntu Linux: http://www.ubuntu.com/
.. _current Ubuntu package: http://packages.ubuntu.com/feisty/python/python-django
.. _current Ubuntu package: http://packages.ubuntu.com/gutsy/python/python-django
Mac OS X

View File

@ -716,8 +716,8 @@ in Python package syntax, e.g. ``mysite.settings``. If this isn't provided,
``django-admin.py`` will use the ``DJANGO_SETTINGS_MODULE`` environment
variable.
Note that this option is unnecessary in ``manage.py``, because it takes care of
setting ``DJANGO_SETTINGS_MODULE`` for you.
Note that this option is unnecessary in ``manage.py``, because it uses
``settings.py`` from the current project by default.
Extra niceties
==============

View File

@ -100,6 +100,8 @@ any code you'd like to contribute. One thing we ask is that you please use
Unicode objects (``u'mystring'``) for strings, rather than setting the encoding
in the file. See any of the existing flavors for examples.
.. _create a ticket: http://code.djangoproject.com/simpleticket
Argentina (``django.contrib.localflavor.ar``)
=============================================
@ -181,7 +183,7 @@ CASocialInsuranceNumberField
----------------------------
A form field that validates input as a Canadian Social Insurance Number (SIN).
A valid number must have the format XXX-XXX-XXXX and pass a `Luhn mod-10
A valid number must have the format XXX-XXX-XXX and pass a `Luhn mod-10
checksum`_.
.. _Luhn mod-10 checksum: http://en.wikipedia.org/wiki/Luhn_algorithm

View File

@ -154,6 +154,17 @@ every incoming ``HttpRequest`` object. See `Authentication in Web requests`_.
.. _Authentication in Web requests: ../authentication/#authentication-in-web-requests
django.contrib.csrf.middleware.CsrfMiddleware
---------------------------------------------
**New in Django development version**
Adds protection against Cross Site Request Forgeries by adding hidden form
fields to POST forms and checking requests for the correct value. See the
`Cross Site Request Forgery protection documentation`_.
.. _`Cross Site Request Forgery protection documentation`: ../csrf/
django.middleware.transaction.TransactionMiddleware
---------------------------------------------------

View File

@ -94,7 +94,7 @@ This example is equivalent to::
def my_view(request):
try:
my_object = MyModel.object.get(pk=1)
my_object = MyModel.objects.get(pk=1)
except MyModel.DoesNotExist:
raise Http404
@ -136,7 +136,7 @@ This example is equivalent to::
from django.http import Http404
def my_view(request):
my_objects = MyModels.object.filter(published=True)
my_objects = MyModel.objects.filter(published=True)
if not my_objects:
raise Http404

View File

@ -97,7 +97,7 @@ Hooking into the current site from views
----------------------------------------
On a lower level, you can use the sites framework in your Django views to do
particular things based on what site in which the view is being called.
particular things based on the site in which the view is being called.
For example::
from django.conf import settings
@ -330,13 +330,13 @@ Here's how Django uses the sites framework:
retrieving flatpages to display.
* In the `syndication framework`_, the templates for ``title`` and
``description`` automatically have access to a variable ``{{{ site }}}``,
``description`` automatically have access to a variable ``{{ site }}``,
which is the ``Site`` object representing the current site. Also, the
hook for providing item URLs will use the ``domain`` from the current
``Site`` object if you don't specify a fully-qualified domain.
* In the `authentication framework`_, the ``django.contrib.auth.views.login``
view passes the current ``Site`` name to the template as ``{{{ site_name }}}``.
view passes the current ``Site`` name to the template as ``{{ site_name }}``.
* The shortcut view (``django.views.defaults.shortcut``) uses the domain of
the current ``Site`` object when calculating an object's URL.

View File

@ -201,7 +201,7 @@ the feed.
An example makes this clear. Here's the code for these beat-specific feeds::
from django.contrib.syndication import FeedDoesNotExist
from django.contrib.syndication.feeds import FeedDoesNotExist
class BeatFeed(Feed):
def get_object(self, bits):

View File

@ -953,7 +953,7 @@ Available format strings:
U Not implemented.
w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday)
leading zeros.
W ISO-8601 week number of year, with ``1``, ``23``
W ISO-8601 week number of year, with ``1``, ``53``
weeks starting on Monday.
y Year, 2 digits. ``'99'``
Y Year, 4 digits. ``'1999'``
@ -1230,7 +1230,7 @@ addslashes
Adds slashes before quotes. Useful for escaping strings in CSV, for example.
**New in Django development version**: for escaping data in JavaScript strings,
use the `escapejs` filter instead.
use the `escapejs`_ filter instead.
capfirst
~~~~~~~~
@ -1403,6 +1403,11 @@ join
Joins a list with a string, like Python's ``str.join(list)``.
last
~~~~
Returns the last item in a list.
length
~~~~~~

View File

@ -823,11 +823,11 @@ Template filter code falls into one of two situations:
can operate in templates where auto-escaping is either on or off in
order to make things easier for your template authors.
In order for you filter to know the current auto-escaping state, set the
``needs_autoescape`` attribute to ``True`` on your function. (If you
In order for your filter to know the current auto-escaping state, set
the ``needs_autoescape`` attribute to ``True`` on your function. (If you
don't specify this attribute, it defaults to ``False``). This attribute
tells Django that your filter function wants to be passed an extra
keyword argument, called ``autoescape``, that is ``True`` is
keyword argument, called ``autoescape``, that is ``True`` if
auto-escaping is in effect and ``False`` otherwise.
For example, let's write a filter that emphasizes the first character of

View File

@ -14,7 +14,7 @@ from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
parent = models.ForeignKey('self', null=True, related_name='child_set')
parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set')
def __unicode__(self):
return self.name

View File

@ -7,6 +7,9 @@ examples are probably a poor fit for the ModelForm syntax. In other words,
most of these tests should be rewritten.
"""
import os
import tempfile
from django.db import models
ARTICLE_STATUS = (
@ -55,6 +58,13 @@ class PhoneNumber(models.Model):
def __unicode__(self):
return self.phone
class TextFile(models.Model):
description = models.CharField(max_length=20)
file = models.FileField(upload_to=tempfile.gettempdir())
def __unicode__(self):
return self.description
__test__ = {'API_TESTS': """
>>> from django import newforms as forms
>>> from django.newforms.models import ModelForm
@ -701,4 +711,75 @@ ValidationError: [u'Select a valid choice. 4 is not one of the available choices
True
>>> f.cleaned_data
{'phone': u'312-555-1212', 'description': u'Assistance'}
# FileField ###################################################################
>>> class TextFileForm(ModelForm):
... class Meta:
... model = TextFile
Test conditions when files is either not given or empty.
>>> f = TextFileForm(data={'description': u'Assistance'})
>>> f.is_valid()
False
>>> f = TextFileForm(data={'description': u'Assistance'}, files={})
>>> f.is_valid()
False
Upload a file and ensure it all works as expected.
>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test1.txt', 'content': 'hello world'}})
>>> f.is_valid()
True
>>> type(f.cleaned_data['file'])
<class 'django.newforms.fields.UploadedFile'>
>>> instance = f.save()
>>> instance.file
u'.../test1.txt'
Edit an instance that already has the file defined in the model. This will not
save the file again, but leave it exactly as it is.
>>> f = TextFileForm(data={'description': u'Assistance'}, instance=instance)
>>> f.is_valid()
True
>>> f.cleaned_data['file']
u'.../test1.txt'
>>> instance = f.save()
>>> instance.file
u'.../test1.txt'
Delete the current file since this is not done by Django.
>>> os.unlink(instance.get_file_filename())
Override the file by uploading a new one.
>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test2.txt', 'content': 'hello world'}}, instance=instance)
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.file
u'.../test2.txt'
>>> instance.delete()
Test the non-required FileField
>>> f = TextFileForm(data={'description': u'Assistance'})
>>> f.fields['file'].required = False
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.file
''
>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test3.txt', 'content': 'hello world'}}, instance=instance)
>>> f.is_valid()
True
>>> instance = f.save()
>>> instance.file
u'.../test3.txt'
>>> instance.delete()
"""}

View File

@ -8,6 +8,13 @@ class Square(models.Model):
def __unicode__(self):
return "%s ** 2 == %s" % (self.root, self.square)
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
if connection.features.uses_case_insensitive_names:
t_convert = lambda x: x.upper()
else:
@ -32,4 +39,25 @@ __test__ = {'API_TESTS': """
>>> Square.objects.count()
11
#6254: fetchone, fetchmany, fetchall return strings as unicode objects
>>> Person(first_name="John", last_name="Doe").save()
>>> Person(first_name="Jane", last_name="Doe").save()
>>> Person(first_name="Mary", last_name="Agnelline").save()
>>> Person(first_name="Peter", last_name="Parker").save()
>>> Person(first_name="Clark", last_name="Kent").save()
>>> opts2 = Person._meta
>>> f3, f4 = opts2.get_field('first_name'), opts2.get_field('last_name')
>>> query2 = ('SELECT %s, %s FROM %s ORDER BY %s'
... % (qn(f3.column), qn(f4.column), t_convert(opts2.db_table),
... qn(f3.column)))
>>> cursor.execute(query2) and None or None
>>> cursor.fetchone()
(u'Clark', u'Kent')
>>> list(cursor.fetchmany(2))
[(u'Jane', u'Doe'), (u'John', u'Doe')]
>>> list(cursor.fetchall())
[(u'Mary', u'Agnelline'), (u'Peter', u'Parker')]
"""}

View File

@ -749,32 +749,59 @@ Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean('', '')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean('', 'files/test1.pdf')
'files/test1.pdf'
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None, '')
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> f.clean(None, 'files/test2.pdf')
'files/test2.pdf'
>>> f.clean({})
Traceback (most recent call last):
...
ValidationError: [u'No file was submitted.']
>>> f.clean({}, '')
Traceback (most recent call last):
...
ValidationError: [u'No file was submitted.']
>>> f.clean({}, 'files/test3.pdf')
'files/test3.pdf'
>>> f.clean('some content that is not a file')
Traceback (most recent call last):
...
ValidationError: [u'No file was submitted. Check the encoding type on the form.']
>>> f.clean({'filename': 'name', 'content':None})
>>> f.clean({'filename': 'name', 'content': None})
Traceback (most recent call last):
...
ValidationError: [u'The submitted file is empty.']
>>> f.clean({'filename': 'name', 'content':''})
>>> f.clean({'filename': 'name', 'content': ''})
Traceback (most recent call last):
...
ValidationError: [u'The submitted file is empty.']
>>> type(f.clean({'filename': 'name', 'content':'Some File Content'}))
>>> type(f.clean({'filename': 'name', 'content': 'Some File Content'}))
<class 'django.newforms.fields.UploadedFile'>
>>> type(f.clean({'filename': 'name', 'content': 'Some File Content'}, 'files/test4.pdf'))
<class 'django.newforms.fields.UploadedFile'>
# URLField ##################################################################

View File

@ -213,13 +213,13 @@ u'046-454-286'
>>> f.clean('046-454-287')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
>>> f.clean('046 454 286')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
>>> f.clean('046-44-286')
Traceback (most recent call last):
...
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.']
ValidationError: [u'Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
"""

View File

@ -0,0 +1 @@
# models.py file for tests to run.

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
import unittest
from django.test import TestCase
from django.http import HttpRequest
from django.middleware.common import CommonMiddleware
@ -19,7 +17,7 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_have_slash(self):
"""
tests that urls with slashes go unmolested
Tests that URLs with slashes go unmolested.
"""
settings.APPEND_SLASH = True
request = self._get_request('slash/')
@ -27,7 +25,7 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_slashless_resource(self):
"""
tests that matches to explicit slashless urls go unmolested
Tests that matches to explicit slashless URLs go unmolested.
"""
settings.APPEND_SLASH = True
request = self._get_request('noslash')
@ -35,7 +33,7 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_slashless_unknown(self):
"""
tests that APPEND_SLASH doesn't redirect to unknown resources
Tests that APPEND_SLASH doesn't redirect to unknown resources.
"""
settings.APPEND_SLASH = True
request = self._get_request('unknown')
@ -43,7 +41,7 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_redirect(self):
"""
tests that APPEND_SLASH redirects slashless urls to a valid pattern
Tests that APPEND_SLASH redirects slashless URLs to a valid pattern.
"""
settings.APPEND_SLASH = True
request = self._get_request('slash')
@ -53,9 +51,9 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_no_redirect_on_POST_in_DEBUG(self):
"""
tests that while in debug mode, an exception is raised with a warning
when a failed attempt is made to POST to an url which would normally be
redirected to a slashed version
Tests that while in debug mode, an exception is raised with a warning
when a failed attempt is made to POST to an URL which would normally be
redirected to a slashed version.
"""
settings.APPEND_SLASH = True
settings.DEBUG = True
@ -68,11 +66,12 @@ class CommonMiddlewareTest(TestCase):
try:
CommonMiddleware().process_request(request)
except RuntimeError, e:
self.assertTrue('end in a slash' in str(e))
self.failUnless('end in a slash' in str(e))
settings.DEBUG = False
def test_append_slash_disabled(self):
"""
tests disabling append slash functionality
Tests disabling append slash functionality.
"""
settings.APPEND_SLASH = False
request = self._get_request('slash')
@ -80,8 +79,8 @@ class CommonMiddlewareTest(TestCase):
def test_append_slash_quoted(self):
"""
tests that urls which require quoting are redirected to their slash
version ok
Tests that URLs which require quoting are redirected to their slash
version ok.
"""
settings.APPEND_SLASH = True
request = self._get_request('needsquoting#')
@ -90,4 +89,3 @@ class CommonMiddlewareTest(TestCase):
self.assertEquals(
r['Location'],
'http://testserver/middleware/needsquoting%23/')

View File

@ -179,6 +179,9 @@ def get_filter_tests():
'filter-first01': ('{{ a|first }} {{ b|first }}', {"a": ["a&b", "x"], "b": [mark_safe("a&b"), "x"]}, "a&amp;b a&b"),
'filter-first02': ('{% autoescape off %}{{ a|first }} {{ b|first }}{% endautoescape %}', {"a": ["a&b", "x"], "b": [mark_safe("a&b"), "x"]}, "a&b a&b"),
'filter-last01': ('{{ a|last }} {{ b|last }}', {"a": ["x", "a&b"], "b": ["x", mark_safe("a&b")]}, "a&amp;b a&b"),
'filter-last02': ('{% autoescape off %}{{ a|last }} {{ b|last }}{% endautoescape %}', {"a": ["x", "a&b"], "b": ["x", mark_safe("a&b")]}, "a&b a&b"),
'filter-random01': ('{{ a|random }} {{ b|random }}', {"a": ["a&b", "a&b"], "b": [mark_safe("a&b"), mark_safe("a&b")]}, "a&amp;b a&b"),
'filter-random02': ('{% autoescape off %}{{ a|random }} {{ b|random }}{% endautoescape %}', {"a": ["a&b", "a&b"], "b": [mark_safe("a&b"), mark_safe("a&b")]}, "a&b a&b"),

View File

@ -441,6 +441,8 @@ class Templates(unittest.TestCase):
'for-tag-vars02': ("{% for val in values %}{{ forloop.counter0 }}{% endfor %}", {"values": [6, 6, 6]}, "012"),
'for-tag-vars03': ("{% for val in values %}{{ forloop.revcounter }}{% endfor %}", {"values": [6, 6, 6]}, "321"),
'for-tag-vars04': ("{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}", {"values": [6, 6, 6]}, "210"),
'for-tag-vars05': ("{% for val in values %}{% if forloop.first %}f{% else %}x{% endif %}{% endfor %}", {"values": [6, 6, 6]}, "fxx"),
'for-tag-vars06': ("{% for val in values %}{% if forloop.last %}l{% else %}x{% endif %}{% endfor %}", {"values": [6, 6, 6]}, "xxl"),
'for-tag-unpack01': ("{% for key,value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"),
'for-tag-unpack03': ("{% for key, value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"),
'for-tag-unpack04': ("{% for key , value in items %}{{ key }}:{{ value }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, "one:1/two:2/"),