mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
sqlalchemy: Merged revisions 4054 to 4185 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/sqlalchemy@4186 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
dadfca08c0
commit
122426e745
2
AUTHORS
2
AUTHORS
@ -51,6 +51,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Jiri Barton
|
||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||
Esdras Beleza <linux@esdrasbeleza.com>
|
||||
James Bennett
|
||||
Paul Bissex <http://e-scribe.com/>
|
||||
Simon Blanchard
|
||||
@ -150,6 +151,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
SmileyChris <smileychris@gmail.com>
|
||||
sopel
|
||||
Thomas Steinacher <tom@eggdrop.ch>
|
||||
nowell strite
|
||||
Radek Švarz <http://www.svarz.cz/translate/>
|
||||
Swaroop C H <http://www.swaroopch.info>
|
||||
Aaron Swartz <http://www.aaronsw.com/>
|
||||
|
Binary file not shown.
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-09-25 16:04+0200\n"
|
||||
"POT-Creation-Date: 2006-11-15 18:35+0100\n"
|
||||
"PO-Revision-Date: 2005-10-08 00:03+0200\n"
|
||||
"Last-Translator: Georg Bauer <gb@bofh.ms>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -452,7 +452,7 @@ msgid ""
|
||||
"Looks like your browser isn't configured to accept cookies. Please enable "
|
||||
"cookies, reload this page, and try again."
|
||||
msgstr ""
|
||||
"Es sieht danach aus, das der Browser keine Cookies akzeptiert. Bitte im "
|
||||
"Es sieht danach aus, dass der Browser keine Cookies akzeptiert. Bitte im "
|
||||
"Browser Cookies aktivieren und diese Seite neu laden."
|
||||
|
||||
#: contrib/admin/views/decorators.py:83
|
||||
@ -470,13 +470,13 @@ msgstr ""
|
||||
msgid "Site administration"
|
||||
msgstr "Website Verwaltung"
|
||||
|
||||
#: contrib/admin/views/main.py:257 contrib/admin/views/auth.py:17
|
||||
#: contrib/admin/views/main.py:257 contrib/admin/views/auth.py:18
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" wurde erfolgreich hinzugefügt."
|
||||
|
||||
#: contrib/admin/views/main.py:261 contrib/admin/views/main.py:347
|
||||
#: contrib/admin/views/auth.py:22
|
||||
#: contrib/admin/views/auth.py:23
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Das Element kann jetzt weiter geändert werden."
|
||||
|
||||
@ -496,7 +496,7 @@ msgid "Added %s."
|
||||
msgstr "%s hinzugefügt."
|
||||
|
||||
#: contrib/admin/views/main.py:335 contrib/admin/views/main.py:337
|
||||
#: contrib/admin/views/main.py:339
|
||||
#: contrib/admin/views/main.py:339 db/models/manipulators.py:306
|
||||
msgid "and"
|
||||
msgstr "und"
|
||||
|
||||
@ -702,7 +702,7 @@ msgstr "XML Text"
|
||||
msgid "%s does not appear to be a urlpattern object"
|
||||
msgstr "%s ist scheinbar kein urlpattern Objekt"
|
||||
|
||||
#: contrib/admin/views/auth.py:28
|
||||
#: contrib/admin/views/auth.py:29
|
||||
msgid "Add user"
|
||||
msgstr "Benutzer zufügen"
|
||||
|
||||
@ -861,10 +861,6 @@ msgstr "Keine vorhanden"
|
||||
msgid "Add %(name)s"
|
||||
msgstr "%(name)s zufügen"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:22
|
||||
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
msgstr "Haben Sie <a href=\"/password_reset/\">ihr Passwort vergessen</a>?"
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:25
|
||||
msgid "Welcome,"
|
||||
msgstr "Willkommen,"
|
||||
@ -891,7 +887,7 @@ msgid ""
|
||||
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
|
||||
"All of the following related items will be deleted:"
|
||||
msgstr ""
|
||||
"Sind Sie sicher, das Sie %(object_name)s \"%(escaped_object)s\" löschen "
|
||||
"Sind Sie sicher, dass Sie %(object_name)s \"%(escaped_object)s\" löschen "
|
||||
"wollen? Es werden zusätzlich die folgenden abhängigen Daten mit gelöscht:"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:26
|
||||
@ -1061,7 +1057,7 @@ msgid ""
|
||||
"password twice so we can verify you typed it in correctly."
|
||||
msgstr ""
|
||||
"Bitte geben Sie aus Sicherheitsgründen erst Ihr altes Kennwort und darunter "
|
||||
"dann zweimal (um sicherzustellen, das Sie es korrekt eingegeben haben) das "
|
||||
"dann zweimal (um sicherzustellen, dass Sie es korrekt eingegeben haben) das "
|
||||
"neue Kennwort ein."
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:17
|
||||
@ -1087,7 +1083,7 @@ msgstr "Sie erhalten diese Mail, weil Sie ein neues Kennwort"
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:3
|
||||
#, python-format
|
||||
msgid "for your user account at %(site_name)s"
|
||||
msgstr "für ihren Benutzer bei %(site_name)s angefordert haben."
|
||||
msgstr "für Ihren Benutzer bei %(site_name)s angefordert haben."
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:5
|
||||
#, python-format
|
||||
@ -1104,7 +1100,7 @@ msgstr "Ihr Benutzername, falls Sie ihn vergessen haben:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:13
|
||||
msgid "Thanks for using our site!"
|
||||
msgstr "Vielen Dank, das Sie unsere Seiten benutzen!"
|
||||
msgstr "Vielen Dank, dass Sie unsere Seiten benutzen!"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:15
|
||||
#, python-format
|
||||
@ -1367,7 +1363,7 @@ msgid ""
|
||||
"Designates that this user has all permissions without explicitly assigning "
|
||||
"them."
|
||||
msgstr ""
|
||||
"Bestimmt, das dieser Benutzer alle Berechtigungen hat, ohne diese einzeln "
|
||||
"Bestimmt, dass dieser Benutzer alle Berechtigungen hat, ohne diese einzeln "
|
||||
"zuweisen zu müssen."
|
||||
|
||||
#: contrib/auth/models.py:98
|
||||
@ -1414,10 +1410,18 @@ msgstr "Wichtige Daten"
|
||||
msgid "Groups"
|
||||
msgstr "Gruppen"
|
||||
|
||||
#: contrib/auth/models.py:256
|
||||
#: contrib/auth/models.py:258
|
||||
msgid "message"
|
||||
msgstr "Mitteilung"
|
||||
|
||||
#: contrib/auth/forms.py:16
|
||||
msgid "The two password fields didn't match."
|
||||
msgstr "Die zwei Passwörter sind nicht gleich."
|
||||
|
||||
#: contrib/auth/forms.py:24
|
||||
msgid "A user with that username already exists."
|
||||
msgstr "Ein Benutzer mit diesem Namen existiert bereits."
|
||||
|
||||
#: contrib/auth/forms.py:52
|
||||
msgid ""
|
||||
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
|
||||
@ -1432,10 +1436,10 @@ msgstr "Dieser Benutzer ist inaktiv."
|
||||
|
||||
#: contrib/auth/forms.py:84
|
||||
msgid ""
|
||||
"That e-mail address doesn't have an associated user acount. Are you sure "
|
||||
"That e-mail address doesn't have an associated user account. Are you sure "
|
||||
"you've registered?"
|
||||
msgstr ""
|
||||
"Die Email-Adresse hat keinen Benutzer zugeordnet. Sicher, das die Adresse "
|
||||
"Die Email-Adresse hat keinen Benutzer zugeordnet. Sicher, dass die Adresse "
|
||||
"hier angemeldet ist?"
|
||||
|
||||
#: contrib/auth/forms.py:116
|
||||
@ -1783,58 +1787,62 @@ msgid "Norwegian"
|
||||
msgstr "Norwegisch"
|
||||
|
||||
#: conf/global_settings.py:59
|
||||
msgid "Polish"
|
||||
msgstr "Polnisch"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
msgid "Brazilian"
|
||||
msgstr "Brasilianisch"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
#: conf/global_settings.py:61
|
||||
msgid "Romanian"
|
||||
msgstr "Rumänisch"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Russian"
|
||||
msgstr "Russisch"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
#: conf/global_settings.py:63
|
||||
msgid "Slovak"
|
||||
msgstr "Slowakisch"
|
||||
|
||||
#: conf/global_settings.py:63
|
||||
#: conf/global_settings.py:64
|
||||
msgid "Slovenian"
|
||||
msgstr "Slowenisch"
|
||||
|
||||
#: conf/global_settings.py:64
|
||||
#: conf/global_settings.py:65
|
||||
msgid "Serbian"
|
||||
msgstr "Serbisch"
|
||||
|
||||
#: conf/global_settings.py:65
|
||||
#: conf/global_settings.py:66
|
||||
msgid "Swedish"
|
||||
msgstr "Schwedisch"
|
||||
|
||||
#: conf/global_settings.py:66
|
||||
#: conf/global_settings.py:67
|
||||
msgid "Tamil"
|
||||
msgstr "Tamilisch"
|
||||
|
||||
#: conf/global_settings.py:67
|
||||
#: conf/global_settings.py:68
|
||||
msgid "Turkish"
|
||||
msgstr "Türkisch"
|
||||
|
||||
#: conf/global_settings.py:68
|
||||
#: conf/global_settings.py:69
|
||||
msgid "Ukrainian"
|
||||
msgstr "Ukrainisch"
|
||||
|
||||
#: conf/global_settings.py:69
|
||||
#: conf/global_settings.py:70
|
||||
msgid "Simplified Chinese"
|
||||
msgstr "Vereinfachtes Chinesisch"
|
||||
|
||||
#: conf/global_settings.py:70
|
||||
#: conf/global_settings.py:71
|
||||
msgid "Traditional Chinese"
|
||||
msgstr "Traditionelles Chinesisch"
|
||||
|
||||
#: core/validators.py:63
|
||||
#: core/validators.py:64
|
||||
msgid "This value must contain only letters, numbers and underscores."
|
||||
msgstr "Dieser Wert darf nur Buchstaben, Ziffern und Unterstriche enthalten."
|
||||
|
||||
#: core/validators.py:67
|
||||
#: core/validators.py:68
|
||||
msgid ""
|
||||
"This value must contain only letters, numbers, underscores, dashes or "
|
||||
"slashes."
|
||||
@ -1842,85 +1850,85 @@ msgstr ""
|
||||
"Dieser Wert darf nur Buchstaben, Ziffern, Unterstriche und Schrägstriche "
|
||||
"enthalten."
|
||||
|
||||
#: core/validators.py:71
|
||||
#: core/validators.py:72
|
||||
msgid "This value must contain only letters, numbers, underscores or hyphens."
|
||||
msgstr ""
|
||||
"Dieser Wert darf nur Buchstaben, Ziffern, Unterstriche und Bindestriche "
|
||||
"enthalten."
|
||||
|
||||
#: core/validators.py:75
|
||||
#: core/validators.py:76
|
||||
msgid "Uppercase letters are not allowed here."
|
||||
msgstr "Großbuchstaben sind hier nicht erlaubt."
|
||||
|
||||
#: core/validators.py:79
|
||||
#: core/validators.py:80
|
||||
msgid "Lowercase letters are not allowed here."
|
||||
msgstr "Kleinbuchstaben sind hier nicht erlaubt."
|
||||
|
||||
#: core/validators.py:86
|
||||
#: core/validators.py:87
|
||||
msgid "Enter only digits separated by commas."
|
||||
msgstr "Hier sind nur durch Komma getrennte Ziffern erlaubt."
|
||||
|
||||
#: core/validators.py:98
|
||||
#: core/validators.py:99
|
||||
msgid "Enter valid e-mail addresses separated by commas."
|
||||
msgstr "Bitte mit Komma getrennte, gültige eMail-Adressen eingeben."
|
||||
|
||||
#: core/validators.py:102
|
||||
#: core/validators.py:103
|
||||
msgid "Please enter a valid IP address."
|
||||
msgstr "Bitte eine gültige IP-Adresse eingeben."
|
||||
|
||||
#: core/validators.py:106
|
||||
#: core/validators.py:107
|
||||
msgid "Empty values are not allowed here."
|
||||
msgstr "Dieses Feld darf nicht leer sein."
|
||||
|
||||
#: core/validators.py:110
|
||||
#: core/validators.py:111
|
||||
msgid "Non-numeric characters aren't allowed here."
|
||||
msgstr "Nichtnumerische Zeichen sind hier nicht erlaubt."
|
||||
|
||||
#: core/validators.py:114
|
||||
#: core/validators.py:115
|
||||
msgid "This value can't be comprised solely of digits."
|
||||
msgstr "Dieser Wert darf nicht nur aus Ziffern bestehen."
|
||||
|
||||
#: core/validators.py:119
|
||||
#: core/validators.py:120
|
||||
msgid "Enter a whole number."
|
||||
msgstr "Bitte eine ganze Zahl eingeben."
|
||||
|
||||
#: core/validators.py:123
|
||||
#: core/validators.py:124
|
||||
msgid "Only alphabetical characters are allowed here."
|
||||
msgstr "Nur alphabetische Zeichen sind hier erlaubt."
|
||||
|
||||
#: core/validators.py:138
|
||||
#: core/validators.py:139
|
||||
msgid "Year must be 1900 or later."
|
||||
msgstr "Das Jahr muss 1900 oder später sein."
|
||||
|
||||
#: core/validators.py:142
|
||||
#: core/validators.py:143
|
||||
#, python-format
|
||||
msgid "Invalid date: %s."
|
||||
msgstr "Ungültiges Datum: %s"
|
||||
|
||||
#: core/validators.py:146 db/models/fields/__init__.py:415
|
||||
#: core/validators.py:147 db/models/fields/__init__.py:424
|
||||
msgid "Enter a valid date in YYYY-MM-DD format."
|
||||
msgstr "Bitte ein gültiges Datum im Format JJJJ-MM-TT eingeben."
|
||||
|
||||
#: core/validators.py:151
|
||||
#: core/validators.py:152
|
||||
msgid "Enter a valid time in HH:MM format."
|
||||
msgstr "Bitte eine gültige Zeit im Format SS:MM eingeben."
|
||||
|
||||
#: core/validators.py:155 db/models/fields/__init__.py:477
|
||||
#: core/validators.py:156 db/models/fields/__init__.py:488
|
||||
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
|
||||
msgstr ""
|
||||
"Bitte eine gültige Datums- und Zeitangabe im Format JJJJ-MM-TT SS:MM "
|
||||
"eingeben."
|
||||
|
||||
#: core/validators.py:160
|
||||
#: core/validators.py:161
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr "Bitte eine gültige eMail-Adresse eingeben"
|
||||
|
||||
#: core/validators.py:172 core/validators.py:401 forms/__init__.py:661
|
||||
#: core/validators.py:173 core/validators.py:442 forms/__init__.py:667
|
||||
msgid "No file was submitted. Check the encoding type on the form."
|
||||
msgstr ""
|
||||
"Es wurde keine Datei geschickt. Eventuell ist das Formular-Encoding falsch."
|
||||
|
||||
#: core/validators.py:176
|
||||
#: core/validators.py:177
|
||||
msgid ""
|
||||
"Upload a valid image. The file you uploaded was either not an image or a "
|
||||
"corrupted image."
|
||||
@ -1928,27 +1936,27 @@ msgstr ""
|
||||
"Bitte ein Bild hochladen. Die Datei, die hochgeladen wurde, ist kein Bild "
|
||||
"oder ist defekt."
|
||||
|
||||
#: core/validators.py:183
|
||||
#: core/validators.py:184
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid image."
|
||||
msgstr "Die URL %s zeigt nicht auf ein gültiges Bild."
|
||||
|
||||
#: core/validators.py:187
|
||||
#: core/validators.py:188
|
||||
#, python-format
|
||||
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
|
||||
msgstr ""
|
||||
"Telefonnummern müssen im Format XXX-XXX-XXXX sein. \"%s\" ist ungültig."
|
||||
|
||||
#: core/validators.py:195
|
||||
#: core/validators.py:196
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid QuickTime video."
|
||||
msgstr "Die URL %s zeigt nicht auf ein gültiges QuickTime video."
|
||||
|
||||
#: core/validators.py:199
|
||||
#: core/validators.py:200
|
||||
msgid "A valid URL is required."
|
||||
msgstr "Eine gültige URL ist hier verlangt."
|
||||
|
||||
#: core/validators.py:213
|
||||
#: core/validators.py:214
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Valid HTML is required. Specific errors are:\n"
|
||||
@ -1957,71 +1965,83 @@ msgstr ""
|
||||
"Bitte gültiges HTML eingeben. Fehler sind:\n"
|
||||
"%s"
|
||||
|
||||
#: core/validators.py:220
|
||||
#: core/validators.py:221
|
||||
#, python-format
|
||||
msgid "Badly formed XML: %s"
|
||||
msgstr "Ungültiges XML: %s"
|
||||
|
||||
#: core/validators.py:230
|
||||
#: core/validators.py:238
|
||||
#, python-format
|
||||
msgid "Invalid URL: %s"
|
||||
msgstr "Ungültige URL: %s"
|
||||
|
||||
#: core/validators.py:234 core/validators.py:236
|
||||
#: core/validators.py:243 core/validators.py:245
|
||||
#, python-format
|
||||
msgid "The URL %s is a broken link."
|
||||
msgstr "Die URL %s funktioniert nicht."
|
||||
|
||||
#: core/validators.py:242
|
||||
#: core/validators.py:251
|
||||
msgid "Enter a valid U.S. state abbreviation."
|
||||
msgstr "Bitte eine gültige Abkürzung für einen US-Staat eingeben."
|
||||
|
||||
#: core/validators.py:256
|
||||
#: core/validators.py:265
|
||||
#, python-format
|
||||
msgid "Watch your mouth! The word %s is not allowed here."
|
||||
msgid_plural "Watch your mouth! The words %s are not allowed here."
|
||||
msgstr[0] "Keine Schimpfworte! Das Wort %s ist hier nicht gern gesehen!"
|
||||
msgstr[1] "Keine Schimpfworte! Die Wörter %s sind hier nicht gern gesehen!"
|
||||
|
||||
#: core/validators.py:263
|
||||
#: core/validators.py:272
|
||||
#, python-format
|
||||
msgid "This field must match the '%s' field."
|
||||
msgstr "Dieses Feld muss zum Feld '%s' passen."
|
||||
|
||||
#: core/validators.py:282
|
||||
#: core/validators.py:291
|
||||
msgid "Please enter something for at least one field."
|
||||
msgstr "Bitte mindestens eines der Felder ausfüllen."
|
||||
|
||||
#: core/validators.py:291 core/validators.py:302
|
||||
#: core/validators.py:300 core/validators.py:311
|
||||
msgid "Please enter both fields or leave them both empty."
|
||||
msgstr "Bitte entweder beide Felder ausfüllen, oder beide leer lassen."
|
||||
|
||||
#: core/validators.py:309
|
||||
#: core/validators.py:318
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is %(value)s"
|
||||
msgstr ""
|
||||
"Dieses Feld muss gefüllt sein, wenn Feld %(field)s den Wert %(value)s hat."
|
||||
|
||||
#: core/validators.py:321
|
||||
#: core/validators.py:330
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is not %(value)s"
|
||||
msgstr ""
|
||||
"Dieses Feld muss gefüllt sein, wenn Feld %(field)s nicht %(value)s ist."
|
||||
|
||||
#: core/validators.py:340
|
||||
#: core/validators.py:349
|
||||
msgid "Duplicate values are not allowed."
|
||||
msgstr "Doppelte Werte sind hier nicht erlaubt."
|
||||
|
||||
#: core/validators.py:363
|
||||
#: core/validators.py:364
|
||||
msgid "This value must be between %s and %s."
|
||||
msgstr "Dieser Wert muss zwischen %s und %s sein."
|
||||
|
||||
#: core/validators.py:366
|
||||
msgid "This value must be at least %s."
|
||||
msgstr "Dieser Wert muss mindestens %s sein."
|
||||
|
||||
#: core/validators.py:368
|
||||
msgid "This value must be no more than %s."
|
||||
msgstr "Dieser Wert darf maximal %s sein."
|
||||
|
||||
#: core/validators.py:404
|
||||
#, python-format
|
||||
msgid "This value must be a power of %s."
|
||||
msgstr "Dieser Wert muss eine Potenz von %s sein."
|
||||
|
||||
#: core/validators.py:374
|
||||
#: core/validators.py:415
|
||||
msgid "Please enter a valid decimal number."
|
||||
msgstr "Bitte eine gültige Dezimalzahl eingeben."
|
||||
|
||||
#: core/validators.py:378
|
||||
#: core/validators.py:419
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s total digit."
|
||||
msgid_plural ""
|
||||
@ -2029,7 +2049,7 @@ msgid_plural ""
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffer eingeben."
|
||||
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffern eingeben."
|
||||
|
||||
#: core/validators.py:381
|
||||
#: core/validators.py:422
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please enter a valid decimal number with a whole part of at most %s digit."
|
||||
@ -2038,7 +2058,7 @@ msgid_plural ""
|
||||
msgstr[0] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffer eingeben."
|
||||
msgstr[1] "Bitte eine gültige Dezimalzahl mit maximal %s Ziffern eingeben."
|
||||
|
||||
#: core/validators.py:384
|
||||
#: core/validators.py:425
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural ""
|
||||
@ -2048,39 +2068,39 @@ msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
"Bitte eine gültige Dezimalzahl mit maximal %s Dezimalstellen eingeben."
|
||||
|
||||
#: core/validators.py:394
|
||||
#: core/validators.py:435
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr ""
|
||||
"Bitte sicherstellen, daß die hochgeladene Datei mindestens %s Bytes gross "
|
||||
"ist."
|
||||
|
||||
#: core/validators.py:395
|
||||
#: core/validators.py:436
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr ""
|
||||
"Bitte sicherstellen, daß die hochgeladene Datei maximal %s Bytes gross ist."
|
||||
|
||||
#: core/validators.py:412
|
||||
#: core/validators.py:453
|
||||
msgid "The format for this field is wrong."
|
||||
msgstr "Das Format für dieses Feld ist falsch."
|
||||
|
||||
#: core/validators.py:427
|
||||
#: core/validators.py:468
|
||||
msgid "This field is invalid."
|
||||
msgstr "Dieses Feld ist ungültig."
|
||||
|
||||
#: core/validators.py:463
|
||||
#: core/validators.py:504
|
||||
#, python-format
|
||||
msgid "Could not retrieve anything from %s."
|
||||
msgstr "Konnte nichts von %s empfangen."
|
||||
|
||||
#: core/validators.py:466
|
||||
#: core/validators.py:507
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
msgstr "Die URL %(url)s lieferte den falschen Content-Type '%(contenttype)s'."
|
||||
|
||||
#: core/validators.py:499
|
||||
#: core/validators.py:540
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
|
||||
@ -2089,7 +2109,7 @@ msgstr ""
|
||||
"Bitte das ungeschlossene %(tag)s Tag in Zeile %(line)s schließen. Die Zeile "
|
||||
"beginnt mit \"%(start)s\"."
|
||||
|
||||
#: core/validators.py:503
|
||||
#: core/validators.py:544
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Some text starting on line %(line)s is not allowed in that context. (Line "
|
||||
@ -2098,7 +2118,7 @@ msgstr ""
|
||||
"In Zeile %(line)s ist Text, der nicht in dem Kontext erlaubt ist. Die Zeile "
|
||||
"beginnt mit \"%(start)s\"."
|
||||
|
||||
#: core/validators.py:508
|
||||
#: core/validators.py:549
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
|
||||
@ -2107,7 +2127,7 @@ msgstr ""
|
||||
"Das Attribute %(attr)s in Zeile %(line)s ist ungültig. Die Zeile beginnt mit "
|
||||
"\"%(start)s\"."
|
||||
|
||||
#: core/validators.py:513
|
||||
#: core/validators.py:554
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
|
||||
@ -2116,7 +2136,7 @@ msgstr ""
|
||||
"<%(tag)s> in Zeile %(line)s ist ungültig. Die Zeile beginnt mit \"%(start)s"
|
||||
"\"."
|
||||
|
||||
#: core/validators.py:517
|
||||
#: core/validators.py:558
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A tag on line %(line)s is missing one or more required attributes. (Line "
|
||||
@ -2125,7 +2145,7 @@ msgstr ""
|
||||
"Ein Tag in Zeile %(line)s hat eines oder mehrere Pflichtattribute nicht. Die "
|
||||
"Zeile beginnt mit \"%(start)s\"."
|
||||
|
||||
#: core/validators.py:522
|
||||
#: core/validators.py:563
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
|
||||
@ -2149,37 +2169,37 @@ msgstr "%(verbose_name)s wurde erfolgreich aktualisiert."
|
||||
msgid "The %(verbose_name)s was deleted."
|
||||
msgstr "%(verbose_name)s wurde gelöscht"
|
||||
|
||||
#: db/models/manipulators.py:302
|
||||
#: db/models/manipulators.py:305
|
||||
#, python-format
|
||||
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
|
||||
msgstr ""
|
||||
"Ein '%(object)s' in dieser '%(type)s' existiert bereits für dieses '%(field)"
|
||||
"s'."
|
||||
|
||||
#: db/models/fields/__init__.py:40
|
||||
#: db/models/fields/__init__.py:41
|
||||
#, python-format
|
||||
msgid "%(optname)s with this %(fieldname)s already exists."
|
||||
msgstr "Ein '%(optname)s' mit diesem '%(fieldname)s' existiert bereits."
|
||||
|
||||
#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265
|
||||
#: db/models/fields/__init__.py:551 db/models/fields/__init__.py:562
|
||||
#: forms/__init__.py:346
|
||||
#: db/models/fields/__init__.py:115 db/models/fields/__init__.py:266
|
||||
#: db/models/fields/__init__.py:569 db/models/fields/__init__.py:580
|
||||
#: forms/__init__.py:352
|
||||
msgid "This field is required."
|
||||
msgstr "Dieses Feld ist zwingend."
|
||||
|
||||
#: db/models/fields/__init__.py:340
|
||||
#: db/models/fields/__init__.py:349
|
||||
msgid "This value must be an integer."
|
||||
msgstr "Dieser Wert muss eine Ganzzahl sein."
|
||||
|
||||
#: db/models/fields/__init__.py:372
|
||||
#: db/models/fields/__init__.py:381
|
||||
msgid "This value must be either True or False."
|
||||
msgstr "Dieser Wert muss wahr oder falsch sein."
|
||||
|
||||
#: db/models/fields/__init__.py:388
|
||||
#: db/models/fields/__init__.py:397
|
||||
msgid "This field cannot be null."
|
||||
msgstr "Dieses Feld darf nicht leer sein."
|
||||
|
||||
#: db/models/fields/__init__.py:571
|
||||
#: db/models/fields/__init__.py:589
|
||||
msgid "Enter a valid filename."
|
||||
msgstr "Bitte einen gültigen Dateinamen eingeben"
|
||||
|
||||
@ -2209,36 +2229,36 @@ msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
"Bitte gültige IDs für %(self)s eingeben. Die Werte %(value)r sind ungültig."
|
||||
|
||||
#: forms/__init__.py:381
|
||||
#: forms/__init__.py:387
|
||||
#, python-format
|
||||
msgid "Ensure your text is less than %s character."
|
||||
msgid_plural "Ensure your text is less than %s characters."
|
||||
msgstr[0] "Bitte sicherstellen, das der Text weniger als %s Zeichen hat."
|
||||
msgstr[1] "Bitte sicherstellen, das der Text weniger als %s Zeichen hat."
|
||||
msgstr[0] "Bitte sicherstellen, dass der Text weniger als %s Zeichen hat."
|
||||
msgstr[1] "Bitte sicherstellen, dass der Text weniger als %s Zeichen hat."
|
||||
|
||||
#: forms/__init__.py:386
|
||||
#: forms/__init__.py:392
|
||||
msgid "Line breaks are not allowed here."
|
||||
msgstr "Zeilenumbrüche sind hier nicht erlaubt."
|
||||
|
||||
#: forms/__init__.py:487 forms/__init__.py:560 forms/__init__.py:599
|
||||
#: forms/__init__.py:493 forms/__init__.py:566 forms/__init__.py:605
|
||||
#, python-format
|
||||
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
|
||||
msgstr ""
|
||||
"Bitte eine gültige Auswahl treffen; '%(data)s' ist nicht in %(choices)s."
|
||||
|
||||
#: forms/__init__.py:663
|
||||
#: forms/__init__.py:669
|
||||
msgid "The submitted file is empty."
|
||||
msgstr "Die ausgewählte Datei ist leer."
|
||||
|
||||
#: forms/__init__.py:719
|
||||
#: forms/__init__.py:725
|
||||
msgid "Enter a whole number between -32,768 and 32,767."
|
||||
msgstr "Bitte eine ganze Zahl zwischen -32.768 und 32.767 eingeben."
|
||||
|
||||
#: forms/__init__.py:729
|
||||
#: forms/__init__.py:735
|
||||
msgid "Enter a positive number."
|
||||
msgstr "Bitte eine ganze, positive Zahl eingeben."
|
||||
|
||||
#: forms/__init__.py:739
|
||||
#: forms/__init__.py:745
|
||||
msgid "Enter a whole number between 0 and 32,767."
|
||||
msgstr "Bitte eine ganze Zahl zwischen 0 und 32.767 eingeben."
|
||||
|
||||
|
Binary file not shown.
@ -107,6 +107,11 @@ msgid ""
|
||||
"\n"
|
||||
"http://%(domain)s%(url)s"
|
||||
msgstr ""
|
||||
"Σχόλιο από τον/την %(user)s την %(date)s\n"
|
||||
"\n"
|
||||
"%(comment)s\n"
|
||||
"\n"
|
||||
"http://%(domain)s%(url)s"
|
||||
|
||||
#: contrib/comments/models.py:168
|
||||
msgid "person's name"
|
||||
@ -141,11 +146,11 @@ msgstr "ημερομηνία βαθμολογίας"
|
||||
#: contrib/comments/models.py:237
|
||||
#, fuzzy
|
||||
msgid "karma score"
|
||||
msgstr "βαθμολογία"
|
||||
msgstr "karma"
|
||||
|
||||
#: contrib/comments/models.py:238
|
||||
msgid "karma scores"
|
||||
msgstr ""
|
||||
msgstr "karma"
|
||||
|
||||
#: contrib/comments/models.py:242
|
||||
#, python-format
|
||||
@ -159,7 +164,7 @@ msgid ""
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr ""
|
||||
"Αυτο το σχόλιο σημειώθει απο %(χρήστη)ες\n"
|
||||
"Αυτο το σχόλιο σημειώθηκε απο %(χρήστη)ες\n"
|
||||
"\n"
|
||||
"%(κείμενο)α"
|
||||
|
||||
@ -245,7 +250,7 @@ msgstr ""
|
||||
#: contrib/comments/views/comments.py:193
|
||||
#: contrib/comments/views/comments.py:284
|
||||
msgid "One or more of the required fields wasn't submitted"
|
||||
msgstr "Ένα ή περισσότερα από τα απαιτούμενα πεδία δεν υποβλίθει"
|
||||
msgstr "Ένα ή περισσότερα από τα απαιτούμενα πεδία δεν υπεβλήθει"
|
||||
|
||||
#: contrib/comments/views/comments.py:197
|
||||
#: contrib/comments/views/comments.py:286
|
||||
@ -268,7 +273,7 @@ msgstr ""
|
||||
#: contrib/comments/templates/comments/form.html:8
|
||||
#: contrib/admin/templates/admin/login.html:17
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
msgstr "Όνομα χρήστη:"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:6
|
||||
#: contrib/admin/templates/admin/login.html:20
|
||||
@ -298,21 +303,21 @@ msgstr "Ξεχάσατε τον κωδικό σας;"
|
||||
#: contrib/admin/templates/admin_doc/index.html:4
|
||||
#: contrib/admin/templates/admin_doc/model_index.html:5
|
||||
msgid "Log out"
|
||||
msgstr ""
|
||||
msgstr "Αποσύνδεση"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
msgid "Ratings"
|
||||
msgstr ""
|
||||
msgstr "Βαθμολογίες"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Required"
|
||||
msgstr ""
|
||||
msgstr "Απαραίτητο"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Optional"
|
||||
msgstr ""
|
||||
msgstr "Προαιρετικό"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Post a photo"
|
||||
@ -326,11 +331,11 @@ msgstr "Σχόλιο:"
|
||||
#: contrib/comments/templates/comments/form.html:32
|
||||
#: contrib/comments/templates/comments/freeform.html:9
|
||||
msgid "Preview comment"
|
||||
msgstr ""
|
||||
msgstr "Προεπισκόπηση σχολίου"
|
||||
|
||||
#: contrib/comments/templates/comments/freeform.html:4
|
||||
msgid "Your name:"
|
||||
msgstr ""
|
||||
msgstr "Το όνομα σας:"
|
||||
|
||||
#: contrib/admin/filterspecs.py:40
|
||||
#, python-format
|
||||
@ -338,15 +343,17 @@ msgid ""
|
||||
"<h3>By %s:</h3>\n"
|
||||
"<ul>\n"
|
||||
msgstr ""
|
||||
"<h3>Από %s:</h3>\n"
|
||||
"<ul>\n"
|
||||
|
||||
#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88
|
||||
#: contrib/admin/filterspecs.py:143
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
msgstr "Όλα"
|
||||
|
||||
#: contrib/admin/filterspecs.py:109
|
||||
msgid "Any date"
|
||||
msgstr ""
|
||||
msgstr "Όλες οι ημερομηνίες"
|
||||
|
||||
#: contrib/admin/filterspecs.py:110
|
||||
msgid "Today"
|
||||
@ -354,7 +361,7 @@ msgstr "Σήμερα"
|
||||
|
||||
#: contrib/admin/filterspecs.py:113
|
||||
msgid "Past 7 days"
|
||||
msgstr ""
|
||||
msgstr "Τις προηγούμενες 7 ημέρες"
|
||||
|
||||
#: contrib/admin/filterspecs.py:115
|
||||
msgid "This month"
|
||||
@ -374,7 +381,7 @@ msgstr "Όχι"
|
||||
|
||||
#: contrib/admin/filterspecs.py:150
|
||||
msgid "Unknown"
|
||||
msgstr "’γνωστο"
|
||||
msgstr "Άγνωστο"
|
||||
|
||||
#: contrib/admin/models.py:16
|
||||
msgid "action time"
|
||||
@ -441,7 +448,7 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/views/decorators.py:82
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
msgstr "Τα ονόματα των Χρηστών δεν μπορόυν να περιέχουν τον χαρακτήρα '@'."
|
||||
msgstr "Τα ονόματα των χρηστών δεν μπορόυν να περιέχουν τον χαρακτήρα '@'."
|
||||
|
||||
#: contrib/admin/views/decorators.py:84
|
||||
#, python-format
|
||||
@ -452,16 +459,16 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/views/main.py:226
|
||||
msgid "Site administration"
|
||||
msgstr "Διαχείριση του Διαδυκτιακού χώρου"
|
||||
msgstr "Διαχείριση του Διαδικτυακού χώρου"
|
||||
|
||||
#: contrib/admin/views/main.py:260
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully."
|
||||
msgstr ""
|
||||
msgstr "Το %(name)s \"%(obj)s\" αποθηκεύτηκε επιτυχώς."
|
||||
|
||||
#: contrib/admin/views/main.py:264 contrib/admin/views/main.py:348
|
||||
msgid "You may edit it again below."
|
||||
msgstr ""
|
||||
msgstr "Μπορείτε να το επεξεργαστείτε ξανα παρακάτω."
|
||||
|
||||
#: contrib/admin/views/main.py:272 contrib/admin/views/main.py:357
|
||||
#, python-format
|
||||
@ -471,12 +478,12 @@ msgstr "Μπορείτε να προσθέσετε ακόμα ένα %s απο
|
||||
#: contrib/admin/views/main.py:290
|
||||
#, python-format
|
||||
msgid "Add %s"
|
||||
msgstr ""
|
||||
msgstr "Προσθήκη %s"
|
||||
|
||||
#: contrib/admin/views/main.py:336
|
||||
#, python-format
|
||||
msgid "Added %s."
|
||||
msgstr ""
|
||||
msgstr "Προστέθηκε %s."
|
||||
|
||||
#: contrib/admin/views/main.py:336 contrib/admin/views/main.py:338
|
||||
#: contrib/admin/views/main.py:340
|
||||
@ -486,32 +493,33 @@ msgstr "και"
|
||||
#: contrib/admin/views/main.py:338
|
||||
#, python-format
|
||||
msgid "Changed %s."
|
||||
msgstr ""
|
||||
msgstr "Επεξεργάσθηκε %s."
|
||||
|
||||
#: contrib/admin/views/main.py:340
|
||||
#, python-format
|
||||
msgid "Deleted %s."
|
||||
msgstr ""
|
||||
msgstr "Διεγράφη %s."
|
||||
|
||||
#: contrib/admin/views/main.py:343
|
||||
msgid "No fields changed."
|
||||
msgstr ""
|
||||
msgstr "Κανένα πεδίο δεν άλλαξε."
|
||||
|
||||
#: contrib/admin/views/main.py:346
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was changed successfully."
|
||||
msgstr ""
|
||||
msgstr "Το %(name)s \"%(obj)s\" επεξεργάσθηκε επιτυχώς."
|
||||
|
||||
#: contrib/admin/views/main.py:354
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr ""
|
||||
"Το %(name)s \"%(obj)s\" αποθηκεύθηκε επιτυχώς. Μπορείτε να το επεξεργαστείτε πάλι παρακάτω."
|
||||
|
||||
#: contrib/admin/views/main.py:392
|
||||
#, python-format
|
||||
msgid "Change %s"
|
||||
msgstr ""
|
||||
msgstr "Αλλαγή %s"
|
||||
|
||||
#: contrib/admin/views/main.py:470
|
||||
#, python-format
|
||||
@ -535,17 +543,17 @@ msgstr "Είστε σίγουρος;"
|
||||
#: contrib/admin/views/main.py:533
|
||||
#, python-format
|
||||
msgid "Change history: %s"
|
||||
msgstr ""
|
||||
msgstr "Ιστορικό Αλλαγών: %s"
|
||||
|
||||
#: contrib/admin/views/main.py:565
|
||||
#, python-format
|
||||
msgid "Select %s"
|
||||
msgstr ""
|
||||
msgstr "Επιλογή %s"
|
||||
|
||||
#: contrib/admin/views/main.py:565
|
||||
#, python-format
|
||||
msgid "Select %s to change"
|
||||
msgstr ""
|
||||
msgstr "Επιλέξτε %s προς αλλαγή"
|
||||
|
||||
#: contrib/admin/views/doc.py:277 contrib/admin/views/doc.py:286
|
||||
#: contrib/admin/views/doc.py:288 contrib/admin/views/doc.py:294
|
||||
@ -555,7 +563,7 @@ msgstr "Ακέραιος"
|
||||
|
||||
#: contrib/admin/views/doc.py:278
|
||||
msgid "Boolean (Either True or False)"
|
||||
msgstr "Boolean (Είτε Αλήθεια ή Ψέμα)"
|
||||
msgstr "Boolean (Είτε Αληθές ή Ψέυδές)"
|
||||
|
||||
#: contrib/admin/views/doc.py:279 contrib/admin/views/doc.py:296
|
||||
#, python-format
|
||||
@ -580,7 +588,7 @@ msgstr "Ηλεκτρονική διεύθυνση"
|
||||
|
||||
#: contrib/admin/views/doc.py:284 contrib/admin/views/doc.py:287
|
||||
msgid "File path"
|
||||
msgstr ""
|
||||
msgstr "Τοποθεσία Αρχείου"
|
||||
|
||||
#: contrib/admin/views/doc.py:285
|
||||
msgid "Decimal number"
|
||||
@ -592,7 +600,7 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/views/doc.py:292
|
||||
msgid "Relation to parent model"
|
||||
msgstr ""
|
||||
msgstr "Σχέση με το γονεϊκό μοντέλο"
|
||||
|
||||
#: contrib/admin/views/doc.py:293
|
||||
msgid "Phone number"
|
||||
@ -627,7 +635,7 @@ msgstr ""
|
||||
#: contrib/admin/templates/registration/password_change_form.html:3
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
|
||||
msgid "Documentation"
|
||||
msgstr ""
|
||||
msgstr "Τεκμηρίωση"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:3
|
||||
#: contrib/admin/templates/admin/change_list.html:5
|
||||
@ -667,11 +675,11 @@ msgstr "Home"
|
||||
#: contrib/admin/templates/admin/object_history.html:5
|
||||
#: contrib/admin/templates/admin/change_form.html:20
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
msgstr "Ιστορικό"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:18
|
||||
msgid "Date/time"
|
||||
msgstr ""
|
||||
msgstr "Ημερομηνία/Ώρα"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:19
|
||||
msgid "User"
|
||||
@ -679,7 +687,7 @@ msgstr "Χρήστης"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:20
|
||||
msgid "Action"
|
||||
msgstr ""
|
||||
msgstr "Δράση"
|
||||
|
||||
#: contrib/admin/templates/admin/object_history.html:26
|
||||
msgid "DATE_WITH_TIME_FULL"
|
||||
@ -697,19 +705,19 @@ msgstr "Διαχειριστής ιστοσελίδας Django"
|
||||
|
||||
#: contrib/admin/templates/admin/base_site.html:7
|
||||
msgid "Django administration"
|
||||
msgstr ""
|
||||
msgstr "Διαχείριση Django"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:4
|
||||
msgid "Server error"
|
||||
msgstr ""
|
||||
msgstr "Σφάλμα Διακομιστή"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:6
|
||||
msgid "Server error (500)"
|
||||
msgstr ""
|
||||
msgstr "Σφάλμα Διακομιστή (500)"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:9
|
||||
msgid "Server Error <em>(500)</em>"
|
||||
msgstr ""
|
||||
msgstr "Σφάλμα Διακομιστή <em>(500)</em>"
|
||||
|
||||
#: contrib/admin/templates/admin/500.html:10
|
||||
msgid ""
|
||||
@ -720,7 +728,7 @@ msgstr ""
|
||||
#: contrib/admin/templates/admin/404.html:4
|
||||
#: contrib/admin/templates/admin/404.html:8
|
||||
msgid "Page not found"
|
||||
msgstr ""
|
||||
msgstr "Η σελίδα δε βρέθηκε."
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:10
|
||||
msgid "We're sorry, but the requested page could not be found."
|
||||
@ -729,24 +737,24 @@ msgstr ""
|
||||
#: contrib/admin/templates/admin/index.html:17
|
||||
#, python-format
|
||||
msgid "Models available in the %(name)s application."
|
||||
msgstr ""
|
||||
msgstr "Διαθέσιμα μοντέλα στην εφαρμογή %(name)s."
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:28
|
||||
#: contrib/admin/templates/admin/change_form.html:15
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Προσθήκη"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:34
|
||||
msgid "Change"
|
||||
msgstr ""
|
||||
msgstr "Επεξεργασία"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:44
|
||||
msgid "You don't have permission to edit anything."
|
||||
msgstr ""
|
||||
msgstr "Δεν έχετε άδεια να επεξεργαστείτε τίποτα."
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:52
|
||||
msgid "Recent Actions"
|
||||
msgstr ""
|
||||
msgstr "Πρόσφατες Πράξεις"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:53
|
||||
msgid "My Actions"
|
||||
@ -754,16 +762,16 @@ msgstr "Οι πράξεις μου"
|
||||
|
||||
#: contrib/admin/templates/admin/index.html:57
|
||||
msgid "None available"
|
||||
msgstr ""
|
||||
msgstr "Κανένα διαθέσιμο"
|
||||
|
||||
#: contrib/admin/templates/admin/change_list.html:11
|
||||
#, python-format
|
||||
msgid "Add %(name)s"
|
||||
msgstr ""
|
||||
msgstr "Προσθήκη %(name)s"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:22
|
||||
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
msgstr ""
|
||||
msgstr "<a href=\"/password_reset/\">Ξεχάσατε τον κωδικό σας;</a> "
|
||||
|
||||
#: contrib/admin/templates/admin/base.html:23
|
||||
msgid "Welcome,"
|
||||
@ -772,7 +780,7 @@ msgstr "Καλωσήρθατε,"
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:9
|
||||
#: contrib/admin/templates/admin/submit_line.html:3
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
msgstr "Διαγραφή"
|
||||
|
||||
#: contrib/admin/templates/admin/delete_confirmation.html:14
|
||||
#, python-format
|
||||
@ -800,37 +808,37 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/templates/admin/search_form.html:8
|
||||
msgid "Go"
|
||||
msgstr ""
|
||||
msgstr "Πήγαινε"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:21
|
||||
msgid "View on site"
|
||||
msgstr ""
|
||||
msgstr "Προβολή στην ιστοσελίδα"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:30
|
||||
msgid "Please correct the error below."
|
||||
msgid_plural "Please correct the errors below."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "Παρακαλώ διορθώστε το παρακάτω λάθος."
|
||||
msgstr[1] "Παρακαλώ διορθώστε τα παρακάτω λάθη."
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:48
|
||||
msgid "Ordering"
|
||||
msgstr ""
|
||||
msgstr "Σειρά"
|
||||
|
||||
#: contrib/admin/templates/admin/change_form.html:51
|
||||
msgid "Order:"
|
||||
msgstr ""
|
||||
msgstr "Σειρά:"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:4
|
||||
msgid "Save as new"
|
||||
msgstr ""
|
||||
msgstr "Αποθήκευση καινούριου"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:5
|
||||
msgid "Save and add another"
|
||||
msgstr ""
|
||||
msgstr "Αποθήκευση και προσθήκη καινούριου."
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:6
|
||||
msgid "Save and continue editing"
|
||||
msgstr ""
|
||||
msgstr "Αποθήκευση και συνέχεια επεξεργασίας"
|
||||
|
||||
#: contrib/admin/templates/admin/submit_line.html:7
|
||||
msgid "Save"
|
||||
@ -841,12 +849,12 @@ msgstr "Αποθήκευση"
|
||||
#: contrib/admin/templates/registration/password_change_form.html:6
|
||||
#: contrib/admin/templates/registration/password_change_form.html:10
|
||||
msgid "Password change"
|
||||
msgstr ""
|
||||
msgstr "Αλλαγή Κωδικού"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_done.html:6
|
||||
#: contrib/admin/templates/registration/password_change_done.html:10
|
||||
msgid "Password change successful"
|
||||
msgstr ""
|
||||
msgstr "Αλλαγή κωδικού επιτυχής"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_done.html:12
|
||||
msgid "Your password was changed."
|
||||
@ -857,7 +865,7 @@ msgstr "Ο κωδίκός σας άλλαξε."
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:10
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:4
|
||||
msgid "Password reset"
|
||||
msgstr ""
|
||||
msgstr "Επαναφορά κωδικού"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:12
|
||||
msgid ""
|
||||
@ -867,11 +875,11 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:16
|
||||
msgid "E-mail address:"
|
||||
msgstr ""
|
||||
msgstr "E-mail διεύθυνση:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_form.html:16
|
||||
msgid "Reset my password"
|
||||
msgstr ""
|
||||
msgstr "Επαναφορά του κωδικού μου"
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:8
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
@ -880,7 +888,7 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:10
|
||||
msgid "Log in again"
|
||||
msgstr ""
|
||||
msgstr "Εισαγωγή ξανά"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:6
|
||||
#: contrib/admin/templates/registration/password_reset_done.html:10
|
||||
@ -909,11 +917,11 @@ msgstr "Νέος κωδικός:"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:21
|
||||
msgid "Confirm password:"
|
||||
msgstr ""
|
||||
msgstr "Επιβεβαίωση κωδικού"
|
||||
|
||||
#: contrib/admin/templates/registration/password_change_form.html:23
|
||||
msgid "Change my password"
|
||||
msgstr ""
|
||||
msgstr "Αλλαγή του κωδικού μου"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:2
|
||||
msgid "You're receiving this e-mail because you requested a password reset"
|
||||
@ -1003,19 +1011,19 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/templates/widget/date_time.html:3
|
||||
msgid "Date:"
|
||||
msgstr ""
|
||||
msgstr "Ημ/νία:"
|
||||
|
||||
#: contrib/admin/templates/widget/date_time.html:4
|
||||
msgid "Time:"
|
||||
msgstr ""
|
||||
msgstr " Ώρα:"
|
||||
|
||||
#: contrib/admin/templates/widget/file.html:2
|
||||
msgid "Currently:"
|
||||
msgstr ""
|
||||
msgstr "Τρέχον:"
|
||||
|
||||
#: contrib/admin/templates/widget/file.html:3
|
||||
msgid "Change:"
|
||||
msgstr ""
|
||||
msgstr "Αλλαγή:"
|
||||
|
||||
#: contrib/redirects/models.py:7
|
||||
msgid "redirect from"
|
||||
@ -1271,192 +1279,192 @@ msgstr "P"
|
||||
|
||||
#: utils/dates.py:6
|
||||
msgid "Monday"
|
||||
msgstr ""
|
||||
msgstr "Δευτέρα"
|
||||
|
||||
#: utils/dates.py:6
|
||||
msgid "Tuesday"
|
||||
msgstr ""
|
||||
msgstr "Τρίτη"
|
||||
|
||||
#: utils/dates.py:6
|
||||
msgid "Wednesday"
|
||||
msgstr ""
|
||||
msgstr "Τετάρτη"
|
||||
|
||||
#: utils/dates.py:6
|
||||
msgid "Thursday"
|
||||
msgstr ""
|
||||
msgstr "Πέμπτη"
|
||||
|
||||
#: utils/dates.py:6
|
||||
msgid "Friday"
|
||||
msgstr ""
|
||||
msgstr "Παρασκευή"
|
||||
|
||||
#: utils/dates.py:7
|
||||
msgid "Saturday"
|
||||
msgstr ""
|
||||
msgstr "Σάββατο"
|
||||
|
||||
#: utils/dates.py:7
|
||||
msgid "Sunday"
|
||||
msgstr ""
|
||||
msgstr "Κυριακή"
|
||||
|
||||
#: utils/dates.py:14
|
||||
msgid "January"
|
||||
msgstr ""
|
||||
msgstr "Ιανουάριος"
|
||||
|
||||
#: utils/dates.py:14
|
||||
msgid "February"
|
||||
msgstr ""
|
||||
msgstr "Φεβρουάριος"
|
||||
|
||||
#: utils/dates.py:14 utils/dates.py:27
|
||||
msgid "March"
|
||||
msgstr ""
|
||||
msgstr "Μάρτιος"
|
||||
|
||||
#: utils/dates.py:14 utils/dates.py:27
|
||||
msgid "April"
|
||||
msgstr ""
|
||||
msgstr "Απρίλιος"
|
||||
|
||||
#: utils/dates.py:14 utils/dates.py:27
|
||||
msgid "May"
|
||||
msgstr ""
|
||||
msgstr "Μάιος"
|
||||
|
||||
#: utils/dates.py:14 utils/dates.py:27
|
||||
msgid "June"
|
||||
msgstr ""
|
||||
msgstr "Ιούνιος"
|
||||
|
||||
#: utils/dates.py:15 utils/dates.py:27
|
||||
msgid "July"
|
||||
msgstr ""
|
||||
msgstr "Ιούλιος"
|
||||
|
||||
#: utils/dates.py:15
|
||||
msgid "August"
|
||||
msgstr ""
|
||||
msgstr "Αύγουστος"
|
||||
|
||||
#: utils/dates.py:15
|
||||
msgid "September"
|
||||
msgstr ""
|
||||
msgstr "Σεπτέμβριος"
|
||||
|
||||
#: utils/dates.py:15
|
||||
msgid "October"
|
||||
msgstr ""
|
||||
msgstr "Οκτώβριος"
|
||||
|
||||
#: utils/dates.py:15
|
||||
msgid "November"
|
||||
msgstr ""
|
||||
msgstr "Νοέμβριος"
|
||||
|
||||
#: utils/dates.py:16
|
||||
msgid "December"
|
||||
msgstr ""
|
||||
msgstr "Δεκέμβριος"
|
||||
|
||||
#: utils/dates.py:19
|
||||
#, fuzzy
|
||||
msgid "jan"
|
||||
msgstr "και"
|
||||
msgstr "Ιαν"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "feb"
|
||||
msgstr ""
|
||||
msgstr "Φεβ"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "mar"
|
||||
msgstr ""
|
||||
msgstr "Μάρ"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "apr"
|
||||
msgstr ""
|
||||
msgstr "Απρ"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "may"
|
||||
msgstr ""
|
||||
msgstr "Μάι"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "jun"
|
||||
msgstr ""
|
||||
msgstr "Ιούν"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "jul"
|
||||
msgstr ""
|
||||
msgstr "Ιούλ"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "aug"
|
||||
msgstr ""
|
||||
msgstr "Αύγ"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "sep"
|
||||
msgstr ""
|
||||
msgstr "Σεπ"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "oct"
|
||||
msgstr ""
|
||||
msgstr "Οκτ"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "nov"
|
||||
msgstr ""
|
||||
msgstr "Νοέ"
|
||||
|
||||
#: utils/dates.py:20
|
||||
msgid "dec"
|
||||
msgstr ""
|
||||
msgstr "Δεκ"
|
||||
|
||||
#: utils/dates.py:27
|
||||
msgid "Jan."
|
||||
msgstr ""
|
||||
msgstr "Ιάν."
|
||||
|
||||
#: utils/dates.py:27
|
||||
msgid "Feb."
|
||||
msgstr ""
|
||||
msgstr "Φεβ."
|
||||
|
||||
#: utils/dates.py:28
|
||||
msgid "Aug."
|
||||
msgstr ""
|
||||
msgstr "Αύγ."
|
||||
|
||||
#: utils/dates.py:28
|
||||
msgid "Sept."
|
||||
msgstr ""
|
||||
msgstr "Σεπτ."
|
||||
|
||||
#: utils/dates.py:28
|
||||
msgid "Oct."
|
||||
msgstr ""
|
||||
msgstr "Οκτ."
|
||||
|
||||
#: utils/dates.py:28
|
||||
msgid "Nov."
|
||||
msgstr ""
|
||||
msgstr "Νοέ."
|
||||
|
||||
#: utils/dates.py:28
|
||||
msgid "Dec."
|
||||
msgstr ""
|
||||
msgstr "Δεκ."
|
||||
|
||||
#: utils/timesince.py:12
|
||||
msgid "year"
|
||||
msgid_plural "years"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "χρόνος"
|
||||
msgstr[1] "χρόνια"
|
||||
|
||||
#: utils/timesince.py:13
|
||||
msgid "month"
|
||||
msgid_plural "months"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "μήνας"
|
||||
msgstr[1] "μήνες"
|
||||
|
||||
#: utils/timesince.py:14
|
||||
msgid "week"
|
||||
msgid_plural "weeks"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "εβδομάδα"
|
||||
msgstr[1] "εβδομάδες"
|
||||
|
||||
#: utils/timesince.py:15
|
||||
msgid "day"
|
||||
msgid_plural "days"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "ημέρα"
|
||||
msgstr[1] "ημέρες"
|
||||
|
||||
#: utils/timesince.py:16
|
||||
msgid "hour"
|
||||
msgid_plural "hours"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "ώρα"
|
||||
msgstr[1] "ώρες"
|
||||
|
||||
#: utils/timesince.py:17
|
||||
msgid "minute"
|
||||
msgid_plural "minutes"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "λεπτό"
|
||||
msgstr[1] "λεπτά"
|
||||
|
||||
#: conf/global_settings.py:37
|
||||
msgid "Bengali"
|
||||
@ -1630,7 +1638,7 @@ msgstr ""
|
||||
|
||||
#: core/validators.py:136
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr ""
|
||||
msgstr "Εισάγετε ένα σωστό e-mail."
|
||||
|
||||
#: core/validators.py:148
|
||||
msgid ""
|
||||
@ -1745,12 +1753,12 @@ msgstr[1] ""
|
||||
#: core/validators.py:362
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr "Σιγουρευτείτε ότι το αρχείου που ανεβάζετε είναι %s bytes τουλάχιστον."
|
||||
msgstr "Σιγουρευτείτε ότι το αρχείο που ανεβάζετε είναι %s bytes τουλάχιστον."
|
||||
|
||||
#: core/validators.py:363
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr ""
|
||||
msgstr "Σιγουρευτείτε ότι το αρχείο που ανεβάζετε έχει μέγεθος μέχρι %s bytes."
|
||||
|
||||
#: core/validators.py:376
|
||||
msgid "The format for this field is wrong."
|
||||
@ -1827,7 +1835,7 @@ msgstr ""
|
||||
#: db/models/fields/__init__.py:542 db/models/fields/__init__.py:553
|
||||
#: forms/__init__.py:346
|
||||
msgid "This field is required."
|
||||
msgstr ""
|
||||
msgstr "Αυτό το πεδίο είναι απαραίτητο"
|
||||
|
||||
#: db/models/fields/__init__.py:337
|
||||
msgid "This value must be an integer."
|
||||
@ -1836,12 +1844,12 @@ msgstr ""
|
||||
#: db/models/fields/__init__.py:369
|
||||
#, fuzzy
|
||||
msgid "This value must be either True or False."
|
||||
msgstr "Boolean (Είτε Αλήθεια ή Ψέμα)"
|
||||
msgstr "Boolean (Είτε Αληθές ή Ψευδές)"
|
||||
|
||||
#: db/models/fields/__init__.py:385
|
||||
#, fuzzy
|
||||
msgid "This field cannot be null."
|
||||
msgstr "Αυτό το πεδίο είναι άκυρο"
|
||||
msgstr "Αυτό το πεδίο δεν μπορεί να είναι κενό (null)"
|
||||
|
||||
#: db/models/fields/__init__.py:562
|
||||
msgid "Enter a valid filename."
|
||||
@ -1850,7 +1858,7 @@ msgstr "Εισάγετε ένα έγκυρο όνομα αρχείου"
|
||||
#: db/models/fields/related.py:43
|
||||
#, python-format
|
||||
msgid "Please enter a valid %s."
|
||||
msgstr ""
|
||||
msgstr "Παρακαλώ εισάγετε ένα/μία έγκυρο/η %s"
|
||||
|
||||
#: db/models/fields/related.py:579
|
||||
#, fuzzy
|
||||
|
BIN
django/conf/locale/el/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/el/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
109
django/conf/locale/el/LC_MESSAGES/djangojs.po
Normal file
109
django/conf/locale/el/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,109 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) 2006 and beyond.
|
||||
# This file is distributed under the same license as the Django package.
|
||||
# Orestis Markou <orestis@orestis.gr>, 2006.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Orestis Markou <orestis@orestis.gr>\n"
|
||||
"Language-Team: Greek\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Διαθέσιμο %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Επιλογή Όλων"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "Προσθήκη"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr "Αφαίρεση"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Επιλεχθέντα %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Επιλέξτε και κάντε κλικ."
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr "Καθαρισμός όλων"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:26
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr "Ιανουάριος Φεβρουάριος Μάρτιος Απρίλιος Μάιος Ιούνιος Ιούλιος Αύγουστος Σεπτέμβριος Οκτώβριος Νοέμβριος "
|
||||
"Δεκέμβριος"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Κυριακή Δευτέρα Τρίτη Τετάρτη Πέμπτη Παρασκευή Σάββατο"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "Κ Δ Τ Τ Π Π Σ"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
msgid "Now"
|
||||
msgstr "Τώρα"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
msgid "Clock"
|
||||
msgstr "Ρολόι"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
msgid "Choose a time"
|
||||
msgstr "Διαλέξτε ώρα"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Midnight"
|
||||
msgstr "Μεσάνυχτα"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "6 a.m."
|
||||
msgstr "6 π.μ."
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "Noon"
|
||||
msgstr "Μεσημέρι"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
msgid "Cancel"
|
||||
msgstr "Άκυρο"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
msgid "Today"
|
||||
msgstr "Σήμερα"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
msgid "Calendar"
|
||||
msgstr "Ημερολόγιο"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
msgid "Yesterday"
|
||||
msgstr "Χθες"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "Αύριο"
|
Binary file not shown.
@ -8,8 +8,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-08-18 18:57-0300\n"
|
||||
"PO-Revision-Date: 2006-08-21 18:06-0300\n"
|
||||
"POT-Creation-Date: 2006-11-05 19:57-0300\n"
|
||||
"PO-Revision-Date: 2006-11-05 20:00-0300\n"
|
||||
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -165,10 +165,18 @@ msgstr "Fechas importantes"
|
||||
msgid "Groups"
|
||||
msgstr "Grupos"
|
||||
|
||||
#: contrib/auth/models.py:256
|
||||
#: contrib/auth/models.py:258
|
||||
msgid "message"
|
||||
msgstr "mensaje"
|
||||
|
||||
#: contrib/auth/forms.py:16
|
||||
msgid "The two password fields didn't match."
|
||||
msgstr "Los dos campos de contraseñas no coinciden entre si."
|
||||
|
||||
#: contrib/auth/forms.py:24
|
||||
msgid "A user with that username already exists."
|
||||
msgstr "Ya existe un usuario con ese nombre."
|
||||
|
||||
#: contrib/auth/forms.py:52
|
||||
msgid ""
|
||||
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
|
||||
@ -189,6 +197,24 @@ msgstr ""
|
||||
msgid "This account is inactive."
|
||||
msgstr "Esta cuenta está inactiva"
|
||||
|
||||
#: contrib/auth/forms.py:84
|
||||
msgid ""
|
||||
"That e-mail address doesn't have an associated user account. Are you sure "
|
||||
"you've registered?"
|
||||
msgstr ""
|
||||
"Esa dirección de e-mail no está asociada a ninguna cuenta de usuario. ¿Está "
|
||||
"seguro de que ya se ha registrado?"
|
||||
|
||||
#: contrib/auth/forms.py:116
|
||||
msgid "The two 'new password' fields didn't match."
|
||||
msgstr "Los dos campos 'nueva contraseña' no coinciden entre si."
|
||||
|
||||
#: contrib/auth/forms.py:123
|
||||
msgid "Your old password was entered incorrectly. Please enter it again."
|
||||
msgstr ""
|
||||
"La antigua contraseña ingresada es incorrecta. Por favor ingrésela "
|
||||
"nuevamente."
|
||||
|
||||
#: contrib/redirects/models.py:7
|
||||
msgid "redirect from"
|
||||
msgstr "redirigir desde"
|
||||
@ -754,13 +780,13 @@ msgstr ""
|
||||
msgid "Site administration"
|
||||
msgstr "Sitio administrativo"
|
||||
|
||||
#: contrib/admin/views/main.py:257 contrib/admin/views/auth.py:14
|
||||
#: contrib/admin/views/main.py:257 contrib/admin/views/auth.py:18
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully."
|
||||
msgstr "Se agregó con éxito el %(name)s \"%(obj)s\"."
|
||||
msgstr "Se agregó con éxito %(name)s \"%(obj)s\"."
|
||||
|
||||
#: contrib/admin/views/main.py:261 contrib/admin/views/main.py:347
|
||||
#: contrib/admin/views/auth.py:19
|
||||
#: contrib/admin/views/auth.py:23
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Puede modificarlo nuevamente abajo."
|
||||
|
||||
@ -780,7 +806,7 @@ msgid "Added %s."
|
||||
msgstr "Agregado %s."
|
||||
|
||||
#: contrib/admin/views/main.py:335 contrib/admin/views/main.py:337
|
||||
#: contrib/admin/views/main.py:339
|
||||
#: contrib/admin/views/main.py:339 db/models/manipulators.py:306
|
||||
msgid "and"
|
||||
msgstr "y"
|
||||
|
||||
@ -801,15 +827,14 @@ msgstr "No ha modificado ning
|
||||
#: contrib/admin/views/main.py:345
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was changed successfully."
|
||||
msgstr "Se modificó con éxito el %(name)s \"%(obj)s."
|
||||
msgstr "Se modificó con éxito %(name)s \"%(obj)s."
|
||||
|
||||
#: contrib/admin/views/main.py:353
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr ""
|
||||
"Se agregó con éxito el %(name)s \"%(obj)s. Puede modificarlo nuevamente "
|
||||
"abajo."
|
||||
"Se agregó con éxito %(name)s \"%(obj)s. Puede modificarlo nuevamente abajo."
|
||||
|
||||
#: contrib/admin/views/main.py:391
|
||||
#, python-format
|
||||
@ -829,7 +854,7 @@ msgstr "Uno o m
|
||||
#: contrib/admin/views/main.py:511
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
|
||||
msgstr "Se eliminó con éxito el %(name)s \"%(obj)s\"."
|
||||
msgstr "Se eliminó con éxito %(name)s \"%(obj)s\"."
|
||||
|
||||
#: contrib/admin/views/main.py:514
|
||||
msgid "Are you sure?"
|
||||
@ -850,7 +875,7 @@ msgstr "Seleccione %s"
|
||||
msgid "Select %s to change"
|
||||
msgstr "Seleccione %s a modificar"
|
||||
|
||||
#: contrib/admin/views/main.py:756
|
||||
#: contrib/admin/views/main.py:758
|
||||
msgid "Database error"
|
||||
msgstr "Error de base de datos"
|
||||
|
||||
@ -977,12 +1002,12 @@ msgstr "Estado de los EEUU (dos letras may
|
||||
msgid "XML text"
|
||||
msgstr "Texto XML"
|
||||
|
||||
#: contrib/admin/views/doc.py:339
|
||||
#: contrib/admin/views/doc.py:343
|
||||
#, python-format
|
||||
msgid "%s does not appear to be a urlpattern object"
|
||||
msgstr "%s no parece ser un objeto urlpattern"
|
||||
|
||||
#: contrib/admin/views/auth.py:25
|
||||
#: contrib/admin/views/auth.py:29
|
||||
msgid "Add user"
|
||||
msgstr "Agregar usuario"
|
||||
|
||||
@ -1181,10 +1206,6 @@ msgstr "P
|
||||
msgid "We're sorry, but the requested page could not be found."
|
||||
msgstr "Lo sentimos, pero no se encuentra la página solicitada."
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:22
|
||||
msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
msgstr "¿Ha <a href=\"/password_reset/\">olvidado su contraseña</a>?"
|
||||
|
||||
#: contrib/admin/templates/admin/filters.html:4
|
||||
msgid "Filter"
|
||||
msgstr "Filtrar"
|
||||
@ -1726,123 +1747,134 @@ msgid "Argentinean Spanish"
|
||||
msgstr "Español Argentino"
|
||||
|
||||
#: conf/global_settings.py:49
|
||||
msgid "Finnish"
|
||||
msgstr "Finlandés"
|
||||
|
||||
#: conf/global_settings.py:50
|
||||
msgid "French"
|
||||
msgstr "Francés"
|
||||
|
||||
#: conf/global_settings.py:50
|
||||
#: conf/global_settings.py:51
|
||||
msgid "Galician"
|
||||
msgstr "Gallego"
|
||||
|
||||
#: conf/global_settings.py:51
|
||||
#: conf/global_settings.py:52
|
||||
msgid "Hungarian"
|
||||
msgstr "Húngaro"
|
||||
|
||||
#: conf/global_settings.py:52
|
||||
#: conf/global_settings.py:53
|
||||
msgid "Hebrew"
|
||||
msgstr "Hebreo"
|
||||
|
||||
#: conf/global_settings.py:53
|
||||
#: conf/global_settings.py:54
|
||||
msgid "Icelandic"
|
||||
msgstr "Islandés"
|
||||
|
||||
#: conf/global_settings.py:54
|
||||
#: conf/global_settings.py:55
|
||||
msgid "Italian"
|
||||
msgstr "Italiano"
|
||||
|
||||
#: conf/global_settings.py:55
|
||||
#: conf/global_settings.py:56
|
||||
msgid "Japanese"
|
||||
msgstr "Japonés"
|
||||
|
||||
#: conf/global_settings.py:56
|
||||
#: conf/global_settings.py:57
|
||||
msgid "Dutch"
|
||||
msgstr "Holandés"
|
||||
|
||||
#: conf/global_settings.py:57
|
||||
#: conf/global_settings.py:58
|
||||
msgid "Norwegian"
|
||||
msgstr "Noruego"
|
||||
|
||||
#: conf/global_settings.py:58
|
||||
#: conf/global_settings.py:59
|
||||
msgid "Polish"
|
||||
msgstr "Polaco"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
msgid "Brazilian"
|
||||
msgstr "Brasileño"
|
||||
|
||||
#: conf/global_settings.py:59
|
||||
#: conf/global_settings.py:61
|
||||
msgid "Romanian"
|
||||
msgstr "Rumano"
|
||||
|
||||
#: conf/global_settings.py:60
|
||||
#: conf/global_settings.py:62
|
||||
msgid "Russian"
|
||||
msgstr "Ruso"
|
||||
|
||||
#: conf/global_settings.py:61
|
||||
#: conf/global_settings.py:63
|
||||
msgid "Slovak"
|
||||
msgstr "Eslovaco"
|
||||
|
||||
#: conf/global_settings.py:62
|
||||
#: conf/global_settings.py:64
|
||||
msgid "Slovenian"
|
||||
msgstr "Esloveno"
|
||||
|
||||
#: conf/global_settings.py:63
|
||||
#: conf/global_settings.py:65
|
||||
msgid "Serbian"
|
||||
msgstr "Serbio"
|
||||
|
||||
#: conf/global_settings.py:64
|
||||
#: conf/global_settings.py:66
|
||||
msgid "Swedish"
|
||||
msgstr "Sueco"
|
||||
|
||||
#: conf/global_settings.py:65
|
||||
#: conf/global_settings.py:67
|
||||
msgid "Tamil"
|
||||
msgstr "Tamil"
|
||||
|
||||
#: conf/global_settings.py:66
|
||||
#: conf/global_settings.py:68
|
||||
msgid "Turkish"
|
||||
msgstr "Turco"
|
||||
|
||||
#: conf/global_settings.py:69
|
||||
msgid "Ukrainian"
|
||||
msgstr "Ucraniano"
|
||||
|
||||
#: conf/global_settings.py:67
|
||||
#: conf/global_settings.py:70
|
||||
msgid "Simplified Chinese"
|
||||
msgstr "Chino simplificado"
|
||||
|
||||
#: conf/global_settings.py:68
|
||||
#: conf/global_settings.py:71
|
||||
msgid "Traditional Chinese"
|
||||
msgstr "Chino tradicional"
|
||||
|
||||
#: db/models/manipulators.py:302
|
||||
#: db/models/manipulators.py:305
|
||||
#, python-format
|
||||
msgid "%(object)s with this %(type)s already exists for the given %(field)s."
|
||||
msgstr ""
|
||||
"Ya existen %(object)s con este %(type)s para el %(field)s especificado."
|
||||
msgstr "Ya existe un(a) %(object)s con este/a %(type)s para %(field)s."
|
||||
|
||||
#: db/models/fields/__init__.py:40
|
||||
#: db/models/fields/__init__.py:41
|
||||
#, python-format
|
||||
msgid "%(optname)s with this %(fieldname)s already exists."
|
||||
msgstr "Ya existe %(optname)s con este %(fieldname)s."
|
||||
|
||||
#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265
|
||||
#: db/models/fields/__init__.py:551 db/models/fields/__init__.py:562
|
||||
#: forms/__init__.py:346
|
||||
#: db/models/fields/__init__.py:115 db/models/fields/__init__.py:266
|
||||
#: db/models/fields/__init__.py:569 db/models/fields/__init__.py:580
|
||||
#: forms/__init__.py:347
|
||||
msgid "This field is required."
|
||||
msgstr "Este campo es obligatorio."
|
||||
|
||||
#: db/models/fields/__init__.py:340
|
||||
#: db/models/fields/__init__.py:349
|
||||
msgid "This value must be an integer."
|
||||
msgstr "Este valor debe ser un número entero."
|
||||
|
||||
#: db/models/fields/__init__.py:372
|
||||
#: db/models/fields/__init__.py:381
|
||||
msgid "This value must be either True or False."
|
||||
msgstr "Este valor debe ser True o False."
|
||||
|
||||
#: db/models/fields/__init__.py:388
|
||||
#: db/models/fields/__init__.py:397
|
||||
msgid "This field cannot be null."
|
||||
msgstr "Este campo no puede ser nulo."
|
||||
|
||||
#: db/models/fields/__init__.py:415 core/validators.py:127
|
||||
#: db/models/fields/__init__.py:424 core/validators.py:146
|
||||
msgid "Enter a valid date in YYYY-MM-DD format."
|
||||
msgstr "Introduzca una fecha válida en formato AAAA-MM-DD."
|
||||
|
||||
#: db/models/fields/__init__.py:477 core/validators.py:135
|
||||
#: db/models/fields/__init__.py:488 core/validators.py:155
|
||||
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
|
||||
msgstr "Introduzca una fecha/hora válida en formato YYYY-MM-DD HH:MM."
|
||||
|
||||
#: db/models/fields/__init__.py:571
|
||||
#: db/models/fields/__init__.py:589
|
||||
msgid "Enter a valid filename."
|
||||
msgstr "Introduzca un nombre de achivo válido"
|
||||
|
||||
@ -1859,7 +1891,8 @@ msgstr " Separe m
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
"Pulse \"Control\", o \"Command\" en un Mac, para seleccionar más de uno."
|
||||
"Mantenga presionada \"Control\" (\"Command\" en un Mac) para seleccionar más "
|
||||
"de uno."
|
||||
|
||||
#: db/models/fields/related.py:664
|
||||
#, python-format
|
||||
@ -1873,42 +1906,42 @@ msgstr[1] ""
|
||||
"Por favor, introduzca IDs de %(self)s válidos. Los valores %(value)r no son "
|
||||
"válidos."
|
||||
|
||||
#: forms/__init__.py:381
|
||||
#: forms/__init__.py:382
|
||||
#, python-format
|
||||
msgid "Ensure your text is less than %s character."
|
||||
msgid_plural "Ensure your text is less than %s characters."
|
||||
msgstr[0] "Asegúrese de que su texto tiene menos de %s carácter."
|
||||
msgstr[1] "Asegúrese de que su texto tiene menos de %s caracteres."
|
||||
|
||||
#: forms/__init__.py:386
|
||||
#: forms/__init__.py:387
|
||||
msgid "Line breaks are not allowed here."
|
||||
msgstr "No se permiten saltos de línea."
|
||||
|
||||
#: forms/__init__.py:487 forms/__init__.py:560 forms/__init__.py:599
|
||||
#: forms/__init__.py:488 forms/__init__.py:561 forms/__init__.py:600
|
||||
#, python-format
|
||||
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
|
||||
msgstr "Seleccione una opción válida; '%(data)s' no está en %(choices)s."
|
||||
|
||||
#: forms/__init__.py:661 core/validators.py:151 core/validators.py:379
|
||||
#: forms/__init__.py:662 core/validators.py:172 core/validators.py:401
|
||||
msgid "No file was submitted. Check the encoding type on the form."
|
||||
msgstr ""
|
||||
"No se envió un archivo. Verifique el tipo de codificación en el formulario."
|
||||
|
||||
#: forms/__init__.py:663
|
||||
#: forms/__init__.py:664
|
||||
msgid "The submitted file is empty."
|
||||
msgstr "El archivo enviado está vacío."
|
||||
|
||||
#: forms/__init__.py:719
|
||||
#: forms/__init__.py:720
|
||||
msgid "Enter a whole number between -32,768 and 32,767."
|
||||
msgstr "Introduzca un número entero entre -32,768 y 32,767."
|
||||
msgstr "Introduzca un número entero entre -32.768 y 32.767."
|
||||
|
||||
#: forms/__init__.py:729
|
||||
#: forms/__init__.py:730
|
||||
msgid "Enter a positive number."
|
||||
msgstr "Introduzca un número positivo."
|
||||
|
||||
#: forms/__init__.py:739
|
||||
#: forms/__init__.py:740
|
||||
msgid "Enter a whole number between 0 and 32,767."
|
||||
msgstr "Introduzca un número entero entre 0 y 32,767."
|
||||
msgstr "Introduzca un número entero entre 0 y 32.767."
|
||||
|
||||
#: core/validators.py:63
|
||||
msgid "This value must contain only letters, numbers and underscores."
|
||||
@ -1919,8 +1952,13 @@ msgid ""
|
||||
"This value must contain only letters, numbers, underscores, dashes or "
|
||||
"slashes."
|
||||
msgstr ""
|
||||
"Este valor debe contener sólo letras, números, guiones bajos, barras (/) o "
|
||||
"slashes."
|
||||
"Este valor debe contener sólo letras, números, guiones bajos, guiones o "
|
||||
"barras (/)"
|
||||
|
||||
#: core/validators.py:71
|
||||
msgid "This value must contain only letters, numbers, underscores or hyphens."
|
||||
msgstr ""
|
||||
"Este valor debe contener sólo letras, números, guiones bajos o guiones."
|
||||
|
||||
#: core/validators.py:75
|
||||
msgid "Uppercase letters are not allowed here."
|
||||
@ -1962,15 +2000,24 @@ msgstr "Introduzca un n
|
||||
msgid "Only alphabetical characters are allowed here."
|
||||
msgstr "Sólo se admiten caracteres alfabéticos."
|
||||
|
||||
#: core/validators.py:131
|
||||
#: core/validators.py:138
|
||||
msgid "Year must be 1900 or later."
|
||||
msgstr "El año debe ser 1900 o posterior."
|
||||
|
||||
#: core/validators.py:142
|
||||
#, python-format
|
||||
msgid "Invalid date: %s."
|
||||
msgstr "Fecha no válida: %s."
|
||||
|
||||
#: core/validators.py:151
|
||||
msgid "Enter a valid time in HH:MM format."
|
||||
msgstr "Introduzca una hora válida en formato HH:MM."
|
||||
|
||||
#: core/validators.py:139
|
||||
#: core/validators.py:160
|
||||
msgid "Enter a valid e-mail address."
|
||||
msgstr "Introduzca una dirección de correo electrónico válida"
|
||||
|
||||
#: core/validators.py:155
|
||||
#: core/validators.py:176
|
||||
msgid ""
|
||||
"Upload a valid image. The file you uploaded was either not an image or a "
|
||||
"corrupted image."
|
||||
@ -1978,28 +2025,28 @@ msgstr ""
|
||||
"Envíe una imagen válida. El archivo que ha enviado no era una imagen o se "
|
||||
"trataba de una imagen corrupta."
|
||||
|
||||
#: core/validators.py:162
|
||||
#: core/validators.py:183
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid image."
|
||||
msgstr "La URL %s no apunta a una imagen válida."
|
||||
|
||||
#: core/validators.py:166
|
||||
#: core/validators.py:187
|
||||
#, python-format
|
||||
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
|
||||
msgstr ""
|
||||
"Los números de teléfono deben guardar el formato XXX-XXX-XXXX format. \"%s\" "
|
||||
"no es válido."
|
||||
"Los números telefónicos deben respetar el formato XXX-XXX-XXXX. \"%s\" no es "
|
||||
"válido."
|
||||
|
||||
#: core/validators.py:174
|
||||
#: core/validators.py:195
|
||||
#, python-format
|
||||
msgid "The URL %s does not point to a valid QuickTime video."
|
||||
msgstr "La URL %s no apunta a un vídeo QuickTime válido."
|
||||
|
||||
#: core/validators.py:178
|
||||
#: core/validators.py:199
|
||||
msgid "A valid URL is required."
|
||||
msgstr "Se precisa una URL válida."
|
||||
|
||||
#: core/validators.py:192
|
||||
#: core/validators.py:213
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Valid HTML is required. Specific errors are:\n"
|
||||
@ -2008,69 +2055,69 @@ msgstr ""
|
||||
"Se precisa HTML válido. Los errores específicos son:\n"
|
||||
"%s"
|
||||
|
||||
#: core/validators.py:199
|
||||
#: core/validators.py:220
|
||||
#, python-format
|
||||
msgid "Badly formed XML: %s"
|
||||
msgstr "XML mal formado: %s"
|
||||
|
||||
#: core/validators.py:209
|
||||
#: core/validators.py:230
|
||||
#, python-format
|
||||
msgid "Invalid URL: %s"
|
||||
msgstr "URL no válida: %s"
|
||||
|
||||
#: core/validators.py:213 core/validators.py:215
|
||||
#: core/validators.py:234 core/validators.py:236
|
||||
#, python-format
|
||||
msgid "The URL %s is a broken link."
|
||||
msgstr "La URL %s es un enlace roto."
|
||||
|
||||
#: core/validators.py:221
|
||||
#: core/validators.py:242
|
||||
msgid "Enter a valid U.S. state abbreviation."
|
||||
msgstr "Introduzca una abreviatura válida de estado de los EEUU."
|
||||
|
||||
#: core/validators.py:236
|
||||
#: core/validators.py:256
|
||||
#, python-format
|
||||
msgid "Watch your mouth! The word %s is not allowed here."
|
||||
msgid_plural "Watch your mouth! The words %s are not allowed here."
|
||||
msgstr[0] "¡Vigila tu boca! Aquí no admitimos la palabra %s."
|
||||
msgstr[1] "¡Vigila tu boca! Aquí no admitimos las palabras %s."
|
||||
|
||||
#: core/validators.py:243
|
||||
#: core/validators.py:263
|
||||
#, python-format
|
||||
msgid "This field must match the '%s' field."
|
||||
msgstr "Este campo debe concordar con el campo '%s'."
|
||||
|
||||
#: core/validators.py:262
|
||||
#: core/validators.py:282
|
||||
msgid "Please enter something for at least one field."
|
||||
msgstr "Por favor, introduzca algo en al menos un campo."
|
||||
|
||||
#: core/validators.py:271 core/validators.py:282
|
||||
#: core/validators.py:291 core/validators.py:302
|
||||
msgid "Please enter both fields or leave them both empty."
|
||||
msgstr "Por favor, rellene ambos campos o deje ambos vacíos."
|
||||
|
||||
#: core/validators.py:289
|
||||
#: core/validators.py:309
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is %(value)s"
|
||||
msgstr "Se debe proporcionar este campo si %(field)s es %(value)s"
|
||||
|
||||
#: core/validators.py:301
|
||||
#: core/validators.py:321
|
||||
#, python-format
|
||||
msgid "This field must be given if %(field)s is not %(value)s"
|
||||
msgstr "Se debe proporcionar este campo si %(field)s no es %(value)s"
|
||||
|
||||
#: core/validators.py:320
|
||||
#: core/validators.py:340
|
||||
msgid "Duplicate values are not allowed."
|
||||
msgstr "No se admiten valores duplicados."
|
||||
|
||||
#: core/validators.py:343
|
||||
#: core/validators.py:363
|
||||
#, python-format
|
||||
msgid "This value must be a power of %s."
|
||||
msgstr "Este valor debe ser una potencia de %s."
|
||||
|
||||
#: core/validators.py:354
|
||||
#: core/validators.py:374
|
||||
msgid "Please enter a valid decimal number."
|
||||
msgstr "Por favor, introduzca un número decimal válido."
|
||||
|
||||
#: core/validators.py:356
|
||||
#: core/validators.py:378
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s total digit."
|
||||
msgid_plural ""
|
||||
@ -2082,7 +2129,7 @@ msgstr[1] ""
|
||||
"Por favor, introduzca un número decimal válido con un maximo de %s dígitos "
|
||||
"en total."
|
||||
|
||||
#: core/validators.py:359
|
||||
#: core/validators.py:381
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please enter a valid decimal number with a whole part of at most %s digit."
|
||||
@ -2095,7 +2142,7 @@ msgstr[1] ""
|
||||
"Por favor, introduzca un número decimal válido con un máximo de %s dígitos "
|
||||
"enteros."
|
||||
|
||||
#: core/validators.py:362
|
||||
#: core/validators.py:384
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural ""
|
||||
@ -2107,30 +2154,30 @@ msgstr[1] ""
|
||||
"Por favor, introduzca un número decimal válido con un máximo de %s "
|
||||
"posiciones decimales."
|
||||
|
||||
#: core/validators.py:372
|
||||
#: core/validators.py:394
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr "Asegúrese de que el archivo que envía tiene al menos %s bytes."
|
||||
|
||||
#: core/validators.py:373
|
||||
#: core/validators.py:395
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr "Asegúrese de que el archivo que envía tiene como máximo %s bytes."
|
||||
|
||||
#: core/validators.py:390
|
||||
#: core/validators.py:412
|
||||
msgid "The format for this field is wrong."
|
||||
msgstr "El formato de este campo es incorrecto."
|
||||
|
||||
#: core/validators.py:405
|
||||
#: core/validators.py:427
|
||||
msgid "This field is invalid."
|
||||
msgstr "Este campo no es válido."
|
||||
|
||||
#: core/validators.py:441
|
||||
#: core/validators.py:463
|
||||
#, python-format
|
||||
msgid "Could not retrieve anything from %s."
|
||||
msgstr "No pude obtener nada de %s."
|
||||
|
||||
#: core/validators.py:444
|
||||
#: core/validators.py:466
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
@ -2138,7 +2185,7 @@ msgstr ""
|
||||
"La URL %(url)s devolvió la cabecera Content-Type '%(contenttype)s', que no "
|
||||
"es válida."
|
||||
|
||||
#: core/validators.py:477
|
||||
#: core/validators.py:499
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
|
||||
@ -2147,7 +2194,7 @@ msgstr ""
|
||||
"Por favor, cierre la etiqueta %(tag)s de la línea %(line)s. (La línea "
|
||||
"empieza por \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:481
|
||||
#: core/validators.py:503
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Some text starting on line %(line)s is not allowed in that context. (Line "
|
||||
@ -2156,7 +2203,7 @@ msgstr ""
|
||||
"Parte del texto que comienza en la línea %(line)s no está permitido en ese "
|
||||
"contexto. (La línea empieza por \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:486
|
||||
#: core/validators.py:508
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
|
||||
@ -2165,7 +2212,7 @@ msgstr ""
|
||||
"El \"%(attr)s\" de la línea %(line)s no es un atributo válido. (La línea "
|
||||
"empieza por \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:491
|
||||
#: core/validators.py:513
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
|
||||
@ -2174,7 +2221,7 @@ msgstr ""
|
||||
"La \"<%(tag)s>\" de la línea %(line)s no es una etiqueta válida. (La línea "
|
||||
"empieza por \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:495
|
||||
#: core/validators.py:517
|
||||
#, python-format
|
||||
msgid ""
|
||||
"A tag on line %(line)s is missing one or more required attributes. (Line "
|
||||
@ -2183,7 +2230,7 @@ msgstr ""
|
||||
"A una etiqueta de la línea %(line)s le faltan uno o más atributos "
|
||||
"requeridos. (La línea empieza por \"%(start)s\".)"
|
||||
|
||||
#: core/validators.py:500
|
||||
#: core/validators.py:522
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
|
||||
@ -2199,17 +2246,20 @@ msgstr "si,no,tal vez"
|
||||
#: views/generic/create_update.py:43
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was created successfully."
|
||||
msgstr "Se creó con éxito el %(verbose_name)."
|
||||
msgstr "Se creó con éxito %(verbose_name)."
|
||||
|
||||
#: views/generic/create_update.py:117
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was updated successfully."
|
||||
msgstr "Se actualizó con éxito el %(verbose_name)s."
|
||||
msgstr "Se actualizó con éxito %(verbose_name)s."
|
||||
|
||||
#: views/generic/create_update.py:184
|
||||
#, python-format
|
||||
msgid "The %(verbose_name)s was deleted."
|
||||
msgstr "Se eliminó el %(verbose_name)s."
|
||||
msgstr "Se eliminó %(verbose_name)s."
|
||||
|
||||
#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
|
||||
#~ msgstr "¿Ha <a href=\"/password_reset/\">olvidado su contraseña</a>?"
|
||||
|
||||
#~ msgid "%(content_type_name)s"
|
||||
#~ msgstr "tipos de contenido"
|
||||
|
Binary file not shown.
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Django JavaScript 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-19 12:15-0300\n"
|
||||
"POT-Creation-Date: 2006-09-25 15:09-0300\n"
|
||||
"PO-Revision-Date: 2006-05-16 10:20-0300\n"
|
||||
"Last-Translator: Ramiro Morales <rm0@gmx.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -39,7 +39,7 @@ msgstr "%s elegidos"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Haga sus elecciones y haga click en "
|
||||
msgstr "Seleccione los items a agregar y haga click en "
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
@ -51,7 +51,7 @@ msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
"Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre "
|
||||
"Enero Febrero Marzo Abril Mayo Junio Julio Agosto Setiembre Octubre "
|
||||
"Noviembre Diciembre"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
@ -71,49 +71,49 @@ msgstr "Mostrar"
|
||||
msgid "Hide"
|
||||
msgstr "Ocultar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:89
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr "Ahora"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "Reloj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:86
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Elija una hora"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:90
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Medianoche"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:91
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "6 a.m."
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:92
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Mediodía"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:96
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:187
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:120
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:181
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr "Hoy"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:123
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "Calendario"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "Ayer"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Mañana"
|
||||
|
@ -2,7 +2,7 @@ from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Example:
|
||||
# (r'^{{ project_name }}/', include('{{ project_name }}.apps.foo.urls.foo')),
|
||||
# (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
|
||||
|
||||
# Uncomment this for admin:
|
||||
# (r'^admin/', include('django.contrib.admin.urls')),
|
||||
|
@ -44,7 +44,7 @@ var DateTimeShortcuts = {
|
||||
var shortcuts_span = document.createElement('span');
|
||||
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
||||
var now_link = document.createElement('a');
|
||||
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinute());");
|
||||
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());");
|
||||
now_link.appendChild(document.createTextNode(gettext('Now')));
|
||||
var clock_link = document.createElement('a');
|
||||
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');');
|
||||
@ -80,10 +80,10 @@ var DateTimeShortcuts = {
|
||||
quickElement('h2', clock_box, gettext('Choose a time'));
|
||||
time_list = quickElement('ul', clock_box, '');
|
||||
time_list.className = 'timelist';
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinute());")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().getHourMinuteSecond());")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '00:00:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '06:00:00');")
|
||||
quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", '12:00:00');")
|
||||
|
||||
cancel_p = quickElement('p', clock_box, '');
|
||||
cancel_p.className = 'calendar-cancel';
|
||||
|
@ -119,6 +119,10 @@ Date.prototype.getTwoDigitMinute = function() {
|
||||
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
|
||||
}
|
||||
|
||||
Date.prototype.getTwoDigitSecond = function() {
|
||||
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
|
||||
}
|
||||
|
||||
Date.prototype.getISODate = function() {
|
||||
return this.getCorrectYear() + '-' + this.getTwoDigitMonth() + '-' + this.getTwoDigitDate();
|
||||
}
|
||||
@ -127,6 +131,10 @@ Date.prototype.getHourMinute = function() {
|
||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();
|
||||
}
|
||||
|
||||
Date.prototype.getHourMinuteSecond = function() {
|
||||
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// String object extensions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -7,7 +7,7 @@
|
||||
<input type="text" size="40" name="{{ search_var }}" value="{{ cl.query|escape }}" id="searchbar" />
|
||||
<input type="submit" value="{% trans 'Go' %}" />
|
||||
{% if show_result_count %}
|
||||
<span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
|
||||
<span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}pop=1{% endif %}">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
|
||||
{% endif %}
|
||||
{% for pair in cl.params.items %}
|
||||
{% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0|escape }}" value="{{ pair.1|escape }}"/>{% endifnotequal %}
|
||||
|
@ -226,7 +226,7 @@ index = staff_member_required(never_cache(index))
|
||||
def add_stage(request, app_label, model_name, show_delete=False, form_url='', post_url=None, post_url_continue='../%s/', object_id_override=None):
|
||||
model = models.get_model(app_label, model_name)
|
||||
if model is None:
|
||||
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
|
||||
raise Http404("App %r, model %r, not found" % (app_label, model_name))
|
||||
opts = model._meta
|
||||
|
||||
if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
|
||||
@ -302,7 +302,7 @@ def change_stage(request, app_label, model_name, object_id):
|
||||
model = models.get_model(app_label, model_name)
|
||||
object_id = unquote(object_id)
|
||||
if model is None:
|
||||
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
|
||||
raise Http404("App %r, model %r, not found" % (app_label, model_name))
|
||||
opts = model._meta
|
||||
|
||||
if not request.user.has_perm(app_label + '.' + opts.get_change_permission()):
|
||||
@ -313,8 +313,8 @@ def change_stage(request, app_label, model_name, object_id):
|
||||
|
||||
try:
|
||||
manipulator = model.ChangeManipulator(object_id)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404
|
||||
except model.DoesNotExist:
|
||||
raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id)))
|
||||
|
||||
if request.POST:
|
||||
new_data = request.POST.copy()
|
||||
@ -490,7 +490,7 @@ def delete_stage(request, app_label, model_name, object_id):
|
||||
model = models.get_model(app_label, model_name)
|
||||
object_id = unquote(object_id)
|
||||
if model is None:
|
||||
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
|
||||
raise Http404("App %r, model %r, not found" % (app_label, model_name))
|
||||
opts = model._meta
|
||||
if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()):
|
||||
raise PermissionDenied
|
||||
@ -527,7 +527,7 @@ def history(request, app_label, model_name, object_id):
|
||||
model = models.get_model(app_label, model_name)
|
||||
object_id = unquote(object_id)
|
||||
if model is None:
|
||||
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
|
||||
raise Http404("App %r, model %r, not found" % (app_label, model_name))
|
||||
action_list = LogEntry.objects.filter(object_id=object_id,
|
||||
content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time')
|
||||
# If no history was found, see whether this object even exists.
|
||||
@ -743,7 +743,7 @@ class ChangeList(object):
|
||||
def change_list(request, app_label, model_name):
|
||||
model = models.get_model(app_label, model_name)
|
||||
if model is None:
|
||||
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
|
||||
raise Http404("App %r, model %r, not found" % (app_label, model_name))
|
||||
if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()):
|
||||
raise PermissionDenied
|
||||
try:
|
||||
|
@ -3,9 +3,9 @@ Creates content types for all installed models.
|
||||
"""
|
||||
|
||||
from django.dispatch import dispatcher
|
||||
from django.db.models import get_models, signals
|
||||
from django.db.models import get_apps, get_models, signals
|
||||
|
||||
def create_contenttypes(app, created_models, verbosity):
|
||||
def create_contenttypes(app, created_models, verbosity=2):
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
app_models = get_models(app)
|
||||
if not app_models:
|
||||
@ -22,4 +22,11 @@ def create_contenttypes(app, created_models, verbosity):
|
||||
if verbosity >= 2:
|
||||
print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
|
||||
|
||||
def create_all_contenttypes(verbosity=2):
|
||||
for app in get_apps():
|
||||
create_contenttypes(app, None, verbosity)
|
||||
|
||||
dispatcher.connect(create_contenttypes, signal=signals.post_syncdb)
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_all_contenttypes()
|
||||
|
0
django/contrib/formtools/__init__.py
Normal file
0
django/contrib/formtools/__init__.py
Normal file
160
django/contrib/formtools/preview.py
Normal file
160
django/contrib/formtools/preview.py
Normal file
@ -0,0 +1,160 @@
|
||||
"""
|
||||
Formtools Preview application.
|
||||
|
||||
This is an abstraction of the following workflow:
|
||||
|
||||
"Display an HTML form, force a preview, then do something with the submission."
|
||||
|
||||
Given a django.newforms.Form object that you define, this takes care of the
|
||||
following:
|
||||
|
||||
* Displays the form as HTML on a Web page.
|
||||
* Validates the form data once it's submitted via POST.
|
||||
* If it's valid, displays a preview page.
|
||||
* If it's not valid, redisplays the form with error messages.
|
||||
* At the preview page, if the preview confirmation button is pressed, calls
|
||||
a hook that you define -- a done() method.
|
||||
|
||||
The framework enforces the required preview by passing a shared-secret hash to
|
||||
the preview page. If somebody tweaks the form parameters on the preview page,
|
||||
the form submission will fail the hash comparison test.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Subclass FormPreview and define a done() method:
|
||||
|
||||
def done(self, request, clean_data):
|
||||
# ...
|
||||
|
||||
This method takes an HttpRequest object and a dictionary of the form data after
|
||||
it has been validated and cleaned. It should return an HttpResponseRedirect.
|
||||
|
||||
Then, just instantiate your FormPreview subclass by passing it a Form class,
|
||||
and pass that to your URLconf, like so:
|
||||
|
||||
(r'^post/$', MyFormPreview(MyForm)),
|
||||
|
||||
The FormPreview class has a few other hooks. See the docstrings in the source
|
||||
code below.
|
||||
|
||||
The framework also uses two templates: 'formtools/preview.html' and
|
||||
'formtools/form.html'. You can override these by setting 'preview_template' and
|
||||
'form_template' attributes on your FormPreview subclass. See
|
||||
django/contrib/formtools/templates for the default templates.
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.http import Http404
|
||||
from django.shortcuts import render_to_response
|
||||
import cPickle as pickle
|
||||
import md5
|
||||
|
||||
AUTO_ID = 'formtools_%s' # Each form here uses this as its auto_id parameter.
|
||||
|
||||
class FormPreview(object):
|
||||
preview_template = 'formtools/preview.html'
|
||||
form_template = 'formtools/form.html'
|
||||
|
||||
# METHODS SUBCLASSES SHOULDN'T OVERRIDE ###################################
|
||||
|
||||
def __init__(self, form):
|
||||
# form should be a Form class, not an instance.
|
||||
self.form, self.state = form, {}
|
||||
|
||||
def __call__(self, request, *args, **kwargs):
|
||||
stage = {'1': 'preview', '2': 'post'}.get(request.POST.get(self.unused_name('stage')), 'preview')
|
||||
self.parse_params(*args, **kwargs)
|
||||
try:
|
||||
method = getattr(self, stage + '_' + request.method.lower())
|
||||
except AttributeError:
|
||||
raise Http404
|
||||
return method(request)
|
||||
|
||||
def unused_name(self, name):
|
||||
"""
|
||||
Given a first-choice name, adds an underscore to the name until it
|
||||
reaches a name that isn't claimed by any field in the form.
|
||||
|
||||
This is calculated rather than being hard-coded so that no field names
|
||||
are off-limits for use in the form.
|
||||
"""
|
||||
while 1:
|
||||
try:
|
||||
f = self.form.fields[name]
|
||||
except KeyError:
|
||||
break # This field name isn't being used by the form.
|
||||
name += '_'
|
||||
return name
|
||||
|
||||
def preview_get(self, request):
|
||||
"Displays the form"
|
||||
f = self.form(auto_id=AUTO_ID)
|
||||
return render_to_response(self.form_template, {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state})
|
||||
|
||||
def preview_post(self, request):
|
||||
"Validates the POST data. If valid, displays the preview page. Else, redisplays form."
|
||||
f = self.form(request.POST, auto_id=AUTO_ID)
|
||||
context = {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state}
|
||||
if f.is_valid():
|
||||
context['hash_field'] = self.unused_name('hash')
|
||||
context['hash_value'] = self.security_hash(request, f)
|
||||
return render_to_response(self.preview_template, context)
|
||||
else:
|
||||
return render_to_response(self.form_template, context)
|
||||
|
||||
def post_post(self, request):
|
||||
"Validates the POST data. If valid, calls done(). Else, redisplays form."
|
||||
f = self.form(request.POST, auto_id=AUTO_ID)
|
||||
if f.is_valid():
|
||||
if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')):
|
||||
return self.failed_hash(request) # Security hash failed.
|
||||
return self.done(request, f.clean_data)
|
||||
else:
|
||||
return render_to_response(self.form_template, {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state})
|
||||
|
||||
# METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
|
||||
|
||||
def parse_params(self, *args, **kwargs):
|
||||
"""
|
||||
Given captured args and kwargs from the URLconf, saves something in
|
||||
self.state and/or raises Http404 if necessary.
|
||||
|
||||
For example, this URLconf captures a user_id variable:
|
||||
|
||||
(r'^contact/(?P<user_id>\d{1,6})/$', MyFormPreview(MyForm)),
|
||||
|
||||
In this case, the kwargs variable in parse_params would be
|
||||
{'user_id': 32} for a request to '/contact/32/'. You can use that
|
||||
user_id to make sure it's a valid user and/or save it for later, for
|
||||
use in done().
|
||||
"""
|
||||
pass
|
||||
|
||||
def security_hash(self, request, form):
|
||||
"""
|
||||
Calculates the security hash for the given Form instance.
|
||||
|
||||
This creates a list of the form field names/values in a deterministic
|
||||
order, pickles the result with the SECRET_KEY setting and takes an md5
|
||||
hash of that.
|
||||
|
||||
Subclasses may want to take into account request-specific information
|
||||
such as the IP address.
|
||||
"""
|
||||
data = [(bf.name, bf.data) for bf in form] + [settings.SECRET_KEY]
|
||||
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
|
||||
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
|
||||
pickled = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
|
||||
return md5.new(pickled).hexdigest()
|
||||
|
||||
def failed_hash(self, request):
|
||||
"Returns an HttpResponse in the case of an invalid security hash."
|
||||
return self.preview_post(request)
|
||||
|
||||
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
||||
|
||||
def done(self, request, clean_data):
|
||||
"Does something with the clean_data and returns an HttpResponseRedirect."
|
||||
raise NotImplementedError('You must define a done() method on your %s subclass.' % self.__class__.__name__)
|
15
django/contrib/formtools/templates/formtools/form.html
Normal file
15
django/contrib/formtools/templates/formtools/form.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if form.errors %}<h1>Please correct the following errors</h1>{% else %}<h1>Submit</h1>{% endif %}
|
||||
|
||||
<form action="" method="post">
|
||||
<table>
|
||||
{{ form }}
|
||||
</table>
|
||||
<input type="hidden" name="{{ stage_field }}" value="1" />
|
||||
<p><input type="submit" value="Submit" /></p>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
36
django/contrib/formtools/templates/formtools/preview.html
Normal file
36
django/contrib/formtools/templates/formtools/preview.html
Normal file
@ -0,0 +1,36 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Preview your submission</h1>
|
||||
|
||||
<table>
|
||||
{% for field in form %}
|
||||
<tr>
|
||||
<th>{{ field.verbose_name }}:</th>
|
||||
<td>{{ field.data|escape }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<p>Security hash: {{ hash_value }}</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% for field in form %}{{ field.as_hidden }}
|
||||
{% endfor %}
|
||||
<input type="hidden" name="{{ stage_field }}" value="2" />
|
||||
<input type="hidden" name="{{ hash_field }}" value="{{ hash_value }}" />
|
||||
<p><input type="submit" value="Submit" /></p>
|
||||
</form>
|
||||
|
||||
<h1>Or edit it again</h1>
|
||||
|
||||
<form action="" method="post">
|
||||
<table>
|
||||
{{ form }}
|
||||
</table>
|
||||
<input type="hidden" name="{{ stage_field }}" value="1" />
|
||||
<p><input type="submit" value="Submit changes" /></p>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
@ -29,7 +29,7 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
url = "%s%s" % (current_site.domain, sitemap)
|
||||
url = "%s%s" % (current_site.domain, sitemap_url)
|
||||
params = urllib.urlencode({'sitemap':url})
|
||||
urllib.urlopen("%s?%s" % (ping_url, params))
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{% spaceless %}
|
||||
{% for url in urlset %}
|
||||
<url>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84">
|
||||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{% for location in sitemaps %}<sitemap><loc>{{ location|escape }}</loc></sitemap>{% endfor %}
|
||||
</sitemapindex>
|
||||
|
@ -84,7 +84,11 @@ class BaseHandler(object):
|
||||
|
||||
# Complain if the view returned None (a common error).
|
||||
if response is None:
|
||||
raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, callback.func_name)
|
||||
try:
|
||||
view_name = callback.func_name # If it's a function
|
||||
except AttributeError:
|
||||
view_name = callback.__class__.__name__ + '.__call__' # If it's a class
|
||||
raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)
|
||||
|
||||
return response
|
||||
except http.Http404, e:
|
||||
|
@ -62,7 +62,7 @@ def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
|
||||
data in the body.
|
||||
"""
|
||||
if not size:
|
||||
return copyfileobj(fsrc, fdst, length)
|
||||
return
|
||||
while size > 0:
|
||||
buf = fsrc.read(min(length, size))
|
||||
if not buf:
|
||||
@ -157,7 +157,11 @@ class WSGIRequest(http.HttpRequest):
|
||||
return self._raw_post_data
|
||||
except AttributeError:
|
||||
buf = StringIO()
|
||||
content_length = int(self.environ['CONTENT_LENGTH'])
|
||||
try:
|
||||
# CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd)
|
||||
content_length = int(self.environ.get('CONTENT_LENGTH', 0))
|
||||
except ValueError: # if CONTENT_LENGTH was empty string or not an integer
|
||||
content_length = 0
|
||||
safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
|
||||
self._raw_post_data = buf.getvalue()
|
||||
buf.close()
|
||||
|
@ -8,6 +8,8 @@ import socket
|
||||
import time
|
||||
import random
|
||||
|
||||
DNS_NAME = socket.getfqdn() # Cache the hostname
|
||||
|
||||
class BadHeaderError(ValueError):
|
||||
pass
|
||||
|
||||
@ -53,7 +55,11 @@ def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST
|
||||
msg['From'] = from_email
|
||||
msg['To'] = ', '.join(recipient_list)
|
||||
msg['Date'] = rfc822.formatdate()
|
||||
msg['Message-ID'] = "<%d.%d@%s>" % (time.time(), random.getrandbits(64), socket.getfqdn())
|
||||
try:
|
||||
random_bits = str(random.getrandbits(64))
|
||||
except AttributeError: # Python 2.3 doesn't have random.getrandbits().
|
||||
random_bits = ''.join([random.choice('1234567890') for i in range(19)])
|
||||
msg['Message-ID'] = "<%d.%s@%s>" % (time.time(), random_bits, DNS_NAME)
|
||||
try:
|
||||
server.sendmail(from_email, recipient_list, msg.as_string())
|
||||
num_sent += 1
|
||||
|
@ -118,6 +118,8 @@ def runfastcgi(argset=[], **kwargs):
|
||||
else:
|
||||
return fastcgi_help("ERROR: Implementation must be one of prefork or thread.")
|
||||
|
||||
wsgi_opts['debug'] = False # Turn off flup tracebacks
|
||||
|
||||
# Prep up and go
|
||||
from django.core.handlers.wsgi import WSGIHandler
|
||||
|
||||
|
@ -17,6 +17,6 @@ def populate_xheaders(request, response, model, object_id):
|
||||
or if the request is from a logged in staff member.
|
||||
"""
|
||||
from django.conf import settings
|
||||
if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or (request.user.is_authenticated() and request.user.is_staff):
|
||||
if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or (hasattr(request, 'user') and request.user.is_authenticated() and request.user.is_staff):
|
||||
response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.object_name.lower())
|
||||
response['X-Object-Id'] = str(object_id)
|
||||
|
@ -18,7 +18,7 @@ except ImportError, e:
|
||||
available_backends = [f for f in os.listdir(backend_dir) if not f.startswith('_') and not f.startswith('.') and not f.endswith('.py') and not f.endswith('.pyc')]
|
||||
available_backends.sort()
|
||||
if settings.DATABASE_ENGINE not in available_backends:
|
||||
raise ImproperlyConfigured, "%r isn't an available database backend. vailable options are: %s" % \
|
||||
raise ImproperlyConfigured, "%r isn't an available database backend. Available options are: %s" % \
|
||||
(settings.DATABASE_ENGINE, ", ".join(map(repr, available_backends)))
|
||||
else:
|
||||
raise # If there's some other error, this must be an error in Django itself.
|
||||
|
@ -457,9 +457,7 @@ class DateField(Field):
|
||||
|
||||
def get_db_prep_save(self, value):
|
||||
# Casts dates into string format for entry into database.
|
||||
if isinstance(value, datetime.datetime):
|
||||
value = value.date().strftime('%Y-%m-%d')
|
||||
elif isinstance(value, datetime.date):
|
||||
if value is not None:
|
||||
value = value.strftime('%Y-%m-%d')
|
||||
return Field.get_db_prep_save(self, value)
|
||||
|
||||
@ -489,19 +487,12 @@ class DateTimeField(DateField):
|
||||
|
||||
def get_db_prep_save(self, value):
|
||||
# Casts dates into string format for entry into database.
|
||||
if isinstance(value, datetime.datetime):
|
||||
if value is not None:
|
||||
# MySQL will throw a warning if microseconds are given, because it
|
||||
# doesn't support microseconds.
|
||||
if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
|
||||
value = value.replace(microsecond=0)
|
||||
value = str(value)
|
||||
elif isinstance(value, datetime.date):
|
||||
# MySQL will throw a warning if microseconds are given, because it
|
||||
# doesn't support microseconds.
|
||||
if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
|
||||
value = datetime.datetime(value.year, value.month, value.day, microsecond=0)
|
||||
value = str(value)
|
||||
|
||||
return Field.get_db_prep_save(self, value)
|
||||
|
||||
def get_db_prep_lookup(self, lookup_type, value):
|
||||
|
@ -208,7 +208,7 @@ class HttpResponse(object):
|
||||
if path is not None:
|
||||
self.cookies[key]['path'] = path
|
||||
if domain is not None:
|
||||
self.cookies[key]['domain'] = path
|
||||
self.cookies[key]['domain'] = domain
|
||||
self.cookies[key]['expires'] = 0
|
||||
self.cookies[key]['max-age'] = 0
|
||||
|
||||
|
@ -25,4 +25,5 @@ class GZipMiddleware(object):
|
||||
|
||||
response.content = compress_string(response.content)
|
||||
response['Content-Encoding'] = 'gzip'
|
||||
response['Content-Length'] = str(len(response.content))
|
||||
return response
|
||||
|
@ -14,15 +14,4 @@ from util import ValidationError
|
||||
from widgets import *
|
||||
from fields import *
|
||||
from forms import Form
|
||||
|
||||
##########################
|
||||
# DATABASE API SHORTCUTS #
|
||||
##########################
|
||||
|
||||
def form_for_model(model):
|
||||
"Returns a Form instance for the given Django model class."
|
||||
raise NotImplementedError
|
||||
|
||||
def form_for_fields(field_list):
|
||||
"Returns a Form instance for the given list of Django database field instances."
|
||||
raise NotImplementedError
|
||||
from models import *
|
||||
|
@ -2,7 +2,8 @@
|
||||
Field classes
|
||||
"""
|
||||
|
||||
from util import ValidationError, DEFAULT_ENCODING
|
||||
from django.utils.translation import gettext
|
||||
from util import ValidationError, smart_unicode
|
||||
from widgets import TextInput, CheckboxInput, Select, SelectMultiple
|
||||
import datetime
|
||||
import re
|
||||
@ -28,6 +29,9 @@ except NameError:
|
||||
class Field(object):
|
||||
widget = TextInput # Default widget to use when rendering this type of Field.
|
||||
|
||||
# Tracks each time a Field instance is created. Used to retain order.
|
||||
creation_counter = 0
|
||||
|
||||
def __init__(self, required=True, widget=None):
|
||||
self.required = required
|
||||
widget = widget or self.widget
|
||||
@ -35,6 +39,10 @@ class Field(object):
|
||||
widget = widget()
|
||||
self.widget = widget
|
||||
|
||||
# Increase the creation counter, and save our local copy.
|
||||
self.creation_counter = Field.creation_counter
|
||||
Field.creation_counter += 1
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
Validates the given value and returns its "cleaned" value as an
|
||||
@ -43,7 +51,7 @@ class Field(object):
|
||||
Raises ValidationError for any errors.
|
||||
"""
|
||||
if self.required and value in EMPTY_VALUES:
|
||||
raise ValidationError(u'This field is required.')
|
||||
raise ValidationError(gettext(u'This field is required.'))
|
||||
return value
|
||||
|
||||
class CharField(Field):
|
||||
@ -55,14 +63,11 @@ class CharField(Field):
|
||||
"Validates max_length and min_length. Returns a Unicode object."
|
||||
Field.clean(self, value)
|
||||
if value in EMPTY_VALUES: value = u''
|
||||
if not isinstance(value, basestring):
|
||||
value = unicode(str(value), DEFAULT_ENCODING)
|
||||
elif not isinstance(value, unicode):
|
||||
value = unicode(value, DEFAULT_ENCODING)
|
||||
value = smart_unicode(value)
|
||||
if self.max_length is not None and len(value) > self.max_length:
|
||||
raise ValidationError(u'Ensure this value has at most %d characters.' % self.max_length)
|
||||
raise ValidationError(gettext(u'Ensure this value has at most %d characters.') % self.max_length)
|
||||
if self.min_length is not None and len(value) < self.min_length:
|
||||
raise ValidationError(u'Ensure this value has at least %d characters.' % self.min_length)
|
||||
raise ValidationError(gettext(u'Ensure this value has at least %d characters.') % self.min_length)
|
||||
return value
|
||||
|
||||
class IntegerField(Field):
|
||||
@ -72,10 +77,12 @@ class IntegerField(Field):
|
||||
of int().
|
||||
"""
|
||||
super(IntegerField, self).clean(value)
|
||||
if not self.required and value in EMPTY_VALUES:
|
||||
return u''
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
raise ValidationError(u'Enter a whole number.')
|
||||
raise ValidationError(gettext(u'Enter a whole number.'))
|
||||
|
||||
DEFAULT_DATE_INPUT_FORMATS = (
|
||||
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
|
||||
@ -107,7 +114,7 @@ class DateField(Field):
|
||||
return datetime.date(*time.strptime(value, format)[:3])
|
||||
except ValueError:
|
||||
continue
|
||||
raise ValidationError(u'Enter a valid date.')
|
||||
raise ValidationError(gettext(u'Enter a valid date.'))
|
||||
|
||||
DEFAULT_DATETIME_INPUT_FORMATS = (
|
||||
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
|
||||
@ -143,7 +150,7 @@ class DateTimeField(Field):
|
||||
return datetime.datetime(*time.strptime(value, format)[:6])
|
||||
except ValueError:
|
||||
continue
|
||||
raise ValidationError(u'Enter a valid date/time.')
|
||||
raise ValidationError(gettext(u'Enter a valid date/time.'))
|
||||
|
||||
class RegexField(Field):
|
||||
def __init__(self, regex, error_message=None, required=True, widget=None):
|
||||
@ -156,7 +163,7 @@ class RegexField(Field):
|
||||
if isinstance(regex, basestring):
|
||||
regex = re.compile(regex)
|
||||
self.regex = regex
|
||||
self.error_message = error_message or u'Enter a valid value.'
|
||||
self.error_message = error_message or gettext(u'Enter a valid value.')
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
@ -165,10 +172,9 @@ class RegexField(Field):
|
||||
"""
|
||||
Field.clean(self, value)
|
||||
if value in EMPTY_VALUES: value = u''
|
||||
if not isinstance(value, basestring):
|
||||
value = unicode(str(value), DEFAULT_ENCODING)
|
||||
elif not isinstance(value, unicode):
|
||||
value = unicode(value, DEFAULT_ENCODING)
|
||||
value = smart_unicode(value)
|
||||
if not self.required and value == u'':
|
||||
return value
|
||||
if not self.regex.search(value):
|
||||
raise ValidationError(self.error_message)
|
||||
return value
|
||||
@ -180,7 +186,7 @@ email_re = re.compile(
|
||||
|
||||
class EmailField(RegexField):
|
||||
def __init__(self, required=True, widget=None):
|
||||
RegexField.__init__(self, email_re, u'Enter a valid e-mail address.', required, widget)
|
||||
RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget)
|
||||
|
||||
url_re = re.compile(
|
||||
r'^https?://' # http:// or https://
|
||||
@ -198,7 +204,7 @@ except ImportError:
|
||||
class URLField(RegexField):
|
||||
def __init__(self, required=True, verify_exists=False, widget=None,
|
||||
validator_user_agent=URL_VALIDATOR_USER_AGENT):
|
||||
RegexField.__init__(self, url_re, u'Enter a valid URL.', required, widget)
|
||||
RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget)
|
||||
self.verify_exists = verify_exists
|
||||
self.user_agent = validator_user_agent
|
||||
|
||||
@ -215,12 +221,12 @@ class URLField(RegexField):
|
||||
"User-Agent": self.user_agent,
|
||||
}
|
||||
try:
|
||||
req = urllib2.Request(field_data, None, headers)
|
||||
req = urllib2.Request(value, None, headers)
|
||||
u = urllib2.urlopen(req)
|
||||
except ValueError:
|
||||
raise ValidationError(u'Enter a valid URL.')
|
||||
raise ValidationError(gettext(u'Enter a valid URL.'))
|
||||
except: # urllib2.URLError, httplib.InvalidURL, etc.
|
||||
raise ValidationError(u'This URL appears to be a broken link.')
|
||||
raise ValidationError(gettext(u'This URL appears to be a broken link.'))
|
||||
return value
|
||||
|
||||
class BooleanField(Field):
|
||||
@ -244,13 +250,12 @@ class ChoiceField(Field):
|
||||
"""
|
||||
value = Field.clean(self, value)
|
||||
if value in EMPTY_VALUES: value = u''
|
||||
if not isinstance(value, basestring):
|
||||
value = unicode(str(value), DEFAULT_ENCODING)
|
||||
elif not isinstance(value, unicode):
|
||||
value = unicode(value, DEFAULT_ENCODING)
|
||||
value = smart_unicode(value)
|
||||
if not self.required and value == u'':
|
||||
return value
|
||||
valid_values = set([str(k) for k, v in self.choices])
|
||||
if value not in valid_values:
|
||||
raise ValidationError(u'Select a valid choice. %s is not one of the available choices.' % value)
|
||||
raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % value)
|
||||
return value
|
||||
|
||||
class MultipleChoiceField(ChoiceField):
|
||||
@ -261,27 +266,31 @@ class MultipleChoiceField(ChoiceField):
|
||||
"""
|
||||
Validates that the input is a list or tuple.
|
||||
"""
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValidationError(u'Enter a list of values.')
|
||||
if self.required and not value:
|
||||
raise ValidationError(u'This field is required.')
|
||||
raise ValidationError(gettext(u'This field is required.'))
|
||||
elif not self.required and not value:
|
||||
return []
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValidationError(gettext(u'Enter a list of values.'))
|
||||
new_value = []
|
||||
for val in value:
|
||||
if not isinstance(val, basestring):
|
||||
value = unicode(str(val), DEFAULT_ENCODING)
|
||||
elif not isinstance(val, unicode):
|
||||
value = unicode(val, DEFAULT_ENCODING)
|
||||
new_value.append(value)
|
||||
val = smart_unicode(val)
|
||||
new_value.append(val)
|
||||
# Validate that each value in the value list is in self.choices.
|
||||
valid_values = set([k for k, v in self.choices])
|
||||
valid_values = set([smart_unicode(k) for k, v in self.choices])
|
||||
for val in new_value:
|
||||
if val not in valid_values:
|
||||
raise ValidationError(u'Select a valid choice. %s is not one of the available choices.' % val)
|
||||
raise ValidationError(gettext(u'Select a valid choice. %s is not one of the available choices.') % val)
|
||||
return new_value
|
||||
|
||||
class ComboField(Field):
|
||||
def __init__(self, fields=(), required=True, widget=None):
|
||||
Field.__init__(self, required, widget)
|
||||
# Set 'required' to False on the individual fields, because the
|
||||
# required validation will be handled by ComboField, not by those
|
||||
# individual fields.
|
||||
for f in fields:
|
||||
f.required = False
|
||||
self.fields = fields
|
||||
|
||||
def clean(self, value):
|
||||
|
@ -2,9 +2,11 @@
|
||||
Form classes
|
||||
"""
|
||||
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.html import escape
|
||||
from fields import Field
|
||||
from widgets import TextInput, Textarea
|
||||
from util import ErrorDict, ErrorList, ValidationError
|
||||
from widgets import TextInput, Textarea, HiddenInput
|
||||
from util import StrAndUnicode, ErrorDict, ErrorList, ValidationError
|
||||
|
||||
NON_FIELD_ERRORS = '__all__'
|
||||
|
||||
@ -13,22 +15,35 @@ def pretty_name(name):
|
||||
name = name[0].upper() + name[1:]
|
||||
return name.replace('_', ' ')
|
||||
|
||||
class SortedDictFromList(SortedDict):
|
||||
"A dictionary that keeps its keys in the order in which they're inserted."
|
||||
# This is different than django.utils.datastructures.SortedDict, because
|
||||
# this takes a list/tuple as the argument to __init__().
|
||||
def __init__(self, data=None):
|
||||
if data is None: data = []
|
||||
self.keyOrder = [d[0] for d in data]
|
||||
dict.__init__(self, dict(data))
|
||||
|
||||
class DeclarativeFieldsMetaclass(type):
|
||||
"Metaclass that converts Field attributes to a dictionary called 'fields'."
|
||||
def __new__(cls, name, bases, attrs):
|
||||
attrs['fields'] = dict([(name, attrs.pop(name)) for name, obj in attrs.items() if isinstance(obj, Field)])
|
||||
fields = [(name, attrs.pop(name)) for name, obj in attrs.items() if isinstance(obj, Field)]
|
||||
fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
|
||||
attrs['fields'] = SortedDictFromList(fields)
|
||||
return type.__new__(cls, name, bases, attrs)
|
||||
|
||||
class Form(object):
|
||||
class Form(StrAndUnicode):
|
||||
"A collection of Fields, plus their associated data."
|
||||
__metaclass__ = DeclarativeFieldsMetaclass
|
||||
|
||||
def __init__(self, data=None): # TODO: prefix stuff
|
||||
def __init__(self, data=None, auto_id=False): # TODO: prefix stuff
|
||||
self.ignore_errors = data is None
|
||||
self.data = data or {}
|
||||
self.auto_id = auto_id
|
||||
self.clean_data = None # Stores the data after clean() has been called.
|
||||
self.__errors = None # Stores the errors after clean() has been called.
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.as_table()
|
||||
|
||||
def __iter__(self):
|
||||
@ -43,62 +58,66 @@ class Form(object):
|
||||
raise KeyError('Key %r not found in Form' % name)
|
||||
return BoundField(self, field, name)
|
||||
|
||||
def clean(self):
|
||||
if self.__errors is None:
|
||||
self.full_clean()
|
||||
return self.clean_data
|
||||
|
||||
def errors(self):
|
||||
def _errors(self):
|
||||
"Returns an ErrorDict for self.data"
|
||||
if self.__errors is None:
|
||||
self.full_clean()
|
||||
return self.__errors
|
||||
errors = property(_errors)
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
Returns True if the form has no errors. Otherwise, False. This exists
|
||||
solely for convenience, so client code can use positive logic rather
|
||||
than confusing negative logic ("if not form.errors()").
|
||||
Returns True if the form has no errors. Otherwise, False. If errors are
|
||||
being ignored, returns False.
|
||||
"""
|
||||
return not bool(self.errors())
|
||||
return not self.ignore_errors and not bool(self.errors)
|
||||
|
||||
def _html_output(self, normal_row, error_row, row_ender, errors_on_separate_row):
|
||||
"Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
|
||||
top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
|
||||
output, hidden_fields = [], []
|
||||
for name, field in self.fields.items():
|
||||
bf = BoundField(self, field, name)
|
||||
bf_errors = bf.errors # Cache in local variable.
|
||||
if bf.is_hidden:
|
||||
if bf_errors:
|
||||
top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors])
|
||||
hidden_fields.append(unicode(bf))
|
||||
else:
|
||||
if errors_on_separate_row and bf_errors:
|
||||
output.append(error_row % bf_errors)
|
||||
output.append(normal_row % {'errors': bf_errors, 'label': bf.label_tag(escape(bf.verbose_name+':')), 'field': bf})
|
||||
if top_errors:
|
||||
output.insert(0, error_row % top_errors)
|
||||
if hidden_fields: # Insert any hidden fields in the last row.
|
||||
str_hidden = u''.join(hidden_fields)
|
||||
if output:
|
||||
last_row = output[-1]
|
||||
# Chop off the trailing row_ender (e.g. '</td></tr>') and insert the hidden fields.
|
||||
output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender
|
||||
else: # If there aren't any rows in the output, just append the hidden fields.
|
||||
output.append(str_hidden)
|
||||
return u'\n'.join(output)
|
||||
|
||||
def as_table(self):
|
||||
"Returns this form rendered as an HTML <table>."
|
||||
output = u'\n'.join(['<tr><td>%s:</td><td>%s</td></tr>' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
|
||||
return '<table>\n%s\n</table>' % output
|
||||
"Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
|
||||
return self._html_output(u'<tr><td>%(label)s</td><td>%(field)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', True)
|
||||
|
||||
def as_ul(self):
|
||||
"Returns this form rendered as an HTML <ul>."
|
||||
output = u'\n'.join(['<li>%s: %s</li>' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
|
||||
return '<ul>\n%s\n</ul>' % output
|
||||
"Returns this form rendered as HTML <li>s -- excluding the <ul></ul>."
|
||||
return self._html_output(u'<li>%(errors)s%(label)s %(field)s</li>', u'<li>%s</li>', '</li>', False)
|
||||
|
||||
def as_table_with_errors(self):
|
||||
"Returns this form rendered as an HTML <table>, with errors."
|
||||
output = []
|
||||
if self.errors().get(NON_FIELD_ERRORS):
|
||||
# Errors not corresponding to a particular field are displayed at the top.
|
||||
output.append('<tr><td colspan="2"><ul>%s</ul></td></tr>' % '\n'.join(['<li>%s</li>' % e for e in self.errors()[NON_FIELD_ERRORS]]))
|
||||
for name, field in self.fields.items():
|
||||
bf = BoundField(self, field, name)
|
||||
if bf.errors:
|
||||
output.append('<tr><td colspan="2"><ul>%s</ul></td></tr>' % '\n'.join(['<li>%s</li>' % e for e in bf.errors]))
|
||||
output.append('<tr><td>%s:</td><td>%s</td></tr>' % (pretty_name(name), bf))
|
||||
return '<table>\n%s\n</table>' % '\n'.join(output)
|
||||
def as_p(self):
|
||||
"Returns this form rendered as HTML <p>s."
|
||||
return self._html_output(u'<p>%(label)s %(field)s</p>', u'<p>%s</p>', '</p>', True)
|
||||
|
||||
def as_ul_with_errors(self):
|
||||
"Returns this form rendered as an HTML <ul>, with errors."
|
||||
output = []
|
||||
if self.errors().get(NON_FIELD_ERRORS):
|
||||
# Errors not corresponding to a particular field are displayed at the top.
|
||||
output.append('<li><ul>%s</ul></li>' % '\n'.join(['<li>%s</li>' % e for e in self.errors()[NON_FIELD_ERRORS]]))
|
||||
for name, field in self.fields.items():
|
||||
bf = BoundField(self, field, name)
|
||||
line = '<li>'
|
||||
if bf.errors:
|
||||
line += '<ul>%s</ul>' % '\n'.join(['<li>%s</li>' % e for e in bf.errors])
|
||||
line += '%s: %s</li>' % (pretty_name(name), bf)
|
||||
output.append(line)
|
||||
return '<ul>\n%s\n</ul>' % '\n'.join(output)
|
||||
def non_field_errors(self):
|
||||
"""
|
||||
Returns an ErrorList of errors that aren't associated with a particular
|
||||
field -- i.e., from Form.clean(). Returns an empty ErrorList if there
|
||||
are none.
|
||||
"""
|
||||
return self.errors.get(NON_FIELD_ERRORS, ErrorList())
|
||||
|
||||
def full_clean(self):
|
||||
"""
|
||||
@ -106,8 +125,14 @@ class Form(object):
|
||||
"""
|
||||
self.clean_data = {}
|
||||
errors = ErrorDict()
|
||||
if self.ignore_errors: # Stop further processing.
|
||||
self.__errors = errors
|
||||
return
|
||||
for name, field in self.fields.items():
|
||||
value = self.data.get(name, None)
|
||||
# value_from_datadict() gets the data from the dictionary.
|
||||
# Each widget type knows how to retrieve its own data, because some
|
||||
# widgets split data over several HTML fields.
|
||||
value = field.widget.value_from_datadict(self.data, name)
|
||||
try:
|
||||
value = field.clean(value)
|
||||
self.clean_data[name] = value
|
||||
@ -127,36 +152,45 @@ class Form(object):
|
||||
def clean(self):
|
||||
"""
|
||||
Hook for doing any extra form-wide cleaning after Field.clean() been
|
||||
called on every field.
|
||||
called on every field. Any ValidationError raised by this method will
|
||||
not be associated with a particular field; it will have a special-case
|
||||
association with the field named '__all__'.
|
||||
"""
|
||||
return self.clean_data
|
||||
|
||||
class BoundField(object):
|
||||
class BoundField(StrAndUnicode):
|
||||
"A Field plus data"
|
||||
def __init__(self, form, field, name):
|
||||
self._form = form
|
||||
self._field = field
|
||||
self._name = name
|
||||
self.form = form
|
||||
self.field = field
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
"Renders this field as an HTML widget."
|
||||
# Use the 'widget' attribute on the field to determine which type
|
||||
# of HTML widget to use.
|
||||
return self.as_widget(self._field.widget)
|
||||
value = self.as_widget(self.field.widget)
|
||||
if not isinstance(value, basestring):
|
||||
# Some Widget render() methods -- notably RadioSelect -- return a
|
||||
# "special" object rather than a string. Call the __str__() on that
|
||||
# object to get its rendered value.
|
||||
value = value.__str__()
|
||||
return value
|
||||
|
||||
def _errors(self):
|
||||
"""
|
||||
Returns an ErrorList for this field. Returns an empty ErrorList
|
||||
if there are none.
|
||||
"""
|
||||
try:
|
||||
return self._form.errors()[self._name]
|
||||
except KeyError:
|
||||
return ErrorList()
|
||||
return self.form.errors.get(self.name, ErrorList())
|
||||
errors = property(_errors)
|
||||
|
||||
def as_widget(self, widget, attrs=None):
|
||||
return widget.render(self._name, self._form.data.get(self._name, None), attrs=attrs)
|
||||
attrs = attrs or {}
|
||||
auto_id = self.auto_id
|
||||
if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'):
|
||||
attrs['id'] = auto_id
|
||||
return widget.render(self.name, self.data, attrs=attrs)
|
||||
|
||||
def as_text(self, attrs=None):
|
||||
"""
|
||||
@ -167,3 +201,49 @@ class BoundField(object):
|
||||
def as_textarea(self, attrs=None):
|
||||
"Returns a string of HTML for representing this as a <textarea>."
|
||||
return self.as_widget(Textarea(), attrs)
|
||||
|
||||
def as_hidden(self, attrs=None):
|
||||
"""
|
||||
Returns a string of HTML for representing this as an <input type="hidden">.
|
||||
"""
|
||||
return self.as_widget(HiddenInput(), attrs)
|
||||
|
||||
def _data(self):
|
||||
"Returns the data for this BoundField, or None if it wasn't given."
|
||||
return self.form.data.get(self.name, None)
|
||||
data = property(_data)
|
||||
|
||||
def _verbose_name(self):
|
||||
return pretty_name(self.name)
|
||||
verbose_name = property(_verbose_name)
|
||||
|
||||
def label_tag(self, contents=None):
|
||||
"""
|
||||
Wraps the given contents in a <label>, if the field has an ID attribute.
|
||||
Does not HTML-escape the contents. If contents aren't given, uses the
|
||||
field's HTML-escaped verbose_name.
|
||||
"""
|
||||
contents = contents or escape(self.verbose_name)
|
||||
widget = self.field.widget
|
||||
id_ = widget.attrs.get('id') or self.auto_id
|
||||
if id_:
|
||||
contents = '<label for="%s">%s</label>' % (widget.id_for_label(id_), contents)
|
||||
return contents
|
||||
|
||||
def _is_hidden(self):
|
||||
"Returns True if this BoundField's widget is hidden."
|
||||
return self.field.widget.is_hidden
|
||||
is_hidden = property(_is_hidden)
|
||||
|
||||
def _auto_id(self):
|
||||
"""
|
||||
Calculates and returns the ID attribute for this BoundField, if the
|
||||
associated Form has specified auto_id. Returns an empty string otherwise.
|
||||
"""
|
||||
auto_id = self.form.auto_id
|
||||
if auto_id and '%s' in str(auto_id):
|
||||
return str(auto_id) % self.name
|
||||
elif auto_id:
|
||||
return self.name
|
||||
return ''
|
||||
auto_id = property(_auto_id)
|
||||
|
13
django/newforms/models.py
Normal file
13
django/newforms/models.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""
|
||||
Helper functions for creating Forms from Django models and database field objects.
|
||||
"""
|
||||
|
||||
__all__ = ('form_for_model', 'form_for_fields')
|
||||
|
||||
def form_for_model(model):
|
||||
"Returns a Form instance for the given Django model class."
|
||||
raise NotImplementedError
|
||||
|
||||
def form_for_fields(field_list):
|
||||
"Returns a Form instance for the given list of Django database field instances."
|
||||
raise NotImplementedError
|
@ -1,11 +1,22 @@
|
||||
# Default encoding for input byte strings.
|
||||
DEFAULT_ENCODING = 'utf-8' # TODO: First look at django.conf.settings, then fall back to this.
|
||||
from django.conf import settings
|
||||
|
||||
def smart_unicode(s):
|
||||
if not isinstance(s, unicode):
|
||||
s = unicode(s, DEFAULT_ENCODING)
|
||||
if not isinstance(s, basestring):
|
||||
s = unicode(str(s))
|
||||
elif not isinstance(s, unicode):
|
||||
s = unicode(s, settings.DEFAULT_CHARSET)
|
||||
return s
|
||||
|
||||
class StrAndUnicode(object):
|
||||
"""
|
||||
A class whose __str__ returns its __unicode__ as a bytestring
|
||||
according to settings.DEFAULT_CHARSET.
|
||||
|
||||
Useful as a mix-in.
|
||||
"""
|
||||
def __str__(self):
|
||||
return self.__unicode__().encode(settings.DEFAULT_CHARSET)
|
||||
|
||||
class ErrorDict(dict):
|
||||
"""
|
||||
A collection of errors that knows how to display itself in various formats.
|
||||
|
@ -5,9 +5,10 @@ HTML Widget classes
|
||||
__all__ = (
|
||||
'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'FileInput',
|
||||
'Textarea', 'CheckboxInput',
|
||||
'Select', 'SelectMultiple',
|
||||
'Select', 'SelectMultiple', 'RadioSelect', 'CheckboxSelectMultiple',
|
||||
)
|
||||
|
||||
from util import StrAndUnicode, smart_unicode
|
||||
from django.utils.html import escape
|
||||
from itertools import chain
|
||||
|
||||
@ -16,27 +17,57 @@ try:
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
|
||||
# Converts a dictionary to a single string with key="value", XML-style.
|
||||
# Assumes keys do not need to be XML-escaped.
|
||||
flatatt = lambda attrs: ' '.join(['%s="%s"' % (k, escape(v)) for k, v in attrs.items()])
|
||||
# Converts a dictionary to a single string with key="value", XML-style with
|
||||
# a leading space. Assumes keys do not need to be XML-escaped.
|
||||
flatatt = lambda attrs: u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
|
||||
|
||||
class Widget(object):
|
||||
requires_data_list = False # Determines whether render()'s 'value' argument should be a list.
|
||||
is_hidden = False # Determines whether this corresponds to an <input type="hidden">.
|
||||
|
||||
def __init__(self, attrs=None):
|
||||
self.attrs = attrs or {}
|
||||
|
||||
def render(self, name, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def build_attrs(self, extra_attrs=None, **kwargs):
|
||||
"Helper function for building an attribute dictionary."
|
||||
attrs = dict(self.attrs, **kwargs)
|
||||
if extra_attrs:
|
||||
attrs.update(extra_attrs)
|
||||
return attrs
|
||||
|
||||
def value_from_datadict(self, data, name):
|
||||
"""
|
||||
Given a dictionary of data and this widget's name, returns the value
|
||||
of this widget. Returns None if it's not provided.
|
||||
"""
|
||||
return data.get(name, None)
|
||||
|
||||
def id_for_label(self, id_):
|
||||
"""
|
||||
Returns the HTML ID attribute of this Widget for use by a <label>,
|
||||
given the ID of the field. Returns None if no ID is available.
|
||||
|
||||
This hook is necessary because some widgets have multiple HTML
|
||||
elements and, thus, multiple IDs. In that case, this method should
|
||||
return an ID value that corresponds to the first ID in the widget's
|
||||
tags.
|
||||
"""
|
||||
return id_
|
||||
id_for_label = classmethod(id_for_label)
|
||||
|
||||
class Input(Widget):
|
||||
"Base class for all <input> widgets (except type='checkbox', which is special)"
|
||||
"""
|
||||
Base class for all <input> widgets (except type='checkbox' and
|
||||
type='radio', which are special).
|
||||
"""
|
||||
input_type = None # Subclasses must define this.
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is None: value = ''
|
||||
final_attrs = dict(self.attrs, type=self.input_type, name=name)
|
||||
if attrs:
|
||||
final_attrs.update(attrs)
|
||||
if value != '': final_attrs['value'] = value # Only add the 'value' attribute if a value is non-empty.
|
||||
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
|
||||
if value != '': final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty.
|
||||
return u'<input%s />' % flatatt(final_attrs)
|
||||
|
||||
class TextInput(Input):
|
||||
@ -47,6 +78,7 @@ class PasswordInput(Input):
|
||||
|
||||
class HiddenInput(Input):
|
||||
input_type = 'hidden'
|
||||
is_hidden = True
|
||||
|
||||
class FileInput(Input):
|
||||
input_type = 'file'
|
||||
@ -54,17 +86,27 @@ class FileInput(Input):
|
||||
class Textarea(Widget):
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is None: value = ''
|
||||
final_attrs = dict(self.attrs, name=name)
|
||||
if attrs:
|
||||
final_attrs.update(attrs)
|
||||
value = smart_unicode(value)
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
return u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), escape(value))
|
||||
|
||||
class CheckboxInput(Widget):
|
||||
def __init__(self, attrs=None, check_test=bool):
|
||||
# check_test is a callable that takes a value and returns True
|
||||
# if the checkbox should be checked for that value.
|
||||
self.attrs = attrs or {}
|
||||
self.check_test = check_test
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
final_attrs = dict(self.attrs, type='checkbox', name=name)
|
||||
if attrs:
|
||||
final_attrs.update(attrs)
|
||||
if value: final_attrs['checked'] = 'checked'
|
||||
final_attrs = self.build_attrs(attrs, type='checkbox', name=name)
|
||||
try:
|
||||
result = self.check_test(value)
|
||||
except: # Silently catch exceptions
|
||||
result = False
|
||||
if result:
|
||||
final_attrs['checked'] = 'checked'
|
||||
if value not in ('', True, False, None):
|
||||
final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty.
|
||||
return u'<input%s />' % flatatt(final_attrs)
|
||||
|
||||
class Select(Widget):
|
||||
@ -75,14 +117,13 @@ class Select(Widget):
|
||||
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
if value is None: value = ''
|
||||
final_attrs = dict(self.attrs, name=name)
|
||||
if attrs:
|
||||
final_attrs.update(attrs)
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
output = [u'<select%s>' % flatatt(final_attrs)]
|
||||
str_value = str(value) # Normalize to string.
|
||||
str_value = smart_unicode(value) # Normalize to string.
|
||||
for option_value, option_label in chain(self.choices, choices):
|
||||
selected_html = (str(option_value) == str_value) and ' selected="selected"' or ''
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label)))
|
||||
option_value = smart_unicode(option_value)
|
||||
selected_html = (option_value == str_value) and u' selected="selected"' or ''
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(smart_unicode(option_label))))
|
||||
output.append(u'</select>')
|
||||
return u'\n'.join(output)
|
||||
|
||||
@ -95,19 +136,87 @@ class SelectMultiple(Widget):
|
||||
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
if value is None: value = []
|
||||
final_attrs = dict(self.attrs, name=name)
|
||||
if attrs:
|
||||
final_attrs.update(attrs)
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)]
|
||||
str_values = set([str(v) for v in value]) # Normalize to strings.
|
||||
str_values = set([smart_unicode(v) for v in value]) # Normalize to strings.
|
||||
for option_value, option_label in chain(self.choices, choices):
|
||||
selected_html = (str(option_value) in str_values) and ' selected="selected"' or ''
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label)))
|
||||
option_value = smart_unicode(option_value)
|
||||
selected_html = (option_value in str_values) and ' selected="selected"' or ''
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(smart_unicode(option_label))))
|
||||
output.append(u'</select>')
|
||||
return u'\n'.join(output)
|
||||
|
||||
class RadioSelect(Widget):
|
||||
pass
|
||||
class RadioInput(StrAndUnicode):
|
||||
"An object used by RadioFieldRenderer that represents a single <input type='radio'>."
|
||||
def __init__(self, name, value, attrs, choice, index):
|
||||
self.name, self.value = name, value
|
||||
self.attrs = attrs
|
||||
self.choice_value, self.choice_label = choice
|
||||
self.index = index
|
||||
|
||||
class CheckboxSelectMultiple(Widget):
|
||||
pass
|
||||
def __unicode__(self):
|
||||
return u'<label>%s %s</label>' % (self.tag(), self.choice_label)
|
||||
|
||||
def is_checked(self):
|
||||
return self.value == smart_unicode(self.choice_value)
|
||||
|
||||
def tag(self):
|
||||
if self.attrs.has_key('id'):
|
||||
self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
|
||||
final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
|
||||
if self.is_checked():
|
||||
final_attrs['checked'] = 'checked'
|
||||
return u'<input%s />' % flatatt(final_attrs)
|
||||
|
||||
class RadioFieldRenderer(StrAndUnicode):
|
||||
"An object used by RadioSelect to enable customization of radio widgets."
|
||||
def __init__(self, name, value, attrs, choices):
|
||||
self.name, self.value, self.attrs = name, value, attrs
|
||||
self.choices = choices
|
||||
|
||||
def __iter__(self):
|
||||
for i, choice in enumerate(self.choices):
|
||||
yield RadioInput(self.name, self.value, self.attrs.copy(), choice, i)
|
||||
|
||||
def __unicode__(self):
|
||||
"Outputs a <ul> for this set of radio fields."
|
||||
return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % w for w in self])
|
||||
|
||||
class RadioSelect(Select):
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
"Returns a RadioFieldRenderer instance rather than a Unicode string."
|
||||
if value is None: value = ''
|
||||
str_value = smart_unicode(value) # Normalize to string.
|
||||
attrs = attrs or {}
|
||||
return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
|
||||
|
||||
def id_for_label(self, id_):
|
||||
# RadioSelect is represented by multiple <input type="radio"> fields,
|
||||
# each of which has a distinct ID. The IDs are made distinct by a "_X"
|
||||
# suffix, where X is the zero-based index of the radio field. Thus,
|
||||
# the label for a RadioSelect should reference the first one ('_0').
|
||||
if id_:
|
||||
id_ += '_0'
|
||||
return id_
|
||||
id_for_label = classmethod(id_for_label)
|
||||
|
||||
class CheckboxSelectMultiple(SelectMultiple):
|
||||
def render(self, name, value, attrs=None, choices=()):
|
||||
if value is None: value = []
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
output = [u'<ul>']
|
||||
str_values = set([smart_unicode(v) for v in value]) # Normalize to strings.
|
||||
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
|
||||
for option_value, option_label in chain(self.choices, choices):
|
||||
option_value = smart_unicode(option_value)
|
||||
rendered_cb = cb.render(name, option_value)
|
||||
output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(smart_unicode(option_label))))
|
||||
output.append(u'</ul>')
|
||||
return u'\n'.join(output)
|
||||
|
||||
def id_for_label(self, id_):
|
||||
# See the comment for RadioSelect.id_for_label()
|
||||
if id_:
|
||||
id_ += '_0'
|
||||
return id_
|
||||
id_for_label = classmethod(id_for_label)
|
||||
|
@ -742,7 +742,11 @@ class VariableNode(Node):
|
||||
def encode_output(self, output):
|
||||
# Check type so that we don't run str() on a Unicode object
|
||||
if not isinstance(output, basestring):
|
||||
try:
|
||||
return str(output)
|
||||
except UnicodeEncodeError:
|
||||
# If __str__() returns a Unicode object, convert it to bytestring.
|
||||
return unicode(output).encode(settings.DEFAULT_CHARSET)
|
||||
elif isinstance(output, unicode):
|
||||
return output.encode(settings.DEFAULT_CHARSET)
|
||||
else:
|
||||
|
@ -84,7 +84,7 @@ def object_detail(request, queryset, object_id=None, slug=None,
|
||||
context_processors=None, template_object_name='object',
|
||||
mimetype=None):
|
||||
"""
|
||||
Generic list of objects.
|
||||
Generic detail of an object.
|
||||
|
||||
Templates: ``<app_label>/<model_name>_detail.html``
|
||||
Context:
|
||||
|
@ -48,6 +48,23 @@ See the `csrf documentation`_.
|
||||
|
||||
.. _csrf documentation: http://www.djangoproject.com/documentation/csrf/
|
||||
|
||||
formtools
|
||||
=========
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
A set of high-level abstractions for Django forms (django.newforms).
|
||||
|
||||
django.contrib.formtools.preview
|
||||
--------------------------------
|
||||
|
||||
An abstraction of the following workflow:
|
||||
|
||||
"Display an HTML form, force a preview, then do something with the submission."
|
||||
|
||||
Full documentation for this feature does not yet exist, but you can read the
|
||||
code and docstrings in ``django/contrib/formtools/preview.py`` for a start.
|
||||
|
||||
humanize
|
||||
========
|
||||
|
||||
|
79
docs/newforms.txt
Normal file
79
docs/newforms.txt
Normal file
@ -0,0 +1,79 @@
|
||||
====================
|
||||
The newforms library
|
||||
====================
|
||||
|
||||
``django.newforms`` is a new replacement for ``django.forms``, the old Django
|
||||
form/manipulator/validation framework. This document explains how to use this
|
||||
new form library.
|
||||
|
||||
Migration plan
|
||||
==============
|
||||
|
||||
``django.newforms`` currently is only available in the Django development version
|
||||
-- i.e., it's not available in the Django 0.95 release. For the next Django
|
||||
release, our plan is to do the following:
|
||||
|
||||
* Move the current ``django.forms`` to ``django.oldforms``. This will allow
|
||||
for an eased migration of form code. You'll just have to change your
|
||||
import statements::
|
||||
|
||||
from django import forms # old
|
||||
from django import oldforms as forms # new
|
||||
|
||||
* Move the current ``django.newforms`` to ``django.forms``.
|
||||
|
||||
* We will remove ``django.oldforms`` in the release *after* the next Django
|
||||
release -- the release that comes after the release in which we're
|
||||
creating ``django.oldforms``.
|
||||
|
||||
With this in mind, we recommend you use the following import statement when
|
||||
using ``django.newforms``::
|
||||
|
||||
from django import newforms as forms
|
||||
|
||||
This way, your code can refer to the ``forms`` module, and when
|
||||
``django.newforms`` is renamed to ``django.forms``, you'll only have to change
|
||||
your ``import`` statements.
|
||||
|
||||
If you prefer "``import *``" syntax, you can do the following::
|
||||
|
||||
from django.newforms import *
|
||||
|
||||
This will import all fields, widgets, form classes and other various utilities
|
||||
into your local namespace. Some people find this convenient; others find it
|
||||
too messy. The choice is yours.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
As the ``django.forms`` system before it, ``django.newforms`` is intended to
|
||||
handle HTML form display, validation and redisplay. It's what you use if you
|
||||
want to perform server-side validation for an HTML form.
|
||||
|
||||
The library deals with these concepts:
|
||||
|
||||
* **Widget** -- A class that corresponds to an HTML form widget, e.g.
|
||||
``<input type="text">`` or ``<textarea>``. This handles rendering of the
|
||||
widget as HTML.
|
||||
|
||||
* **Field** -- A class that is responsible for doing validation, e.g.
|
||||
an ``EmailField`` that makes sure its data is a valid e-mail address.
|
||||
|
||||
* **Form** -- A collection of fields that knows how to validate itself and
|
||||
display itself as HTML.
|
||||
|
||||
|
||||
|
||||
Using forms with templates
|
||||
==========================
|
||||
|
||||
Using forms in views
|
||||
====================
|
||||
|
||||
More coming soon
|
||||
================
|
||||
|
||||
That's all the documentation for now. For more, see the file
|
||||
http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py
|
||||
-- the unit tests for ``django.newforms``. This can give you a good idea of
|
||||
what's possible.
|
@ -141,7 +141,7 @@ Do this after you've verified that the test cookie worked.
|
||||
Here's a typical usage example::
|
||||
|
||||
def login(request):
|
||||
if request.POST:
|
||||
if request.method == 'POST':
|
||||
if request.session.test_cookie_worked():
|
||||
request.session.delete_test_cookie()
|
||||
return HttpResponse("You're logged in.")
|
||||
|
@ -830,7 +830,7 @@ Default: ``Django/<version> (http://www.djangoproject.com/)``
|
||||
The string to use as the ``User-Agent`` header when checking to see if URLs
|
||||
exist (see the ``verify_exists`` option on URLField_).
|
||||
|
||||
.. URLField: ../model_api/#urlfield
|
||||
.. _URLField: ../model_api/#urlfield
|
||||
|
||||
USE_ETAGS
|
||||
---------
|
||||
|
@ -5,9 +5,9 @@ The sitemap framework
|
||||
**New in Django development version**.
|
||||
|
||||
Django comes with a high-level sitemap-generating framework that makes
|
||||
creating `Google Sitemap`_ XML files easy.
|
||||
creating sitemap_ XML files easy.
|
||||
|
||||
.. _Google Sitemap: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html
|
||||
.. _sitemap: http://www.sitemaps.org/
|
||||
|
||||
Overview
|
||||
========
|
||||
@ -55,11 +55,12 @@ URLconf_:
|
||||
|
||||
This tells Django to build a sitemap when a client accesses ``/sitemap.xml``.
|
||||
|
||||
The name of the sitemap file is not important, but the location is. Google will
|
||||
only index links in your sitemap for the current URL level and below. For
|
||||
instance, if ``sitemap.xml`` lives in your root directory, it may reference any
|
||||
URL in your site. However, if your sitemap lives at ``/content/sitemap.xml``,
|
||||
it may only reference URLs that begin with ``/content/``.
|
||||
The name of the sitemap file is not important, but the location is. Search
|
||||
engines will only index links in your sitemap for the current URL level and
|
||||
below. For instance, if ``sitemap.xml`` lives in your root directory, it may
|
||||
reference any URL in your site. However, if your sitemap lives at
|
||||
``/content/sitemap.xml``, it may only reference URLs that begin with
|
||||
``/content/``.
|
||||
|
||||
The sitemap view takes an extra, required argument: ``{'sitemaps': sitemaps}``.
|
||||
``sitemaps`` should be a dictionary that maps a short section label (e.g.,
|
||||
@ -199,9 +200,9 @@ If it's an attribute, its value should be either a string or float representing
|
||||
the priority of *every* object returned by ``items()``.
|
||||
|
||||
Example values for ``priority``: ``0.4``, ``1.0``. The default priority of a
|
||||
page is ``0.5``. See Google's documentation for more documentation.
|
||||
page is ``0.5``. See the `sitemaps.org documentation`_ for more.
|
||||
|
||||
.. _Google's documentation: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html
|
||||
.. _sitemaps.org documentation: http://www.sitemaps.org/protocol.html#prioritydef
|
||||
|
||||
Shortcuts
|
||||
=========
|
||||
|
@ -571,7 +571,7 @@ The arguments can be hard-coded strings, so the following is valid::
|
||||
It is only possible to compare an argument to template variables or strings.
|
||||
You cannot check for equality with Python objects such as ``True`` or
|
||||
``False``. If you need to test if something is true or false, use the ``if``
|
||||
and ``ifnot`` tags instead.
|
||||
tag instead.
|
||||
|
||||
ifnotequal
|
||||
~~~~~~~~~~
|
||||
|
@ -321,7 +321,7 @@ Note::
|
||||
|
||||
def some_view(request):
|
||||
# ...
|
||||
return render_to_response('my_template'html',
|
||||
return render_to_response('my_template.html',
|
||||
my_data_dictionary,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
@ -10,7 +10,7 @@ used to validate that code behaves as expected. When refactoring or
|
||||
modifying code, tests serve as a guide to ensure that behavior hasn't
|
||||
changed unexpectedly as a result of the refactor.
|
||||
|
||||
Testing an web application is a complex task, as there are many
|
||||
Testing a web application is a complex task, as there are many
|
||||
components of a web application that must be validated and tested. To
|
||||
help you test your application, Django provides a test execution
|
||||
framework, and range of utilities that can be used to stimulate and
|
||||
@ -133,7 +133,7 @@ together, picking the test system to match the type of tests you need to
|
||||
write.
|
||||
|
||||
For developers new to testing, however, this choice can seem
|
||||
confusing, so here are a few key differences to help you decide weather
|
||||
confusing, so here are a few key differences to help you decide whether
|
||||
doctests or unit tests are right for you.
|
||||
|
||||
If you've been using Python for a while, ``doctest`` will probably feel more
|
||||
|
10
setup.py
10
setup.py
@ -11,13 +11,17 @@ for scheme in INSTALL_SCHEMES.values():
|
||||
# Compile the list of packages available, because distutils doesn't have
|
||||
# an easy way to do this.
|
||||
packages, data_files = [], []
|
||||
root_dir = os.path.join(os.path.dirname(__file__), 'django')
|
||||
for dirpath, dirnames, filenames in os.walk(root_dir):
|
||||
root_dir = os.path.dirname(__file__)
|
||||
len_root_dir = len(root_dir)
|
||||
django_dir = os.path.join(root_dir, 'django')
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(django_dir):
|
||||
# Ignore dirnames that start with '.'
|
||||
for i, dirname in enumerate(dirnames):
|
||||
if dirname.startswith('.'): del dirnames[i]
|
||||
if '__init__.py' in filenames:
|
||||
packages.append(dirpath.replace('/', '.'))
|
||||
package = dirpath[len_root_dir:].lstrip('/').replace('/', '.')
|
||||
packages.append(package)
|
||||
else:
|
||||
data_files.append((dirpath, [os.path.join(dirpath, f) for f in filenames]))
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.conf import settings
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -62,6 +63,11 @@ class OtherClass:
|
||||
def method(self):
|
||||
return "OtherClass.method"
|
||||
|
||||
class UnicodeInStrClass:
|
||||
"Class whose __str__ returns a Unicode object."
|
||||
def __str__(self):
|
||||
return u'ŠĐĆŽćžšđ'
|
||||
|
||||
class Templates(unittest.TestCase):
|
||||
def test_templates(self):
|
||||
# NOW and NOW_tz are used by timesince tag tests.
|
||||
@ -173,6 +179,10 @@ class Templates(unittest.TestCase):
|
||||
# Empty strings can be passed as arguments to filters
|
||||
'basic-syntax36': (r'{{ var|join:"" }}', {'var': ['a', 'b', 'c']}, 'abc'),
|
||||
|
||||
# If a variable has a __str__() that returns a Unicode object, the value
|
||||
# will be converted to a bytestring.
|
||||
'basic-syntax37': (r'{{ var }}', {'var': UnicodeInStrClass()}, '\xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91'),
|
||||
|
||||
### COMMENT SYNTAX ########################################################
|
||||
'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),
|
||||
'comment-syntax02': ("{# this is hidden #}hello{# foo #}", {}, "hello"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user