mirror of
https://github.com/django/django.git
synced 2025-07-06 02:39:12 +00:00
queryset-refactor: Merged from trunk up to [6724].
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6726 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5d85a5147b
commit
a97abcffc2
@ -11,11 +11,10 @@ except NameError:
|
||||
|
||||
|
||||
def compile_messages(locale=None):
|
||||
basedirs = [os.path.join('conf', 'locale'), 'locale']
|
||||
basedirs = (os.path.join('conf', 'locale'), 'locale')
|
||||
if os.environ.get('DJANGO_SETTINGS_MODULE'):
|
||||
from django.conf import settings
|
||||
if hasattr(settings, 'LOCALE_PATHS'):
|
||||
basedirs += settings.LOCALE_PATHS
|
||||
basedirs += settings.LOCALE_PATHS
|
||||
|
||||
# Gather existing directories.
|
||||
basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))
|
||||
|
@ -90,6 +90,8 @@ LANGUAGES_BIDI = ("he", "ar", "fa")
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
LOCALE_PATHS = ()
|
||||
|
||||
# Not-necessarily-technical managers of the site. They get broken link
|
||||
# notifications and other various e-mails.
|
||||
MANAGERS = ADMINS
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-11-13 21:55+0100\n"
|
||||
"POT-Creation-Date: 2007-11-15 15:28+0100\n"
|
||||
"PO-Revision-Date: 2007-05-08 20:29+0200\n"
|
||||
"Last-Translator: Jarek Zgoda <jarek.zgoda@gmail.com>\n"
|
||||
"Language-Team: Polish <pl@li.org>\n"
|
||||
@ -196,7 +196,7 @@ msgstr "Uproszczony chiński"
|
||||
msgid "Traditional Chinese"
|
||||
msgstr "Chiński tradycyjny"
|
||||
|
||||
#: contrib/admin/filterspecs.py:42
|
||||
#: contrib/admin/filterspecs.py:44
|
||||
#, python-format
|
||||
msgid ""
|
||||
"<h3>By %s:</h3>\n"
|
||||
@ -205,71 +205,71 @@ msgstr ""
|
||||
"<h3>Przez %s:</h3>\n"
|
||||
"</ul>\n"
|
||||
|
||||
#: contrib/admin/filterspecs.py:72 contrib/admin/filterspecs.py:90
|
||||
#: contrib/admin/filterspecs.py:145 contrib/admin/filterspecs.py:171
|
||||
#: contrib/admin/filterspecs.py:74 contrib/admin/filterspecs.py:92
|
||||
#: contrib/admin/filterspecs.py:147 contrib/admin/filterspecs.py:173
|
||||
msgid "All"
|
||||
msgstr "Wszystko"
|
||||
|
||||
#: contrib/admin/filterspecs.py:111
|
||||
#: contrib/admin/filterspecs.py:113
|
||||
msgid "Any date"
|
||||
msgstr "Dowolna data"
|
||||
|
||||
#: contrib/admin/filterspecs.py:112
|
||||
#: contrib/admin/filterspecs.py:114
|
||||
msgid "Today"
|
||||
msgstr "Dzisiaj"
|
||||
|
||||
#: contrib/admin/filterspecs.py:115
|
||||
#: contrib/admin/filterspecs.py:117
|
||||
msgid "Past 7 days"
|
||||
msgstr "Ostatnie 7 dni"
|
||||
|
||||
#: contrib/admin/filterspecs.py:117
|
||||
#: contrib/admin/filterspecs.py:119
|
||||
msgid "This month"
|
||||
msgstr "Ten miesiąc"
|
||||
|
||||
#: contrib/admin/filterspecs.py:119
|
||||
#: contrib/admin/filterspecs.py:121
|
||||
msgid "This year"
|
||||
msgstr "Ten rok"
|
||||
|
||||
#: contrib/admin/filterspecs.py:145 newforms/widgets.py:221
|
||||
#: oldforms/__init__.py:591
|
||||
#: contrib/admin/filterspecs.py:147 newforms/widgets.py:229
|
||||
#: oldforms/__init__.py:592
|
||||
msgid "Yes"
|
||||
msgstr "Tak"
|
||||
|
||||
#: contrib/admin/filterspecs.py:145 newforms/widgets.py:221
|
||||
#: oldforms/__init__.py:591
|
||||
#: contrib/admin/filterspecs.py:147 newforms/widgets.py:229
|
||||
#: oldforms/__init__.py:592
|
||||
msgid "No"
|
||||
msgstr "Nie"
|
||||
|
||||
#: contrib/admin/filterspecs.py:152 newforms/widgets.py:221
|
||||
#: oldforms/__init__.py:591
|
||||
#: contrib/admin/filterspecs.py:154 newforms/widgets.py:229
|
||||
#: oldforms/__init__.py:592
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
#: contrib/admin/models.py:17
|
||||
#: contrib/admin/models.py:18
|
||||
msgid "action time"
|
||||
msgstr "czas akcji"
|
||||
|
||||
#: contrib/admin/models.py:20
|
||||
#: contrib/admin/models.py:21
|
||||
msgid "object id"
|
||||
msgstr "id obiektu"
|
||||
|
||||
#: contrib/admin/models.py:21
|
||||
#: contrib/admin/models.py:22
|
||||
msgid "object repr"
|
||||
msgstr "reprezentacj obiektu"
|
||||
|
||||
#: contrib/admin/models.py:22
|
||||
#: contrib/admin/models.py:23
|
||||
msgid "action flag"
|
||||
msgstr "flaga akcji"
|
||||
|
||||
#: contrib/admin/models.py:23
|
||||
#: contrib/admin/models.py:24
|
||||
msgid "change message"
|
||||
msgstr "zmień wiadomość"
|
||||
|
||||
#: contrib/admin/models.py:26
|
||||
#: contrib/admin/models.py:27
|
||||
msgid "log entry"
|
||||
msgstr "log"
|
||||
|
||||
#: contrib/admin/models.py:27
|
||||
#: contrib/admin/models.py:28
|
||||
msgid "log entries"
|
||||
msgstr "logi"
|
||||
|
||||
@ -472,7 +472,7 @@ msgid "Password:"
|
||||
msgstr "Hasło:"
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:25
|
||||
#: contrib/admin/views/decorators.py:24
|
||||
#: contrib/admin/views/decorators.py:25
|
||||
msgid "Log in"
|
||||
msgstr "Zaloguj się"
|
||||
|
||||
@ -764,17 +764,17 @@ msgstr "Teraz:"
|
||||
msgid "Change:"
|
||||
msgstr "Zmień:"
|
||||
|
||||
#: contrib/admin/templatetags/admin_list.py:254
|
||||
#: contrib/admin/templatetags/admin_list.py:255
|
||||
msgid "All dates"
|
||||
msgstr "Wszystkie daty"
|
||||
|
||||
#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:264
|
||||
#: contrib/admin/views/auth.py:20 contrib/admin/views/main.py:267
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" dodany pomyślnie."
|
||||
|
||||
#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:268
|
||||
#: contrib/admin/views/main.py:354
|
||||
#: contrib/admin/views/auth.py:25 contrib/admin/views/main.py:271
|
||||
#: contrib/admin/views/main.py:357
|
||||
msgid "You may edit it again below."
|
||||
msgstr "Możesz ponownie edytować wpis poniżej."
|
||||
|
||||
@ -791,7 +791,7 @@ msgstr "Hasło zostało zmienione pomyślnie."
|
||||
msgid "Change password: %s"
|
||||
msgstr "Zmień hasło: %s"
|
||||
|
||||
#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60
|
||||
#: contrib/admin/views/decorators.py:11 contrib/auth/forms.py:60
|
||||
msgid ""
|
||||
"Please enter a correct username and password. Note that both fields are case-"
|
||||
"sensitive."
|
||||
@ -799,7 +799,7 @@ msgstr ""
|
||||
"Proszę wpisać poprawną nazwę użytkownika i hasło. Uwaga: wielkość liter ma "
|
||||
"znaczenie."
|
||||
|
||||
#: contrib/admin/views/decorators.py:62
|
||||
#: contrib/admin/views/decorators.py:63
|
||||
msgid ""
|
||||
"Please log in again, because your session has expired. Don't worry: Your "
|
||||
"submission has been saved."
|
||||
@ -807,7 +807,7 @@ msgstr ""
|
||||
"Zaloguj się ponownie. Twoja sesja wygasła lecz twoje zgłoszenie zostało "
|
||||
"zapisane."
|
||||
|
||||
#: contrib/admin/views/decorators.py:69
|
||||
#: contrib/admin/views/decorators.py:70
|
||||
msgid ""
|
||||
"Looks like your browser isn't configured to accept cookies. Please enable "
|
||||
"cookies, reload this page, and try again."
|
||||
@ -815,246 +815,246 @@ msgstr ""
|
||||
"Twoja przeglądarka nie chce akceptować ciasteczek. Zmień jej ustawienia i "
|
||||
"spróbuj ponownie."
|
||||
|
||||
#: contrib/admin/views/decorators.py:83
|
||||
#: contrib/admin/views/decorators.py:84
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
msgstr "Nazwy użytkowników nie mogą zawierać znaków '@'."
|
||||
|
||||
#: contrib/admin/views/decorators.py:85
|
||||
#: contrib/admin/views/decorators.py:86
|
||||
#, python-format
|
||||
msgid "Your e-mail address is not your username. Try '%s' instead."
|
||||
msgstr "Twój adres e-mail to nie jest twój login. Spróbuj '%s'."
|
||||
|
||||
#: contrib/admin/views/doc.py:47 contrib/admin/views/doc.py:49
|
||||
#: contrib/admin/views/doc.py:51
|
||||
#: contrib/admin/views/doc.py:48 contrib/admin/views/doc.py:50
|
||||
#: contrib/admin/views/doc.py:52
|
||||
msgid "tag:"
|
||||
msgstr "tag:"
|
||||
|
||||
#: contrib/admin/views/doc.py:78 contrib/admin/views/doc.py:80
|
||||
#: contrib/admin/views/doc.py:82
|
||||
#: contrib/admin/views/doc.py:79 contrib/admin/views/doc.py:81
|
||||
#: contrib/admin/views/doc.py:83
|
||||
msgid "filter:"
|
||||
msgstr "filtr:"
|
||||
|
||||
#: contrib/admin/views/doc.py:136 contrib/admin/views/doc.py:138
|
||||
#: contrib/admin/views/doc.py:140
|
||||
#: contrib/admin/views/doc.py:137 contrib/admin/views/doc.py:139
|
||||
#: contrib/admin/views/doc.py:141
|
||||
msgid "view:"
|
||||
msgstr "widok:"
|
||||
|
||||
#: contrib/admin/views/doc.py:165
|
||||
#: contrib/admin/views/doc.py:166
|
||||
#, python-format
|
||||
msgid "App %r not found"
|
||||
msgstr "Aplikacja %r nie została znaleziona"
|
||||
|
||||
#: contrib/admin/views/doc.py:172
|
||||
#: contrib/admin/views/doc.py:173
|
||||
#, python-format
|
||||
msgid "Model %(name)r not found in app %(label)r"
|
||||
msgstr "Model %(name)r nie został znaleziony w aplikacji %(label)r"
|
||||
|
||||
#: contrib/admin/views/doc.py:184
|
||||
#: contrib/admin/views/doc.py:185
|
||||
#, python-format
|
||||
msgid "the related `%(label)s.%(type)s` object"
|
||||
msgstr "powiązany obiekt `%(label)s.%(type)s`"
|
||||
|
||||
#: contrib/admin/views/doc.py:184 contrib/admin/views/doc.py:206
|
||||
#: contrib/admin/views/doc.py:220 contrib/admin/views/doc.py:225
|
||||
#: contrib/admin/views/doc.py:185 contrib/admin/views/doc.py:207
|
||||
#: contrib/admin/views/doc.py:221 contrib/admin/views/doc.py:226
|
||||
msgid "model:"
|
||||
msgstr "model:"
|
||||
|
||||
#: contrib/admin/views/doc.py:215
|
||||
#: contrib/admin/views/doc.py:216
|
||||
#, python-format
|
||||
msgid "related `%(label)s.%(name)s` objects"
|
||||
msgstr "powiązane obiekty `%(label)s.%(name)s`"
|
||||
|
||||
#: contrib/admin/views/doc.py:220
|
||||
#: contrib/admin/views/doc.py:221
|
||||
#, python-format
|
||||
msgid "all %s"
|
||||
msgstr "wszystkie %s"
|
||||
|
||||
#: contrib/admin/views/doc.py:225
|
||||
#: contrib/admin/views/doc.py:226
|
||||
#, python-format
|
||||
msgid "number of %s"
|
||||
msgstr "liczba %s"
|
||||
|
||||
#: contrib/admin/views/doc.py:230
|
||||
#: contrib/admin/views/doc.py:231
|
||||
#, python-format
|
||||
msgid "Fields on %s objects"
|
||||
msgstr "Pola obiektów %s"
|
||||
|
||||
#: contrib/admin/views/doc.py:292 contrib/admin/views/doc.py:303
|
||||
#: contrib/admin/views/doc.py:305 contrib/admin/views/doc.py:311
|
||||
#: contrib/admin/views/doc.py:312 contrib/admin/views/doc.py:314
|
||||
#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:304
|
||||
#: contrib/admin/views/doc.py:306 contrib/admin/views/doc.py:312
|
||||
#: contrib/admin/views/doc.py:313 contrib/admin/views/doc.py:315
|
||||
msgid "Integer"
|
||||
msgstr "Liczba całkowita"
|
||||
|
||||
#: contrib/admin/views/doc.py:293
|
||||
#: contrib/admin/views/doc.py:294
|
||||
msgid "Boolean (Either True or False)"
|
||||
msgstr "Wartość logiczna (True, False - prawda lub fałsz)"
|
||||
|
||||
#: contrib/admin/views/doc.py:294 contrib/admin/views/doc.py:313
|
||||
#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:314
|
||||
#, python-format
|
||||
msgid "String (up to %(max_length)s)"
|
||||
msgstr "Łańcuch (do %(max_length)s znaków)"
|
||||
|
||||
#: contrib/admin/views/doc.py:295
|
||||
#: contrib/admin/views/doc.py:296
|
||||
msgid "Comma-separated integers"
|
||||
msgstr "Liczby całkowite rozdzielone przecinkami"
|
||||
|
||||
#: contrib/admin/views/doc.py:296
|
||||
#: contrib/admin/views/doc.py:297
|
||||
msgid "Date (without time)"
|
||||
msgstr "Data (bez godziny)"
|
||||
|
||||
#: contrib/admin/views/doc.py:297
|
||||
#: contrib/admin/views/doc.py:298
|
||||
msgid "Date (with time)"
|
||||
msgstr "Data (z godziną)"
|
||||
|
||||
#: contrib/admin/views/doc.py:298
|
||||
#: contrib/admin/views/doc.py:299
|
||||
msgid "Decimal number"
|
||||
msgstr "Numer dziesiętny"
|
||||
|
||||
#: contrib/admin/views/doc.py:299
|
||||
#: contrib/admin/views/doc.py:300
|
||||
msgid "E-mail address"
|
||||
msgstr "Adres e-mail"
|
||||
|
||||
#: contrib/admin/views/doc.py:300 contrib/admin/views/doc.py:301
|
||||
#: contrib/admin/views/doc.py:304
|
||||
#: contrib/admin/views/doc.py:301 contrib/admin/views/doc.py:302
|
||||
#: contrib/admin/views/doc.py:305
|
||||
msgid "File path"
|
||||
msgstr "Ścieżka do pliku"
|
||||
|
||||
#: contrib/admin/views/doc.py:302
|
||||
#: contrib/admin/views/doc.py:303
|
||||
msgid "Floating point number"
|
||||
msgstr "Liczba zmiennoprzecinkowa"
|
||||
|
||||
#: contrib/admin/views/doc.py:306 contrib/comments/models.py:85
|
||||
#: contrib/admin/views/doc.py:307 contrib/comments/models.py:85
|
||||
msgid "IP address"
|
||||
msgstr "Adres IP"
|
||||
|
||||
#: contrib/admin/views/doc.py:308
|
||||
#: contrib/admin/views/doc.py:309
|
||||
msgid "Boolean (Either True, False or None)"
|
||||
msgstr "Wartość logiczna (True, False, None - prawda, fałsz lub nic)"
|
||||
|
||||
#: contrib/admin/views/doc.py:309
|
||||
#: contrib/admin/views/doc.py:310
|
||||
msgid "Relation to parent model"
|
||||
msgstr "Relacja do modelu rodzica"
|
||||
|
||||
#: contrib/admin/views/doc.py:310
|
||||
#: contrib/admin/views/doc.py:311
|
||||
msgid "Phone number"
|
||||
msgstr "Numer telefonu"
|
||||
|
||||
#: contrib/admin/views/doc.py:315
|
||||
#: contrib/admin/views/doc.py:316
|
||||
msgid "Text"
|
||||
msgstr "Tekst"
|
||||
|
||||
#: contrib/admin/views/doc.py:316
|
||||
#: contrib/admin/views/doc.py:317
|
||||
msgid "Time"
|
||||
msgstr "Czas"
|
||||
|
||||
#: contrib/admin/views/doc.py:317 contrib/flatpages/models.py:7
|
||||
#: contrib/admin/views/doc.py:318 contrib/flatpages/models.py:7
|
||||
msgid "URL"
|
||||
msgstr "URL"
|
||||
|
||||
#: contrib/admin/views/doc.py:318
|
||||
#: contrib/admin/views/doc.py:319
|
||||
msgid "U.S. state (two uppercase letters)"
|
||||
msgstr "Stan USA (dwie duże litery)"
|
||||
|
||||
#: contrib/admin/views/doc.py:319
|
||||
#: contrib/admin/views/doc.py:320
|
||||
msgid "XML text"
|
||||
msgstr "Tekst XML"
|
||||
|
||||
#: contrib/admin/views/doc.py:345
|
||||
#: contrib/admin/views/doc.py:346
|
||||
#, python-format
|
||||
msgid "%s does not appear to be a urlpattern object"
|
||||
msgstr "%s nie jest obiektem urlpattern"
|
||||
|
||||
#: contrib/admin/views/main.py:230
|
||||
#: contrib/admin/views/main.py:233
|
||||
msgid "Site administration"
|
||||
msgstr "Administracja stroną"
|
||||
|
||||
#: contrib/admin/views/main.py:278 contrib/admin/views/main.py:363
|
||||
#: contrib/admin/views/main.py:281 contrib/admin/views/main.py:366
|
||||
#, python-format
|
||||
msgid "You may add another %s below."
|
||||
msgstr "Możesz dodać nowy wpis %s poniżej."
|
||||
|
||||
#: contrib/admin/views/main.py:296
|
||||
#: contrib/admin/views/main.py:299
|
||||
#, python-format
|
||||
msgid "Add %s"
|
||||
msgstr "Dodaj %s"
|
||||
|
||||
#: contrib/admin/views/main.py:342
|
||||
#: contrib/admin/views/main.py:345
|
||||
#, python-format
|
||||
msgid "Added %s."
|
||||
msgstr "Dodano %s"
|
||||
|
||||
#: contrib/admin/views/main.py:342 contrib/admin/views/main.py:344
|
||||
#: contrib/admin/views/main.py:346 core/validators.py:283
|
||||
#: contrib/admin/views/main.py:345 contrib/admin/views/main.py:347
|
||||
#: contrib/admin/views/main.py:349 core/validators.py:283
|
||||
#: db/models/manipulators.py:309
|
||||
msgid "and"
|
||||
msgstr "i"
|
||||
|
||||
#: contrib/admin/views/main.py:344
|
||||
#: contrib/admin/views/main.py:347
|
||||
#, python-format
|
||||
msgid "Changed %s."
|
||||
msgstr "Zmieniono %s"
|
||||
|
||||
#: contrib/admin/views/main.py:346
|
||||
#: contrib/admin/views/main.py:349
|
||||
#, python-format
|
||||
msgid "Deleted %s."
|
||||
msgstr "Skasowano %s"
|
||||
|
||||
#: contrib/admin/views/main.py:349
|
||||
#: contrib/admin/views/main.py:352
|
||||
msgid "No fields changed."
|
||||
msgstr "Żadne pole nie zmienione."
|
||||
|
||||
#: contrib/admin/views/main.py:352
|
||||
#: contrib/admin/views/main.py:355
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was changed successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" zostało pomyślnie zmienione."
|
||||
|
||||
#: contrib/admin/views/main.py:360
|
||||
#: contrib/admin/views/main.py:363
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr ""
|
||||
"%(name)s \"%(obj)s\" dodane pomyślnie. Możesz edytować ponownie wpis poniżej."
|
||||
|
||||
#: contrib/admin/views/main.py:398
|
||||
#: contrib/admin/views/main.py:401
|
||||
#, python-format
|
||||
msgid "Change %s"
|
||||
msgstr "Zmień %s"
|
||||
|
||||
#: contrib/admin/views/main.py:483
|
||||
#: contrib/admin/views/main.py:488
|
||||
#, python-format
|
||||
msgid "One or more %(fieldname)s in %(name)s: %(obj)s"
|
||||
msgstr "Jedno lub więcej %(fieldname)s w %(name)s: %(obj)s"
|
||||
|
||||
#: contrib/admin/views/main.py:488
|
||||
#: contrib/admin/views/main.py:493
|
||||
#, python-format
|
||||
msgid "One or more %(fieldname)s in %(name)s:"
|
||||
msgstr "Jedno lub więcej %(fieldname)s w %(name)s:"
|
||||
|
||||
#: contrib/admin/views/main.py:520
|
||||
#: contrib/admin/views/main.py:525
|
||||
#, python-format
|
||||
msgid "The %(name)s \"%(obj)s\" was deleted successfully."
|
||||
msgstr "%(name)s \"%(obj)s\" usunięty pomyślnie."
|
||||
|
||||
#: contrib/admin/views/main.py:523
|
||||
#: contrib/admin/views/main.py:528
|
||||
msgid "Are you sure?"
|
||||
msgstr "Jesteś pewien?"
|
||||
|
||||
#: contrib/admin/views/main.py:545
|
||||
#: contrib/admin/views/main.py:550
|
||||
#, python-format
|
||||
msgid "Change history: %s"
|
||||
msgstr "Historia zmian: %s"
|
||||
|
||||
#: contrib/admin/views/main.py:579
|
||||
#: contrib/admin/views/main.py:584
|
||||
#, python-format
|
||||
msgid "Select %s"
|
||||
msgstr "Zaznacz %s"
|
||||
|
||||
#: contrib/admin/views/main.py:579
|
||||
#: contrib/admin/views/main.py:584
|
||||
#, python-format
|
||||
msgid "Select %s to change"
|
||||
msgstr "Zaznacz %s aby zmienić"
|
||||
|
||||
#: contrib/admin/views/main.py:780
|
||||
#: contrib/admin/views/main.py:785
|
||||
msgid "Database error"
|
||||
msgstr "Błąd bazy danych"
|
||||
|
||||
@ -1618,7 +1618,7 @@ msgstr "-gi"
|
||||
msgid "rd"
|
||||
msgstr "-ci"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:50
|
||||
#: contrib/humanize/templatetags/humanize.py:52
|
||||
#, python-format
|
||||
msgid "%(value).1f million"
|
||||
msgid_plural "%(value).1f million"
|
||||
@ -1626,7 +1626,7 @@ msgstr[0] "%(value).1f milion"
|
||||
msgstr[1] "%(value).1f miliony"
|
||||
msgstr[2] "%(value).1f milionów"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:53
|
||||
#: contrib/humanize/templatetags/humanize.py:55
|
||||
#, python-format
|
||||
msgid "%(value).1f billion"
|
||||
msgid_plural "%(value).1f billion"
|
||||
@ -1634,7 +1634,7 @@ msgstr[0] "%(value).1f miliard"
|
||||
msgstr[1] "%(value).1f miliardy"
|
||||
msgstr[2] "%(value).1f miliardów"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:56
|
||||
#: contrib/humanize/templatetags/humanize.py:58
|
||||
#, python-format
|
||||
msgid "%(value).1f trillion"
|
||||
msgid_plural "%(value).1f trillion"
|
||||
@ -1642,51 +1642,51 @@ msgstr[0] "%(value).1f bilion"
|
||||
msgstr[1] "%(value).1f biliony"
|
||||
msgstr[2] "%(value).1f bilionów"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "one"
|
||||
msgstr "jeden"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "two"
|
||||
msgstr "dwa"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "three"
|
||||
msgstr "trzy"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "four"
|
||||
msgstr "cztery"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "five"
|
||||
msgstr "pięć"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "six"
|
||||
msgstr "sześć"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "seven"
|
||||
msgstr "siedem"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "eight"
|
||||
msgstr "osiem"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:71
|
||||
#: contrib/humanize/templatetags/humanize.py:74
|
||||
msgid "nine"
|
||||
msgstr "dziewięć"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:90
|
||||
#: contrib/humanize/templatetags/humanize.py:94
|
||||
msgid "today"
|
||||
msgstr "dzisiaj"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:92
|
||||
#: contrib/humanize/templatetags/humanize.py:96
|
||||
msgid "tomorrow"
|
||||
msgstr "jutro"
|
||||
|
||||
#: contrib/humanize/templatetags/humanize.py:94
|
||||
#: contrib/humanize/templatetags/humanize.py:98
|
||||
msgid "yesterday"
|
||||
msgstr "wczoraj"
|
||||
|
||||
@ -1705,8 +1705,7 @@ msgstr "To pole musi zawierać 7 lub 8 cyfr."
|
||||
|
||||
#: contrib/localflavor/ar/forms.py:75
|
||||
msgid "Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format."
|
||||
msgstr ""
|
||||
"Podaj poprawny numer CUIT w formacie XX-XXXXXXXX-X lub XXXXXXXXXXXX."
|
||||
msgstr "Podaj poprawny numer CUIT w formacie XX-XXXXXXXX-X lub XXXXXXXXXXXX."
|
||||
|
||||
#: contrib/localflavor/ar/forms.py:88
|
||||
msgid "Invalid CUIT."
|
||||
@ -1725,11 +1724,12 @@ msgid "Phone numbers must be in XX-XXXX-XXXX format."
|
||||
msgstr "Numery telefoniczne muszą być w formacie XX-XXXX-XXXX."
|
||||
|
||||
#: contrib/localflavor/br/forms.py:68
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Select a valid brazilian state. That state is not one of the available "
|
||||
"states."
|
||||
msgstr "Wybierz poprawną wartość. Podana nie jest jednym z dostępnych wyborów."
|
||||
msgstr ""
|
||||
"Wybierz poprawny brazylijski stan. Ten stan nie jest jednym z dostępnych "
|
||||
"stanów."
|
||||
|
||||
#: contrib/localflavor/br/forms.py:105
|
||||
msgid "This field requires at most 11 digits or 14 characters."
|
||||
@ -1748,14 +1748,13 @@ msgid "Invalid CNPJ number."
|
||||
msgstr "Błędny numer CNPJ."
|
||||
|
||||
#: contrib/localflavor/ca/forms.py:19
|
||||
#, fuzzy
|
||||
msgid "Enter a postal code in the format XXX XXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXX XXX."
|
||||
|
||||
#: contrib/localflavor/ca/forms.py:81
|
||||
#, fuzzy
|
||||
msgid "Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format."
|
||||
msgstr "Wpisz poprawny numer U.S. Social Security w formacie XXX-XX-XXXX."
|
||||
msgstr ""
|
||||
"Wpisz poprawny numer kanadyjskiego ubezpieczenia w formacie XXX-XXX-XXXX."
|
||||
|
||||
#: contrib/localflavor/ch/ch_states.py:5
|
||||
msgid "Aargau"
|
||||
@ -1870,7 +1869,7 @@ msgid ""
|
||||
"Enter a valid Swiss identity or passport card number in X1234567<0 or "
|
||||
"1234567890 format."
|
||||
msgstr ""
|
||||
"Podaj poprawny numer szwajarskiego dowodu osobistego lub paszportu w "
|
||||
"Podaj poprawny numer szwajcarskiego dowodu osobistego lub paszportu w "
|
||||
"formacie X1234567<0 lub 1234567890."
|
||||
|
||||
#: contrib/localflavor/cl/forms.py:32
|
||||
@ -2237,16 +2236,15 @@ msgid "Valencian Community"
|
||||
msgstr ""
|
||||
|
||||
#: contrib/localflavor/es/forms.py:22
|
||||
#, fuzzy
|
||||
msgid "Enter a valid postal code in the range and format 01XXX - 52XXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXXXX lub XXX-XXXX."
|
||||
msgstr "Wpisz kod pocztowy w zakresie i formacie 01XXX - 52XX."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:39
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or "
|
||||
"9XXXXXXXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXXXX lub XXX-XXXX."
|
||||
msgstr ""
|
||||
"Wpisz numer telefoniczny w formacie 6XXXXXXXX, 8XXXXXXXX lub 9XXXXXXXX."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:73 contrib/localflavor/es/forms.py:108
|
||||
#: db/models/fields/related.py:55
|
||||
@ -2256,36 +2254,33 @@ msgstr "Proszę wpisać poprawne %s."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:91
|
||||
msgid "Invalid checksum for NIF."
|
||||
msgstr ""
|
||||
msgstr "Niepoprawna suma kontrolna NIF."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:97
|
||||
msgid "Invalid checksum for NIE."
|
||||
msgstr ""
|
||||
msgstr "Niepoprawna suma kontrolna NIE."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:106
|
||||
msgid "Invalid checksum for CIF."
|
||||
msgstr ""
|
||||
msgstr "Niepoprawna suma kontrolna CIF."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:136
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX."
|
||||
msgstr ""
|
||||
"Podaj poprawny niemiecki numer dowodu osobistego w formacie XXXXXXXXXXX-"
|
||||
"XXXXXXX-XXXXXXX-X."
|
||||
"Podaj poprawny numer konta bankowego w formacie XXXX-XXXX-XX-XXXXXXXXXX."
|
||||
|
||||
#: contrib/localflavor/es/forms.py:150
|
||||
msgid "Invalid checksum for bank account number."
|
||||
msgstr ""
|
||||
msgstr "Niepoprawna suma kontrolna numeru konta bankowego."
|
||||
|
||||
#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
|
||||
msgid "Enter a valid Finnish social security number."
|
||||
msgstr "Wpis poprawny numer fińskiego ubezpieczenia socjalnego."
|
||||
|
||||
#: contrib/localflavor/in_/forms.py:16
|
||||
#, fuzzy
|
||||
msgid "Enter a zip code in the format XXXXXXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXX-XXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXXXX."
|
||||
|
||||
#: contrib/localflavor/is_/forms.py:17
|
||||
msgid ""
|
||||
@ -2502,19 +2497,16 @@ msgid "Okinawa"
|
||||
msgstr ""
|
||||
|
||||
#: contrib/localflavor/nl/forms.py:25
|
||||
#, fuzzy
|
||||
msgid "Enter a valid postal code"
|
||||
msgstr "Wpisz poprawny kod pocztowy."
|
||||
|
||||
#: contrib/localflavor/nl/forms.py:53
|
||||
#, fuzzy
|
||||
msgid "Enter a valid phone number"
|
||||
msgstr "Wpisz poprawny numer VAT."
|
||||
msgstr "Wpisz poprawny numer telefonu."
|
||||
|
||||
#: contrib/localflavor/nl/forms.py:76
|
||||
#, fuzzy
|
||||
msgid "Enter a valid SoFi number"
|
||||
msgstr "Wpisz poprawny numer VAT."
|
||||
msgstr "Wpisz poprawny numer SoFi."
|
||||
|
||||
#: contrib/localflavor/nl/nl_provinces.py:4
|
||||
#, fuzzy
|
||||
@ -2574,13 +2566,12 @@ msgid "Enter a valid Norwegian social security number."
|
||||
msgstr "Wpis poprawny numer norweskiego ubezpieczenia socjalnego."
|
||||
|
||||
#: contrib/localflavor/pe/forms.py:36
|
||||
#, fuzzy
|
||||
msgid "This field requires 8 digits."
|
||||
msgstr "To pole musi zawierać co najmniej 14 cyfr."
|
||||
msgstr "To pole musi zawierać 8 cyfr."
|
||||
|
||||
#: contrib/localflavor/pe/forms.py:59
|
||||
msgid "This field requires 11 digits."
|
||||
msgstr "To pole musi zawierać co najmniej 11 cyfr."
|
||||
msgstr "To pole musi zawierać 11 cyfr."
|
||||
|
||||
#: contrib/localflavor/pl/forms.py:41
|
||||
msgid "National Identification Number consists of 11 digits."
|
||||
@ -2676,9 +2667,8 @@ msgid "West Pomerania"
|
||||
msgstr "Zachodniopomorskie"
|
||||
|
||||
#: contrib/localflavor/sk/forms.py:32
|
||||
#, fuzzy
|
||||
msgid "Enter a postal code in the format XXXXX or XXX XX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXXXX lub XXX-XXXX."
|
||||
msgstr "Wpisz kod pocztowy w formacie XXXXX or XXX XX."
|
||||
|
||||
#: contrib/localflavor/sk/sk_districts.py:8
|
||||
msgid "Banska Bystrica"
|
||||
@ -3198,7 +3188,7 @@ msgid "Enter a valid e-mail address."
|
||||
msgstr "Wprowadź poprawny adres e-mail."
|
||||
|
||||
#: core/validators.py:182 core/validators.py:474 newforms/fields.py:438
|
||||
#: oldforms/__init__.py:686
|
||||
#: oldforms/__init__.py:687
|
||||
msgid "No file was submitted. Check the encoding type on the form."
|
||||
msgstr "Nie wysłano żadnego pliku. Sprawdź typ kodowania formularza."
|
||||
|
||||
@ -3460,7 +3450,7 @@ msgstr "Już istnieje %(optname)s z %(fieldname)s."
|
||||
|
||||
#: db/models/fields/__init__.py:161 db/models/fields/__init__.py:318
|
||||
#: db/models/fields/__init__.py:735 db/models/fields/__init__.py:746
|
||||
#: newforms/fields.py:45 newforms/models.py:220 oldforms/__init__.py:373
|
||||
#: newforms/fields.py:45 newforms/models.py:220 oldforms/__init__.py:374
|
||||
msgid "This field is required."
|
||||
msgstr "To pole jest wymagane."
|
||||
|
||||
@ -3523,15 +3513,15 @@ msgstr "Wpisz poprawną wartość."
|
||||
#, python-format
|
||||
msgid "Ensure this value has at most %(max)d characters (it has %(length)d)."
|
||||
msgstr ""
|
||||
"Upewnij się, że ta wartość ma co najwyżej %(max)d znaków "
|
||||
"(ma długość %(length)d)."
|
||||
"Upewnij się, że ta wartość ma co najwyżej %(max)d znaków (ma długość %"
|
||||
"(length)d)."
|
||||
|
||||
#: newforms/fields.py:130
|
||||
#, python-format
|
||||
msgid "Ensure this value has at least %(min)d characters (it has %(length)d)."
|
||||
msgstr ""
|
||||
"Upewnij się, że ta wartość ma co najmniej %(min)d znaków "
|
||||
"(ma długość %(length)d)."
|
||||
"Upewnij się, że ta wartość ma co najmniej %(min)d znaków (ma długość %"
|
||||
"(length)d)."
|
||||
|
||||
#: newforms/fields.py:158 newforms/fields.py:187 newforms/fields.py:216
|
||||
#, python-format
|
||||
@ -3578,7 +3568,7 @@ msgstr "Wpisz poprawną datę/godzinę."
|
||||
msgid "No file was submitted."
|
||||
msgstr "Żaden plik nie został przesłany."
|
||||
|
||||
#: newforms/fields.py:440 oldforms/__init__.py:688
|
||||
#: newforms/fields.py:440 oldforms/__init__.py:689
|
||||
msgid "The submitted file is empty."
|
||||
msgstr "Wysłany plik jest pusty."
|
||||
|
||||
@ -3613,7 +3603,7 @@ msgstr "Wprowadź poprawny adres IPv4."
|
||||
msgid "Select a valid choice. %s is not one of the available choices."
|
||||
msgstr "Wybierz poprawną wartość. %s nie jest jednym z dostępnych wyborów."
|
||||
|
||||
#: oldforms/__init__.py:408
|
||||
#: oldforms/__init__.py:409
|
||||
#, python-format
|
||||
msgid "Ensure your text is less than %s character."
|
||||
msgid_plural "Ensure your text is less than %s characters."
|
||||
@ -3621,32 +3611,32 @@ msgstr[0] "Upewnij się, że tekst ma mniej niż %s znak."
|
||||
msgstr[1] "Upewnij się, że tekst ma mniej niż %s znaki."
|
||||
msgstr[2] "Upewnij się, że tekst ma mniej niż %s znaków."
|
||||
|
||||
#: oldforms/__init__.py:413
|
||||
#: oldforms/__init__.py:414
|
||||
msgid "Line breaks are not allowed here."
|
||||
msgstr "Znaki nowej linii są tutaj niedopuszczalne."
|
||||
|
||||
#: oldforms/__init__.py:511 oldforms/__init__.py:585 oldforms/__init__.py:624
|
||||
#: oldforms/__init__.py:512 oldforms/__init__.py:586 oldforms/__init__.py:625
|
||||
#, python-format
|
||||
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
|
||||
msgstr "Wybierz poprawną opcję; '%(data)s' nie jest wśród %(choices)s."
|
||||
|
||||
#: oldforms/__init__.py:744
|
||||
#: oldforms/__init__.py:745
|
||||
msgid "Enter a whole number between -32,768 and 32,767."
|
||||
msgstr "Proszę wpisać liczbę całkowitą z zakresu od -32 768 do 32 767"
|
||||
|
||||
#: oldforms/__init__.py:754
|
||||
#: oldforms/__init__.py:755
|
||||
msgid "Enter a positive number."
|
||||
msgstr "Proszę wpisać liczbę dodatnią."
|
||||
|
||||
#: oldforms/__init__.py:764
|
||||
#: oldforms/__init__.py:765
|
||||
msgid "Enter a whole number between 0 and 32,767."
|
||||
msgstr "Proszę wpisać liczbę całkowitą z zakresu od 0 do 32 767"
|
||||
|
||||
#: template/defaultfilters.py:555
|
||||
#: template/defaultfilters.py:655
|
||||
msgid "yes,no,maybe"
|
||||
msgstr "tak,nie,może"
|
||||
|
||||
#: template/defaultfilters.py:585
|
||||
#: template/defaultfilters.py:686
|
||||
#, python-format
|
||||
msgid "%(size)d byte"
|
||||
msgid_plural "%(size)d bytes"
|
||||
@ -3654,17 +3644,17 @@ msgstr[0] "%(size)d bajt"
|
||||
msgstr[1] "%(size)d bajty"
|
||||
msgstr[2] "%(size)d bajtów"
|
||||
|
||||
#: template/defaultfilters.py:587
|
||||
#: template/defaultfilters.py:688
|
||||
#, python-format
|
||||
msgid "%.1f KB"
|
||||
msgstr "%.1f KB"
|
||||
|
||||
#: template/defaultfilters.py:589
|
||||
#: template/defaultfilters.py:690
|
||||
#, python-format
|
||||
msgid "%.1f MB"
|
||||
msgstr "%.1f MB"
|
||||
|
||||
#: template/defaultfilters.py:590
|
||||
#: template/defaultfilters.py:691
|
||||
#, python-format
|
||||
msgid "%.1f GB"
|
||||
msgstr "%.1f GB"
|
||||
|
@ -4,11 +4,11 @@
|
||||
*/
|
||||
|
||||
/* Block IE 5 */
|
||||
@import "null?\"\{";
|
||||
@import "null.css?\"\{";
|
||||
|
||||
/* Import other styles */
|
||||
@import url('global.css');
|
||||
@import url('layout.css');
|
||||
|
||||
/* Import patch for IE 6 Windows */
|
||||
/*\*/ @import "patch-iewin.css"; /**/
|
||||
/*\*/ @import "patch-iewin.css"; /**/
|
||||
|
@ -1,6 +1,16 @@
|
||||
// Handles related-objects functionality: lookup link for raw_id_admin=True
|
||||
// and Add Another links.
|
||||
|
||||
function html_unescape(text) {
|
||||
// Unescape a string that was escaped using django.utils.html.escape.
|
||||
text = text.replace(/</g, '<');
|
||||
text = text.replace(/>/g, '>');
|
||||
text = text.replace(/"/g, '"');
|
||||
text = text.replace(/'/g, "'");
|
||||
text = text.replace(/&/g, '&');
|
||||
return text;
|
||||
}
|
||||
|
||||
function showRelatedObjectLookupPopup(triggeringLink) {
|
||||
var name = triggeringLink.id.replace(/^lookup_/, '');
|
||||
// IE doesn't like periods in the window name, so convert temporarily.
|
||||
@ -42,6 +52,10 @@ function showAddAnotherPopup(triggeringLink) {
|
||||
}
|
||||
|
||||
function dismissAddAnotherPopup(win, newId, newRepr) {
|
||||
// newId and newRepr are expected to have previously been escaped by
|
||||
// django.utils.html.escape.
|
||||
newId = html_unescape(newId);
|
||||
newRepr = html_unescape(newRepr);
|
||||
var name = win.name.replace(/___/g, '.');
|
||||
var elem = document.getElementById(name);
|
||||
if (elem) {
|
||||
|
@ -148,6 +148,8 @@ def items_for_result(cl, result):
|
||||
# function has an "allow_tags" attribute set to True.
|
||||
if not allow_tags:
|
||||
result_repr = escape(result_repr)
|
||||
else:
|
||||
result_repr = mark_safe(result_repr)
|
||||
else:
|
||||
field_val = getattr(result, f.attname)
|
||||
|
||||
@ -185,7 +187,7 @@ def items_for_result(cl, result):
|
||||
else:
|
||||
result_repr = escape(field_val)
|
||||
if force_unicode(result_repr) == '':
|
||||
result_repr = ' '
|
||||
result_repr = mark_safe(' ')
|
||||
# If list_display_links not defined, add the link tag to the first field
|
||||
if (first and not cl.lookup_opts.admin.list_display_links) or field_name in cl.lookup_opts.admin.list_display_links:
|
||||
table_tag = {True:'th', False:'td'}[first]
|
||||
|
@ -118,7 +118,7 @@ class FieldWrapper(object):
|
||||
return not isinstance(self.field, models.AutoField)
|
||||
|
||||
def header_class_attribute(self):
|
||||
return self.field.blank and ' class="optional"' or ''
|
||||
return self.field.blank and mark_safe(' class="optional"') or ''
|
||||
|
||||
def use_raw_id_admin(self):
|
||||
return isinstance(self.field.rel, (models.ManyToOneRel, models.ManyToManyRel)) \
|
||||
|
@ -273,10 +273,9 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
|
||||
post_url_continue += "?_popup=1"
|
||||
return HttpResponseRedirect(post_url_continue % pk_value)
|
||||
if "_popup" in request.POST:
|
||||
if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
|
||||
pk_value = '"%s"' % pk_value.replace('"', '\\"')
|
||||
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
|
||||
(pk_value, force_unicode(new_object).replace('"', '\\"')))
|
||||
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
|
||||
# escape() calls force_unicode.
|
||||
(escape(pk_value), escape(new_object)))
|
||||
elif "_addanother" in request.POST:
|
||||
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
|
||||
return HttpResponseRedirect(request.path)
|
||||
|
7
django/core/cache/backends/locmem.py
vendored
7
django/core/cache/backends/locmem.py
vendored
@ -16,8 +16,12 @@ class CacheClass(SimpleCacheClass):
|
||||
|
||||
def add(self, key, value, timeout=None):
|
||||
self._lock.writer_enters()
|
||||
# Python 2.3 and 2.4 don't allow combined try-except-finally blocks.
|
||||
try:
|
||||
SimpleCacheClass.add(self, key, value, timeout)
|
||||
try:
|
||||
super(CacheClass, self).add(key, pickle.dumps(value), timeout)
|
||||
except pickle.PickleError:
|
||||
pass
|
||||
finally:
|
||||
self._lock.writer_leaves()
|
||||
|
||||
@ -49,6 +53,7 @@ class CacheClass(SimpleCacheClass):
|
||||
|
||||
def set(self, key, value, timeout=None):
|
||||
self._lock.writer_enters()
|
||||
# Python 2.3 and 2.4 don't allow combined try-except-finally blocks.
|
||||
try:
|
||||
try:
|
||||
super(CacheClass, self).set(key, pickle.dumps(value), timeout)
|
||||
|
@ -52,7 +52,7 @@ def load_command_class(app_name, name):
|
||||
return getattr(__import__('%s.management.commands.%s' % (app_name, name),
|
||||
{}, {}, ['Command']), 'Command')()
|
||||
|
||||
def get_commands(load_user_commands=True, project_directory=None):
|
||||
def get_commands():
|
||||
"""
|
||||
Returns a dictionary of commands against the application in which
|
||||
those commands can be found. This works by looking for a
|
||||
@ -60,10 +60,10 @@ def get_commands(load_user_commands=True, project_directory=None):
|
||||
application -- if a commands package exists, all commands in that
|
||||
package are registered.
|
||||
|
||||
Core commands are always included; user-defined commands will also
|
||||
be included if ``load_user_commands`` is True. If a project directory
|
||||
is provided, the startproject command will be disabled, and the
|
||||
startapp command will be modified to use that directory.
|
||||
Core commands are always included. If a settings module has been
|
||||
specified, user-defined commands will also be included, the
|
||||
startproject command will be disabled, and the startapp command
|
||||
will be modified to use the directory in which that module appears.
|
||||
|
||||
The dictionary is in the format {command_name: app_name}. Key-value
|
||||
pairs from this dictionary can then be used in calls to
|
||||
@ -80,16 +80,27 @@ def get_commands(load_user_commands=True, project_directory=None):
|
||||
if _commands is None:
|
||||
_commands = dict([(name, 'django.core')
|
||||
for name in find_commands(__path__[0])])
|
||||
if load_user_commands:
|
||||
# Get commands from all installed apps.
|
||||
# Get commands from all installed apps.
|
||||
try:
|
||||
from django.conf import settings
|
||||
for app_name in settings.INSTALLED_APPS:
|
||||
try:
|
||||
path = find_management_module(app_name)
|
||||
_commands.update(dict([(name, app_name)
|
||||
for name in find_commands(path)]))
|
||||
except ImportError:
|
||||
pass # No management module - ignore this app
|
||||
apps = settings.INSTALLED_APPS
|
||||
except (AttributeError, EnvironmentError):
|
||||
apps = []
|
||||
|
||||
for app_name in apps:
|
||||
try:
|
||||
path = find_management_module(app_name)
|
||||
_commands.update(dict([(name, app_name)
|
||||
for name in find_commands(path)]))
|
||||
except ImportError:
|
||||
pass # No management module - ignore this app
|
||||
|
||||
# Try to determine the project directory
|
||||
try:
|
||||
from django.conf import settings
|
||||
project_directory = setup_environ(__import__(settings.SETTINGS_MODULE))
|
||||
except (AttributeError, EnvironmentError, ImportError):
|
||||
project_directory = None
|
||||
|
||||
if project_directory:
|
||||
# Remove the "startproject" command from self.commands, because
|
||||
@ -146,8 +157,6 @@ class ManagementUtility(object):
|
||||
def __init__(self, argv=None):
|
||||
self.argv = argv or sys.argv[:]
|
||||
self.prog_name = os.path.basename(self.argv[0])
|
||||
self.project_directory = None
|
||||
self.user_commands = False
|
||||
|
||||
def main_help_text(self):
|
||||
"""
|
||||
@ -159,8 +168,7 @@ class ManagementUtility(object):
|
||||
usage.append("Type '%s help <subcommand>' for help on a specific"
|
||||
" subcommand." % self.prog_name)
|
||||
usage.append('Available subcommands:')
|
||||
commands = get_commands(self.user_commands,
|
||||
self.project_directory).keys()
|
||||
commands = get_commands().keys()
|
||||
commands.sort()
|
||||
for cmd in commands:
|
||||
usage.append(' %s' % cmd)
|
||||
@ -173,8 +181,7 @@ class ManagementUtility(object):
|
||||
django-admin.py or manage.py) if it can't be found.
|
||||
"""
|
||||
try:
|
||||
app_name = get_commands(self.user_commands,
|
||||
self.project_directory)[subcommand]
|
||||
app_name = get_commands()[subcommand]
|
||||
if isinstance(app_name, BaseCommand):
|
||||
# If the command is already loaded, use it directly.
|
||||
klass = app_name
|
||||
@ -235,8 +242,6 @@ class ProjectManagementUtility(ManagementUtility):
|
||||
"""
|
||||
def __init__(self, argv, project_directory):
|
||||
super(ProjectManagementUtility, self).__init__(argv)
|
||||
self.project_directory = project_directory
|
||||
self.user_commands = True
|
||||
|
||||
def setup_environ(settings_mod):
|
||||
"""
|
||||
|
@ -91,7 +91,7 @@ class ObjectPaginator(object):
|
||||
a template for loop.
|
||||
"""
|
||||
if self._page_range is None:
|
||||
self._page_range = range(1, self._pages + 1)
|
||||
self._page_range = range(1, self.pages + 1)
|
||||
return self._page_range
|
||||
|
||||
hits = property(_get_hits)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import re
|
||||
|
||||
from django.utils.text import compress_string
|
||||
from django.utils.cache import patch_vary_headers
|
||||
|
||||
@ -11,18 +12,21 @@ class GZipMiddleware(object):
|
||||
on the Accept-Encoding header.
|
||||
"""
|
||||
def process_response(self, request, response):
|
||||
# It's not worth compressing non-OK or really short responses.
|
||||
if response.status_code != 200 or len(response.content) < 200:
|
||||
# Not worth compressing really short responses or 304 status
|
||||
# responses, etc.
|
||||
return response
|
||||
|
||||
patch_vary_headers(response, ('Accept-Encoding',))
|
||||
|
||||
# Avoid gzipping if we've already got a content-encoding or if the
|
||||
# content-type is Javascript and the user's browser is IE.
|
||||
is_js = ("msie" in request.META.get('HTTP_USER_AGENT', '').lower() and
|
||||
"javascript" in response.get('Content-Type', '').lower())
|
||||
if response.has_header('Content-Encoding') or is_js:
|
||||
# Avoid gzipping if we've already got a content-encoding.
|
||||
if response.has_header('Content-Encoding'):
|
||||
return response
|
||||
|
||||
# Older versions of IE have issues with gzipped javascript.
|
||||
# See http://code.djangoproject.com/ticket/2449
|
||||
is_ie = "msie" in request.META.get('HTTP_USER_AGENT', '').lower()
|
||||
is_js = "javascript" in response.get('Content-Type', '').lower()
|
||||
if is_ie and is_js:
|
||||
return response
|
||||
|
||||
ae = request.META.get('HTTP_ACCEPT_ENCODING', '')
|
||||
|
@ -6,6 +6,7 @@ import datetime
|
||||
|
||||
from django.newforms.widgets import Widget, Select
|
||||
from django.utils.dates import MONTHS
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
__all__ = ('SelectDateWidget',)
|
||||
|
||||
@ -51,7 +52,7 @@ class SelectDateWidget(Widget):
|
||||
select_html = Select(choices=year_choices).render(self.year_field % name, year_val)
|
||||
output.append(select_html)
|
||||
|
||||
return u'\n'.join(output)
|
||||
return mark_safe(u'\n'.join(output))
|
||||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name)
|
||||
|
@ -3,13 +3,13 @@ Helper functions for creating Form classes from Django models
|
||||
and database field objects.
|
||||
"""
|
||||
|
||||
from django.utils.translation import ugettext
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.utils.datastructures import SortedDict
|
||||
|
||||
from util import ValidationError
|
||||
from forms import BaseForm
|
||||
from fields import Field, ChoiceField
|
||||
from fields import Field, ChoiceField, EMPTY_VALUES
|
||||
from widgets import Select, SelectMultiple, MultipleHiddenInput
|
||||
|
||||
__all__ = (
|
||||
@ -151,15 +151,20 @@ class ModelChoiceField(ChoiceField):
|
||||
"""A ChoiceField whose choices are a model QuerySet."""
|
||||
# This class is a subclass of ChoiceField for purity, but it doesn't
|
||||
# actually use any of ChoiceField's implementation.
|
||||
default_error_messages = {
|
||||
'invalid_choice': _(u'Select a valid choice. That choice is not one of'
|
||||
u' the available choices.'),
|
||||
}
|
||||
|
||||
def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
|
||||
required=True, widget=Select, label=None, initial=None,
|
||||
help_text=None):
|
||||
help_text=None, *args, **kwargs):
|
||||
self.empty_label = empty_label
|
||||
self.cache_choices = cache_choices
|
||||
# Call Field instead of ChoiceField __init__() because we don't need
|
||||
# ChoiceField.__init__().
|
||||
Field.__init__(self, required, widget, label, initial, help_text)
|
||||
Field.__init__(self, required, widget, label, initial, help_text,
|
||||
*args, **kwargs)
|
||||
self.queryset = queryset
|
||||
|
||||
def _get_queryset(self):
|
||||
@ -195,41 +200,43 @@ class ModelChoiceField(ChoiceField):
|
||||
|
||||
def clean(self, value):
|
||||
Field.clean(self, value)
|
||||
if value in ('', None):
|
||||
if value in EMPTY_VALUES:
|
||||
return None
|
||||
try:
|
||||
value = self.queryset.get(pk=value)
|
||||
except self.queryset.model.DoesNotExist:
|
||||
raise ValidationError(ugettext(u'Select a valid choice. That'
|
||||
u' choice is not one of the'
|
||||
u' available choices.'))
|
||||
raise ValidationError(self.error_messages['invalid_choice'])
|
||||
return value
|
||||
|
||||
class ModelMultipleChoiceField(ModelChoiceField):
|
||||
"""A MultipleChoiceField whose choices are a model QuerySet."""
|
||||
hidden_widget = MultipleHiddenInput
|
||||
default_error_messages = {
|
||||
'list': _(u'Enter a list of values.'),
|
||||
'invalid_choice': _(u'Select a valid choice. %s is not one of the'
|
||||
u' available choices.'),
|
||||
}
|
||||
|
||||
def __init__(self, queryset, cache_choices=False, required=True,
|
||||
widget=SelectMultiple, label=None, initial=None,
|
||||
help_text=None):
|
||||
help_text=None, *args, **kwargs):
|
||||
super(ModelMultipleChoiceField, self).__init__(queryset, None,
|
||||
cache_choices, required, widget, label, initial, help_text)
|
||||
cache_choices, required, widget, label, initial, help_text,
|
||||
*args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
if self.required and not value:
|
||||
raise ValidationError(ugettext(u'This field is required.'))
|
||||
raise ValidationError(self.error_messages['required'])
|
||||
elif not self.required and not value:
|
||||
return []
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValidationError(ugettext(u'Enter a list of values.'))
|
||||
raise ValidationError(self.error_messages['list'])
|
||||
final_values = []
|
||||
for val in value:
|
||||
try:
|
||||
obj = self.queryset.get(pk=val)
|
||||
except self.queryset.model.DoesNotExist:
|
||||
raise ValidationError(ugettext(u'Select a valid choice. %s is'
|
||||
u' not one of the available'
|
||||
u' choices.') % val)
|
||||
raise ValidationError(self.error_messages['invalid_choice'] % val)
|
||||
else:
|
||||
final_values.append(obj)
|
||||
return final_values
|
||||
|
@ -11,7 +11,7 @@ import copy
|
||||
from itertools import chain
|
||||
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.html import escape
|
||||
from django.utils.html import escape, conditional_escape
|
||||
from django.utils.translation import ugettext
|
||||
from django.utils.encoding import StrAndUnicode, force_unicode
|
||||
from django.utils.safestring import mark_safe
|
||||
@ -155,7 +155,7 @@ class Textarea(Widget):
|
||||
value = force_unicode(value)
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs),
|
||||
escape(value)))
|
||||
conditional_escape(force_unicode(value))))
|
||||
|
||||
class DateTimeInput(Input):
|
||||
input_type = 'text'
|
||||
@ -217,7 +217,9 @@ class Select(Widget):
|
||||
for option_value, option_label in chain(self.choices, choices):
|
||||
option_value = force_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(force_unicode(option_label))))
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (
|
||||
escape(option_value), selected_html,
|
||||
conditional_escape(force_unicode(option_label))))
|
||||
output.append(u'</select>')
|
||||
return mark_safe(u'\n'.join(output))
|
||||
|
||||
@ -254,7 +256,9 @@ class SelectMultiple(Widget):
|
||||
for option_value, option_label in chain(self.choices, choices):
|
||||
option_value = force_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(force_unicode(option_label))))
|
||||
output.append(u'<option value="%s"%s>%s</option>' % (
|
||||
escape(option_value), selected_html,
|
||||
conditional_escape(force_unicode(option_label))))
|
||||
output.append(u'</select>')
|
||||
return mark_safe(u'\n'.join(output))
|
||||
|
||||
@ -278,7 +282,7 @@ class RadioInput(StrAndUnicode):
|
||||
|
||||
def __unicode__(self):
|
||||
return mark_safe(u'<label>%s %s</label>' % (self.tag(),
|
||||
self.choice_label))
|
||||
conditional_escape(force_unicode(self.choice_label))))
|
||||
|
||||
def is_checked(self):
|
||||
return self.value == self.choice_value
|
||||
@ -317,11 +321,13 @@ class RadioFieldRenderer(StrAndUnicode):
|
||||
% force_unicode(w) for w in self]))
|
||||
|
||||
class RadioSelect(Select):
|
||||
renderer = RadioFieldRenderer
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.renderer = kwargs.pop('renderer', None)
|
||||
if not self.renderer:
|
||||
self.renderer = RadioFieldRenderer
|
||||
# Override the default renderer if we were passed one.
|
||||
renderer = kwargs.pop('renderer', None)
|
||||
if renderer:
|
||||
self.renderer = renderer
|
||||
super(RadioSelect, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_renderer(self, name, value, attrs=None, choices=()):
|
||||
@ -361,7 +367,8 @@ class CheckboxSelectMultiple(SelectMultiple):
|
||||
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
|
||||
option_value = force_unicode(option_value)
|
||||
rendered_cb = cb.render(name, option_value)
|
||||
output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(force_unicode(option_label))))
|
||||
output.append(u'<li><label>%s %s</label></li>' % (rendered_cb,
|
||||
conditional_escape(force_unicode(option_label))))
|
||||
output.append(u'</ul>')
|
||||
return mark_safe(u'\n'.join(output))
|
||||
|
||||
|
@ -547,9 +547,9 @@ class FilterExpression(object):
|
||||
if var == None:
|
||||
var, constant, i18n_constant = match.group("var", "constant", "i18n_constant")
|
||||
if i18n_constant:
|
||||
var = '"%s"' % _(i18n_constant)
|
||||
var = '"%s"' % _(i18n_constant.replace(r'\"', '"'))
|
||||
elif constant:
|
||||
var = '"%s"' % constant
|
||||
var = '"%s"' % constant.replace(r'\"', '"')
|
||||
upto = match.end()
|
||||
if var == None:
|
||||
raise TemplateSyntaxError, "Could not find variable at start of %s" % token
|
||||
|
@ -25,6 +25,8 @@ def stringfilter(func):
|
||||
if args:
|
||||
args = list(args)
|
||||
args[0] = force_unicode(args[0])
|
||||
if isinstance(args[0], SafeData) and getattr(func, 'is_safe', False):
|
||||
return mark_safe(func(*args, **kwargs))
|
||||
return func(*args, **kwargs)
|
||||
|
||||
# Include a reference to the real function (used to check original
|
||||
@ -106,6 +108,7 @@ floatformat.is_safe = True
|
||||
def iriencode(value):
|
||||
"""Escapes an IRI value for use in a URL."""
|
||||
return force_unicode(iri_to_uri(value))
|
||||
iriencode.is_safe = True
|
||||
iriencode = stringfilter(iriencode)
|
||||
|
||||
def linenumbers(value, autoescape=None):
|
||||
|
@ -51,9 +51,9 @@ class TestCase(unittest.TestCase):
|
||||
def _pre_setup(self):
|
||||
"""Performs any pre-test setup. This includes:
|
||||
|
||||
* If the Test Case class has a 'fixtures' member, clearing the
|
||||
database and installing the named fixtures at the start of each
|
||||
test.
|
||||
* Flushing the database.
|
||||
* If the Test Case class has a 'fixtures' member, installing the
|
||||
named fixtures.
|
||||
* Clearing the mail test outbox.
|
||||
"""
|
||||
call_command('flush', verbosity=0, interactive=False)
|
||||
|
@ -20,6 +20,10 @@ An example: i18n middleware would need to distinguish caches by the
|
||||
import md5
|
||||
import re
|
||||
import time
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
@ -70,8 +74,6 @@ def patch_cache_control(response, **kwargs):
|
||||
cc = ', '.join([dictvalue(el) for el in cc.items()])
|
||||
response['Cache-Control'] = cc
|
||||
|
||||
vary_delim_re = re.compile(r',\s*')
|
||||
|
||||
def patch_response_headers(response, cache_timeout=None):
|
||||
"""
|
||||
Adds some useful headers to the given HttpResponse object:
|
||||
@ -109,14 +111,15 @@ def patch_vary_headers(response, newheaders):
|
||||
# Note that we need to keep the original order intact, because cache
|
||||
# implementations may rely on the order of the Vary contents in, say,
|
||||
# computing an MD5 hash.
|
||||
vary = []
|
||||
if response.has_header('Vary'):
|
||||
vary = vary_delim_re.split(response['Vary'])
|
||||
oldheaders = dict([(el.lower(), 1) for el in vary])
|
||||
for newheader in newheaders:
|
||||
if not newheader.lower() in oldheaders:
|
||||
vary.append(newheader)
|
||||
response['Vary'] = ', '.join(vary)
|
||||
vary_headers = cc_delim_re.split(response['Vary'])
|
||||
else:
|
||||
vary_headers = []
|
||||
# Use .lower() here so we treat headers as case-insensitive.
|
||||
existing_headers = set([header.lower() for header in vary_headers])
|
||||
additional_headers = [newheader for newheader in newheaders
|
||||
if newheader.lower() not in existing_headers]
|
||||
response['Vary'] = ', '.join(vary_headers + additional_headers)
|
||||
|
||||
def _generate_cache_key(request, headerlist, key_prefix):
|
||||
"""Returns a cache key from the headers given in the header list."""
|
||||
@ -169,7 +172,7 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None):
|
||||
key_prefix, iri_to_uri(request.path))
|
||||
if response.has_header('Vary'):
|
||||
headerlist = ['HTTP_'+header.upper().replace('-', '_')
|
||||
for header in vary_delim_re.split(response['Vary'])]
|
||||
for header in cc_delim_re.split(response['Vary'])]
|
||||
cache.set(cache_key, headerlist, cache_timeout)
|
||||
return _generate_cache_key(request, headerlist, key_prefix)
|
||||
else:
|
||||
|
@ -7,9 +7,9 @@ class MergeDict(object):
|
||||
self.dicts = dicts
|
||||
|
||||
def __getitem__(self, key):
|
||||
for dict in self.dicts:
|
||||
for dict_ in self.dicts:
|
||||
try:
|
||||
return dict[key]
|
||||
return dict_[key]
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError
|
||||
@ -24,22 +24,22 @@ class MergeDict(object):
|
||||
return default
|
||||
|
||||
def getlist(self, key):
|
||||
for dict in self.dicts:
|
||||
for dict_ in self.dicts:
|
||||
try:
|
||||
return dict.getlist(key)
|
||||
return dict_.getlist(key)
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError
|
||||
|
||||
def items(self):
|
||||
item_list = []
|
||||
for dict in self.dicts:
|
||||
item_list.extend(dict.items())
|
||||
for dict_ in self.dicts:
|
||||
item_list.extend(dict_.items())
|
||||
return item_list
|
||||
|
||||
def has_key(self, key):
|
||||
for dict in self.dicts:
|
||||
if key in dict:
|
||||
for dict_ in self.dicts:
|
||||
if key in dict_:
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -56,7 +56,7 @@ class SortedDict(dict):
|
||||
def __init__(self, data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
dict.__init__(self, data)
|
||||
super(SortedDict, self).__init__(data)
|
||||
if isinstance(data, dict):
|
||||
self.keyOrder = data.keys()
|
||||
else:
|
||||
@ -68,12 +68,12 @@ class SortedDict(dict):
|
||||
for key, value in self.iteritems()])
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
dict.__setitem__(self, key, value)
|
||||
super(SortedDict, self).__setitem__(key, value)
|
||||
if key not in self.keyOrder:
|
||||
self.keyOrder.append(key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
dict.__delitem__(self, key)
|
||||
super(SortedDict, self).__delitem__(key)
|
||||
self.keyOrder.remove(key)
|
||||
|
||||
def __iter__(self):
|
||||
@ -81,7 +81,7 @@ class SortedDict(dict):
|
||||
yield k
|
||||
|
||||
def pop(self, k, *args):
|
||||
result = dict.pop(self, k, *args)
|
||||
result = super(SortedDict, self).pop(k, *args)
|
||||
try:
|
||||
self.keyOrder.remove(k)
|
||||
except ValueError:
|
||||
@ -90,7 +90,7 @@ class SortedDict(dict):
|
||||
return result
|
||||
|
||||
def popitem(self):
|
||||
result = dict.popitem(self)
|
||||
result = super(SortedDict, self).popitem()
|
||||
self.keyOrder.remove(result[0])
|
||||
return result
|
||||
|
||||
@ -99,7 +99,7 @@ class SortedDict(dict):
|
||||
|
||||
def iteritems(self):
|
||||
for key in self.keyOrder:
|
||||
yield key, dict.__getitem__(self, key)
|
||||
yield key, super(SortedDict, self).__getitem__(key)
|
||||
|
||||
def keys(self):
|
||||
return self.keyOrder[:]
|
||||
@ -108,20 +108,20 @@ class SortedDict(dict):
|
||||
return iter(self.keyOrder)
|
||||
|
||||
def values(self):
|
||||
return [dict.__getitem__(self, k) for k in self.keyOrder]
|
||||
return [super(SortedDict, self).__getitem__(k) for k in self.keyOrder]
|
||||
|
||||
def itervalues(self):
|
||||
for key in self.keyOrder:
|
||||
yield dict.__getitem__(self, key)
|
||||
yield super(SortedDict, self).__getitem__(key)
|
||||
|
||||
def update(self, dict):
|
||||
for k, v in dict.items():
|
||||
def update(self, dict_):
|
||||
for k, v in dict_.items():
|
||||
self.__setitem__(k, v)
|
||||
|
||||
def setdefault(self, key, default):
|
||||
if key not in self.keyOrder:
|
||||
self.keyOrder.append(key)
|
||||
return dict.setdefault(self, key, default)
|
||||
return super(SortedDict, self).setdefault(key, default)
|
||||
|
||||
def value_for_index(self, index):
|
||||
"""Returns the value of the item at the given zero-based index."""
|
||||
@ -135,7 +135,7 @@ class SortedDict(dict):
|
||||
if n < index:
|
||||
index -= 1
|
||||
self.keyOrder.insert(index, key)
|
||||
dict.__setitem__(self, key, value)
|
||||
super(SortedDict, self).__setitem__(key, value)
|
||||
|
||||
def copy(self):
|
||||
"""Returns a copy of this object."""
|
||||
@ -173,10 +173,11 @@ class MultiValueDict(dict):
|
||||
single name-value pairs.
|
||||
"""
|
||||
def __init__(self, key_to_list_mapping=()):
|
||||
dict.__init__(self, key_to_list_mapping)
|
||||
super(MultiValueDict, self).__init__(key_to_list_mapping)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (self.__class__.__name__, dict.__repr__(self))
|
||||
return "<%s: %s>" % (self.__class__.__name__,
|
||||
super(MultiValueDict, self).__repr__())
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""
|
||||
@ -184,7 +185,7 @@ class MultiValueDict(dict):
|
||||
raises KeyError if not found.
|
||||
"""
|
||||
try:
|
||||
list_ = dict.__getitem__(self, key)
|
||||
list_ = super(MultiValueDict, self).__getitem__(key)
|
||||
except KeyError:
|
||||
raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self)
|
||||
try:
|
||||
@ -193,10 +194,10 @@ class MultiValueDict(dict):
|
||||
return []
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
dict.__setitem__(self, key, [value])
|
||||
super(MultiValueDict, self).__setitem__(key, [value])
|
||||
|
||||
def __copy__(self):
|
||||
return self.__class__(dict.items(self))
|
||||
return self.__class__(super(MultiValueDict, self).items())
|
||||
|
||||
def __deepcopy__(self, memo=None):
|
||||
import copy
|
||||
@ -210,7 +211,10 @@ class MultiValueDict(dict):
|
||||
return result
|
||||
|
||||
def get(self, key, default=None):
|
||||
"""Returns the default value if the requested data doesn't exist."""
|
||||
"""
|
||||
Returns the last data value for the passed key. If key doesn't exist
|
||||
or value is an empty list, then default is returned.
|
||||
"""
|
||||
try:
|
||||
val = self[key]
|
||||
except KeyError:
|
||||
@ -220,14 +224,17 @@ class MultiValueDict(dict):
|
||||
return val
|
||||
|
||||
def getlist(self, key):
|
||||
"""Returns an empty list if the requested data doesn't exist."""
|
||||
"""
|
||||
Returns the list of values for the passed key. If key doesn't exist,
|
||||
then an empty list is returned.
|
||||
"""
|
||||
try:
|
||||
return dict.__getitem__(self, key)
|
||||
return super(MultiValueDict, self).__getitem__(key)
|
||||
except KeyError:
|
||||
return []
|
||||
|
||||
def setlist(self, key, list_):
|
||||
dict.__setitem__(self, key, list_)
|
||||
super(MultiValueDict, self).__setitem__(key, list_)
|
||||
|
||||
def setdefault(self, key, default=None):
|
||||
if key not in self:
|
||||
@ -242,7 +249,7 @@ class MultiValueDict(dict):
|
||||
def appendlist(self, key, value):
|
||||
"""Appends an item to the internal list associated with key."""
|
||||
self.setlistdefault(key, [])
|
||||
dict.__setitem__(self, key, self.getlist(key) + [value])
|
||||
super(MultiValueDict, self).__setitem__(key, self.getlist(key) + [value])
|
||||
|
||||
def items(self):
|
||||
"""
|
||||
@ -253,7 +260,7 @@ class MultiValueDict(dict):
|
||||
|
||||
def lists(self):
|
||||
"""Returns a list of (key, list) pairs."""
|
||||
return dict.items(self)
|
||||
return super(MultiValueDict, self).items()
|
||||
|
||||
def values(self):
|
||||
"""Returns a list of the last value on every key list."""
|
||||
@ -315,7 +322,7 @@ class DotExpandedDict(dict):
|
||||
try:
|
||||
current[bits[-1]] = v
|
||||
except TypeError: # Special-case if current isn't a dict.
|
||||
current = {bits[-1] : v}
|
||||
current = {bits[-1]: v}
|
||||
|
||||
class FileDict(dict):
|
||||
"""
|
||||
|
@ -168,10 +168,9 @@ def translation(language):
|
||||
res.merge(t)
|
||||
return res
|
||||
|
||||
if hasattr(settings, 'LOCALE_PATHS'):
|
||||
for localepath in settings.LOCALE_PATHS:
|
||||
if os.path.isdir(localepath):
|
||||
res = _merge(localepath)
|
||||
for localepath in settings.LOCALE_PATHS:
|
||||
if os.path.isdir(localepath):
|
||||
res = _merge(localepath)
|
||||
|
||||
if projectpath and os.path.isdir(projectpath):
|
||||
res = _merge(projectpath)
|
||||
|
@ -422,11 +422,11 @@ TECHNICAL_500_TEMPLATE = """
|
||||
{% if frame.context_line %}
|
||||
<div class="context" id="c{{ frame.id }}">
|
||||
{% if frame.pre_context %}
|
||||
<ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line }}</li>{% endfor %}</ol>
|
||||
<ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
|
||||
{% endif %}
|
||||
<ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line }} <span>...</span></li></ol>
|
||||
<ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol>
|
||||
{% if frame.post_context %}
|
||||
<ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line }}</li>{% endfor %}</ol>
|
||||
<ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@ -445,8 +445,8 @@ TECHNICAL_500_TEMPLATE = """
|
||||
<tbody>
|
||||
{% for var in frame.vars|dictsort:"0" %}
|
||||
<tr>
|
||||
<td>{{ var.0 }}</td>
|
||||
<td class="code"><div>{{ var.1|pprint }}</div></td>
|
||||
<td>{{ var.0|escape }}</td>
|
||||
<td class="code"><div>{{ var.1|pprint|escape }}</div></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@ -466,7 +466,7 @@ Traceback (most recent call last):<br/>
|
||||
{% for frame in frames %}
|
||||
File "{{ frame.filename }}" in {{ frame.function }}<br/>
|
||||
{% if frame.context_line %}
|
||||
{{ frame.lineno }}. {{ frame.context_line }}<br/>
|
||||
{{ frame.lineno }}. {{ frame.context_line|escape }}<br/>
|
||||
{% endif %}
|
||||
{% endfor %}<br/>
|
||||
{{ exception_type }} at {{ request.path|escape }}<br/>
|
||||
|
@ -658,7 +658,7 @@ message file. The choice is yours.
|
||||
of the settings file to determine this, and a settings file doesn't exist
|
||||
if you're manually configuring your settings.)
|
||||
|
||||
.. _settings documentation: ../settings/#using-settings-without-the-django-settings-module-environment-variable
|
||||
.. _settings documentation: ../settings/#using-settings-without-setting-django-settings-module
|
||||
|
||||
All message file repositories are structured the same way. They are:
|
||||
|
||||
|
@ -583,7 +583,7 @@ LOCALE_PATHS
|
||||
|
||||
Default: ``()`` (Empty tuple)
|
||||
|
||||
A list of directories where Django looks for translation files.
|
||||
A tuple of directories where Django looks for translation files.
|
||||
See the `internationalization docs section`_ explaining the variable and the
|
||||
default behavior.
|
||||
|
||||
|
@ -755,61 +755,106 @@ inside the template code:
|
||||
``EscapeString`` and ``EscapeUnicode``. You will not normally need to worry
|
||||
about these; they exist for the implementation of the ``escape`` filter.
|
||||
|
||||
Inside your filter, you will need to think about three areas in order to be
|
||||
auto-escaping compliant:
|
||||
When you are writing a filter, your code will typically fall into one of two
|
||||
situations:
|
||||
|
||||
1. If your filter returns a string that is ready for direct output (it should
|
||||
be considered a "safe" string), you should call
|
||||
``django.utils.safestring.mark_safe()`` on the result prior to returning.
|
||||
This will turn the result into the appropriate ``SafeData`` type. This is
|
||||
often the case when you are returning raw HTML, for example.
|
||||
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
|
||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||
this case, you can let Django take care of all the auto-escaping handling
|
||||
for you. All you need to do is put the ``is_safe`` attribute on your
|
||||
filter function and set it to ``True``. This attribute tells Django that
|
||||
is a "safe" string is passed into your filter, the result will still be
|
||||
"safe" and if a non-safe string is passed in, Django will automatically
|
||||
escape it, if necessary. The reason ``is_safe`` is necessary is because
|
||||
there are plenty of normal string operations that will turn a ``SafeData``
|
||||
object back into a normal ``str`` or ``unicode`` object and, rather than
|
||||
try to catch them all, which would be very difficult, Django repairs the
|
||||
damage after the filter has completed.
|
||||
|
||||
2. If your filter is given a "safe" string, is it guaranteed to return a
|
||||
"safe" string? If so, set the ``is_safe`` attribute on the function to be
|
||||
``True``. For example, a filter that replaced a word consisting only of
|
||||
digits with the number spelt out in words is going to be
|
||||
safe-string-preserving, since it cannot introduce any of the five dangerous
|
||||
characters: <, >, ", ' or &. We can write::
|
||||
For example, suppose you have a filter that adds the string ``xx`` to the
|
||||
end of any input. Since this introduces no dangerous HTML characters into
|
||||
the result (aside from any that were already present), you should mark
|
||||
your filter with ``is_safe``::
|
||||
|
||||
@register.filter
|
||||
def convert_to_words(value):
|
||||
# ... implementation here ...
|
||||
return result
|
||||
def add_xx(value):
|
||||
return '%sxx' % value
|
||||
add_xx.is_safe = True
|
||||
|
||||
convert_to_words.is_safe = True
|
||||
When this filter is used in a template where auto-escaping is enabled,
|
||||
Django will escape the output whenever the input is not already marked as
|
||||
"safe".
|
||||
|
||||
Note that this filter does not return a universally safe result (it does
|
||||
not return ``mark_safe(result)``) because if it is handed a raw string such
|
||||
as '<a>', this will need further escaping in an auto-escape environment.
|
||||
The ``is_safe`` attribute only talks about the the result when a safe
|
||||
string is passed into the filter.
|
||||
By default, ``is_safe`` defaults to ``False`` and you can omit it from
|
||||
any filters where it isn't required.
|
||||
|
||||
3. Will your filter behave differently depending upon whether auto-escaping
|
||||
is currently in effect or not? This is normally a concern when you are
|
||||
returning mixed content (HTML elements mixed with user-supplied content).
|
||||
For example, the ``ordered_list`` filter that ships with Django needs to
|
||||
know whether to escape its content or not. It will always return a safe
|
||||
string. Since it returns raw HTML, we cannot apply escaping to the
|
||||
result -- it needs to be done in-situ.
|
||||
Be careful when deciding if your filter really does leave safe strings
|
||||
as safe. Sometimes if you are *removing* characters, you can
|
||||
inadvertently leave unbalanced HTML tags or entities in the result.
|
||||
For example, removing a ``>`` from the input might turn ``<a>`` into
|
||||
``<a``, which would need to be escaped on output to avoid causing
|
||||
problems. Similarly, removing a semicolon (``;``) can turn ``&``
|
||||
into ``&``, which is no longer a valid entity and thus needs
|
||||
further escaping. Most cases won't be nearly this tricky, but keep an
|
||||
eye out for any problems like that when reviewing your code.
|
||||
|
||||
For these cases, the filter function needs to be told what the current
|
||||
auto-escaping setting is. Set the ``needs_autoescape`` attribute on the
|
||||
filter to ``True`` and have your function take an extra argument called
|
||||
``autoescape`` with a default value of ``None``. When the filter is called,
|
||||
the ``autoescape`` keyword argument will be ``True`` if auto-escaping is in
|
||||
effect. For example, the ``unordered_list`` filter is written as::
|
||||
2. Alternatively, your filter code can manually take care of any necessary
|
||||
escaping. This is usually necessary when you are introducing new HTML
|
||||
markup into the result. You want to mark the output as safe from further
|
||||
escaping so that your HTML markup isn't escaped further, so you'll need to
|
||||
handle the input yourself.
|
||||
|
||||
def unordered_list(value, autoescape=None):
|
||||
# ... lots of code here ...
|
||||
To mark the output as a safe string, use
|
||||
``django.utils.safestring.mark_safe()``.
|
||||
|
||||
return mark_safe(...)
|
||||
Be careful, though. You need to do more than just mark the output as
|
||||
safe. You need to ensure it really *is* safe and what you do will often
|
||||
depend upon whether or not auto-escaping is in effect. The idea is to
|
||||
write filters than can operate in templates where auto-escaping is either
|
||||
on or off in order to make things easier for your template authors.
|
||||
|
||||
unordered_list.is_safe = True
|
||||
unordered_list.needs_autoescape = True
|
||||
In order for you filter to know the current auto-escaping state, set the
|
||||
``needs_autoescape`` attribute to ``True`` on your function (if you don't
|
||||
specify this attribute, it defaults to ``False``). This attribute tells
|
||||
Django that your filter function wants to be passed an extra keyword
|
||||
argument, called ``autoescape`` that is ``True`` is auto-escaping is in
|
||||
effect and ``False`` otherwise.
|
||||
|
||||
By default, both the ``is_safe`` and ``needs_autoescape`` attributes are
|
||||
``False``. You do not need to specify them if ``False`` is an acceptable
|
||||
value.
|
||||
An example might make this clearer. Let's write a filter that emphasizes
|
||||
the first character of a string::
|
||||
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
def initial_letter_filter(text, autoescape=None):
|
||||
first, other = text[0] ,text[1:]
|
||||
if autoescape:
|
||||
esc = conditional_escape
|
||||
else:
|
||||
esc = lambda x: x
|
||||
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
|
||||
return mark_safe(result)
|
||||
initial_letter_filter.needs_autoescape = True
|
||||
|
||||
The ``needs_autoescape`` attribute on the filter function and the
|
||||
``autoescape`` keyword argument mean that our function will know whether
|
||||
or not automatic escaping is in effect when the filter is called. We use
|
||||
``autoescape`` to decide whether the input data needs to be passed through
|
||||
``django.utils.html.conditional_escape`` or not (in the latter case, we
|
||||
just use the identity function as the "escape" function). The
|
||||
``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
escaping.
|
||||
|
||||
There is no need to worry about the ``is_safe`` attribute in this case
|
||||
(although including it wouldn't hurt anything). Whenever you are manually
|
||||
handling the auto-escaping issues and returning a safe string, the
|
||||
``is_safe`` attribute won't change anything either way.
|
||||
|
||||
Writing custom template tags
|
||||
----------------------------
|
||||
@ -932,7 +977,9 @@ without having to be parsed multiple times.
|
||||
Auto-escaping considerations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The output from template tags is not automatically run through the
|
||||
**New in Django development version**
|
||||
|
||||
The output from template tags is **not** automatically run through the
|
||||
auto-escaping filters. However, there are still a couple of things you should
|
||||
keep in mind when writing a template tag:
|
||||
|
||||
|
@ -78,7 +78,8 @@ True
|
||||
>>> paginator.pages
|
||||
2
|
||||
|
||||
# The paginator can provide a list of all available pages
|
||||
# The paginator can provide a list of all available pages.
|
||||
>>> paginator = ObjectPaginator(Article.objects.all(), 10)
|
||||
>>> paginator.page_range
|
||||
[1, 2]
|
||||
"""}
|
||||
|
30
tests/regressiontests/cache/tests.py
vendored
30
tests/regressiontests/cache/tests.py
vendored
@ -3,9 +3,12 @@
|
||||
# Unit tests for cache framework
|
||||
# Uses whatever cache backend is set in the test settings file.
|
||||
|
||||
from django.core.cache import cache
|
||||
import time, unittest
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.utils.cache import patch_vary_headers
|
||||
from django.http import HttpResponse
|
||||
|
||||
# functions/classes for complex data type tests
|
||||
def f():
|
||||
return 42
|
||||
@ -87,5 +90,30 @@ class Cache(unittest.TestCase):
|
||||
cache.set(key, value)
|
||||
self.assertEqual(cache.get(key), value)
|
||||
|
||||
|
||||
class CacheUtils(unittest.TestCase):
|
||||
"""TestCase for django.utils.cache functions."""
|
||||
|
||||
def test_patch_vary_headers(self):
|
||||
headers = (
|
||||
# Initial vary, new headers, resulting vary.
|
||||
(None, ('Accept-Encoding',), 'Accept-Encoding'),
|
||||
('Accept-Encoding', ('accept-encoding',), 'Accept-Encoding'),
|
||||
('Accept-Encoding', ('ACCEPT-ENCODING',), 'Accept-Encoding'),
|
||||
('Cookie', ('Accept-Encoding',), 'Cookie, Accept-Encoding'),
|
||||
('Cookie, Accept-Encoding', ('Accept-Encoding',), 'Cookie, Accept-Encoding'),
|
||||
('Cookie, Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
||||
(None, ('Accept-Encoding', 'COOKIE'), 'Accept-Encoding, COOKIE'),
|
||||
('Cookie, Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
||||
('Cookie , Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
|
||||
)
|
||||
for initial_vary, newheaders, resulting_vary in headers:
|
||||
response = HttpResponse()
|
||||
if initial_vary is not None:
|
||||
response['Vary'] = initial_vary
|
||||
patch_vary_headers(response, newheaders)
|
||||
self.assertEqual(response['Vary'], resulting_vary)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -25,11 +25,23 @@
|
||||
>>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
|
||||
>>> d['name']
|
||||
'Simon'
|
||||
>>> d.get('name')
|
||||
'Simon'
|
||||
>>> d.getlist('name')
|
||||
['Adrian', 'Simon']
|
||||
>>> d['lastname']
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
MultiValueDictKeyError: "Key 'lastname' not found in <MultiValueDict: {'position': ['Developer'], 'name': ['Adrian', 'Simon']}>"
|
||||
>>> d.get('lastname')
|
||||
|
||||
>>> d.get('lastname', 'nonexistent')
|
||||
'nonexistent'
|
||||
>>> d.getlist('lastname')
|
||||
[]
|
||||
>>> d.setlist('lastname', ['Holovaty', 'Willison'])
|
||||
>>> d.getlist('lastname')
|
||||
['Holovaty', 'Willison']
|
||||
|
||||
### SortedDict #################################################################
|
||||
|
||||
|
360
tests/regressiontests/forms/error_messages.py
Normal file
360
tests/regressiontests/forms/error_messages.py
Normal file
@ -0,0 +1,360 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
tests = r"""
|
||||
>>> from django.newforms import *
|
||||
|
||||
# CharField ###################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['min_length'] = 'LENGTH %(length)s, MIN LENGTH %(min)s'
|
||||
>>> e['max_length'] = 'LENGTH %(length)s, MAX LENGTH %(max)s'
|
||||
>>> f = CharField(min_length=5, max_length=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('1234')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 4, MIN LENGTH 5']
|
||||
>>> f.clean('12345678901')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 11, MAX LENGTH 10']
|
||||
|
||||
# IntegerField ################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> f = IntegerField(min_value=5, max_value=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MIN VALUE IS 5']
|
||||
>>> f.clean('11')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX VALUE IS 10']
|
||||
|
||||
# FloatField ##################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> f = FloatField(min_value=5, max_value=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MIN VALUE IS 5']
|
||||
>>> f.clean('11')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX VALUE IS 10']
|
||||
|
||||
# DecimalField ################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_value'] = 'MIN VALUE IS %s'
|
||||
>>> e['max_value'] = 'MAX VALUE IS %s'
|
||||
>>> e['max_digits'] = 'MAX DIGITS IS %s'
|
||||
>>> e['max_decimal_places'] = 'MAX DP IS %s'
|
||||
>>> e['max_whole_digits'] = 'MAX DIGITS BEFORE DP IS %s'
|
||||
>>> f = DecimalField(min_value=5, max_value=10, error_messages=e)
|
||||
>>> f2 = DecimalField(max_digits=4, decimal_places=2, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MIN VALUE IS 5']
|
||||
>>> f.clean('11')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX VALUE IS 10']
|
||||
>>> f2.clean('123.45')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX DIGITS IS 4']
|
||||
>>> f2.clean('1.234')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX DP IS 2']
|
||||
>>> f2.clean('123.4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MAX DIGITS BEFORE DP IS 2']
|
||||
|
||||
# DateField ###################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> f = DateField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
|
||||
# TimeField ###################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> f = TimeField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
|
||||
# DateTimeField ###############################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> f = DateTimeField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
|
||||
# RegexField ##################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_length'] = 'LENGTH %(length)s, MIN LENGTH %(min)s'
|
||||
>>> e['max_length'] = 'LENGTH %(length)s, MAX LENGTH %(max)s'
|
||||
>>> f = RegexField(r'^\d+$', min_length=5, max_length=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abcde')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('1234')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 4, MIN LENGTH 5']
|
||||
>>> f.clean('12345678901')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 11, MAX LENGTH 10']
|
||||
|
||||
# EmailField ##################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['min_length'] = 'LENGTH %(length)s, MIN LENGTH %(min)s'
|
||||
>>> e['max_length'] = 'LENGTH %(length)s, MAX LENGTH %(max)s'
|
||||
>>> f = EmailField(min_length=8, max_length=10, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abcdefgh')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('a@b.com')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 7, MIN LENGTH 8']
|
||||
>>> f.clean('aye@bee.com')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'LENGTH 11, MAX LENGTH 10']
|
||||
|
||||
# FileField ##################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['missing'] = 'MISSING'
|
||||
>>> e['empty'] = 'EMPTY FILE'
|
||||
>>> f = FileField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean({})
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'MISSING']
|
||||
>>> f.clean({'filename': 'name', 'content':''})
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'EMPTY FILE']
|
||||
|
||||
# URLField ##################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID'
|
||||
>>> e['invalid_link'] = 'INVALID LINK'
|
||||
>>> f = URLField(verify_exists=True, error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('abc.c')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID']
|
||||
>>> f.clean('http://www.jfoiwjfoi23jfoijoaijfoiwjofiwjefewl.com')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID LINK']
|
||||
|
||||
# BooleanField ################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> f = BooleanField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
|
||||
# ChoiceField #################################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid_choice'] = '%(value)s IS INVALID CHOICE'
|
||||
>>> f = ChoiceField(choices=[('a', 'aye')], error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('b')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'b IS INVALID CHOICE']
|
||||
|
||||
# MultipleChoiceField #########################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid_choice'] = '%(value)s IS INVALID CHOICE'
|
||||
>>> e['invalid_list'] = 'NOT A LIST'
|
||||
>>> f = MultipleChoiceField(choices=[('a', 'aye')], error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('b')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'NOT A LIST']
|
||||
>>> f.clean(['b'])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'b IS INVALID CHOICE']
|
||||
|
||||
# SplitDateTimeField ##########################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid_date'] = 'INVALID DATE'
|
||||
>>> e['invalid_time'] = 'INVALID TIME'
|
||||
>>> f = SplitDateTimeField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean(['a', 'b'])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID DATE', u'INVALID TIME']
|
||||
|
||||
# IPAddressField ##############################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid'] = 'INVALID IP ADDRESS'
|
||||
>>> f = IPAddressField(error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('127.0.0')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID IP ADDRESS']
|
||||
|
||||
###############################################################################
|
||||
|
||||
# Create choices for the model choice field tests below.
|
||||
|
||||
>>> from regressiontests.forms.models import ChoiceModel
|
||||
>>> ChoiceModel.objects.create(pk=1, name='a')
|
||||
<ChoiceModel: ChoiceModel object>
|
||||
>>> ChoiceModel.objects.create(pk=2, name='b')
|
||||
<ChoiceModel: ChoiceModel object>
|
||||
>>> ChoiceModel.objects.create(pk=3, name='c')
|
||||
<ChoiceModel: ChoiceModel object>
|
||||
|
||||
# ModelChoiceField ############################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid_choice'] = 'INVALID CHOICE'
|
||||
>>> f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'INVALID CHOICE']
|
||||
|
||||
# ModelMultipleChoiceField ####################################################
|
||||
|
||||
>>> e = {'required': 'REQUIRED'}
|
||||
>>> e['invalid_choice'] = '%s IS INVALID CHOICE'
|
||||
>>> e['list'] = 'NOT A LIST OF VALUES'
|
||||
>>> f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
||||
>>> f.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'REQUIRED']
|
||||
>>> f.clean('3')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'NOT A LIST OF VALUES']
|
||||
>>> f.clean(['4'])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'4 IS INVALID CHOICE']
|
||||
"""
|
@ -10,6 +10,10 @@ class Defaults(models.Model):
|
||||
def_date = models.DateField(default = datetime.date(1980, 1, 1))
|
||||
value = models.IntegerField(default=42)
|
||||
|
||||
class ChoiceModel(models.Model):
|
||||
"""For ModelChoiceField and ModelMultipleChoiceField tests."""
|
||||
name = models.CharField(max_length=10)
|
||||
|
||||
__test__ = {'API_TESTS': """
|
||||
>>> from django.newforms import form_for_model, form_for_instance
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
tests = r"""
|
||||
>>> from django.newforms import *
|
||||
>>> from django.newforms.widgets import RadioFieldRenderer
|
||||
>>> from django.utils.safestring import mark_safe
|
||||
>>> import datetime
|
||||
>>> import time
|
||||
>>> import re
|
||||
@ -205,6 +206,8 @@ u'<textarea rows="10" cols="40" name="msg"></textarea>'
|
||||
u'<textarea rows="10" cols="40" name="msg">value</textarea>'
|
||||
>>> w.render('msg', 'some "quoted" & ampersanded value')
|
||||
u'<textarea rows="10" cols="40" name="msg">some "quoted" & ampersanded value</textarea>'
|
||||
>>> w.render('msg', mark_safe('pre "quoted" value'))
|
||||
u'<textarea rows="10" cols="40" name="msg">pre "quoted" value</textarea>'
|
||||
>>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20})
|
||||
u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>'
|
||||
|
||||
@ -375,6 +378,17 @@ If 'choices' is passed to both the constructor and render(), then they'll both b
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
|
||||
# Choices are escaped correctly
|
||||
>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me'))))
|
||||
<select name="escape">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="bad">you & me</option>
|
||||
<option value="good">you > me</option>
|
||||
</select>
|
||||
|
||||
# Unicode choices are correctly rendered as HTML
|
||||
>>> w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
|
||||
u'<select name="email">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>'
|
||||
|
||||
@ -538,6 +552,17 @@ If 'choices' is passed to both the constructor and render(), then they'll both b
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
|
||||
# Choices are escaped correctly
|
||||
>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me'))))
|
||||
<select multiple="multiple" name="escape">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="bad">you & me</option>
|
||||
<option value="good">you > me</option>
|
||||
</select>
|
||||
|
||||
# Unicode choices are correctly rendered as HTML
|
||||
>>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
|
||||
u'<select multiple="multiple" name="nums">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>'
|
||||
|
||||
@ -663,6 +688,16 @@ You can create your own custom renderers for RadioSelect to use.
|
||||
<label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br />
|
||||
<label><input type="radio" name="beatle" value="R" /> Ringo</label>
|
||||
|
||||
Or you can use custom RadioSelect fields that use your custom renderer.
|
||||
>>> class CustomRadioSelect(RadioSelect):
|
||||
... renderer = MyRenderer
|
||||
>>> w = CustomRadioSelect()
|
||||
>>> print w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
|
||||
<label><input type="radio" name="beatle" value="J" /> John</label><br />
|
||||
<label><input type="radio" name="beatle" value="P" /> Paul</label><br />
|
||||
<label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br />
|
||||
<label><input type="radio" name="beatle" value="R" /> Ringo</label>
|
||||
|
||||
A RadioFieldRenderer object also allows index access to individual RadioInput
|
||||
objects.
|
||||
>>> w = RadioSelect()
|
||||
@ -682,6 +717,14 @@ Traceback (most recent call last):
|
||||
...
|
||||
IndexError: list index out of range
|
||||
|
||||
# Choices are escaped correctly
|
||||
>>> w = RadioSelect()
|
||||
>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me'))))
|
||||
<ul>
|
||||
<li><label><input type="radio" name="escape" value="bad" /> you & me</label></li>
|
||||
<li><label><input type="radio" name="escape" value="good" /> you > me</label></li>
|
||||
</ul>
|
||||
|
||||
# Unicode choices are correctly rendered as HTML
|
||||
>>> w = RadioSelect()
|
||||
>>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
|
||||
@ -811,6 +854,17 @@ If 'choices' is passed to both the constructor and render(), then they'll both b
|
||||
<li><label><input type="checkbox" name="nums" value="5" /> 5</label></li>
|
||||
</ul>
|
||||
|
||||
# Choices are escaped correctly
|
||||
>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you > me'))))
|
||||
<ul>
|
||||
<li><label><input type="checkbox" name="escape" value="1" /> 1</label></li>
|
||||
<li><label><input type="checkbox" name="escape" value="2" /> 2</label></li>
|
||||
<li><label><input type="checkbox" name="escape" value="3" /> 3</label></li>
|
||||
<li><label><input type="checkbox" name="escape" value="bad" /> you & me</label></li>
|
||||
<li><label><input type="checkbox" name="escape" value="good" /> you > me</label></li>
|
||||
</ul>
|
||||
|
||||
# Unicode choices are correctly rendered as HTML
|
||||
>>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
|
||||
u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
|
||||
|
||||
|
@ -198,6 +198,12 @@ def get_filter_tests():
|
||||
'filter-phone2numeric01': ('{{ a|phone2numeric }} {{ b|phone2numeric }}', {"a": "<1-800-call-me>", "b": mark_safe("<1-800-call-me>") }, "<1-800-2255-63> <1-800-2255-63>"),
|
||||
'filter-phone2numeric02': ('{% autoescape off %}{{ a|phone2numeric }} {{ b|phone2numeric }}{% endautoescape %}', {"a": "<1-800-call-me>", "b": mark_safe("<1-800-call-me>") }, "<1-800-2255-63> <1-800-2255-63>"),
|
||||
|
||||
# Ensure iriencode keeps safe strings:
|
||||
'filter-iriencode01': ('{{ url|iriencode }}', {'url': '?test=1&me=2'}, '?test=1&me=2'),
|
||||
'filter-iriencode02': ('{% autoescape off %}{{ url|iriencode }}{% endautoescape %}', {'url': '?test=1&me=2'}, '?test=1&me=2'),
|
||||
'filter-iriencode03': ('{{ url|iriencode }}', {'url': mark_safe('?test=1&me=2')}, '?test=1&me=2'),
|
||||
'filter-iriencode04': ('{% autoescape off %}{{ url|iriencode }}{% endautoescape %}', {'url': mark_safe('?test=1&me=2')}, '?test=1&me=2'),
|
||||
|
||||
# Chaining a bunch of safeness-preserving filters should not alter
|
||||
# the safe status either way.
|
||||
'chaining01': ('{{ a|capfirst|center:"7" }}.{{ b|capfirst|center:"7" }}', {"a": "a < b", "b": mark_safe("a < b")}, " A < b . A < b "),
|
||||
|
@ -268,6 +268,12 @@ class Templates(unittest.TestCase):
|
||||
# Embedded newlines make it not-a-tag.
|
||||
'basic-syntax24': ("{{ moo\n }}", {}, "{{ moo\n }}"),
|
||||
|
||||
# Literal strings are permitted inside variables, mostly for i18n
|
||||
# purposes.
|
||||
'basic-syntax25': ('{{ "fred" }}', {}, "fred"),
|
||||
'basic-syntax26': (r'{{ "\"fred\"" }}', {}, "\"fred\""),
|
||||
'basic-syntax27': (r'{{ _("\"fred\"") }}', {}, "\"fred\""),
|
||||
|
||||
# List-index syntax allows a template to access a certain item of a subscriptable object.
|
||||
'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"),
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user