diff options
| author | Jason Pellerin <jpellerin@gmail.com> | 2006-07-23 03:31:52 +0000 |
|---|---|---|
| committer | Jason Pellerin <jpellerin@gmail.com> | 2006-07-23 03:31:52 +0000 |
| commit | 438c23a6c6eb71b73272a9b98392af654b76c82c (patch) | |
| tree | c9f9bdfd9db7efc982b5094ba452c5d152881b35 | |
| parent | d345b89bc67b67867a4cc9608a972b7ffa6e0903 (diff) | |
[multi-db] Merge trunk to [3426]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3427 bcc190cf-cafb-0310-a4f2-bffc1f526a37
90 files changed, 3128 insertions, 956 deletions
diff --git a/django/bin/compile-messages.py b/django/bin/compile-messages.py index e33fdd780b..5f653df95d 100755 --- a/django/bin/compile-messages.py +++ b/django/bin/compile-messages.py @@ -2,7 +2,6 @@ import os import sys -import getopt def compile_messages(): basedir = None diff --git a/django/bin/make-messages.py b/django/bin/make-messages.py index 75b0bc0ca0..557cb5eeec 100755 --- a/django/bin/make-messages.py +++ b/django/bin/make-messages.py @@ -1,5 +1,9 @@ #!/usr/bin/env python +# Need to ensure that the i18n framework is enabled +from django.conf import settings +settings.configure(USE_I18N = True) + from django.utils.translation import templatize import re import os diff --git a/django/conf/__init__.py b/django/conf/__init__.py index a6a09d772f..1a04bbfb02 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -7,7 +7,6 @@ a list of all possible variables. """ import os -import sys from django.conf import global_settings ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index e42019ece7..3d203d97de 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -62,6 +62,7 @@ LANGUAGES = ( ('sl', gettext_noop('Slovenian')), ('sr', gettext_noop('Serbian')), ('sv', gettext_noop('Swedish')), + ('ta', gettext_noop('Tamil')), ('uk', gettext_noop('Ukrainian')), ('zh-cn', gettext_noop('Simplified Chinese')), ('zh-tw', gettext_noop('Traditional Chinese')), diff --git a/django/conf/locale/ta/LC_MESSAGES/django.mo b/django/conf/locale/ta/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 0000000000..c85327d06b --- /dev/null +++ b/django/conf/locale/ta/LC_MESSAGES/django.mo diff --git a/django/conf/locale/ta/LC_MESSAGES/django.po b/django/conf/locale/ta/LC_MESSAGES/django.po new file mode 100644 index 0000000000..7637bb9cdb --- /dev/null +++ b/django/conf/locale/ta/LC_MESSAGES/django.po @@ -0,0 +1,2111 @@ +# translation of django.po to +# translation of django_aa.po to +# translation of django_aa.po to tamil +# Parthan <parthan@au-kbc.org>, 2006. +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +msgid "" +msgstr "" +"Project-Id-Version: django\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-05-16 10:14+0200\n" +"PO-Revision-Date: 2006-07-18 16:47+0530\n" +"Last-Translator: R Hariram Aatreya <rha@localhost.localdomain>\n" +"Language-Team: <en@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.9\n" + +#: contrib/comments/models.py:67 contrib/comments/models.py:166 +msgid "object ID" +msgstr "அடையாளம்" + +#: contrib/comments/models.py:68 +msgid "headline" +msgstr "தலையங்கம்" + +#: contrib/comments/models.py:69 contrib/comments/models.py:90 +#: contrib/comments/models.py:167 +msgid "comment" +msgstr "குறிப்பு" + +#: contrib/comments/models.py:70 +msgid "rating #1" +msgstr "#1 தரவரிசை" + +#: contrib/comments/models.py:71 +msgid "rating #2" +msgstr "#2 தரவரிசை" + +#: contrib/comments/models.py:72 +msgid "rating #3" +msgstr "#3 தரவரிசை" + +#: contrib/comments/models.py:73 +msgid "rating #4" +msgstr "#4 தரவரிசை" + +#: contrib/comments/models.py:74 +msgid "rating #5" +msgstr "#5 தரவரிசை" + +#: contrib/comments/models.py:75 +msgid "rating #6" +msgstr "#6 தரவரிசை" + +#: contrib/comments/models.py:76 +msgid "rating #7" +msgstr "#7 தரவரிசை" + +#: contrib/comments/models.py:77 +msgid "rating #8" +msgstr "#8 தரவரிசை" + +#: contrib/comments/models.py:82 +msgid "is valid rating" +msgstr "அங்கீகரிக்கப்பட்ட தரவரிசை" + +#: contrib/comments/models.py:83 contrib/comments/models.py:169 +msgid "date/time submitted" +msgstr "தேதிநேரம் சமர்ப்பிக்கப்பட்டுள்ளது" + +#: contrib/comments/models.py:84 contrib/comments/models.py:170 +msgid "is public" +msgstr "பொதுவானது" + +#: contrib/comments/models.py:85 contrib/admin/views/doc.py:289 +msgid "IP address" +msgstr "ip விலாசம்" + +#: contrib/comments/models.py:86 +msgid "is removed" +msgstr "நீக்கபட்டது" + +#: contrib/comments/models.py:86 +msgid "" +"Check this box if the comment is inappropriate. A \"This comment has been " +"removed\" message will be displayed instead." +msgstr "குறிப்பு செரியாக இல்லையென்றால் இந்த் பெட்டியில் குறியிடவும். இதற்கு பதிலாக \"இந்த குறிப்பு நீக்கபட்டது\" காண்பிக்கபடும்." + +#: contrib/comments/models.py:91 +msgid "comments" +msgstr "குறிப்பு" + +#: contrib/comments/models.py:131 contrib/comments/models.py:207 +msgid "Content object" +msgstr "பொருள் அடக்க object" + +#: contrib/comments/models.py:159 +#, python-format +msgid "" +"Posted by %(user)s at %(date)s\n" +"\n" +"%(comment)s\n" +"\n" +"http://%(domain)s%(url)s" +msgstr "" +"%(user)s ஆல் %(date)s இல் அளிக்கப்பட்டது \n" +"\n" +"%(comment)s\n" +"\n" +"http://%(domain)s%(url)s" + +#: contrib/comments/models.py:168 +msgid "person's name" +msgstr "நபரின் பெயர்" + +#: contrib/comments/models.py:171 +msgid "ip address" +msgstr "ip விலாசம்" + +#: contrib/comments/models.py:173 +msgid "approved by staff" +msgstr "பணியாளர்களால் அனுமதிக்கப்பட்டது" + +#: contrib/comments/models.py:176 +msgid "free comment" +msgstr "சுதந்தரமான குறிப்பு" + +#: contrib/comments/models.py:177 +msgid "free comments" +msgstr "சுதந்தரமான குறிப்பு" + +#: contrib/comments/models.py:233 +msgid "score" +msgstr "மதிப்பீடு" + +#: contrib/comments/models.py:234 +msgid "score date" +msgstr "மதிப்பீடு தேதி" + +#: contrib/comments/models.py:237 +msgid "karma score" +msgstr "கர்மா மதிப்பீடு" + +#: contrib/comments/models.py:238 +msgid "karma scores" +msgstr "கர்மா மதிப்பீடு" + +#: contrib/comments/models.py:242 +#, python-format +msgid "%(score)d rating by %(user)s" +msgstr "%(user)s ஈட்டய %(score)d " + +#: contrib/comments/models.py:258 +#, python-format +msgid "" +"This comment was flagged by %(user)s:\n" +"\n" +"%(text)s" +msgstr "" +"இந்த குறிப்பு %(user)s ஆல் குறிக்கபட்டது:\n" +"\n" +"%(text)s" + +#: contrib/comments/models.py:265 +msgid "flag date" +msgstr "குறியின் தேதி" + +#: contrib/comments/models.py:268 +msgid "user flag" +msgstr "பயனாளர் குறி" + +#: contrib/comments/models.py:269 +msgid "user flags" +msgstr "பயனாளர் குறிகள்" + +#: contrib/comments/models.py:273 +#, python-format +msgid "Flag by %r" +msgstr "%r ஆல் குறிக்கப்பட்டது" + +#: contrib/comments/models.py:278 +msgid "deletion date" +msgstr "நீக்கப்பட்ட தேதி" + +#: contrib/comments/models.py:280 +msgid "moderator deletion" +msgstr "மட்டொறுத்தால் நீக்கப்பட்டது" + +#: contrib/comments/models.py:281 +msgid "moderator deletions" +msgstr "மட்டொறுத்தால் நீக்கப்பட்டது" + +#: contrib/comments/models.py:285 +#, python-format +msgid "Moderator deletion by %r" +msgstr "மட்டொறுத்தால் நீக்கப்பட்டது %r" + +#: contrib/comments/views/karma.py:19 +msgid "Anonymous users cannot vote" +msgstr "அடயாள்ம் இல்லாத பயனாளறால் வாக்களிக்க முடியாது" + +#: contrib/comments/views/karma.py:23 +msgid "Invalid comment ID" +msgstr "செல்லாத குறிப்பு ID" + +#: contrib/comments/views/karma.py:25 +msgid "No voting for yourself" +msgstr "உங்களை நீங்களே தேர்வு செய்து கொள்ள முடியாது" + +#: contrib/comments/views/comments.py:28 +msgid "This rating is required because you've entered at least one other rating." +msgstr "மற்றொரு தரவரிசை அளிக்க்பட்டதால் இந்த தரவரிசை தேவைப்படுகிறது." + +#: contrib/comments/views/comments.py:112 +#, python-format +msgid "" +"This comment was posted by a user who has posted fewer than %(count)s " +"comment:\n" +"\n" +"%(text)s" +"This comment was posted by a user who has posted fewer than %(count)s " +"comments:\n" +"\n" +"%(text)s" +msgstr "" +"%(count)s குறைவாக அளித்த பயனாளரால் இந்த குரிப்பை அள்த்தபடது:\n" +"\n" +"%(text)s" +"%(count)s குறைவாக அளித்த பயனாளரால் இந்த குரிப்பை அள்த்தபடது:\n" +"\n" +"%(text)s" + +#: contrib/comments/views/comments.py:117 +#, python-format +msgid "" +"This comment was posted by a sketchy user:\n" +"\n" +"%(text)s" +msgstr "" +"முழுமையான விவரஙகளை அளிக்காத பயனாளறால் கொடுக்கப்பட்டது:\n" +"%(text)s" + +#: contrib/comments/views/comments.py:189 +#: contrib/comments/views/comments.py:280 +msgid "Only POSTs are allowed" +msgstr "POSTகளுக்கு மட்டும் அனுமதி உண்டு" + +#: contrib/comments/views/comments.py:193 +#: contrib/comments/views/comments.py:284 +msgid "One or more of the required fields wasn't submitted" +msgstr "ஒன்று அல்லது ஒன்றிற்கு மேற்ப்பட்ட புலங்கள் சமற்பிக்கப்படவில்லை" + +#: contrib/comments/views/comments.py:197 +#: contrib/comments/views/comments.py:286 +msgid "Somebody tampered with the comment form (security violation)" +msgstr "எவறோ குரிப்புறையை செதப்படுத்திவிட்டாற்கள் (பாதுகாப்பு மீறல்)" + +#: contrib/comments/views/comments.py:207 +#: contrib/comments/views/comments.py:292 +msgid "" +"The comment form had an invalid 'target' parameter -- the object ID was " +"invalid" +msgstr "குறிப்புறை படிவத்தில் முறையான இலக்கு அளவுருக்க இல்லை -- object ID முறையானதாக இல்லை" + +#: contrib/comments/views/comments.py:257 +#: contrib/comments/views/comments.py:321 +msgid "The comment form didn't provide either 'preview' or 'post'" +msgstr "குறிப்பு படிவம் முன்னோட்டம் அல்லது பிற்பட்டதை வழங்கவில்லை." + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/comments/templates/comments/form.html:8 +#: contrib/admin/templates/admin/login.html:17 +msgid "Username:" +msgstr "பயணர் பெயர்:" + +#: contrib/comments/templates/comments/form.html:6 +#: contrib/admin/templates/admin/login.html:20 +msgid "Password:" +msgstr "கடவுச்சொல்:" + +#: contrib/comments/templates/comments/form.html:6 +msgid "Forgotten your password?" +msgstr "கடவுச்சொல்லை மறந்துவிட்டீரா?" + +#: contrib/comments/templates/comments/form.html:8 +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/base.html:23 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/view_detail.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 +#: contrib/admin/templates/admin_doc/template_detail.html:4 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 +#: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 +#: contrib/admin/templates/admin_doc/model_index.html:5 +msgid "Log out" +msgstr "வெளியேறு" + +#: contrib/comments/templates/comments/form.html:12 +msgid "Ratings" +msgstr "விகிதம்" + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Required" +msgstr "தேவைப்படுகிறது " + +#: contrib/comments/templates/comments/form.html:12 +#: contrib/comments/templates/comments/form.html:23 +msgid "Optional" +msgstr "விருப்பத்தேர்வு" + +#: contrib/comments/templates/comments/form.html:23 +msgid "Post a photo" +msgstr "புகைப்படத்தை அணுப்பு" + +#: contrib/comments/templates/comments/form.html:27 +#: contrib/comments/templates/comments/freeform.html:5 +msgid "Comment:" +msgstr "விவரம்:" + +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# translation of django_ab.po to +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +#: contrib/comments/templates/comments/form.html:32 +#: contrib/comments/templates/comments/freeform.html:9 +msgid "Preview comment" +msgstr "குறிப்பை முன்னேற்றமிடு" + +#: contrib/comments/templates/comments/freeform.html:4 +msgid "Your name:" +msgstr "உங்கள்பெயர்:" + +#: contrib/admin/filterspecs.py:40 +#, python-format +msgid "" +"<h3>By %s:</h3>\n" +"<ul>\n" +msgstr "" +"<h3> %s ஆல்:</h3>\n" +"<ul>\n" + +#: contrib/admin/filterspecs.py:70 contrib/admin/filterspecs.py:88 +#: contrib/admin/filterspecs.py:143 +msgid "All" +msgstr "அணைத்தும்" + +#: contrib/admin/filterspecs.py:109 +msgid "Any date" +msgstr "எந்த தேதியும்" + +#: contrib/admin/filterspecs.py:110 +msgid "Today" +msgstr "இண்று" + +#: contrib/admin/filterspecs.py:113 +msgid "Past 7 days" +msgstr "கடந்த 7 நாட்களில்" + +#: contrib/admin/filterspecs.py:115 +msgid "This month" +msgstr "இந்த மாதம்" + +#: contrib/admin/filterspecs.py:117 +msgid "This year" +msgstr "இந்த வருடம்" + +#: contrib/admin/filterspecs.py:143 +msgid "Yes" +msgstr "ஆம்" + +#: contrib/admin/filterspecs.py:143 +msgid "No" +msgstr "இல்லை" + +#: contrib/admin/filterspecs.py:150 +msgid "Unknown" +msgstr "தெரியாத" + +#: contrib/admin/models.py:16 +msgid "action time" +msgstr "செயல் நேரம்" + +#: contrib/admin/models.py:19 +msgid "object id" +msgstr "பொருள் அடையாளம்" + +#: contrib/admin/models.py:20 +msgid "object repr" +msgstr "பொருள் உருவகித்தம்" + +#: contrib/admin/models.py:21 +msgid "action flag" +msgstr "செயர்குறி" + +#: contrib/admin/models.py:22 +msgid "change message" +msgstr "செய்தியை மாற்று" + +#: contrib/admin/models.py:25 +msgid "log entry" +msgstr "புகுபதிவு உள்ளீடு" + +#: contrib/admin/models.py:26 +msgid "log entries" +msgstr "புகுபதிவு உள்ளீடு" + +#: contrib/admin/templatetags/admin_list.py:228 +msgid "All dates" +msgstr "அனைத்து தேதியும்" + +#: contrib/admin/views/decorators.py:9 contrib/auth/forms.py:36 +#: contrib/auth/forms.py:41 +msgid "" +"Please enter a correct username and password. Note that both fields are case-" +"sensitive." +msgstr "தயவுசெய்து சரியான பயனர்பபெயர் மற்றும் கடவுச்சொல்லை உள்ள்ளிடவும். இரண்டும் எழுத்துவகையை சார்ந்தது." + +#: contrib/admin/views/decorators.py:23 +#: contrib/admin/templates/admin/login.html:25 +msgid "Log in" +msgstr "உள்ளே போ" + +#: contrib/admin/views/decorators.py:61 +msgid "" +"Please log in again, because your session has expired. Don't worry: Your " +"submission has been saved." +msgstr "தயவுசெய்து மறுபடியும் புகுபதிவு செய். ஏனென்றாள் காலம் முடிவடைந்தவு. கவலை படவேண்டாம்: உங்களுடைய அணுப்புதல் சேமிக்கப்பட்டுள்ளது. " + +#: contrib/admin/views/decorators.py:68 +msgid "" +"Looks like your browser isn't configured to accept cookies. Please enable " +"cookies, reload this page, and try again." +msgstr "உங்களுடைய உலாவி தற்கால நிரல்களை அணுமதிக்காதவாறு உள்ளமைக்கப் பட்டவாறு தெரிகிறது. தயவுசெய்து தற்காலிக நிரலை செயல்பட செய்து, பக்கத்தை மறுபடி உள்ள்வாங்கவும்." + +#: contrib/admin/views/decorators.py:82 +msgid "Usernames cannot contain the '@' character." +msgstr "பயனர் பெயர் '@' குறியீட்டை கொண்டிருக்க முடியாது." + +#: contrib/admin/views/decorators.py:84 +#, python-format +msgid "Your e-mail address is not your username. Try '%s' instead." +msgstr "உன்கள் மிண்அஞ்சள் முகவரிஉங்கள் பயனர் பெயர் இல்லை. '%s' யை முயற்ச்சி செய்யவும். " + +#: contrib/admin/views/main.py:226 +msgid "Site administration" +msgstr "இணைய மேளான்மை" + +#: contrib/admin/views/main.py:260 +#, python-format +msgid "The %(name)s \"%(obj)s\" was added successfully." +msgstr "%(name)s \"%(obj)s\" வெற்றிகரமாக சேர்க்கப்பட்டது." + +#: contrib/admin/views/main.py:264 contrib/admin/views/main.py:348 +msgid "You may edit it again below." +msgstr "நீங்கள் மறுபடியும் தொகுக்க முடியும். " + +#: contrib/admin/views/main.py:272 contrib/admin/views/main.py:357 +#, python-format +msgid "You may add another %s below." +msgstr "நீங்கள் மற்ற %s யை கீழே சேர்க்க முடியும்." + +#: contrib/admin/views/main.py:290 +#, python-format +msgid "Add %s" +msgstr "%s யை சேர்" + +#: contrib/admin/views/main.py:336 +#, python-format +msgid "Added %s." +msgstr "%s சேர்க்கப்பட்டுள்ளது." + +#: contrib/admin/views/main.py:336 contrib/admin/views/main.py:338 +#: contrib/admin/views/main.py:340 +msgid "and" +msgstr "மற்றும்" + +#: contrib/admin/views/main.py:338 +#, python-format +msgid "Changed %s." +msgstr "%s மாற்றப்பட்டுள்ளது." + +#: contrib/admin/views/main.py:340 +#, python-format +msgid "Deleted %s." +msgstr "%s அழிக்கப்பட்டது." + +#: contrib/admin/views/main.py:343 +msgid "No fields changed." +msgstr "எந்த புலமும் மாறவில்லை." + +#: contrib/admin/views/main.py:346 +#, python-format +msgid "The %(name)s \"%(obj)s\" was changed successfully." +msgstr " %(name)s \"%(obj)s\" வெற்றிகரமாக மாற்றப்பட்டது." + +#: contrib/admin/views/main.py:354 +#, python-format +msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below." +msgstr "%(name)s \"%(obj)s\" வெற்றிகரமாக சேர்க்கப்பட்டுள்ளது. நீங்கள் கீழே தொகுக்க முடியும்." + +#: contrib/admin/views/main.py:392 +#, python-format +msgid "Change %s" +msgstr "%s யை மாற்று" + +#: contrib/admin/views/main.py:470 +#, python-format +msgid "One or more %(fieldname)s in %(name)s: %(obj)s" +msgstr "%(name)s ல் உள்ள %(fieldname)s: %(obj)s" + +#: contrib/admin/views/main.py:475 +#, python-format +msgid "One or more %(fieldname)s in %(name)s:" +msgstr "%(name)s ல் உள்ள %(fieldname)s:" + +#: contrib/admin/views/main.py:508 +#, python-format +msgid "The %(name)s \"%(obj)s\" was deleted successfully." +msgstr "%(name)s \"%(obj)s\" வெற்றிகரமாக அழிக்கப்பட்டுள்ளது." + +#: contrib/admin/views/main.py:511 +msgid "Are you sure?" +msgstr "உறுதியாக சொகிறீர்களா?" + +#: contrib/admin/views/main.py:533 +#, python-format +msgid "Change history: %s" +msgstr "வரலாற்றை மாற்று: %s" + +#: contrib/admin/views/main.py:565 +#, python-format +msgid "Select %s" +msgstr "%s யை தேர்ந்தெடு" + +#: contrib/admin/views/main.py:565 +#, python-format +msgid "Select %s to change" +msgstr "%s யை மாற்ற தேர்ந்தெடு" + +#: contrib/admin/views/doc.py:277 contrib/admin/views/doc.py:286 +#: contrib/admin/views/doc.py:288 contrib/admin/views/doc.py:294 +#: contrib/admin/views/doc.py:295 contrib/admin/views/doc.py:297 +msgid "Integer" +msgstr "முழு எண்" + +#: contrib/admin/views/doc.py:278 +msgid "Boolean (Either True or False)" +msgstr "பூலியன் (சரி அல்லது தவறு)" + +#: contrib/admin/views/doc.py:279 contrib/admin/views/doc.py:296 +#, python-format +msgid "String (up to %(maxlength)s)" +msgstr "உரை (%(maxlength)s வரைக்கும்)" + +#: contrib/admin/views/doc.py:280 +msgid "Comma-separated integers" +msgstr "கமாவாள் பிரிக்கப்பட்ட முழு எண்" + +#: contrib/admin/views/doc.py:281 +msgid "Date (without time)" +msgstr "தேதி (நேரமில்லாமல்)" + +#: contrib/admin/views/doc.py:282 +msgid "Date (with time)" +msgstr "தேதி (நேரமுடன்)" + +#: contrib/admin/views/doc.py:283 +msgid "E-mail address" +msgstr "மின் அஞ்சல்" + +#: contrib/admin/views/doc.py:284 contrib/admin/views/doc.py:287 +msgid "File path" +msgstr "கோப்ப்பு பாதை" + +#: contrib/admin/views/doc.py:285 +msgid "Decimal number" +msgstr "புள்ளி எண்கள்" + +#: contrib/admin/views/doc.py:291 +msgid "Boolean (Either True, False or None)" +msgstr "இலக்கு முறை (சரி, தவறு அல்லது ஒன்றும் இல்லை)" + +#: contrib/admin/views/doc.py:292 +msgid "Relation to parent model" +msgstr "ஆதி மாதிரிக்கு தொடர்புடையது" + +#: contrib/admin/views/doc.py:293 +msgid "Phone number" +msgstr "தொலைபேசி எண்" + +#: contrib/admin/views/doc.py:298 +msgid "Text" +msgstr "உரை" + +#: contrib/admin/views/doc.py:299 +msgid "Time" +msgstr "நேரம்" + +#: contrib/admin/views/doc.py:300 contrib/flatpages/models.py:7 +msgid "URL" +msgstr "URL" + +#: contrib/admin/views/doc.py:301 +msgid "U.S. state (two uppercase letters)" +msgstr "U.S. மாநிலம் (இரண்டு மேல் எழுத்துவகை எழுத்து)" + +#: contrib/admin/views/doc.py:302 +msgid "XML text" +msgstr "XML உரை" + +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/base.html:23 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Documentation" +msgstr "ஆவணமாக்கம்" + +# translation of django_ac.po to +# translation of django_ac.po to tamil +# Ashwin <ashwin@au-kbc.org>, 2006. +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +#: contrib/admin/templates/admin/object_history.html:3 +#: contrib/admin/templates/admin/change_list.html:5 +#: contrib/admin/templates/admin/base.html:23 +#: contrib/admin/templates/admin/delete_confirmation.html:3 +#: contrib/admin/templates/admin/change_form.html:10 +#: contrib/admin/templates/registration/password_change_done.html:3 +#: contrib/admin/templates/registration/password_change_form.html:3 +#: contrib/admin/templates/admin_doc/bookmarklets.html:4 +#: contrib/admin/templates/admin_doc/view_detail.html:4 +#: contrib/admin/templates/admin_doc/template_tag_index.html:5 +#: contrib/admin/templates/admin_doc/template_detail.html:4 +#: contrib/admin/templates/admin_doc/template_filter_index.html:5 +#: contrib/admin/templates/admin_doc/missing_docutils.html:4 +#: contrib/admin/templates/admin_doc/view_index.html:5 +#: contrib/admin/templates/admin_doc/model_detail.html:3 +#: contrib/admin/templates/admin_doc/index.html:4 +#: contrib/admin/templates/admin_doc/model_index.html:5 +msgid "Change password" +msgstr "கடவுச்சொல்லை மாற்று " + +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/500.html:4 +#: contrib/admin/templates/admin/change_list.html:6 +#: contrib/admin/templates/admin/base.html:28 +#: contrib/admin/templates/admin/delete_confirmation.html:6 +#: contrib/admin/templates/admin/change_form.html:13 +#: contrib/admin/templates/registration/password_change_done.html:4 +#: contrib/admin/templates/registration/password_reset_form.html:4 +#: contrib/admin/templates/registration/logged_out.html:4 +#: contrib/admin/templates/registration/password_reset_done.html:4 +#: contrib/admin/templates/registration/password_change_form.html:4 +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Home" +msgstr "வீடு" + +#: contrib/admin/templates/admin/object_history.html:5 +#: contrib/admin/templates/admin/change_form.html:20 +msgid "History" +msgstr "வரலாறு" + +#: contrib/admin/templates/admin/object_history.html:18 +msgid "Date/time" +msgstr "தேதி/நேரம் " + +#: contrib/admin/templates/admin/object_history.html:19 +msgid "User" +msgstr "பயனர்" + +#: contrib/admin/templates/admin/object_history.html:20 +msgid "Action" +msgstr "செயல்" + +#: contrib/admin/templates/admin/object_history.html:26 +msgid "DATE_WITH_TIME_FULL" +msgstr "தேதியும் முழு நேரமும்" + +#: contrib/admin/templates/admin/object_history.html:36 +msgid "" +"This object doesn't have a change history. It probably wasn't added via this " +"admin site." +msgstr "" +"இந்த பொருள் மாற்ற வரலாற்றில் இல்லை" +"ஒரு வேளை நிர்வாகத்தளத்தின் மூலம் சேர்க்கப்படாமலிருக்கலாம்" + +#: contrib/admin/templates/admin/base_site.html:4 +msgid "Django site admin" +msgstr "டிஜாங்ஙோ தள நிர்வாகி" + +#: contrib/admin/templates/admin/base_site.html:7 +msgid "Django administration" +msgstr "டிஜாங்ஙோ நிர்வாகம் " + +#: contrib/admin/templates/admin/500.html:4 +msgid "Server error" +msgstr "சேவகன் பிழை" + +#: contrib/admin/templates/admin/500.html:6 +msgid "Server error (500)" +msgstr "சேவையகம் தவறு(500)" + +#: contrib/admin/templates/admin/500.html:9 +msgid "Server Error <em>(500)</em>" +msgstr "சேவையகம் பிழை<em>(500)</em>" + +#: contrib/admin/templates/admin/500.html:10 +msgid "" +"There's been an error. It's been reported to the site administrators via e-" +"mail and should be fixed shortly. Thanks for your patience." +msgstr "" +"தவறு ஏற்பட்டுள்ளது" +"வலைத்தள நிர்வாகிக்கு மின்னஞ்சல் அனுப்பப்பட்டுள்ளது. விரைவில் சரி செய்யப்படும். உங்க்ளது பொறுமைக்கு நன்றி" + +#: contrib/admin/templates/admin/404.html:4 +#: contrib/admin/templates/admin/404.html:8 +msgid "Page not found" +msgstr "பக்கத்தை காணவில்லை" + +#: contrib/admin/templates/admin/404.html:10 +msgid "We're sorry, but the requested page could not be found." +msgstr "" +"நீங்கள் விரும்பிய பக்கத்தை காண இயலவில்லை. " +"அதற்காக வருந்துகிறோம்." + +#: contrib/admin/templates/admin/index.html:17 +#, python-format +msgid "Models available in the %(name)s application." +msgstr "செயலியில் கிடைக்கக் கூடிய %(name)s மாதிரிகள்" + +#: contrib/admin/templates/admin/index.html:28 +#: contrib/admin/templates/admin/change_form.html:15 +msgid "Add" +msgstr "சேர்" + +#: contrib/admin/templates/admin/index.html:34 +msgid "Change" +msgstr "மாற்று" + +#: contrib/admin/templates/admin/index.html:44 +msgid "You don't have permission to edit anything." +msgstr "உங்களுக்கு மாற்றுவதற்கு உரிமையில்லை" + +#: contrib/admin/templates/admin/index.html:52 +msgid "Recent Actions" +msgstr "தற்போதைய செயல்கள்" + +#: contrib/admin/templates/admin/index.html:53 +msgid "My Actions" +msgstr "எனது செயல்கள்" + +#: contrib/admin/templates/admin/index.html:57 +msgid "None available" +msgstr "எதுவும் கிடைக்கவில்லை" + +#: contrib/admin/templates/admin/change_list.html:11 +#, python-format +msgid "Add %(name)s" +msgstr "%(name)s சேர்" + +#: contrib/admin/templates/admin/login.html:22 +msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?" +msgstr "நீங்கள் தங்களது கடவுச்சொல்லை <a href=\"/password_reset/\"> மறந்து விட்டீர்களா?" + +#: contrib/admin/templates/admin/base.html:23 +msgid "Welcome," +msgstr "நல்வரவு," + +#: contrib/admin/templates/admin/delete_confirmation.html:9 +#: contrib/admin/templates/admin/submit_line.html:3 +msgid "Delete" +msgstr "நீக்கு" + +#: contrib/admin/templates/admin/delete_confirmation.html:14 +#, python-format +msgid "" +"Deleting the %(object_name)s '%(object)s' would result in deleting related " +"objects, but your account doesn't have permission to delete the following " +"types of objects:" +msgstr "இந்த '%(object)s' இல் %(object_name)s நீக்குவது தொடர்புடைய மற்றவற்றையும் நீக்கும். ஆனால் அதற்கு உங்களுக்கு உரிமையில்லை" + +#: contrib/admin/templates/admin/delete_confirmation.html:21 +#, python-format +msgid "" +"Are you sure you want to delete the %(object_name)s \"%(object)s\"? All of " +"the following related items will be deleted:" +msgstr "" +"நீங்கள் இந்த \"%(object)s\" %(object_name)s நீக்குவதில் நிச்சயமா?" +"தொடர்புடைய மற்றவையும் நீக்கப்படும். " + +#: contrib/admin/templates/admin/delete_confirmation.html:26 +msgid "Yes, I'm sure" +msgstr "ஆம் எனக்கு உறுதி " + +#: contrib/admin/templates/admin/filter.html:2 +#, python-format +msgid " By %(title)s " +msgstr "%(title)s ஆல் " + +#: contrib/admin/templates/admin/search_form.html:8 +msgid "Go" +msgstr "செல்" + +#: contrib/admin/templates/admin/change_form.html:21 +msgid "View on site" +msgstr "தள்த்தில் பார் " + +#: contrib/admin/templates/admin/change_form.html:30 +msgid "Please correct the error below." +msgstr "கீழே உள்ள தவறுகளைத்திருத்து" + +#: contrib/admin/templates/admin/change_form.html:48 +msgid "Ordering" +msgstr "வரிசைப்படுத்துதல்" + +#: contrib/admin/templates/admin/change_form.html:51 +msgid "Order:" +msgstr "வரிசைப்படுத்து" + +#: contrib/admin/templates/admin/submit_line.html:4 +msgid "Save as new" +msgstr "புதியதாக சேமி" + +#: contrib/admin/templates/admin/submit_line.html:5 +msgid "Save and add another" +msgstr "சேமித்து இன்னுமொன்றைச் சேர்" + +#: contrib/admin/templates/admin/submit_line.html:6 +msgid "Save and continue editing" +msgstr "சேமித்து மாற்றத்தை தொடருக" + +#: contrib/admin/templates/admin/submit_line.html:7 +msgid "Save" +msgstr "சேமி" + +#: contrib/admin/templates/registration/password_change_done.html:4 +#: contrib/admin/templates/registration/password_change_form.html:4 +#: contrib/admin/templates/registration/password_change_form.html:6 +#: contrib/admin/templates/registration/password_change_form.html:10 +msgid "Password change" +msgstr "கடவுச்சொல் மாற்றம்" + +#: contrib/admin/templates/registration/password_change_done.html:6 +#: contrib/admin/templates/registration/password_change_done.html:10 +msgid "Password change successful" +msgstr "கடவுச்சொல் மாற்றம் வெற்றி " + +#: contrib/admin/templates/registration/password_change_done.html:12 +msgid "Your password was changed." +msgstr "உங்கள் கடவுச்சொல் மாற்றப் பட்டுள்ளது" + +#: contrib/admin/templates/registration/password_reset_form.html:4 +#: contrib/admin/templates/registration/password_reset_form.html:6 +#: contrib/admin/templates/registration/password_reset_form.html:10 +#: contrib/admin/templates/registration/password_reset_done.html:4 +msgid "Password reset" +msgstr "கடவுச்சொல்லை மாற்றியமை" + +#: contrib/admin/templates/registration/password_reset_form.html:12 +msgid "" +"Forgotten your password? Enter your e-mail address below, and we'll reset " +"your password and e-mail the new one to you." +msgstr "" +"கடவுச்சொல்லை மறந்து விட்டால்" +"உங்களது மின்னஞ்சல் முகவரியை உள்ளிடுக" +"அதன் பிறகு உங்கள் கடவுச்சொல் மாற்றியமைக்கப்பட்டு " +"உங்களது மின்னஞ்சல் முகவரிக்கு அனுப்பப்படும்" + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "E-mail address:" +msgstr "மின்அஞ்சல் முகவரி:" + +#: contrib/admin/templates/registration/password_reset_form.html:16 +msgid "Reset my password" +msgstr "எனது கடவுச்சொல்லை மாற்றியமை" + +#: contrib/admin/templates/registration/logged_out.html:8 +msgid "Thanks for spending some quality time with the Web site today." +msgstr "" +"வலைத்தளத்தில் உங்களது பொன்னான நேரத்தை " +"செலவழித்தமைக்கு மிகுந்த நன்றி" + +#: contrib/admin/templates/registration/logged_out.html:10 +msgid "Log in again" +msgstr "மீண்டும் உள்ளே பதிவு செய்யவும்" + +#: contrib/admin/templates/registration/password_reset_done.html:6 +#: contrib/admin/templates/registration/password_reset_done.html:10 +msgid "Password reset successful" +msgstr "கடவுச்சொல் மாற்றியமைத்தல் வெற்றி" + +#: contrib/admin/templates/registration/password_reset_done.html:12 +msgid "" +"We've e-mailed a new password to the e-mail address you submitted. You " +"should be receiving it shortly." +msgstr "" +"கடவுச்சொல்லை மறந்து விட்டால்" +"உங்களது மின்னஞ்சல் முகவரியை உள்ளிடுக" +"புதிய கடவுச்சொல் " +"உங்களது மின்னஞ்சல் முகவரிக்கு அனுப்பப்பட்டுள்ளது. விரைவில் அது உங்களுக்கு கிடைக்கும்" + +#: contrib/admin/templates/registration/password_change_form.html:12 +msgid "" +"Please enter your old password, for security's sake, and then enter your new " +"password twice so we can verify you typed it in correctly." +msgstr "பாதுகாப்பு காரணங்களுக்காக , முதலில் உங்களது பழைய கடவுச்சொல்லை உள்ளிடுக. அதன் பிறகு புதிய கடவுச்சொல்லை இரு முறை உள்ளிடுக. இது உங்களது உள்ளிடுதலை சரிபார்க்க உதவும். " + +#: contrib/admin/templates/registration/password_change_form.html:17 +msgid "Old password:" +msgstr "பழைய கடவுச்சொல் :" + +#: contrib/admin/templates/registration/password_change_form.html:19 +msgid "New password:" +msgstr "புதிய கடவுச்சொல்:" + +#: contrib/admin/templates/registration/password_change_form.html:21 +msgid "Confirm password:" +msgstr "கடவுச்சொல் மாற்றத்தை உறுதிப்படுத்து:" + +#: contrib/admin/templates/registration/password_change_form.html:23 +msgid "Change my password" +msgstr "கடவுச் சொல்லை மாற்றவும்" + +#: contrib/admin/templates/registration/password_reset_email.html:2 +msgid "You're receiving this e-mail because you requested a password reset" +msgstr "கடவுச்சொல்லை மாற்றியமைக்க நீங்கள் கேட்டதனால் உங்களுக்கு இந்த மின்னஞ்சல் அனுப்பப்பட்டுள்ளது" + +#: contrib/admin/templates/registration/password_reset_email.html:3 +#, python-format +msgid "for your user account at %(site_name)s" +msgstr "%(site_name)s -இல் உள்ள உங்களது பயனாளர் கணக்கு" + +#: contrib/admin/templates/registration/password_reset_email.html:5 +#, python-format +msgid "Your new password is: %(new_password)s" +msgstr "உங்களது புதிய கடவுச்சொல் : %(new_password)s " + +#: contrib/admin/templates/registration/password_reset_email.html:7 +msgid "Feel free to change this password by going to this page:" +msgstr "கடவுச்சொல்லை மாற்றியமைக்க நீங்கள் இந்த பக்கத்திற்கு தாராளமாக போகலாம்." + +#: contrib/admin/templates/registration/password_reset_email.html:11 +msgid "Your username, in case you've forgotten:" +msgstr "உங்களது பயனாளர் பெயர், (நீங்கள் மறந்திருந்தால் ): " + +#: contrib/admin/templates/registration/password_reset_email.html:13 +msgid "Thanks for using our site!" +msgstr "எங்களது வலைத்தளத்தை பயன் படுத்தியதற்கு மிகுந்த நன்றி" + +#: contrib/admin/templates/registration/password_reset_email.html:15 +#, python-format +msgid "The %(site_name)s team" +msgstr "இந்த %(site_name)s -இன் குழு " + +#: contrib/admin/templates/admin_doc/bookmarklets.html:3 +msgid "Bookmarklets" +msgstr "புத்தகக்குறிகள்" + +# translation of django_ad.po to +# translation of django_ad.po to +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# aukbc-guest, 2006. +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +#: contrib/admin/templates/admin_doc/bookmarklets.html:5 +msgid "Documentation bookmarklets" +msgstr "ஆவணமாக்கக் குறியீடு" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:9 +msgid "" +"\n" +"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n" +"toolbar, or right-click the link and add it to your bookmarks. Now you can\n" +"select the bookmarklet from any page in the site. Note that some of these\n" +"bookmarklets require you to be viewing the site from a computer designated\n" +"as \"internal\" (talk to your system administrator if you aren't sure if\n" +"your computer is \"internal\").</p>\n" +msgstr "" +"\n" +"<p class=\"help\"> புத்தக குறியீடுகளை நிறுவ இந்த இணைப்பினை புத்தகக்குறியீட்டுப் \n" +"பட்டைக்கு இழுக்கவும். அல்லது வலது கிிளிக செய்து புத்தகக்குறியீடுகளில் சேர்க்கவும். \n" +" இனி தளத்தில் எந்தப் பக்கத்தில் இருந்தும் புத்தகக்குறியீட்டினை தேர்வுசெய்ய முடியும். \n" +" நீங்கள் இந்த தளத்தை \"internal\" என குுறிக்கப்பட்ட கணிணியில் இருந்து மட்டுமே \n" +" ஒருசில புத்தகக்குறிகளை செயல்படுத்தமுடியும்\n " +" உங்களுக்கு, கணிணி \"internal\" என உறுதி செய்ய கணிணிமேளாலரை அணுகவும்.</p>\n" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:19 +msgid "Documentation for this page" +msgstr "இந்த பக்கத்திற்கான ஆவணம்" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:20 +msgid "" +"Jumps you from any page to the documentation for the view that generates " +"that page." +msgstr "எந்த ஒரு பக்கத்திலிருந்தும் ஆவணப்பக்கத்தை பார்வையிடுதல், அந்த பக்கத்தை உருவாக்குகிறது." + +#: contrib/admin/templates/admin_doc/bookmarklets.html:22 +msgid "Show object ID" +msgstr "object ID-ஐ காட்டு" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:23 +msgid "" +"Shows the content-type and unique ID for pages that represent a single " +"object." +msgstr "ஒரே object-ஐ குறிக்கும் பக்கங்களின் பொருளடக்க வகை மற்றும் unique ID-ஐ காட்டுகிறது." + +#: contrib/admin/templates/admin_doc/bookmarklets.html:25 +msgid "Edit this object (current window)" +msgstr "இதை திருத்துக (தற்போதைய சாளரம்)" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:26 +msgid "Jumps to the admin page for pages that represent a single object." +msgstr "ஒரே object-ஐ குறிக்கும் பக்கங்களைக் காண மேலாளர் பக்கத்திற்கு செல்க." + +#: contrib/admin/templates/admin_doc/bookmarklets.html:28 +msgid "Edit this object (new window)" +msgstr "இதை திருத்துக. (புதிய சாளரம்)" + +#: contrib/admin/templates/admin_doc/bookmarklets.html:29 +msgid "As above, but opens the admin page in a new window." +msgstr "மேளாலர் பக்கத்தை முன்பு கண்டதுபோல், ஆனால் புதிய சாளரத்தில் திறக்கிறது." + +#: contrib/admin/templates/widget/date_time.html:3 +msgid "Date:" +msgstr "தேதி:" + +#: contrib/admin/templates/widget/date_time.html:4 +msgid "Time:" +msgstr "நேரம்:" + +#: contrib/admin/templates/widget/file.html:2 +msgid "Currently:" +msgstr "தற்போது:" + +#: contrib/admin/templates/widget/file.html:3 +msgid "Change:" +msgstr "மாற்று:" + +#: contrib/redirects/models.py:7 +msgid "redirect from" +msgstr "லிருந்து திசைமாற்று" + +#: contrib/redirects/models.py:8 +msgid "" +"This should be an absolute path, excluding the domain name. Example: '/" +"events/search/'." +msgstr "" +"இது ஒரு முழுமையான பாதையாக இருக்கவேண்டும். " +"இணையத்தளப்பெயராக இருக்கக்கூடாது. உதாரணம்:'/" +"events/search/'." + +#: contrib/redirects/models.py:9 +msgid "redirect to" +msgstr "திரும்ப அனுப்பு" + +#: contrib/redirects/models.py:10 +msgid "" +"This can be either an absolute path (as above) or a full URL starting with " +"'http://'." +msgstr "இது முழுமையான பாதையாக (மேலே உள்ளது போல) அல்லது \"http\"//\" என தொடங்கும் வலை முகவரியாக இருக்கலாம்." + +#: contrib/redirects/models.py:12 +msgid "redirect" +msgstr "திரும்ப அனுப்பு" + +#: contrib/redirects/models.py:13 +msgid "redirects" +msgstr "திரும்ப அனுப்புகிறது. " + +#: contrib/flatpages/models.py:8 +msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes." +msgstr "உதாரணம்: '/about/contact/'. முன்னும் பின்னும் '/' உள்ளதை உறுதி செய்க. " + +#: contrib/flatpages/models.py:9 +msgid "title" +msgstr "தலைப்பு" + +#: contrib/flatpages/models.py:10 +msgid "content" +msgstr "பொருளடக்கம்" + +#: contrib/flatpages/models.py:11 +msgid "enable comments" +msgstr "விமர்சனங்களை செயலாக்கு" + +#: contrib/flatpages/models.py:12 +msgid "template name" +msgstr "வார்ப்புரு பெயர்" + +#: contrib/flatpages/models.py:13 +msgid "" +"Example: 'flatpages/contact_page'. If this isn't provided, the system will " +"use 'flatpages/default'." +msgstr "உதாரணம் 'flatpages/contact_page'. இது இல்லையெனில் 'flatpages/default' என்பதே பயன்படுத்தப்படும்.ப்படும்." + +#: contrib/flatpages/models.py:14 +msgid "registration required" +msgstr "முன்பதிவு தேவை" + +#: contrib/flatpages/models.py:14 +msgid "If this is checked, only logged-in users will be able to view the page." +msgstr "இது தெரிவு செய்யப்பட்டிருந்தால், உள்நுழைந்த பயனர்கள் மட்டுமே இந்தப் பக்கத்தை பார்க்க முடியும்." + +#: contrib/flatpages/models.py:18 +msgid "flat page" +msgstr "எளிய பக்கம்" + +#: contrib/flatpages/models.py:19 +msgid "flat pages" +msgstr "எளிய பக்கங்கள்" + +#: contrib/auth/models.py:13 contrib/auth/models.py:26 +msgid "name" +msgstr "பெயர்" + +#: contrib/auth/models.py:15 +msgid "codename" +msgstr "குறிமுறை பெயர்" + +#: contrib/auth/models.py:17 +msgid "permission" +msgstr "அனுமதி" + +#: contrib/auth/models.py:18 contrib/auth/models.py:27 +msgid "permissions" +msgstr "அனுமதிகள்" + +#: contrib/auth/models.py:29 +msgid "group" +msgstr "குழு" + +#: contrib/auth/models.py:30 contrib/auth/models.py:65 +msgid "groups" +msgstr "குழுக்கள்" + +#: contrib/auth/models.py:55 +msgid "username" +msgstr "பயனர் பெயர்" + +#: contrib/auth/models.py:56 +msgid "first name" +msgstr "முதல் பெயர்" + +#: contrib/auth/models.py:57 +msgid "last name" +msgstr "கடைசி பெயர்" + +#: contrib/auth/models.py:58 +msgid "e-mail address" +msgstr "மின்னஞ்சல் முகவரி" + +#: contrib/auth/models.py:59 +msgid "password" +msgstr "கடவுச்சொல்" + +#: contrib/auth/models.py:59 +msgid "Use '[algo]$[salt]$[hexdigest]'" +msgstr "பயன்படுத்து '[algo]$[salt]$[hexdigest]'" + +#: contrib/auth/models.py:60 +msgid "staff status" +msgstr "பணியாளர் நிலை" + +#: contrib/auth/models.py:60 +msgid "Designates whether the user can log into this admin site." +msgstr "பயனர், 'மேலாளலர்' பக்கத்தில் நுழை்ழைவதை முடிவு செய்கிறது " + +#: contrib/auth/models.py:61 +msgid "active" +msgstr "செயல்படும்" + +#: contrib/auth/models.py:62 +msgid "superuser status" +msgstr "மேலாளர் இருப்பு நிலை" + +#: contrib/auth/models.py:63 +msgid "last login" +msgstr "கடைசி உள்நுழைவு" + +#: contrib/auth/models.py:64 +msgid "date joined" +msgstr "சேர்ந்த தேதி" + +#: contrib/auth/models.py:66 +msgid "" +"In addition to the permissions manually assigned, this user will also get " +"all permissions granted to each group he/she is in." +msgstr "பயனர் தனது அனுமதிகளோடு ,தான் உள்ள குழுவினது அனுமதிகளைையும் பெறுவார்." + +#: contrib/auth/models.py:67 +msgid "user permissions" +msgstr "பயனர் அனுமதிகள்" + +#: contrib/auth/models.py:70 +msgid "user" +msgstr "பயனர்" + +#: contrib/auth/models.py:71 +msgid "users" +msgstr "பயனர்கள்" + +#: contrib/auth/models.py:76 +msgid "Personal info" +msgstr "தனிப்பட்ட விவரம்" + +#: contrib/auth/models.py:77 +msgid "Permissions" +msgstr "அனுமதிகள்" + +#: contrib/auth/models.py:78 +msgid "Important dates" +msgstr "முக்கியமான தேதிகள்" + +#: contrib/auth/models.py:79 +msgid "Groups" +msgstr "குழுக்கள்" + +#: contrib/auth/models.py:219 +msgid "message" +msgstr "செய்தி" + +#: contrib/auth/forms.py:30 +msgid "" +"Your Web browser doesn't appear to have cookies enabled. Cookies are " +"required for logging in." +msgstr " உங்கள் இணைய உலாவியில் குக்கிகள் செயலாக்கம் பெறவில்லை. உள்நுழைவதற்க்கு குக்கிகள் அவசியம்." + +#: contrib/contenttypes/models.py:25 +msgid "python model class name" +msgstr "python model class name" + +#: contrib/contenttypes/models.py:28 +msgid "content type" +msgstr "பொருளடக்க வகை " + +#: contrib/contenttypes/models.py:29 +msgid "content types" +msgstr "பொருளடக்க வகைகள்" + +#: contrib/sessions/models.py:35 +msgid "session key" +msgstr "அமர்வு குறியீ" + +#: contrib/sessions/models.py:36 +msgid "session data" +msgstr "அமர்வு தகவல்" + +#: contrib/sessions/models.py:37 +msgid "expire date" +msgstr "காலாவதியாகும் தேதி" + +#: contrib/sessions/models.py:41 +msgid "session" +msgstr "அமர்வு" + +#: contrib/sessions/models.py:42 +msgid "sessions" +msgstr "அமர்வுகள்" + +#: contrib/sites/models.py:10 +msgid "domain name" +msgstr "களப் பெயர்" + +#: contrib/sites/models.py:11 +msgid "display name" +msgstr "காட்டும் பெயர்" + +#: contrib/sites/models.py:15 +msgid "site" +msgstr "வலைத்தளம்" + +#: contrib/sites/models.py:16 +msgid "sites" +msgstr "வலைத்தளங்கள்" + +#: utils/translation.py:360 +msgid "DATE_FORMAT" +msgstr "தேதி வடிவம்" + +#: utils/translation.py:361 +msgid "DATETIME_FORMAT" +msgstr "தேதிநேர வடிவம்" + +# translation of django_ae.po to +# translation of django_ae.po to +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +#: utils/translation.py:362 +msgid "TIME_FORMAT" +msgstr "நேரத்தின் அமைப்பும்" + +#: utils/dates.py:6 +msgid "Monday" +msgstr "திங்கள்" + +#: utils/dates.py:6 +msgid "Tuesday" +msgstr "செவ்வாய்" + +#: utils/dates.py:6 +msgid "Wednesday" +msgstr "புதன்" + +#: utils/dates.py:6 +msgid "Thursday" +msgstr "வியாழன்" + +#: utils/dates.py:6 +msgid "Friday" +msgstr "வெள்ளி" + +#: utils/dates.py:7 +msgid "Saturday" +msgstr "சனி" + +#: utils/dates.py:7 +msgid "Sunday" +msgstr "ஞாயிறு" + +#: utils/dates.py:14 +msgid "January" +msgstr "ஜனவரி" + +#: utils/dates.py:14 +msgid "February" +msgstr "பிப்ரவரி" + +#: utils/dates.py:14 utils/dates.py:27 +msgid "March" +msgstr "மார்ச்" + +#: utils/dates.py:14 utils/dates.py:27 +msgid "April" +msgstr "ஏப்ரல்" + +#: utils/dates.py:14 utils/dates.py:27 +msgid "May" +msgstr "மே" + +#: utils/dates.py:14 utils/dates.py:27 +msgid "June" +msgstr "ஜூன்" + +#: utils/dates.py:15 utils/dates.py:27 +msgid "July" +msgstr "ஜூலை" + +#: utils/dates.py:15 +msgid "August" +msgstr "ஆகஸ்டு" + +#: utils/dates.py:15 +msgid "September" +msgstr "செப்டம்பர்" + +#: utils/dates.py:15 +msgid "October" +msgstr "அக்டோபர்" + +#: utils/dates.py:15 +msgid "November" +msgstr "நவம்பர்" + +#: utils/dates.py:16 +msgid "December" +msgstr "டிசம்பர்" + +#: utils/dates.py:19 +msgid "jan" +msgstr "ஜன" + +#: utils/dates.py:19 +msgid "feb" +msgstr "பிப்" + +#: utils/dates.py:19 +msgid "mar" +msgstr "மார்" + +#: utils/dates.py:19 +msgid "apr" +msgstr "ஏப்" + +#: utils/dates.py:19 +msgid "may" +msgstr "மே" + +#: utils/dates.py:19 +msgid "jun" +msgstr "ஜூன்" + +#: utils/dates.py:20 +msgid "jul" +msgstr "ஜூலை" + +#: utils/dates.py:20 +msgid "aug" +msgstr "ஆக" + +#: utils/dates.py:20 +msgid "sep" +msgstr "செப்" + +#: utils/dates.py:20 +msgid "oct" +msgstr "அக்" + +#: utils/dates.py:20 +msgid "nov" +msgstr "நவ" + +#: utils/dates.py:20 +msgid "dec" +msgstr "டிச" + +#: utils/dates.py:27 +msgid "Jan." +msgstr "ஜன." + +#: utils/dates.py:27 +msgid "Feb." +msgstr "பிப்." + +#: utils/dates.py:28 +msgid "Aug." +msgstr "ஆக." + +#: utils/dates.py:28 +msgid "Sept." +msgstr "செப்." + +#: utils/dates.py:28 +msgid "Oct." +msgstr "அக்." + +#: utils/dates.py:28 +msgid "Nov." +msgstr "நவ." + +#: utils/dates.py:28 +msgid "Dec." +msgstr "டிச." + +#: utils/timesince.py:12 +msgid "year" +msgstr "வருடம்" + +#: utils/timesince.py:13 +msgid "month" +msgstr "மாதம்" + +#: utils/timesince.py:14 +msgid "week" +msgstr "வாரம்" + +#: utils/timesince.py:15 +msgid "day" +msgstr "நாள்" + +#: utils/timesince.py:16 +msgid "hour" +msgstr "மணி" + +#: utils/timesince.py:17 +msgid "minute" +msgstr "நிமிடம்" + +#: conf/global_settings.py:37 +msgid "Bengali" +msgstr "பெங்காலி" + +#: conf/global_settings.py:38 +msgid "Czech" +msgstr "செக்" + +#: conf/global_settings.py:39 +msgid "Welsh" +msgstr "வெல்ஸ்" + +#: conf/global_settings.py:40 +msgid "Danish" +msgstr "டேனிஷ்" + +#: conf/global_settings.py:41 +msgid "German" +msgstr "ஜெர்மன்" + +#: conf/global_settings.py:42 +msgid "Greek" +msgstr "கிரேக்கம்" + +#: conf/global_settings.py:43 +msgid "English" +msgstr "ஆங்கிலம்" + +#: conf/global_settings.py:44 +msgid "Spanish" +msgstr "ஸ்பானிஷ்" + +#: conf/global_settings.py:45 +msgid "French" +msgstr "ப்ரென்சு" + +#: conf/global_settings.py:46 +msgid "Galician" +msgstr "கலீஷீயன்" + +#: conf/global_settings.py:47 +msgid "Hungarian" +msgstr "ஹங்கேரியன்" + +#: conf/global_settings.py:48 +msgid "Hebrew" +msgstr "ஹீப்ரு" + +#: conf/global_settings.py:49 +msgid "Icelandic" +msgstr "ஐஸ்லான்டிக்" + +#: conf/global_settings.py:50 +msgid "Italian" +msgstr "இத்தாலியன்" + +#: conf/global_settings.py:51 +msgid "Japanese" +msgstr "ஜப்பானிய" + +#: conf/global_settings.py:52 +msgid "Dutch" +msgstr "டச்சு" + +#: conf/global_settings.py:53 +msgid "Norwegian" +msgstr "நார்வீசியன்" + +#: conf/global_settings.py:54 +msgid "Brazilian" +msgstr "பிரேசிலியன்" + +#: conf/global_settings.py:55 +msgid "Romanian" +msgstr "ரோமானியன்" + +#: conf/global_settings.py:56 +msgid "Russian" +msgstr "ரஷ்யன்" + +#: conf/global_settings.py:57 +msgid "Slovak" +msgstr "சுலோவாக்" + +#: conf/global_settings.py:58 +msgid "Slovenian" +msgstr "ஸ்லோவேனியன்" + +#: conf/global_settings.py:59 +msgid "Serbian" +msgstr "செர்பியன்" + +#: conf/global_settings.py:60 +msgid "Swedish" +msgstr "சுவிடிஷ்" + +#: conf/global_settings.py:61 +msgid "Ukrainian" +msgstr "உக்ரேனியன்" + +#: conf/global_settings.py:62 +msgid "Simplified Chinese" +msgstr "எளிய சீன மொழி" + +#: conf/global_settings.py:63 +msgid "Traditional Chinese" +msgstr "மரபு சீன மொழி" + +#: core/validators.py:60 +msgid "This value must contain only letters, numbers and underscores." +msgstr "இந்த மதிப்பு எழுத்துகள் எண்கள் அன்டர்ஸ்கோர் மற்றும் உள்ளடக்க வேண்டும் " + +#: core/validators.py:64 +msgid "" +"This value must contain only letters, numbers, underscores, dashes or " +"slashes." +msgstr "இந்த மதிப்பு எழுத்துகள் எண்கள் அன்டர்ஸ்கோர் டஷ் அல்லது சலஷ் மற்றும் உள்ளடக்க வேண்டும்" + +#: core/validators.py:72 +msgid "Uppercase letters are not allowed here." +msgstr "பெரிய எழுத்துகளுக்கு இங்கு அனுமதி இல்லை இல்லை." + +#: core/validators.py:76 +msgid "Lowercase letters are not allowed here." +msgstr "சிறிய ய எழுத்துகளுக்கு இங்கு அனுமதி இல்லை" + +# translation of django_af.po to +# translation of django_af.po to +# translation of django_af.po to +# translation of django_af.po to +# translation of django_af.po to +# translation of django_af.po to +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# , 2006. +# R Hariram Aatreya <rha@localhost.localdomain>, 2006. +#: core/validators.py:83 +msgid "Enter only digits separated by commas." +msgstr "காற்புள்ளிகளால் தனிமைப்படுத்திய இலக்கஙகள மட்டும் எழுதவும்" + +#: core/validators.py:95 +msgid "Enter valid e-mail addresses separated by commas." +msgstr "காற்புள்ளிகளால் தனிமைப்படுத்திய முறையான e முகவரிகள்் மட்டும் எழுதவும்" + +#: core/validators.py:99 +msgid "Please enter a valid IP address." +msgstr "தயவு செய்து முறையான ஐ.பி முகவறி மட்டும் எழுதவும்" + +#: core/validators.py:103 +msgid "Empty values are not allowed here." +msgstr "காலியான மதிப்புக்கள் அனுமதி இல்லை" + +#: core/validators.py:107 +msgid "Non-numeric characters aren't allowed here." +msgstr "எண் வடிவமில்லாத எழுத்துக்கள் அனுமதி இல்லை" + +#: core/validators.py:111 +msgid "This value can't be comprised solely of digits." +msgstr "இந்த மதிப்பு இலக்கங்கள் மட்டுமே கொண்டதாக இருக்க கூடாது" + +#: core/validators.py:116 +msgid "Enter a whole number." +msgstr "முழு எண் மட்டுமே எழுதவும்" + +#: core/validators.py:120 +msgid "Only alphabetical characters are allowed here." +msgstr "அகர வரிசை எழுத்துக்கள் மட்டுமே அனுமதி உன்டு" + +#: core/validators.py:124 +msgid "Enter a valid date in YYYY-MM-DD format." +msgstr "வவவவ-மாமா-நாநா என்ற அமைப்பில் உள்ள முறையான தேதி மட்டுமே எழுதவும்" + +#: core/validators.py:128 +msgid "Enter a valid time in HH:MM format." +msgstr "மம-நிநி என்ற அமைப்பில் உள்ள முறையான நேரம் மட்டுமே எழுதவும்" + +#: core/validators.py:132 db/models/fields/__init__.py:468 +msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format." +msgstr "வவவவ-மாமா-நாநா மம-நிநி என்ற அமைப்பில் உள்ள முறையான தேதி/நேரம் மட்டுமே எழுதவும்" + +#: core/validators.py:136 +msgid "Enter a valid e-mail address." +msgstr "முறையான e முகவரிகள்் மட்டும் எழுதவும்" + +#: core/validators.py:148 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "முறையான படம் மட்டுமே பதிவேற்றம் செய்யவும். நீங்கள் பதிவேற்றம் செய்த கோப்பு படம் அள்ளாத அள்ளது கெட்டுப்போன கோப்பாகும்" + +#: core/validators.py:155 +#, python-format +msgid "The URL %s does not point to a valid image." +msgstr "%s என்ற இணையதள முகவறி சறியான படத்தைச் சுட்டவில்லை" + +#: core/validators.py:159 +#, python-format +msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid." +msgstr "தொலைபேசி எண்கள் XXX-XXX-XXXX என்ற அமைப்பில் இருக்க வேண்டும். \"%s\" என்பது முறையள்ள" + +#: core/validators.py:167 +#, python-format +msgid "The URL %s does not point to a valid QuickTime video." +msgstr "%s என்ற இணையதள முகவறி முறையான குயிக் டைம் படக்காட்சியைச் சுட்டவில்லை" + +#: core/validators.py:171 +msgid "A valid URL is required." +msgstr "முறையான இணையதள முகவறி தேவை" + +#: core/validators.py:185 +#, python-format +msgid "" +"Valid HTML is required. Specific errors are:\n" +"%s" +msgstr "" +"முறையான இணையதள முகவறி தேவை. குறிப்பிடத்தக்கத் தவறுகளாவன:\n" +"%s" + +#: core/validators.py:192 +#, python-format +msgid "Badly formed XML: %s" +msgstr "முறைப்படுத்தப்படாத XML: %s" + +#: core/validators.py:202 +#, python-format +msgid "Invalid URL: %s" +msgstr "முறைப்படுத்தப்படாத இணையதள முகவறி: %s" + +#: core/validators.py:206 core/validators.py:208 +#, python-format +msgid "The URL %s is a broken link." +msgstr "%s என்ற இணையதள முகவறி உடைந்துள்ளது" + +#: core/validators.py:214 +msgid "Enter a valid U.S. state abbreviation." +msgstr "முறையான U.S மாநில பெயர் சுருக்கம் எழுதவும்ழுதவும்" + +#: core/validators.py:229 +#, python-format +msgid "Watch your mouth! The word %s is not allowed here." +msgstr "வார்த்தைகளை அளன்து பேசுங்கள். %s என்ற வார்த்தை இங்கு அனுமதி இல்லை" + +#: core/validators.py:236 +#, python-format +msgid "This field must match the '%s' field." +msgstr "இந்த புலம் %s என்ற புலத்துடன் ஒத்திறுக்க வேண்டும்" + +#: core/validators.py:255 +msgid "Please enter something for at least one field." +msgstr "தயவு செய்து ஒரு புலத்திலாவது ஏதாவது எழுதவும்" + +#: core/validators.py:264 core/validators.py:275 +msgid "Please enter both fields or leave them both empty." +msgstr "தயவு செய்து இரு்புலங்கலையும்ும் நிரப்பவும்; அல்லது இரண்டையும் காலியாக விடவும்" + +#: core/validators.py:282 +#, python-format +msgid "This field must be given if %(field)s is %(value)s" +msgstr "%(field)s, %(value)s ஆக இருந்தால் இன்த புலம் இருக்க வேண்டும்" + +#: core/validators.py:294 +#, python-format +msgid "This field must be given if %(field)s is not %(value)s" +msgstr "%(field)s, %(value)s ஆக இல்லை என்றால் இன்த புலம் இருக்க வேண்டும்" + +#: core/validators.py:313 +msgid "Duplicate values are not allowed." +msgstr "போலியான மதிப்புகள் அனுமதி இல்லை" + +#: core/validators.py:336 +#, python-format +msgid "This value must be a power of %s." +msgstr "இந்த மதிப்பு %s இன் அடுக்காக இருக்க வேன்டும்" + +#: core/validators.py:347 +msgid "Please enter a valid decimal number." +msgstr "தயவுசெய்து முறையான பதின்ம எண்ணை நழைக்கcவும்" + +#: core/validators.py:349 +#, python-format +msgid "" +"Please enter a valid decimal number with at most %s total digit." +"Please enter a valid decimal number with at most %s total digits." +msgstr "" +"அதிகபட்சம் %s எண்ணை உள்ள பதின்ம எண்ணை நுழை." +"அதிகபட்சம் %s எண்கள் உள்ள பதின்ம எண்ணை நுழை." + +#: core/validators.py:352 +#, python-format +msgid "" +"Please enter a valid decimal number with at most %s decimal place." +"Please enter a valid decimal number with at most %s decimal places." +msgstr "" +"அதிகபட்சம் %s புள்ளி இடம் ள் உள்ள பதின்ம எண்ை நுழை" +"அதிகபட்சம் %s புள்ளி இடங்கள் உள்ள பதின்ம எண்ை நுழை" + +#: core/validators.py:362 +#, python-format +msgid "Make sure your uploaded file is at least %s bytes big." +msgstr "மேல்ஏற்று செய்யப்பட்ட கோப்பு குறைந்தபட்சம் %s பைட்டுகள் உள்ளனவா என சரி பார்க்கவும்" + +#: core/validators.py:363 +#, python-format +msgid "Make sure your uploaded file is at most %s bytes big." +msgstr "மேல்ஏற்று செய்யப்பட்ட கோப்பு அதிகபட்சம் %s பைட்டுகள் உள்ளனவா என சரி பார்க்கவும்." + +#: core/validators.py:376 +msgid "The format for this field is wrong." +msgstr "புலனுடைய அமைப்பு தவறு" + +#: core/validators.py:391 +msgid "This field is invalid." +msgstr "இந்த புலம் செல்லாது." + +#: core/validators.py:426 +#, python-format +msgid "Could not retrieve anything from %s." +msgstr "%s இருந்து எதுவும் எடுக்க முடியவில்லை" + +#: core/validators.py:429 +#, python-format +msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'." +msgstr "வலைமனை %(url)s என்பது செல்லாத உள்ளடக்க-வகை தலைப்பான '%(contenttype)s' ஐ திருப்பி தந்துள்ளது." + +#: core/validators.py:462 +#, python-format +msgid "" +"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with " +"\"%(start)s\".)" +msgstr " %(line)s கோடு லிருந்து மூடாத %(tag)s டாகை மூடு. ( வரி,\"%(start)s\"வுடன் துவங்குகின்றது)" + +#: core/validators.py:466 +#, python-format +msgid "" +"Some text starting on line %(line)s is not allowed in that context. (Line " +"starts with \"%(start)s\".)" +msgstr "வரி %(line)s இல் உள்ள சில உரைகள் இருப்பதற்கு அனுமதி இல்லை.( வரி,\"%(start)s\"வுடன் துவங்குகின்றது)" + +#: core/validators.py:471 +#, python-format +msgid "" +"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%" +"(start)s\".)" +msgstr "வரி %(line)s இல் உள்ள \"%(attr)s\" என்பது தவறான பண்பாகும.( வரி,\"%(start)s\"வுடன் துவங்குகின்றது)" + +#: core/validators.py:476 +#, python-format +msgid "" +"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%" +"(start)s\".)" +msgstr "வரி %(line)s இல் உள்ள \"<%(tag)s>\" என்பது தவறான ஒட்டாகும் .( வரி,\"%(start)s\"வுடன் துவங்குகின்றது)" + +#: core/validators.py:480 +#, python-format +msgid "" +"A tag on line %(line)s is missing one or more required attributes. (Line " +"starts with \"%(start)s\".)" +msgstr "வரி %(line)s இல் உள்ள ஒட்டு இன பண்புகள் தேவைப்படுகின்றன.(வரி,\"%(start)s\" வுடன் துவங்குகின்றது)" + +#: core/validators.py:485 +#, python-format +msgid "" +"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line " +"starts with \"%(start)s\".)" +msgstr "வரி %(line)s இல் உள்ள \"%(attr)s\" பண்பின் மதிப்பு தவறானது.(வரி \"%(start)s\" இருந்து ஆரம்பம்)" + +#: db/models/manipulators.py:302 +#, python-format +#, fuzzy +msgid "%(object)s with this %(type)s already exists for the given %(field)s." +msgstr "%(type)s உடன் உள்ள %(object)s உள்ளது" + +#: db/models/fields/__init__.py:40 +#, python-format +msgid "%(optname)s with this %(fieldname)s already exists." +msgstr "%(fieldname)s உடன் உள்ள %(optname)s உயிருடன உள்ளது" + +#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265 +#: db/models/fields/__init__.py:542 db/models/fields/__init__.py:553 +#: forms/__init__.py:346 +msgid "This field is required." +msgstr "இந்த புலத்தில் மதிப்பு தேவை" + +#: db/models/fields/__init__.py:337 +msgid "This value must be an integer." +msgstr "இந்த மதிப்பு முழுவெண்ணாக இருக்க வேண்டும" + +#: db/models/fields/__init__.py:369 +msgid "This value must be either True or False." +msgstr "இந்த மதிப்பு சரி அல்லது தவறாக இருக்க வேண்டும்" + +#: db/models/fields/__init__.py:385 +msgid "This field cannot be null." +msgstr "இந்த புலம் காலியாக இருக்கக் கூடாது" + +#: db/models/fields/__init__.py:562 +msgid "Enter a valid filename." +msgstr "முறையான கோப்புப் பெயரை எழுதவும்" + +#: db/models/fields/related.py:43 +#, python-format +msgid "Please enter a valid %s." +msgstr "தயவு செய்து முறையான %s எழுதவும்" + +#: db/models/fields/related.py:579 +msgid "Separate multiple IDs with commas." +msgstr "பன்மையிலுள்ள அடையாளங்களை காற்புள்ளிகளால் பிரிக்கவும்" + +#: db/models/fields/related.py:581 +msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." +msgstr "Mac இல், ஒன்றுக்கு மேற்பட்டவற்றை தேர்வு செய்ய \"Control\" அல்லது \"Command\" ஐ அழுத்தவும்" + +#: db/models/fields/related.py:625 +#, python-format +msgid "" +"Please enter valid %(self)s IDs. The value %(value)r is invalid." +"Please enter valid %(self)s IDs. The values %(value)r are invalid." +msgstr "" +"தயவு செய்து முறையான %(self)s அடையாளங்களை எழுதவும். %(value)r என்ற மதிப்பு முறையானதல்ல. " +"தயவு செய்து முறையான %(self)s அடையாளங்களை எழுதவும். %(value)r என்ற மதிப்புகள் முறையானதல்ல. " + +#: forms/__init__.py:380 +#, python-format +msgid "Ensure your text is less than %s character." +msgstr "உங்கள் உரை %s ஐ விட குறைவான எழுத்துக்களை உடையதென உறுதி செய்து கொள்ளுங்கள்" + +#: forms/__init__.py:385 +msgid "Line breaks are not allowed here." +msgstr "வரி உடைவுகள் அனுமதி இல்லை" + +#: forms/__init__.py:480 forms/__init__.py:551 forms/__init__.py:589 +#, python-format +msgid "Select a valid choice; '%(data)s' is not in %(choices)s." +msgstr "முறையான விருப்பத்தை தேர்வு செய்யவும்; '%(data)s என்பது %(choices)s இல் இல்லை" + +#: forms/__init__.py:645 +msgid "The submitted file is empty." +msgstr "சமர்பிக்கப் பட்ட கோப்பு காலியாக உள்ளது" + +#: forms/__init__.py:699 +msgid "Enter a whole number between -32,768 and 32,767." +msgstr "-32,768 மற்றும் 32,767 கு நடுவில் ஒரு முழு எண்ணை எழுதவும்" + +#: forms/__init__.py:708 +msgid "Enter a positive number." +msgstr "ஒரு நேர்க்குறி எண்ணை எழுதவும்" + +#: forms/__init__.py:717 +msgid "Enter a whole number between 0 and 32,767." +msgstr "0 மற்றும் 32,767 கு நடுவில் ஒரு முழு எண்ணை எழுதவும்" + +#: template/defaultfilters.py:379 +msgid "yes,no,maybe" +msgstr "ஆம், இல்லை, இருக்கலாம்" + diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py index 25376be12a..8c2b82147e 100644 --- a/django/contrib/admin/filterspecs.py +++ b/django/contrib/admin/filterspecs.py @@ -123,7 +123,7 @@ class DateFieldFilterSpec(FilterSpec): def choices(self, cl): for title, param_dict in self.links: yield {'selected': self.date_params == param_dict, - 'query_string': cl.get_query_string(param_dict, self.field_generic), + 'query_string': cl.get_query_string(param_dict, [self.field_generic]), 'display': title} FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) diff --git a/django/contrib/admin/media/css/changelists.css b/django/contrib/admin/media/css/changelists.css index fbcbe56f06..4834be4685 100644 --- a/django/contrib/admin/media/css/changelists.css +++ b/django/contrib/admin/media/css/changelists.css @@ -42,9 +42,9 @@ /* PAGINATOR */ .paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; } -.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; } +.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; } .paginator a.showall { padding:0 !important; border:none !important; } .paginator a.showall:hover { color:#036 !important; background:transparent !important; } -.paginator .end { border-width:2px !important; margin-right:6px; } +.paginator .end { border-width:2px !important; margin-right:6px; } .paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; } .paginator a:hover { color:white; background:#5b80b2; border-color:#036; } diff --git a/django/contrib/admin/media/css/forms.css b/django/contrib/admin/media/css/forms.css index b66f268fec..468e06a8a2 100644 --- a/django/contrib/admin/media/css/forms.css +++ b/django/contrib/admin/media/css/forms.css @@ -7,10 +7,10 @@ form .form-row p { padding-left:0; font-size:11px; } /* FORM LABELS */ -form h4 { margin:0 !important; padding:0 !important; border:none !important; } +form h4 { margin:0 !important; padding:0 !important; border:none !important; } label { font-weight:normal !important; color:#666; font-size:12px; } label.inline { margin-left:20px; } -.required label, label.required { font-weight:bold !important; color:#333 !important; } +.required label, label.required { font-weight:bold !important; color:#333 !important; } /* RADIO BUTTONS */ form ul.radiolist li { list-style-type:none; } diff --git a/django/contrib/admin/media/css/global.css b/django/contrib/admin/media/css/global.css index a87931681c..16c582d578 100644 --- a/django/contrib/admin/media/css/global.css +++ b/django/contrib/admin/media/css/global.css @@ -31,7 +31,7 @@ fieldset { margin:0; padding:0; } blockquote { font-size:11px; color:#777; margin-left:2px; padding-left:10px; border-left:5px solid #ddd; } code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background:inherit; color:#666; font-size:11px; } pre.literal-block { margin:10px; background:#eee; padding:6px 8px; } -code strong { color:#930; } +code strong { color:#930; } hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; } /* TEXT STYLES & MODIFIERS */ @@ -81,7 +81,7 @@ table.orderable tbody tr td:first-child { padding-left:14px; background-image:ur table.orderable-initalized .order-cell, body>tr>td.order-cell { display:none; } /* FORM DEFAULTS */ -input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; } +input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; } textarea { vertical-align:top !important; } input[type=text], input[type=password], textarea, select, .vTextField { border:1px solid #ccc; } @@ -92,7 +92,7 @@ input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2 input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; } /* MODULES */ -.module { border:1px solid #ccc; margin-bottom:5px; background:white; } +.module { border:1px solid #ccc; margin-bottom:5px; background:white; } .module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; } .module blockquote { margin-left:12px; } .module ul, .module ol { margin-left:1.5em; } diff --git a/django/contrib/admin/media/css/layout.css b/django/contrib/admin/media/css/layout.css index befe4fc1ca..17c52861ee 100644 --- a/django/contrib/admin/media/css/layout.css +++ b/django/contrib/admin/media/css/layout.css @@ -4,7 +4,7 @@ #header { width:100%; } #content-main { float:left; width:100%; } #content-related { float:right; width:18em; position:relative; margin-right:-19em; } -#footer { clear:both; padding:10px; } +#footer { clear:both; padding:10px; } /* COLUMN TYPES */ .colMS { margin-right:20em !important; } @@ -16,14 +16,14 @@ .dashboard #content { width:500px; } /* HEADER */ -#header { background:#417690; color:#ffc; overflow:hidden; } +#header { background:#417690; color:#ffc; overflow:hidden; } #header a:link, #header a:visited { color:white; } #header a:hover { text-decoration:underline; } #branding h1 { padding:0 10px; font-size:18px; margin:8px 0; font-weight:normal; color:#f4f379; } #branding h2 { padding:0 10px; font-size:14px; margin:-8px 0 8px 0; font-weight:normal; color:#ffc; } -#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; } +#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; } /* SIDEBAR */ #content-related h3 { font-size:12px; color:#666; margin-bottom:3px; } #content-related h4 { font-size:11px; } -#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; }
\ No newline at end of file +#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; }
\ No newline at end of file diff --git a/django/contrib/admin/media/css/rtl.css b/django/contrib/admin/media/css/rtl.css index c29391cabf..1974e7c2ec 100644 --- a/django/contrib/admin/media/css/rtl.css +++ b/django/contrib/admin/media/css/rtl.css @@ -16,7 +16,7 @@ th { text-align: right; } /* layout styles */ -#user-tools { right:auto; left:0; text-align:left; } +#user-tools { right:auto; left:0; text-align:left; } div.breadcrumbs { text-align:right; } #content-main { float:right;} #content-related { float:left; margin-left:-19em; margin-right:auto;} diff --git a/django/contrib/admin/media/js/admin/CollapsedFieldsets.js b/django/contrib/admin/media/js/admin/CollapsedFieldsets.js index 97f0a68d04..c8426db228 100644 --- a/django/contrib/admin/media/js/admin/CollapsedFieldsets.js +++ b/django/contrib/admin/media/js/admin/CollapsedFieldsets.js @@ -3,83 +3,83 @@ // link when the fieldset is visible. function findForm(node) { - // returns the node of the form containing the given node - if (node.tagName.toLowerCase() != 'form') { - return findForm(node.parentNode); - } - return node; + // returns the node of the form containing the given node + if (node.tagName.toLowerCase() != 'form') { + return findForm(node.parentNode); + } + return node; } var CollapsedFieldsets = { - collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with. - collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden. - collapsed_class: 'collapsed', - init: function() { - var fieldsets = document.getElementsByTagName('fieldset'); - var collapsed_seen = false; - for (var i = 0, fs; fs = fieldsets[i]; i++) { - // Collapse this fieldset if it has the correct class, and if it - // doesn't have any errors. (Collapsing shouldn't apply in the case - // of error messages.) - if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) { - collapsed_seen = true; - // Give it an additional class, used by CSS to hide it. - fs.className += ' ' + CollapsedFieldsets.collapsed_class; - // (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>) - var collapse_link = document.createElement('a'); - collapse_link.className = 'collapse-toggle'; - collapse_link.id = 'fieldsetcollapser' + i; - collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;'); - collapse_link.href = '#'; - collapse_link.innerHTML = gettext('Show'); - var h2 = fs.getElementsByTagName('h2')[0]; - h2.appendChild(document.createTextNode(' (')); - h2.appendChild(collapse_link); - h2.appendChild(document.createTextNode(')')); - } - } - if (collapsed_seen) { - // Expand all collapsed fieldsets when form is submitted. - addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); }); - } - }, - fieldset_has_errors: function(fs) { - // Returns true if any fields in the fieldset have validation errors. - var divs = fs.getElementsByTagName('div'); - for (var i=0; i<divs.length; i++) { - if (divs[i].className.match(/\berror\b/)) { - return true; - } - } - return false; - }, - show: function(fieldset_index) { - var fs = document.getElementsByTagName('fieldset')[fieldset_index]; - // Remove the class name that causes the "display: none". - fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, ''); - // Toggle the "Show" link to a "Hide" link - var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index); - collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;'); - collapse_link.innerHTML = gettext('Hide'); - }, - hide: function(fieldset_index) { - var fs = document.getElementsByTagName('fieldset')[fieldset_index]; - // Add the class name that causes the "display: none". - fs.className += ' ' + CollapsedFieldsets.collapsed_class; - // Toggle the "Hide" link to a "Show" link - var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index); + collapse_re: /\bcollapse\b/, // Class of fieldsets that should be dealt with. + collapsed_re: /\bcollapsed\b/, // Class that fieldsets get when they're hidden. + collapsed_class: 'collapsed', + init: function() { + var fieldsets = document.getElementsByTagName('fieldset'); + var collapsed_seen = false; + for (var i = 0, fs; fs = fieldsets[i]; i++) { + // Collapse this fieldset if it has the correct class, and if it + // doesn't have any errors. (Collapsing shouldn't apply in the case + // of error messages.) + if (fs.className.match(CollapsedFieldsets.collapse_re) && !CollapsedFieldsets.fieldset_has_errors(fs)) { + collapsed_seen = true; + // Give it an additional class, used by CSS to hide it. + fs.className += ' ' + CollapsedFieldsets.collapsed_class; + // (<a id="fieldsetcollapser3" class="collapse-toggle" href="#">Show</a>) + var collapse_link = document.createElement('a'); + collapse_link.className = 'collapse-toggle'; + collapse_link.id = 'fieldsetcollapser' + i; + collapse_link.onclick = new Function('CollapsedFieldsets.show('+i+'); return false;'); + collapse_link.href = '#'; + collapse_link.innerHTML = gettext('Show'); + var h2 = fs.getElementsByTagName('h2')[0]; + h2.appendChild(document.createTextNode(' (')); + h2.appendChild(collapse_link); + h2.appendChild(document.createTextNode(')')); + } + } + if (collapsed_seen) { + // Expand all collapsed fieldsets when form is submitted. + addEvent(findForm(document.getElementsByTagName('fieldset')[0]), 'submit', function() { CollapsedFieldsets.uncollapse_all(); }); + } + }, + fieldset_has_errors: function(fs) { + // Returns true if any fields in the fieldset have validation errors. + var divs = fs.getElementsByTagName('div'); + for (var i=0; i<divs.length; i++) { + if (divs[i].className.match(/\berror\b/)) { + return true; + } + } + return false; + }, + show: function(fieldset_index) { + var fs = document.getElementsByTagName('fieldset')[fieldset_index]; + // Remove the class name that causes the "display: none". + fs.className = fs.className.replace(CollapsedFieldsets.collapsed_re, ''); + // Toggle the "Show" link to a "Hide" link + var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index); + collapse_link.onclick = new Function('CollapsedFieldsets.hide('+fieldset_index+'); return false;'); + collapse_link.innerHTML = gettext('Hide'); + }, + hide: function(fieldset_index) { + var fs = document.getElementsByTagName('fieldset')[fieldset_index]; + // Add the class name that causes the "display: none". + fs.className += ' ' + CollapsedFieldsets.collapsed_class; + // Toggle the "Hide" link to a "Show" link + var collapse_link = document.getElementById('fieldsetcollapser' + fieldset_index); collapse_link.onclick = new Function('CollapsedFieldsets.show('+fieldset_index+'); return false;'); - collapse_link.innerHTML = gettext('Show'); - }, + collapse_link.innerHTML = gettext('Show'); + }, - uncollapse_all: function() { - var fieldsets = document.getElementsByTagName('fieldset'); - for (var i=0; i<fieldsets.length; i++) { - if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) { - CollapsedFieldsets.show(i); - } - } - } + uncollapse_all: function() { + var fieldsets = document.getElementsByTagName('fieldset'); + for (var i=0; i<fieldsets.length; i++) { + if (fieldsets[i].className.match(CollapsedFieldsets.collapsed_re)) { + CollapsedFieldsets.show(i); + } + } + } } addEvent(window, 'load', CollapsedFieldsets.init); diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html index 114f98c369..41514e6a81 100644 --- a/django/contrib/admin/templates/admin/base.html +++ b/django/contrib/admin/templates/admin/base.html @@ -20,9 +20,9 @@ <div id="branding"> {% block branding %}{% endblock %} </div> - {% if not user.is_anonymous %}{% if user.is_staff %} + {% if user.is_authenticated and user.is_staff %} <div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>. {% block userlinks %}<a href="doc/">{% trans 'Documentation' %}</a> / <a href="password_change/">{% trans 'Change password' %}</a> / <a href="logout/">{% trans 'Log out' %}</a>{% endblock %}</div> - {% endif %}{% endif %} + {% endif %} {% block nav-global %}{% endblock %} </div> <!-- END Header --> diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html index 5f338f703e..e5bda0f0e6 100644 --- a/django/contrib/admin/templates/admin/login.html +++ b/django/contrib/admin/templates/admin/login.html @@ -13,17 +13,17 @@ {% endif %} <div id="content-main"> <form action="{{ app_path }}" method="post" id="login-form"> - <div class="form-row"> - <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" /> - </div> - <div class="form-row"> - <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" /> - <input type="hidden" name="this_is_the_login_form" value="1" /> - <input type="hidden" name="post_data" value="{{ post_data }}" /> {% comment %}<span class="help">{% trans 'Have you <a href="/password_reset/">forgotten your password</a>?' %}</span>{% endcomment %} - </div> - <div class="submit-row"> - <label> </label><input type="submit" value="{% trans 'Log in' %}" /> - </div> + <div class="form-row"> + <label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" /> + </div> + <div class="form-row"> + <label for="id_password">{% trans 'Password:' %}</label> <input type="password" name="password" id="id_password" /> + <input type="hidden" name="this_is_the_login_form" value="1" /> + <input type="hidden" name="post_data" value="{{ post_data }}" /> {% comment %}<span class="help">{% trans 'Have you <a href="/password_reset/">forgotten your password</a>?' %}</span>{% endcomment %} + </div> + <div class="submit-row"> + <label> </label><input type="submit" value="{% trans 'Log in' %}" /> + </div> </form> <script type="text/javascript"> diff --git a/django/contrib/admin/templates/admin_doc/index.html b/django/contrib/admin/templates/admin_doc/index.html index 331774d2b3..74f9f20916 100644 --- a/django/contrib/admin/templates/admin_doc/index.html +++ b/django/contrib/admin/templates/admin_doc/index.html @@ -9,17 +9,17 @@ <h1>Documentation</h1>
<div id="content-main">
- <h3><a href="tags/">Tags</a></h3>
- <p>List of all the template tags and their functions.</p>
+ <h3><a href="tags/">Tags</a></h3>
+ <p>List of all the template tags and their functions.</p>
- <h3><a href="filters/">Filters</a></h3>
- <p>Filters are actions which can be applied to variables in a template to alter the output.</p>
+ <h3><a href="filters/">Filters</a></h3>
+ <p>Filters are actions which can be applied to variables in a template to alter the output.</p>
- <h3><a href="models/">Models</a></h3>
- <p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
+ <h3><a href="models/">Models</a></h3>
+ <p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
- <h3><a href="views/">Views</a></h3>
- <p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
+ <h3><a href="views/">Views</a></h3>
+ <p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
<h3><a href="bookmarklets/">Bookmarklets</a></h3>
<p>Tools for your browser to quickly access admin functionality.</p>
diff --git a/django/contrib/admin/templates/admin_doc/missing_docutils.html b/django/contrib/admin/templates/admin_doc/missing_docutils.html index d0b571f957..cdeab0cdd8 100644 --- a/django/contrib/admin/templates/admin_doc/missing_docutils.html +++ b/django/contrib/admin/templates/admin_doc/missing_docutils.html @@ -9,9 +9,9 @@ <h1>Documentation</h1> <div id="content-main"> - <h3>The admin documentation system requires Python's <a href="http://docutils.sf.net/">docutils</a> library.</h3> + <h3>The admin documentation system requires Python's <a href="http://docutils.sf.net/">docutils</a> library.</h3> - <p>Please ask your administrators to install <a href="http://docutils.sf.net/">docutils</a>.</p> + <p>Please ask your administrators to install <a href="http://docutils.sf.net/">docutils</a>.</p> </div> {% endblock %} diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ca250ba433..832b3562cd 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -1,8 +1,6 @@ -from django import template from django.conf import settings -from django.contrib.admin.views.main import MAX_SHOW_ALL_ALLOWED, ALL_VAR +from django.contrib.admin.views.main import ALL_VAR, EMPTY_CHANGELIST_VALUE from django.contrib.admin.views.main import ORDER_VAR, ORDER_TYPE_VAR, PAGE_VAR, SEARCH_VAR -from django.contrib.admin.views.main import IS_POPUP_VAR, EMPTY_CHANGELIST_VALUE from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.utils import dateformat @@ -119,7 +117,7 @@ def items_for_result(cl, result): if callable(attr): attr = attr() result_repr = str(attr) - except AttributeError, ObjectDoesNotExist: + except (AttributeError, ObjectDoesNotExist): result_repr = EMPTY_CHANGELIST_VALUE else: # Strip HTML tags in the resulting text, except if the diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py index 2d34452f52..7ba7bef74e 100644 --- a/django/contrib/admin/templatetags/admin_modify.py +++ b/django/contrib/admin/templatetags/admin_modify.py @@ -1,9 +1,7 @@ from django import template from django.contrib.admin.views.main import AdminBoundField from django.template import loader -from django.utils.html import escape from django.utils.text import capfirst -from django.utils.functional import curry from django.db import models from django.db.models.fields import Field from django.db.models.related import BoundRelatedObject diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 0242b2f32e..9adf09b6a5 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -3,7 +3,6 @@ import re from email.Parser import HeaderParser from email.Errors import HeaderParseError -from urlparse import urljoin try: import docutils.core import docutils.nodes diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py index 250c585220..fce50909f0 100644 --- a/django/contrib/admin/views/decorators.py +++ b/django/contrib/admin/views/decorators.py @@ -46,7 +46,7 @@ def staff_member_required(view_func): member, displaying the login page if necessary. """ def _checklogin(request, *args, **kwargs): - if not request.user.is_anonymous() and request.user.is_staff: + if request.user.is_authenticated() and request.user.is_staff: # The user is valid. Continue to the admin page. if request.POST.has_key('post_data'): # User must have re-authenticated through a different window diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py index 5aa143e1fd..68799fcc17 100644 --- a/django/contrib/admin/views/doc.py +++ b/django/contrib/admin/views/doc.py @@ -28,7 +28,7 @@ def bookmarklets(request): # Hack! This couples this view to the URL it lives at. admin_root = request.path[:-len('doc/bookmarklets/')] return render_to_response('admin_doc/bookmarklets.html', { - 'admin_url': "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', get_host(request), admin_root), + 'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', get_host(request), admin_root), }, context_instance=RequestContext(request)) bookmarklets = staff_member_required(bookmarklets) diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index a7ee08f1c0..705dfad6c8 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -10,9 +10,6 @@ from django.shortcuts import get_object_or_404, render_to_response from django.db import models from django.db.models.query import handle_legacy_orderlist, QuerySet from django.http import Http404, HttpResponse, HttpResponseRedirect -from django.template import loader -from django.utils import dateformat -from django.utils.dates import MONTHS from django.utils.html import escape from django.utils.text import capfirst, get_text_list import operator diff --git a/django/contrib/admin/views/template.py b/django/contrib/admin/views/template.py index f73b9e4218..1684870842 100644 --- a/django/contrib/admin/views/template.py +++ b/django/contrib/admin/views/template.py @@ -22,7 +22,7 @@ def template_validator(request): new_data = request.POST.copy() errors = manipulator.get_validation_errors(new_data) if not errors: - request.user.add_message('The template is valid.') + request.user.message_set.create(message='The template is valid.') return render_to_response('admin/template_validator.html', { 'title': 'Template validator', 'form': forms.FormWrapper(manipulator, new_data, errors), @@ -32,7 +32,7 @@ template_validator = staff_member_required(template_validator) class TemplateValidator(forms.Manipulator): def __init__(self, settings_modules): self.settings_modules = settings_modules - site_list = Site.objects.get_in_bulk(settings_modules.keys()).values() + site_list = Site.objects.in_bulk(settings_modules.keys()).values() self.fields = ( forms.SelectField('site', is_required=True, choices=[(s.id, s.name) for s in site_list]), forms.LargeTextField('template', is_required=True, rows=25, validator_list=[self.isValidTemplate]), diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 1c821801ef..a0097a01ed 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -56,8 +56,14 @@ def logout(request): """ Remove the authenticated user's ID from the request. """ - del request.session[SESSION_KEY] - del request.session[BACKEND_SESSION_KEY] + try: + del request.session[SESSION_KEY] + except KeyError: + pass + try: + del request.session[BACKEND_SESSION_KEY] + except KeyError: + pass def get_user(request): from django.contrib.auth.models import AnonymousUser diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py index 3b46b65b0a..4b8efcca46 100644 --- a/django/contrib/auth/backends.py +++ b/django/contrib/auth/backends.py @@ -1,4 +1,4 @@ -from django.contrib.auth.models import User, check_password +from django.contrib.auth.models import User class ModelBackend: """ diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index bc8ec39115..222c311e9c 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -17,7 +17,7 @@ def user_passes_test(test_func, login_url=LOGIN_URL): return _checklogin return _dec -login_required = user_passes_test(lambda u: not u.is_anonymous()) +login_required = user_passes_test(lambda u: u.is_authenticated()) login_required.__doc__ = ( """ Decorator for views that checks that the user is logged in, redirecting diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index cca3c62252..4077237993 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -1,4 +1,5 @@ from django.core import validators +from django.core.exceptions import ImproperlyConfigured from django.db import backend, connection, models from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext_lazy as _ @@ -125,6 +126,11 @@ class User(models.Model): def is_anonymous(self): "Always returns False. This is a way of comparing User objects to anonymous users." return False + + def is_authenticated(self): + """Always return True. This is a way to tell if the user has been authenticated in templates. + """ + return True def get_full_name(self): "Returns the first_name plus the last_name, with a space in between." @@ -293,3 +299,6 @@ class AnonymousUser(object): def is_anonymous(self): return True + + def is_authenticated(self): + return False diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 97ecd6a3fd..0ffa35bcff 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -4,7 +4,7 @@ from django import forms from django.shortcuts import render_to_response from django.template import RequestContext from django.contrib.sites.models import Site -from django.http import HttpResponse, HttpResponseRedirect +from django.http import HttpResponseRedirect from django.contrib.auth.decorators import login_required from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME diff --git a/django/contrib/comments/feeds.py b/django/contrib/comments/feeds.py index cad8c881a1..34cf3d9cef 100644 --- a/django/contrib/comments/feeds.py +++ b/django/contrib/comments/feeds.py @@ -1,7 +1,6 @@ from django.conf import settings from django.contrib.comments.models import Comment, FreeComment from django.contrib.syndication.feeds import Feed -from django.core.exceptions import ObjectDoesNotExist from django.contrib.sites.models import Site class LatestFreeCommentsFeed(Feed): @@ -37,6 +36,6 @@ class LatestCommentsFeed(LatestFreeCommentsFeed): qs = qs.filter(is_removed=False) if settings.COMMENTS_BANNED_USERS_GROUP: where = ['user_id NOT IN (SELECT user_id FROM auth_users_group WHERE group_id = %s)'] - params = [COMMENTS_BANNED_USERS_GROUP] + params = [settings.COMMENTS_BANNED_USERS_GROUP] qs = qs.extra(where=where, params=params) return qs diff --git a/django/contrib/comments/models.py b/django/contrib/comments/models.py index 23b0dfbde6..a8aff1cfb3 100644 --- a/django/contrib/comments/models.py +++ b/django/contrib/comments/models.py @@ -51,7 +51,7 @@ class CommentManager(models.Manager): extra_kwargs.setdefault('select', {}) extra_kwargs['select']['_karma_total_good'] = 'SELECT COUNT(*) FROM comments_karmascore, comments_comment WHERE comments_karmascore.comment_id=comments_comment.id AND score=1' extra_kwargs['select']['_karma_total_bad'] = 'SELECT COUNT(*) FROM comments_karmascore, comments_comment WHERE comments_karmascore.comment_id=comments_comment.id AND score=-1' - return self.filter(**kwargs).extra(**extra_kwargs) + return self.filter(**kwargs).extra(**extra_kwargs) def user_is_moderator(self, user): if user.is_superuser: diff --git a/django/contrib/comments/templates/comments/form.html b/django/contrib/comments/templates/comments/form.html index 4a6b5fc320..c5aa7686a3 100644 --- a/django/contrib/comments/templates/comments/form.html +++ b/django/contrib/comments/templates/comments/form.html @@ -2,10 +2,10 @@ {% if display_form %} <form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post"> -{% if user.is_anonymous %} -<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p> -{% else %} +{% if user.is_authenticated %} <p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p> +{% else %} +<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p> {% endif %} {% if ratings_optional or ratings_required %} diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py index a3893fdf61..c3a2fd40d8 100644 --- a/django/contrib/comments/templatetags/comments.py +++ b/django/contrib/comments/templatetags/comments.py @@ -114,7 +114,7 @@ class CommentListNode(template.Node): comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related() if not self.free: - if context.has_key('user') and not context['user'].is_anonymous(): + if context.has_key('user') and context['user'].is_authenticated(): user_id = context['user'].id context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user']) else: diff --git a/django/contrib/comments/views/comments.py b/django/contrib/comments/views/comments.py index c32a82f4d8..c19c62fc88 100644 --- a/django/contrib/comments/views/comments.py +++ b/django/contrib/comments/views/comments.py @@ -5,7 +5,7 @@ from django.http import Http404 from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import render_to_response from django.template import RequestContext -from django.contrib.comments.models import Comment, FreeComment, PHOTOS_REQUIRED, PHOTOS_OPTIONAL, RATINGS_REQUIRED, RATINGS_OPTIONAL, IS_PUBLIC +from django.contrib.comments.models import Comment, FreeComment, RATINGS_REQUIRED, RATINGS_OPTIONAL, IS_PUBLIC from django.contrib.contenttypes.models import ContentType from django.contrib.auth.forms import AuthenticationForm from django.http import HttpResponseRedirect @@ -63,7 +63,7 @@ class PublicCommentManipulator(AuthenticationForm): validator_list=get_validator_list(8), ), ]) - if not user.is_anonymous(): + if user.is_authenticated(): self["username"].is_required = False self["username"].validator_list = [] self["password"].is_required = False diff --git a/django/contrib/comments/views/karma.py b/django/contrib/comments/views/karma.py index becb02e128..8c18523feb 100644 --- a/django/contrib/comments/views/karma.py +++ b/django/contrib/comments/views/karma.py @@ -15,7 +15,7 @@ def vote(request, comment_id, vote): rating = {'up': 1, 'down': -1}.get(vote, False) if not rating: raise Http404, "Invalid vote" - if request.user.is_anonymous(): + if not request.user.is_authenticated(): raise Http404, _("Anonymous users cannot vote") try: comment = Comment.objects.get(pk=comment_id) diff --git a/django/contrib/flatpages/views.py b/django/contrib/flatpages/views.py index 1441f6f3a3..4ad24795f7 100644 --- a/django/contrib/flatpages/views.py +++ b/django/contrib/flatpages/views.py @@ -22,7 +22,7 @@ def flatpage(request, url): f = get_object_or_404(FlatPage, url__exact=url, sites__id__exact=settings.SITE_ID) # If registration is required for accessing this page, and the user isn't # logged in, redirect to the login page. - if f.registration_required and request.user.is_anonymous(): + if f.registration_required and not request.user.is_authenticated(): from django.contrib.auth.views import redirect_to_login return redirect_to_login(request.path) if f.template_name: diff --git a/django/contrib/sessions/models.py b/django/contrib/sessions/models.py index 8e2d011e3f..f684cd381e 100644 --- a/django/contrib/sessions/models.py +++ b/django/contrib/sessions/models.py @@ -32,11 +32,21 @@ class SessionManager(models.Manager): return s class Session(models.Model): - """Django provides full support for anonymous sessions. The session framework lets you store and retrieve arbitrary data on a per-site-visitor basis. It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID -- not the data itself. + """ + Django provides full support for anonymous sessions. The session + framework lets you store and retrieve arbitrary data on a + per-site-visitor basis. It stores data on the server side and + abstracts the sending and receiving of cookies. Cookies contain a + session ID -- not the data itself. - The Django sessions framework is entirely cookie-based. It does not fall back to putting session IDs in URLs. This is an intentional design decision. Not only does that behavior make URLs ugly, it makes your site vulnerable to session-ID theft via the "Referer" header. + The Django sessions framework is entirely cookie-based. It does + not fall back to putting session IDs in URLs. This is an intentional + design decision. Not only does that behavior make URLs ugly, it makes + your site vulnerable to session-ID theft via the "Referer" header. - For complete documentation on using Sessions in your code, consult the sessions documentation that is shipped with Django (also available on the Django website). + For complete documentation on using Sessions in your code, consult + the sessions documentation that is shipped with Django (also available + on the Django website). """ session_key = models.CharField(_('session key'), maxlength=40, primary_key=True) session_data = models.TextField(_('session data')) diff --git a/django/contrib/syndication/feeds.py b/django/contrib/syndication/feeds.py index e648c6c746..119615a0b9 100644 --- a/django/contrib/syndication/feeds.py +++ b/django/contrib/syndication/feeds.py @@ -73,7 +73,7 @@ class Feed(object): link = link, description = self.__get_dynamic_attr('description', obj), language = settings.LANGUAGE_CODE.decode(), - feed_url = add_domain(current_site, self.feed_url), + feed_url = add_domain(current_site, self.__get_dynamic_attr('feed_url', obj)), author_name = self.__get_dynamic_attr('author_name', obj), author_link = self.__get_dynamic_attr('author_link', obj), author_email = self.__get_dynamic_attr('author_email', obj), diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index 1b54addded..4a0d44a44e 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -1,7 +1,7 @@ "Database cache backend." from django.core.cache.backends.base import BaseCache -from django.db import connection, transaction +from django.db import connection, transaction, DatabaseError import base64, time from datetime import datetime try: diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py index 5bd6da5857..0e21b80ed8 100644 --- a/django/core/cache/backends/locmem.py +++ b/django/core/cache/backends/locmem.py @@ -3,10 +3,6 @@ from django.core.cache.backends.simple import CacheClass as SimpleCacheClass from django.utils.synch import RWLock import copy, time -try: - import cPickle as pickle -except ImportError: - import pickle class CacheClass(SimpleCacheClass): def __init__(self, host, params): diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index c25ff2b14e..62217acdce 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -119,7 +119,6 @@ class BaseHandler(object): Returns an HttpResponse that displays a PUBLIC error message for a fundamental error. """ - from django.core import urlresolvers callback, param_dict = resolver.resolve500() return callback(request, **param_dict) diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index 5a20ce9f67..07c98e3b59 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -23,6 +23,9 @@ class ModPythonRequest(http.HttpRequest): def get_full_path(self): return '%s%s' % (self.path, self._req.args and ('?' + self._req.args) or '') + def is_secure(self): + return self._req.subprocess_env.has_key('HTTPS') and self._req.subprocess_env['HTTPS'] == 'on' + def _load_post_and_files(self): "Populates self._post and self._files" if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'): @@ -145,7 +148,6 @@ class ModPythonHandler(BaseHandler): def populate_apache_request(http_response, mod_python_req): "Populates the mod_python request object with an HttpResponse" - from django.conf import settings mod_python_req.content_type = http_response['Content-Type'] for key, value in http_response.headers.items(): if key != 'Content-Type': diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 00a9a2ca53..5c48c9dace 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -54,18 +54,20 @@ class WSGIRequest(http.HttpRequest): def __init__(self, environ): self.environ = environ self.path = environ['PATH_INFO'] - self.META = environ + self.META = environ self.method = environ['REQUEST_METHOD'].upper() def __repr__(self): - from pprint import pformat - return '<DjangoRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \ + return '<WSGIRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \ (pformat(self.GET), pformat(self.POST), pformat(self.COOKIES), pformat(self.META)) def get_full_path(self): return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '') + def is_secure(self): + return self.environ.has_key('HTTPS') and self.environ['HTTPS'] == 'on' + def _load_post_and_files(self): # Populates self._post and self._files if self.method == 'POST': diff --git a/django/core/management.py b/django/core/management.py index 264e1b4799..8f8d00f167 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -92,11 +92,11 @@ def get_sql_create(app): final_output = [] app_models = models.get_models(app, creation_order=True) - for klass in app_models: - opts = klass._meta - connection_name = model_connection_name(klass) + for model in app_models: + opts = model._meta + connection_name = model_connection_name(model) output = connection_output.setdefault(connection_name, []) - db = klass._default_manager.db + db = model._default_manager.db creation = db.get_creation_module() data_types = creation.DATA_TYPES if not data_types: @@ -110,25 +110,25 @@ def get_sql_create(app): sys.exit(1) # Get installed models, so we generate REFERENCES right - manager = klass._default_manager + manager = model._default_manager tables = manager.get_table_list() installed_models = manager.get_installed_models(tables) models_output = set(installed_models) builder = creation.builder builder.models_already_seen.update(models_output) - model_output, references = builder.get_create_table(klass, style) + model_output, references = builder.get_create_table(model, style) output.extend(model_output) for refto, refs in references.items(): try: pending_references[refto].extend(refs) except KeyError: pending_references[refto] = refs - if klass in pending_references: - output.extend(pending_references.pop(klass)) + if model in pending_references: + output.extend(pending_references.pop(model)) # Create the many-to-many join tables. - many_many = builder.get_create_many_to_many(klass, style) - for refklass, statements in many_many.items(): + many_many = builder.get_create_many_to_many(model, style) + for refmodel, statements in many_many.items(): output.extend(statements) final_output = _collate(connection_output) @@ -137,9 +137,9 @@ def get_sql_create(app): not_installed_models = set(pending_references.keys()) if not_installed_models: final_output.append('-- The following references should be added but depend on non-existant tables:') - for klass in not_installed_models: + for model in not_installed_models: final_output.extend(['-- ' + sql - for sql in pending_references.pop(klass)]) + for sql in pending_references.pop(model)]) # convert BoundStatements into strings final_output = map(str, final_output) @@ -155,18 +155,18 @@ def get_sql_delete(app): connection_output = {} final_output = [] app_models = models.get_models(app, creation_order=True) - for klass in app_models: - db = klass._default_manager.db + for model in app_models: + db = model._default_manager.db connection = db.connection try: cursor = connection.cursor() except: cursor = None builder = db.get_creation_module().builder - connection_name = model_connection_name(klass) + connection_name = model_connection_name(model) output = connection_output.setdefault(connection_name, []) output.extend(map(str, - builder.get_drop_table(klass, + builder.get_drop_table(model, cascade=True, style=style))) if cursor: # Close database connection explicitly, in case this @@ -193,12 +193,12 @@ def get_sql_initial_data(app): connection_output = {} app_models = get_models(app) - for klass in app_models: - opts = klass._meta - connection_name = model_connection_name(klass) + for model in app_models: + opts = model._meta + connection_name = model_connection_name(model) output = connection_output.setdefault(connection_name, []) - builder = klass._default_manager.db.get_creation_module().builder - output.extend(builder.get_initialdata(klass)) + builder = model._default_manager.db.get_creation_module().builder + output.extend(builder.get_initialdata(model)) return _collate(connection_output) get_sql_initial_data.help_doc = "Prints the initial INSERT SQL statements for the given app name(s)." @@ -208,18 +208,18 @@ def get_sql_sequence_reset(app): "Returns a list of the SQL statements to reset PostgreSQL sequences for the given app." from django.db import backend, models output = [] - for klass in models.get_models(app): - for f in klass._meta.fields: + for model in models.get_models(app): + for f in model._meta.fields: if isinstance(f, models.AutoField): output.append("%s setval('%s', (%s max(%s) %s %s));" % \ (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD('%s_%s_seq' % (klass._meta.db_table, f.column)), + style.SQL_FIELD('%s_%s_seq' % (model._meta.db_table, f.column)), style.SQL_KEYWORD('SELECT'), style.SQL_FIELD(backend.quote_name(f.column)), style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(backend.quote_name(klass._meta.db_table)))) + style.SQL_TABLE(backend.quote_name(model._meta.db_table)))) break # Only one AutoField is allowed per model, so don't bother continuing. - for f in klass._meta.many_to_many: + for f in model._meta.many_to_many: output.append("%s setval('%s', (%s max(%s) %s %s));" % \ (style.SQL_KEYWORD('SELECT'), style.SQL_FIELD('%s_id_seq' % f.m2m_db_table()), @@ -237,12 +237,12 @@ def get_sql_indexes(app): from django.db.models import get_models connection_output = {} - for klass in get_models(app): - opts = klass._meta - connection_name = model_connection_name(klass) + for model in get_models(app): + opts = model._meta + connection_name = model_connection_name(model) output = connection_output.setdefault(connection_name, []) - builder = klass._default_manager.db.get_creation_module().builder - output.extend(map(str, builder.get_create_indexes(klass, style))) + builder = model._default_manager.db.get_creation_module().builder + output.extend(map(str, builder.get_create_indexes(model, style))) return _collate(connection_output) get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)." @@ -374,14 +374,14 @@ def get_admin_index(app): app_label = app_models[0]._meta.app_label output.append('{%% if perms.%s %%}' % app_label) output.append('<div class="module"><h2>%s</h2><table>' % app_label.title()) - for klass in app_models: - if klass._meta.admin: + for model in app_models: + if model._meta.admin: output.append(MODULE_TEMPLATE % { 'app': app_label, - 'mod': klass._meta.module_name, - 'name': capfirst(klass._meta.verbose_name_plural), - 'addperm': klass._meta.get_add_permission(), - 'changeperm': klass._meta.get_change_permission(), + 'mod': model._meta.module_name, + 'name': capfirst(model._meta.verbose_name_plural), + 'addperm': model._meta.get_add_permission(), + 'changeperm': model._meta.get_change_permission(), }) output.append('</table></div>') output.append('{% endif %}') @@ -432,23 +432,23 @@ def install(app): pending = {} for model in models.get_models(app, creation_order=True): new_pending = model._default_manager.install(initial_data=True) - for klass, statements in new_pending.items(): - pending.setdefault(klass, []).extend(statements) + for model, statements in new_pending.items(): + pending.setdefault(model, []).extend(statements) # execute any pending statements that were waiting for this model if model in pending: for statement in pending.pop(model): statement.execute() if pending: - for klass, statements in pending.items(): - tables = klass._default_manager.get_table_list() - models_installed = klass._default_manager.get_installed_models(tables) - if klass in models_installed: + for model, statements in pending.items(): + tables = model._default_manager.get_table_list() + models_installed = model._default_manager.get_installed_models(tables) + if model in models_installed: for statement in statements: statement.execute() else: raise Exception("%s is not installed, but there are " "pending statements that need it: %s" - % (klass, statements)) + % (model, statements)) except Exception, e: sys.stderr.write(style.ERROR("""Error: %s couldn't be installed. Possible reasons: * The database isn't running or isn't configured correctly. @@ -465,7 +465,6 @@ install.args = APP_ARGS def reset(app): "Executes the equivalent of 'get_sql_reset' in the current database." from django.db import connection, transaction - from cStringIO import StringIO app_name = app.__name__.split('.')[-2] disable_termcolors() @@ -565,7 +564,6 @@ startapp.args = "[appname]" def inspectdb(): "Generator that introspects the tables in the given database name and returns a Django model, one line at a time." from django.db import connection, get_introspection_module - from django.conf import settings import keyword introspection_module = get_introspection_module() diff --git a/django/core/paginator.py b/django/core/paginator.py index 195ad1009e..026fe0a675 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -1,4 +1,3 @@ -from copy import copy from math import ceil class InvalidPage(Exception): diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 7989e1d469..4181bc7f2b 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -79,7 +79,7 @@ def Deserializer(object_list, **options): elif field.rel and isinstance(field.rel, models.ManyToOneRel): try: data[field.name] = field.rel.to._default_manager.get(pk=field_value) - except RelatedModel.DoesNotExist: + except field.rel.to.DoesNotExist: data[field.name] = None # Handle all other fields diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 259a931594..7ce5706c23 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -8,7 +8,7 @@ been reviewed for security issues. Don't use it for production use. """ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -from types import ListType, StringType, TupleType +from types import ListType, StringType import os, re, sys, time, urllib __version__ = "0.1" diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 5819230496..b20cf0a05c 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -40,7 +40,7 @@ class MysqlDebugWrapper: def executemany(self, sql, param_list): try: return self.cursor.executemany(sql, param_list) - except Database.Warning: + except Database.Warning, w: self.cursor.execute("SHOW WARNINGS") raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall()) diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py index e1fbfff828..2c77f76ee3 100644 --- a/django/db/backends/mysql/introspection.py +++ b/django/db/backends/mysql/introspection.py @@ -1,4 +1,3 @@ -from django.db import transaction from django.db.backends.mysql.base import quote_name from MySQLdb import ProgrammingError, OperationalError from MySQLdb.constants import FIELD_TYPE diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index fe0586b9d0..1279cc9699 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -10,7 +10,6 @@ try: except ImportError, e: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured, "Error loading cx_Oracle module: %s" % e -import types DatabaseError = Database.Error diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py index 656741e440..ecc8f372a8 100644 --- a/django/db/backends/oracle/introspection.py +++ b/django/db/backends/oracle/introspection.py @@ -1,5 +1,3 @@ -from django.db import transaction -from django.db.backends.oracle.base import quote_name import re foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py index c3a16d61c3..6e1d60c4ff 100644 --- a/django/db/backends/postgresql/introspection.py +++ b/django/db/backends/postgresql/introspection.py @@ -1,4 +1,3 @@ -from django.db import transaction from django.db.backends.postgresql.base import quote_name def get_table_list(cursor): diff --git a/django/db/backends/postgresql_psycopg2/introspection.py b/django/db/backends/postgresql_psycopg2/introspection.py index b991493d39..a546da8c45 100644 --- a/django/db/backends/postgresql_psycopg2/introspection.py +++ b/django/db/backends/postgresql_psycopg2/introspection.py @@ -1,4 +1,3 @@ -from django.db import transaction from django.db.backends.postgresql_psycopg2.base import quote_name def get_table_list(cursor): diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index cdabffdc1c..4e22c5ea42 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -1,4 +1,3 @@ -from django.db import transaction from django.db.backends.sqlite3.base import quote_name def get_table_list(cursor): diff --git a/django/db/models/base.py b/django/db/models/base.py index c9336c8fdb..d88265579b 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -4,8 +4,7 @@ from django.core import validators from django.core.exceptions import ObjectDoesNotExist from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist from django.db.models.fields.related import OneToOneRel, ManyToOneRel -from django.db.models.related import RelatedObject -from django.db.models.query import orderlist2sql, delete_objects +from django.db.models.query import delete_objects from django.db.models.options import Options, AdminOptions from django.db import transaction from django.db.models import signals diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 86584b14e9..337a067745 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -4,7 +4,7 @@ from django.conf import settings from django.core import validators from django import forms from django.core.exceptions import ObjectDoesNotExist -from django.utils.functional import curry, lazy +from django.utils.functional import curry from django.utils.text import capfirst from django.utils.translation import gettext, gettext_lazy import datetime, os, time @@ -364,8 +364,8 @@ class BooleanField(Field): def to_python(self, value): if value in (True, False): return value - if value is 't': return True - if value is 'f': return False + if value in ('t', 'True'): return True + if value in ('f', 'False'): return False raise validators.ValidationError, gettext("This value must be either True or False.") def get_manipulator_field_objs(self): diff --git a/django/db/models/manager.py b/django/db/models/manager.py index ebe996adae..ef2a48b02e 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -1,12 +1,8 @@ -from django import core -from django.utils.functional import curry -from django.core.exceptions import ImproperlyConfigured from django.db import ConnectionInfoDescriptor from django.db.models.query import QuerySet from django.dispatch import dispatcher from django.db.models import signals, get_apps, get_models from django.db.models.fields import FieldDoesNotExist -from django.utils.datastructures import SortedDict try: # Only exists in Python 2.4+ diff --git a/django/db/models/manipulators.py b/django/db/models/manipulators.py index 454c318e5d..69e13dd160 100644 --- a/django/db/models/manipulators.py +++ b/django/db/models/manipulators.py @@ -5,7 +5,7 @@ from django.db.models.fields import FileField, AutoField from django.dispatch import dispatcher from django.db.models import signals from django.utils.functional import curry -from django.utils.datastructures import DotExpandedDict, MultiValueDict +from django.utils.datastructures import DotExpandedDict from django.utils.text import capfirst import types @@ -76,7 +76,7 @@ class AutomaticManipulator(forms.Manipulator): # Add field for ordering. if self.change and self.opts.get_ordered_objects(): - self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_")) + self.fields.append(forms.CommaSeparatedIntegerField(field_name="order_")) def save(self, new_data): # TODO: big cleanup when core fields go -> use recursive manipulators. diff --git a/django/db/models/query.py b/django/db/models/query.py index a77963e8ea..78179244e6 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -18,7 +18,7 @@ QUERY_TERMS = ( 'exact', 'iexact', 'contains', 'icontains', 'gt', 'gte', 'lt', 'lte', 'in', 'startswith', 'istartswith', 'endswith', 'iendswith', - 'range', 'year', 'month', 'day', 'isnull', + 'range', 'year', 'month', 'day', 'isnull', 'search', ) # Size of each "chunk" for get_iterator calls. diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index d93f696685..1a617b5946 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -6,24 +6,24 @@ system. Module attributes of note: - Any -- Singleton used to signal either "Any Sender" or - "Any Signal". See documentation of the _Any class. - Anonymous -- Singleton used to signal "Anonymous Sender" - See documentation of the _Anonymous class. + Any -- Singleton used to signal either "Any Sender" or + "Any Signal". See documentation of the _Any class. + Anonymous -- Singleton used to signal "Anonymous Sender" + See documentation of the _Anonymous class. Internal attributes: - WEAKREF_TYPES -- tuple of types/classes which represent - weak references to receivers, and thus must be de- - referenced on retrieval to retrieve the callable - object - connections -- { senderkey (id) : { signal : [receivers...]}} - senders -- { senderkey (id) : weakref(sender) } - used for cleaning up sender references on sender - deletion - sendersBack -- { receiverkey (id) : [senderkey (id)...] } - used for cleaning up receiver references on receiver - deletion, (considerably speeds up the cleanup process - vs. the original code.) + WEAKREF_TYPES -- tuple of types/classes which represent + weak references to receivers, and thus must be de- + referenced on retrieval to retrieve the callable + object + connections -- { senderkey (id) : { signal : [receivers...]}} + senders -- { senderkey (id) : weakref(sender) } + used for cleaning up sender references on sender + deletion + sendersBack -- { receiverkey (id) : [senderkey (id)...] } + used for cleaning up receiver references on receiver + deletion, (considerably speeds up the cleanup process + vs. the original code.) """ from __future__ import generators import types, weakref @@ -34,44 +34,44 @@ __cvsid__ = "$Id: dispatcher.py,v 1.9 2005/09/17 04:55:57 mcfletch Exp $" __version__ = "$Revision: 1.9 $"[11:-2] try: - True + True except NameError: - True = 1==1 - False = 1==0 + True = 1==1 + False = 1==0 class _Parameter: - """Used to represent default parameter values.""" - def __repr__(self): - return self.__class__.__name__ + """Used to represent default parameter values.""" + def __repr__(self): + return self.__class__.__name__ class _Any(_Parameter): - """Singleton used to signal either "Any Sender" or "Any Signal" + """Singleton used to signal either "Any Sender" or "Any Signal" - The Any object can be used with connect, disconnect, - send, or sendExact to signal that the parameter given - Any should react to all senders/signals, not just - a particular sender/signal. - """ + The Any object can be used with connect, disconnect, + send, or sendExact to signal that the parameter given + Any should react to all senders/signals, not just + a particular sender/signal. + """ Any = _Any() class _Anonymous(_Parameter): - """Singleton used to signal "Anonymous Sender" + """Singleton used to signal "Anonymous Sender" - The Anonymous object is used to signal that the sender - of a message is not specified (as distinct from being - "any sender"). Registering callbacks for Anonymous - will only receive messages sent without senders. Sending - with anonymous will only send messages to those receivers - registered for Any or Anonymous. + The Anonymous object is used to signal that the sender + of a message is not specified (as distinct from being + "any sender"). Registering callbacks for Anonymous + will only receive messages sent without senders. Sending + with anonymous will only send messages to those receivers + registered for Any or Anonymous. - Note: - The default sender for connect is Any, while the - default sender for send is Anonymous. This has - the effect that if you do not specify any senders - in either function then all messages are routed - as though there was a single sender (Anonymous) - being used everywhere. - """ + Note: + The default sender for connect is Any, while the + default sender for send is Anonymous. This has + the effect that if you do not specify any senders + in either function then all messages are routed + as though there was a single sender (Anonymous) + being used everywhere. + """ Anonymous = _Anonymous() WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref) @@ -82,416 +82,416 @@ sendersBack = {} def connect(receiver, signal=Any, sender=Any, weak=True): - """Connect receiver to sender for signal + """Connect receiver to sender for signal - receiver -- a callable Python object which is to receive - messages/signals/events. Receivers must be hashable - objects. + receiver -- a callable Python object which is to receive + messages/signals/events. Receivers must be hashable + objects. - if weak is True, then receiver must be weak-referencable - (more precisely saferef.safeRef() must be able to create - a reference to the receiver). - - Receivers are fairly flexible in their specification, - as the machinery in the robustApply module takes care - of most of the details regarding figuring out appropriate - subsets of the sent arguments to apply to a given - receiver. + if weak is True, then receiver must be weak-referencable + (more precisely saferef.safeRef() must be able to create + a reference to the receiver). + + Receivers are fairly flexible in their specification, + as the machinery in the robustApply module takes care + of most of the details regarding figuring out appropriate + subsets of the sent arguments to apply to a given + receiver. - Note: - if receiver is itself a weak reference (a callable), - it will be de-referenced by the system's machinery, - so *generally* weak references are not suitable as - receivers, though some use might be found for the - facility whereby a higher-level library passes in - pre-weakrefed receiver references. + Note: + if receiver is itself a weak reference (a callable), + it will be de-referenced by the system's machinery, + so *generally* weak references are not suitable as + receivers, though some use might be found for the + facility whereby a higher-level library passes in + pre-weakrefed receiver references. - signal -- the signal to which the receiver should respond - - if Any, receiver will receive any signal from the - indicated sender (which might also be Any, but is not - necessarily Any). - - Otherwise must be a hashable Python object other than - None (DispatcherError raised on None). - - sender -- the sender to which the receiver should respond - - if Any, receiver will receive the indicated signals - from any sender. - - if Anonymous, receiver will only receive indicated - signals from send/sendExact which do not specify a - sender, or specify Anonymous explicitly as the sender. + signal -- the signal to which the receiver should respond + + if Any, receiver will receive any signal from the + indicated sender (which might also be Any, but is not + necessarily Any). + + Otherwise must be a hashable Python object other than + None (DispatcherError raised on None). + + sender -- the sender to which the receiver should respond + + if Any, receiver will receive the indicated signals + from any sender. + + if Anonymous, receiver will only receive indicated + signals from send/sendExact which do not specify a + sender, or specify Anonymous explicitly as the sender. - Otherwise can be any python object. - - weak -- whether to use weak references to the receiver - By default, the module will attempt to use weak - references to the receiver objects. If this parameter - is false, then strong references will be used. + Otherwise can be any python object. + + weak -- whether to use weak references to the receiver + By default, the module will attempt to use weak + references to the receiver objects. If this parameter + is false, then strong references will be used. - returns None, may raise DispatcherTypeError - """ - if signal is None: - raise errors.DispatcherTypeError( - 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) - ) - if weak: - receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) - senderkey = id(sender) - if connections.has_key(senderkey): - signals = connections[senderkey] - else: - connections[senderkey] = signals = {} - # Keep track of senders for cleanup. - # Is Anonymous something we want to clean up? - if sender not in (None, Anonymous, Any): - def remove(object, senderkey=senderkey): - _removeSender(senderkey=senderkey) - # Skip objects that can not be weakly referenced, which means - # they won't be automatically cleaned up, but that's too bad. - try: - weakSender = weakref.ref(sender, remove) - senders[senderkey] = weakSender - except: - pass - - receiverID = id(receiver) - # get current set, remove any current references to - # this receiver in the set, including back-references - if signals.has_key(signal): - receivers = signals[signal] - _removeOldBackRefs(senderkey, signal, receiver, receivers) - else: - receivers = signals[signal] = [] - try: - current = sendersBack.get( receiverID ) - if current is None: - sendersBack[ receiverID ] = current = [] - if senderkey not in current: - current.append(senderkey) - except: - pass + returns None, may raise DispatcherTypeError + """ + if signal is None: + raise errors.DispatcherTypeError( + 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) + ) + if weak: + receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) + senderkey = id(sender) + if connections.has_key(senderkey): + signals = connections[senderkey] + else: + connections[senderkey] = signals = {} + # Keep track of senders for cleanup. + # Is Anonymous something we want to clean up? + if sender not in (None, Anonymous, Any): + def remove(object, senderkey=senderkey): + _removeSender(senderkey=senderkey) + # Skip objects that can not be weakly referenced, which means + # they won't be automatically cleaned up, but that's too bad. + try: + weakSender = weakref.ref(sender, remove) + senders[senderkey] = weakSender + except: + pass + + receiverID = id(receiver) + # get current set, remove any current references to + # this receiver in the set, including back-references + if signals.has_key(signal): + receivers = signals[signal] + _removeOldBackRefs(senderkey, signal, receiver, receivers) + else: + receivers = signals[signal] = [] + try: + current = sendersBack.get( receiverID ) + if current is None: + sendersBack[ receiverID ] = current = [] + if senderkey not in current: + current.append(senderkey) + except: + pass - receivers.append(receiver) + receivers.append(receiver) def disconnect(receiver, signal=Any, sender=Any, weak=True): - """Disconnect receiver from sender for signal + """Disconnect receiver from sender for signal - receiver -- the registered receiver to disconnect - signal -- the registered signal to disconnect - sender -- the registered sender to disconnect - weak -- the weakref state to disconnect + receiver -- the registered receiver to disconnect + signal -- the registered signal to disconnect + sender -- the registered sender to disconnect + weak -- the weakref state to disconnect - disconnect reverses the process of connect, - the semantics for the individual elements are - logically equivalent to a tuple of - (receiver, signal, sender, weak) used as a key - to be deleted from the internal routing tables. - (The actual process is slightly more complex - but the semantics are basically the same). + disconnect reverses the process of connect, + the semantics for the individual elements are + logically equivalent to a tuple of + (receiver, signal, sender, weak) used as a key + to be deleted from the internal routing tables. + (The actual process is slightly more complex + but the semantics are basically the same). - Note: - Using disconnect is not required to cleanup - routing when an object is deleted, the framework - will remove routes for deleted objects - automatically. It's only necessary to disconnect - if you want to stop routing to a live object. - - returns None, may raise DispatcherTypeError or - DispatcherKeyError - """ - if signal is None: - raise errors.DispatcherTypeError( - 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) - ) - if weak: receiver = saferef.safeRef(receiver) - senderkey = id(sender) - try: - signals = connections[senderkey] - receivers = signals[signal] - except KeyError: - raise errors.DispatcherKeyError( - """No receivers found for signal %r from sender %r""" %( - signal, - sender - ) - ) - try: - # also removes from receivers - _removeOldBackRefs(senderkey, signal, receiver, receivers) - except ValueError: - raise errors.DispatcherKeyError( - """No connection to receiver %s for signal %s from sender %s""" %( - receiver, - signal, - sender - ) - ) - _cleanupConnections(senderkey, signal) + Note: + Using disconnect is not required to cleanup + routing when an object is deleted, the framework + will remove routes for deleted objects + automatically. It's only necessary to disconnect + if you want to stop routing to a live object. + + returns None, may raise DispatcherTypeError or + DispatcherKeyError + """ + if signal is None: + raise errors.DispatcherTypeError( + 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) + ) + if weak: receiver = saferef.safeRef(receiver) + senderkey = id(sender) + try: + signals = connections[senderkey] + receivers = signals[signal] + except KeyError: + raise errors.DispatcherKeyError( + """No receivers found for signal %r from sender %r""" %( + signal, + sender + ) + ) + try: + # also removes from receivers + _removeOldBackRefs(senderkey, signal, receiver, receivers) + except ValueError: + raise errors.DispatcherKeyError( + """No connection to receiver %s for signal %s from sender %s""" %( + receiver, + signal, + sender + ) + ) + _cleanupConnections(senderkey, signal) def getReceivers( sender = Any, signal = Any ): - """Get list of receivers from global tables + """Get list of receivers from global tables - This utility function allows you to retrieve the - raw list of receivers from the connections table - for the given sender and signal pair. + This utility function allows you to retrieve the + raw list of receivers from the connections table + for the given sender and signal pair. - Note: - there is no guarantee that this is the actual list - stored in the connections table, so the value - should be treated as a simple iterable/truth value - rather than, for instance a list to which you - might append new records. + Note: + there is no guarantee that this is the actual list + stored in the connections table, so the value + should be treated as a simple iterable/truth value + rather than, for instance a list to which you + might append new records. - Normally you would use liveReceivers( getReceivers( ...)) - to retrieve the actual receiver objects as an iterable - object. - """ - try: - return connections[id(sender)][signal] - except KeyError: - return [] + Normally you would use liveReceivers( getReceivers( ...)) + to retrieve the actual receiver objects as an iterable + object. + """ + try: + return connections[id(sender)][signal] + except KeyError: + return [] def liveReceivers(receivers): - """Filter sequence of receivers to get resolved, live receivers + """Filter sequence of receivers to get resolved, live receivers - This is a generator which will iterate over - the passed sequence, checking for weak references - and resolving them, then returning all live - receivers. - """ - for receiver in receivers: - if isinstance( receiver, WEAKREF_TYPES): - # Dereference the weak reference. - receiver = receiver() - if receiver is not None: - yield receiver - else: - yield receiver + This is a generator which will iterate over + the passed sequence, checking for weak references + and resolving them, then returning all live + receivers. + """ + for receiver in receivers: + if isinstance( receiver, WEAKREF_TYPES): + # Dereference the weak reference. + receiver = receiver() + if receiver is not None: + yield receiver + else: + yield receiver def getAllReceivers( sender = Any, signal = Any ): - """Get list of all receivers from global tables + """Get list of all receivers from global tables - This gets all receivers which should receive - the given signal from sender, each receiver should - be produced only once by the resulting generator - """ - receivers = {} - for set in ( - # Get receivers that receive *this* signal from *this* sender. - getReceivers( sender, signal ), - # Add receivers that receive *any* signal from *this* sender. - getReceivers( sender, Any ), - # Add receivers that receive *this* signal from *any* sender. - getReceivers( Any, signal ), - # Add receivers that receive *any* signal from *any* sender. - getReceivers( Any, Any ), - ): - for receiver in set: - if receiver: # filter out dead instance-method weakrefs - try: - if not receivers.has_key( receiver ): - receivers[receiver] = 1 - yield receiver - except TypeError: - # dead weakrefs raise TypeError on hash... - pass + This gets all receivers which should receive + the given signal from sender, each receiver should + be produced only once by the resulting generator + """ + receivers = {} + for set in ( + # Get receivers that receive *this* signal from *this* sender. + getReceivers( sender, signal ), + # Add receivers that receive *any* signal from *this* sender. + getReceivers( sender, Any ), + # Add receivers that receive *this* signal from *any* sender. + getReceivers( Any, signal ), + # Add receivers that receive *any* signal from *any* sender. + getReceivers( Any, Any ), + ): + for receiver in set: + if receiver: # filter out dead instance-method weakrefs + try: + if not receivers.has_key( receiver ): + receivers[receiver] = 1 + yield receiver + except TypeError: + # dead weakrefs raise TypeError on hash... + pass def send(signal=Any, sender=Anonymous, *arguments, **named): - """Send signal from sender to all connected receivers. - - signal -- (hashable) signal value, see connect for details + """Send signal from sender to all connected receivers. + + signal -- (hashable) signal value, see connect for details - sender -- the sender of the signal - - if Any, only receivers registered for Any will receive - the message. + sender -- the sender of the signal + + if Any, only receivers registered for Any will receive + the message. - if Anonymous, only receivers registered to receive - messages from Anonymous or Any will receive the message + if Anonymous, only receivers registered to receive + messages from Anonymous or Any will receive the message - Otherwise can be any python object (normally one - registered with a connect if you actually want - something to occur). + Otherwise can be any python object (normally one + registered with a connect if you actually want + something to occur). - arguments -- positional arguments which will be passed to - *all* receivers. Note that this may raise TypeErrors - if the receivers do not allow the particular arguments. - Note also that arguments are applied before named - arguments, so they should be used with care. + arguments -- positional arguments which will be passed to + *all* receivers. Note that this may raise TypeErrors + if the receivers do not allow the particular arguments. + Note also that arguments are applied before named + arguments, so they should be used with care. - named -- named arguments which will be filtered according - to the parameters of the receivers to only provide those - acceptable to the receiver. + named -- named arguments which will be filtered according + to the parameters of the receivers to only provide those + acceptable to the receiver. - Return a list of tuple pairs [(receiver, response), ... ] + Return a list of tuple pairs [(receiver, response), ... ] - if any receiver raises an error, the error propagates back - through send, terminating the dispatch loop, so it is quite - possible to not have all receivers called if a raises an - error. - """ - # Call each receiver with whatever arguments it can accept. - # Return a list of tuple pairs [(receiver, response), ... ]. - responses = [] - for receiver in liveReceivers(getAllReceivers(sender, signal)): - response = robustapply.robustApply( - receiver, - signal=signal, - sender=sender, - *arguments, - **named - ) - responses.append((receiver, response)) - return responses + if any receiver raises an error, the error propagates back + through send, terminating the dispatch loop, so it is quite + possible to not have all receivers called if a raises an + error. + """ + # Call each receiver with whatever arguments it can accept. + # Return a list of tuple pairs [(receiver, response), ... ]. + responses = [] + for receiver in liveReceivers(getAllReceivers(sender, signal)): + response = robustapply.robustApply( + receiver, + signal=signal, + sender=sender, + *arguments, + **named + ) + responses.append((receiver, response)) + return responses def sendExact( signal=Any, sender=Anonymous, *arguments, **named ): - """Send signal only to those receivers registered for exact message + """Send signal only to those receivers registered for exact message - sendExact allows for avoiding Any/Anonymous registered - handlers, sending only to those receivers explicitly - registered for a particular signal on a particular - sender. - """ - responses = [] - for receiver in liveReceivers(getReceivers(sender, signal)): - response = robustapply.robustApply( - receiver, - signal=signal, - sender=sender, - *arguments, - **named - ) - responses.append((receiver, response)) - return responses - + sendExact allows for avoiding Any/Anonymous registered + handlers, sending only to those receivers explicitly + registered for a particular signal on a particular + sender. + """ + responses = [] + for receiver in liveReceivers(getReceivers(sender, signal)): + response = robustapply.robustApply( + receiver, + signal=signal, + sender=sender, + *arguments, + **named + ) + responses.append((receiver, response)) + return responses + def _removeReceiver(receiver): - """Remove receiver from connections.""" - if not sendersBack: - # During module cleanup the mapping will be replaced with None - return False - backKey = id(receiver) - for senderkey in sendersBack.get(backKey,()): - try: - signals = connections[senderkey].keys() - except KeyError,err: - pass - else: - for signal in signals: - try: - receivers = connections[senderkey][signal] - except KeyError: - pass - else: - try: - receivers.remove( receiver ) - except Exception, err: - pass - _cleanupConnections(senderkey, signal) - try: - del sendersBack[ backKey ] - except KeyError: - pass - + """Remove receiver from connections.""" + if not sendersBack: + # During module cleanup the mapping will be replaced with None + return False + backKey = id(receiver) + for senderkey in sendersBack.get(backKey,()): + try: + signals = connections[senderkey].keys() + except KeyError,err: + pass + else: + for signal in signals: + try: + receivers = connections[senderkey][signal] + except KeyError: + pass + else: + try: + receivers.remove( receiver ) + except Exception, err: + pass + _cleanupConnections(senderkey, signal) + try: + del sendersBack[ backKey ] + except KeyError: + pass + def _cleanupConnections(senderkey, signal): - """Delete any empty signals for senderkey. Delete senderkey if empty.""" - try: - receivers = connections[senderkey][signal] - except: - pass - else: - if not receivers: - # No more connected receivers. Therefore, remove the signal. - try: - signals = connections[senderkey] - except KeyError: - pass - else: - del signals[signal] - if not signals: - # No more signal connections. Therefore, remove the sender. - _removeSender(senderkey) + """Delete any empty signals for senderkey. Delete senderkey if empty.""" + try: + receivers = connections[senderkey][signal] + except: + pass + else: + if not receivers: + # No more connected receivers. Therefore, remove the signal. + try: + signals = connections[senderkey] + except KeyError: + pass + else: + del signals[signal] + if not signals: + # No more signal connections. Therefore, remove the sender. + _removeSender(senderkey) def _removeSender(senderkey): - """Remove senderkey from connections.""" - _removeBackrefs(senderkey) - try: - del connections[senderkey] - except KeyError: - pass - # Senderkey will only be in senders dictionary if sender - # could be weakly referenced. - try: - del senders[senderkey] - except: - pass + """Remove senderkey from connections.""" + _removeBackrefs(senderkey) + try: + del connections[senderkey] + except KeyError: + pass + # Senderkey will only be in senders dictionary if sender + # could be weakly referenced. + try: + del senders[senderkey] + except: + pass def _removeBackrefs( senderkey): - """Remove all back-references to this senderkey""" - try: - signals = connections[senderkey] - except KeyError: - signals = None - else: - items = signals.items() - def allReceivers( ): - for signal,set in items: - for item in set: - yield item - for receiver in allReceivers(): - _killBackref( receiver, senderkey ) + """Remove all back-references to this senderkey""" + try: + signals = connections[senderkey] + except KeyError: + signals = None + else: + items = signals.items() + def allReceivers( ): + for signal,set in items: + for item in set: + yield item + for receiver in allReceivers(): + _killBackref( receiver, senderkey ) def _removeOldBackRefs(senderkey, signal, receiver, receivers): - """Kill old sendersBack references from receiver + """Kill old sendersBack references from receiver - This guards against multiple registration of the same - receiver for a given signal and sender leaking memory - as old back reference records build up. + This guards against multiple registration of the same + receiver for a given signal and sender leaking memory + as old back reference records build up. - Also removes old receiver instance from receivers - """ - try: - index = receivers.index(receiver) - # need to scan back references here and remove senderkey - except ValueError: - return False - else: - oldReceiver = receivers[index] - del receivers[index] - found = 0 - signals = connections.get(signal) - if signals is not None: - for sig,recs in connections.get(signal,{}).iteritems(): - if sig != signal: - for rec in recs: - if rec is oldReceiver: - found = 1 - break - if not found: - _killBackref( oldReceiver, senderkey ) - return True - return False - - + Also removes old receiver instance from receivers + """ + try: + index = receivers.index(receiver) + # need to scan back references here and remove senderkey + except ValueError: + return False + else: + oldReceiver = receivers[index] + del receivers[index] + found = 0 + signals = connections.get(signal) + if signals is not None: + for sig,recs in connections.get(signal,{}).iteritems(): + if sig != signal: + for rec in recs: + if rec is oldReceiver: + found = 1 + break + if not found: + _killBackref( oldReceiver, senderkey ) + return True + return False + + def _killBackref( receiver, senderkey ): - """Do the actual removal of back reference from receiver to senderkey""" - receiverkey = id(receiver) - set = sendersBack.get( receiverkey, () ) - while senderkey in set: - try: - set.remove( senderkey ) - except: - break - if not set: - try: - del sendersBack[ receiverkey ] - except KeyError: - pass - return True + """Do the actual removal of back reference from receiver to senderkey""" + receiverkey = id(receiver) + set = sendersBack.get( receiverkey, () ) + while senderkey in set: + try: + set.remove( senderkey ) + except: + break + if not set: + try: + del sendersBack[ receiverkey ] + except KeyError: + pass + return True diff --git a/django/dispatch/errors.py b/django/dispatch/errors.py index a2eb32ed75..a4c924dbe9 100644 --- a/django/dispatch/errors.py +++ b/django/dispatch/errors.py @@ -2,9 +2,9 @@ """ class DispatcherError(Exception): - """Base class for all Dispatcher errors""" + """Base class for all Dispatcher errors""" class DispatcherKeyError(KeyError, DispatcherError): - """Error raised when unknown (sender,signal) set specified""" + """Error raised when unknown (sender,signal) set specified""" class DispatcherTypeError(TypeError, DispatcherError): - """Error raised when inappropriate signal-type specified (None)""" + """Error raised when inappropriate signal-type specified (None)""" diff --git a/django/dispatch/license.txt b/django/dispatch/license.txt index 2f0b6b5ef2..8ff5d28613 100644 --- a/django/dispatch/license.txt +++ b/django/dispatch/license.txt @@ -1,34 +1,34 @@ PyDispatcher License - Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - The name of Patrick K. O'Brien, or the name of any Contributor, - may not be used to endorse or promote products derived from this - software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - OF THE POSSIBILITY OF SUCH DAMAGE. + Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + The name of Patrick K. O'Brien, or the name of any Contributor, + may not be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/django/dispatch/robust.py b/django/dispatch/robust.py index ba19934d43..8b1590de35 100644 --- a/django/dispatch/robust.py +++ b/django/dispatch/robust.py @@ -3,55 +3,55 @@ from django.dispatch.dispatcher import Any, Anonymous, liveReceivers, getAllRece from django.dispatch.robustapply import robustApply def sendRobust( - signal=Any, - sender=Anonymous, - *arguments, **named + signal=Any, + sender=Anonymous, + *arguments, **named ): - """Send signal from sender to all connected receivers catching errors - - signal -- (hashable) signal value, see connect for details + """Send signal from sender to all connected receivers catching errors + + signal -- (hashable) signal value, see connect for details - sender -- the sender of the signal - - if Any, only receivers registered for Any will receive - the message. + sender -- the sender of the signal + + if Any, only receivers registered for Any will receive + the message. - if Anonymous, only receivers registered to receive - messages from Anonymous or Any will receive the message + if Anonymous, only receivers registered to receive + messages from Anonymous or Any will receive the message - Otherwise can be any python object (normally one - registered with a connect if you actually want - something to occur). + Otherwise can be any python object (normally one + registered with a connect if you actually want + something to occur). - arguments -- positional arguments which will be passed to - *all* receivers. Note that this may raise TypeErrors - if the receivers do not allow the particular arguments. - Note also that arguments are applied before named - arguments, so they should be used with care. + arguments -- positional arguments which will be passed to + *all* receivers. Note that this may raise TypeErrors + if the receivers do not allow the particular arguments. + Note also that arguments are applied before named + arguments, so they should be used with care. - named -- named arguments which will be filtered according - to the parameters of the receivers to only provide those - acceptable to the receiver. + named -- named arguments which will be filtered according + to the parameters of the receivers to only provide those + acceptable to the receiver. - Return a list of tuple pairs [(receiver, response), ... ] + Return a list of tuple pairs [(receiver, response), ... ] - if any receiver raises an error (specifically any subclass of Exception), - the error instance is returned as the result for that receiver. - """ - # Call each receiver with whatever arguments it can accept. - # Return a list of tuple pairs [(receiver, response), ... ]. - responses = [] - for receiver in liveReceivers(getAllReceivers(sender, signal)): - try: - response = robustApply( - receiver, - signal=signal, - sender=sender, - *arguments, - **named - ) - except Exception, err: - responses.append((receiver, err)) - else: - responses.append((receiver, response)) - return responses + if any receiver raises an error (specifically any subclass of Exception), + the error instance is returned as the result for that receiver. + """ + # Call each receiver with whatever arguments it can accept. + # Return a list of tuple pairs [(receiver, response), ... ]. + responses = [] + for receiver in liveReceivers(getAllReceivers(sender, signal)): + try: + response = robustApply( + receiver, + signal=signal, + sender=sender, + *arguments, + **named + ) + except Exception, err: + responses.append((receiver, err)) + else: + responses.append((receiver, response)) + return responses diff --git a/django/dispatch/robustapply.py b/django/dispatch/robustapply.py index 0350e60cfc..14ba2b51ac 100644 --- a/django/dispatch/robustapply.py +++ b/django/dispatch/robustapply.py @@ -7,43 +7,41 @@ those which are acceptable. """ def function( receiver ): - """Get function-like callable object for given receiver + """Get function-like callable object for given receiver - returns (function_or_method, codeObject, fromMethod) + returns (function_or_method, codeObject, fromMethod) - If fromMethod is true, then the callable already - has its first argument bound - """ - if hasattr(receiver, '__call__'): - # receiver is a class instance; assume it is callable. - # Reassign receiver to the actual method that will be called. - if hasattr( receiver.__call__, 'im_func') or hasattr( receiver.__call__, 'im_code'): - receiver = receiver.__call__ - if hasattr( receiver, 'im_func' ): - # an instance-method... - return receiver, receiver.im_func.func_code, 1 - elif not hasattr( receiver, 'func_code'): - raise ValueError('unknown reciever type %s %s'%(receiver, type(receiver))) - return receiver, receiver.func_code, 0 + If fromMethod is true, then the callable already + has its first argument bound + """ + if hasattr(receiver, '__call__'): + # receiver is a class instance; assume it is callable. + # Reassign receiver to the actual method that will be called. + if hasattr( receiver.__call__, 'im_func') or hasattr( receiver.__call__, 'im_code'): + receiver = receiver.__call__ + if hasattr( receiver, 'im_func' ): + # an instance-method... + return receiver, receiver.im_func.func_code, 1 + elif not hasattr( receiver, 'func_code'): + raise ValueError('unknown reciever type %s %s'%(receiver, type(receiver))) + return receiver, receiver.func_code, 0 def robustApply(receiver, *arguments, **named): - """Call receiver with arguments and an appropriate subset of named - """ - receiver, codeObject, startIndex = function( receiver ) - acceptable = codeObject.co_varnames[startIndex+len(arguments):codeObject.co_argcount] - for name in codeObject.co_varnames[startIndex:startIndex+len(arguments)]: - if named.has_key( name ): - raise TypeError( - """Argument %r specified both positionally and as a keyword for calling %r"""% ( - name, receiver, - ) - ) - if not (codeObject.co_flags & 8): - # fc does not have a **kwds type parameter, therefore - # remove unacceptable arguments. - for arg in named.keys(): - if arg not in acceptable: - del named[arg] - return receiver(*arguments, **named) - -
\ No newline at end of file + """Call receiver with arguments and an appropriate subset of named + """ + receiver, codeObject, startIndex = function( receiver ) + acceptable = codeObject.co_varnames[startIndex+len(arguments):codeObject.co_argcount] + for name in codeObject.co_varnames[startIndex:startIndex+len(arguments)]: + if named.has_key( name ): + raise TypeError( + """Argument %r specified both positionally and as a keyword for calling %r"""% ( + name, receiver, + ) + ) + if not (codeObject.co_flags & 8): + # fc does not have a **kwds type parameter, therefore + # remove unacceptable arguments. + for arg in named.keys(): + if arg not in acceptable: + del named[arg] + return receiver(*arguments, **named) diff --git a/django/dispatch/saferef.py b/django/dispatch/saferef.py index 6b3eda1d38..74b7a41942 100644 --- a/django/dispatch/saferef.py +++ b/django/dispatch/saferef.py @@ -2,164 +2,164 @@ import weakref, traceback def safeRef(target, onDelete = None): - """Return a *safe* weak reference to a callable target + """Return a *safe* weak reference to a callable target - target -- the object to be weakly referenced, if it's a - bound method reference, will create a BoundMethodWeakref, - otherwise creates a simple weakref. - onDelete -- if provided, will have a hard reference stored - to the callable to be called after the safe reference - goes out of scope with the reference object, (either a - weakref or a BoundMethodWeakref) as argument. - """ - if hasattr(target, 'im_self'): - if target.im_self is not None: - # Turn a bound method into a BoundMethodWeakref instance. - # Keep track of these instances for lookup by disconnect(). - assert hasattr(target, 'im_func'), """safeRef target %r has im_self, but no im_func, don't know how to create reference"""%( target,) - reference = BoundMethodWeakref( - target=target, - onDelete=onDelete - ) - return reference - if callable(onDelete): - return weakref.ref(target, onDelete) - else: - return weakref.ref( target ) + target -- the object to be weakly referenced, if it's a + bound method reference, will create a BoundMethodWeakref, + otherwise creates a simple weakref. + onDelete -- if provided, will have a hard reference stored + to the callable to be called after the safe reference + goes out of scope with the reference object, (either a + weakref or a BoundMethodWeakref) as argument. + """ + if hasattr(target, 'im_self'): + if target.im_self is not None: + # Turn a bound method into a BoundMethodWeakref instance. + # Keep track of these instances for lookup by disconnect(). + assert hasattr(target, 'im_func'), """safeRef target %r has im_self, but no im_func, don't know how to create reference"""%( target,) + reference = BoundMethodWeakref( + target=target, + onDelete=onDelete + ) + return reference + if callable(onDelete): + return weakref.ref(target, onDelete) + else: + return weakref.ref( target ) class BoundMethodWeakref(object): - """'Safe' and reusable weak references to instance methods + """'Safe' and reusable weak references to instance methods - BoundMethodWeakref objects provide a mechanism for - referencing a bound method without requiring that the - method object itself (which is normally a transient - object) is kept alive. Instead, the BoundMethodWeakref - object keeps weak references to both the object and the - function which together define the instance method. + BoundMethodWeakref objects provide a mechanism for + referencing a bound method without requiring that the + method object itself (which is normally a transient + object) is kept alive. Instead, the BoundMethodWeakref + object keeps weak references to both the object and the + function which together define the instance method. - Attributes: - key -- the identity key for the reference, calculated - by the class's calculateKey method applied to the - target instance method - deletionMethods -- sequence of callable objects taking - single argument, a reference to this object which - will be called when *either* the target object or - target function is garbage collected (i.e. when - this object becomes invalid). These are specified - as the onDelete parameters of safeRef calls. - weakSelf -- weak reference to the target object - weakFunc -- weak reference to the target function + Attributes: + key -- the identity key for the reference, calculated + by the class's calculateKey method applied to the + target instance method + deletionMethods -- sequence of callable objects taking + single argument, a reference to this object which + will be called when *either* the target object or + target function is garbage collected (i.e. when + this object becomes invalid). These are specified + as the onDelete parameters of safeRef calls. + weakSelf -- weak reference to the target object + weakFunc -- weak reference to the target function - Class Attributes: - _allInstances -- class attribute pointing to all live - BoundMethodWeakref objects indexed by the class's - calculateKey(target) method applied to the target - objects. This weak value dictionary is used to - short-circuit creation so that multiple references - to the same (object, function) pair produce the - same BoundMethodWeakref instance. + Class Attributes: + _allInstances -- class attribute pointing to all live + BoundMethodWeakref objects indexed by the class's + calculateKey(target) method applied to the target + objects. This weak value dictionary is used to + short-circuit creation so that multiple references + to the same (object, function) pair produce the + same BoundMethodWeakref instance. - """ - _allInstances = weakref.WeakValueDictionary() - def __new__( cls, target, onDelete=None, *arguments,**named ): - """Create new instance or return current instance + """ + _allInstances = weakref.WeakValueDictionary() + def __new__( cls, target, onDelete=None, *arguments,**named ): + """Create new instance or return current instance - Basically this method of construction allows us to - short-circuit creation of references to already- - referenced instance methods. The key corresponding - to the target is calculated, and if there is already - an existing reference, that is returned, with its - deletionMethods attribute updated. Otherwise the - new instance is created and registered in the table - of already-referenced methods. - """ - key = cls.calculateKey(target) - current =cls._allInstances.get(key) - if current is not None: - current.deletionMethods.append( onDelete) - return current - else: - base = super( BoundMethodWeakref, cls).__new__( cls ) - cls._allInstances[key] = base - base.__init__( target, onDelete, *arguments,**named) - return base - def __init__(self, target, onDelete=None): - """Return a weak-reference-like instance for a bound method + Basically this method of construction allows us to + short-circuit creation of references to already- + referenced instance methods. The key corresponding + to the target is calculated, and if there is already + an existing reference, that is returned, with its + deletionMethods attribute updated. Otherwise the + new instance is created and registered in the table + of already-referenced methods. + """ + key = cls.calculateKey(target) + current =cls._allInstances.get(key) + if current is not None: + current.deletionMethods.append( onDelete) + return current + else: + base = super( BoundMethodWeakref, cls).__new__( cls ) + cls._allInstances[key] = base + base.__init__( target, onDelete, *arguments,**named) + return base + def __init__(self, target, onDelete=None): + """Return a weak-reference-like instance for a bound method - target -- the instance-method target for the weak - reference, must have im_self and im_func attributes - and be reconstructable via: - target.im_func.__get__( target.im_self ) - which is true of built-in instance methods. - onDelete -- optional callback which will be called - when this weak reference ceases to be valid - (i.e. either the object or the function is garbage - collected). Should take a single argument, - which will be passed a pointer to this object. - """ - def remove(weak, self=self): - """Set self.isDead to true when method or instance is destroyed""" - methods = self.deletionMethods[:] - del self.deletionMethods[:] - try: - del self.__class__._allInstances[ self.key ] - except KeyError: - pass - for function in methods: - try: - if callable( function ): - function( self ) - except Exception, e: - try: - traceback.print_exc() - except AttributeError, err: - print '''Exception during saferef %s cleanup function %s: %s'''%( - self, function, e - ) - self.deletionMethods = [onDelete] - self.key = self.calculateKey( target ) - self.weakSelf = weakref.ref(target.im_self, remove) - self.weakFunc = weakref.ref(target.im_func, remove) - self.selfName = str(target.im_self) - self.funcName = str(target.im_func.__name__) - def calculateKey( cls, target ): - """Calculate the reference key for this reference + target -- the instance-method target for the weak + reference, must have im_self and im_func attributes + and be reconstructable via: + target.im_func.__get__( target.im_self ) + which is true of built-in instance methods. + onDelete -- optional callback which will be called + when this weak reference ceases to be valid + (i.e. either the object or the function is garbage + collected). Should take a single argument, + which will be passed a pointer to this object. + """ + def remove(weak, self=self): + """Set self.isDead to true when method or instance is destroyed""" + methods = self.deletionMethods[:] + del self.deletionMethods[:] + try: + del self.__class__._allInstances[ self.key ] + except KeyError: + pass + for function in methods: + try: + if callable( function ): + function( self ) + except Exception, e: + try: + traceback.print_exc() + except AttributeError, err: + print '''Exception during saferef %s cleanup function %s: %s'''%( + self, function, e + ) + self.deletionMethods = [onDelete] + self.key = self.calculateKey( target ) + self.weakSelf = weakref.ref(target.im_self, remove) + self.weakFunc = weakref.ref(target.im_func, remove) + self.selfName = str(target.im_self) + self.funcName = str(target.im_func.__name__) + def calculateKey( cls, target ): + """Calculate the reference key for this reference - Currently this is a two-tuple of the id()'s of the - target object and the target function respectively. - """ - return (id(target.im_self),id(target.im_func)) - calculateKey = classmethod( calculateKey ) - def __str__(self): - """Give a friendly representation of the object""" - return """%s( %s.%s )"""%( - self.__class__.__name__, - self.selfName, - self.funcName, - ) - __repr__ = __str__ - def __nonzero__( self ): - """Whether we are still a valid reference""" - return self() is not None - def __cmp__( self, other ): - """Compare with another reference""" - if not isinstance (other,self.__class__): - return cmp( self.__class__, type(other) ) - return cmp( self.key, other.key) - def __call__(self): - """Return a strong reference to the bound method + Currently this is a two-tuple of the id()'s of the + target object and the target function respectively. + """ + return (id(target.im_self),id(target.im_func)) + calculateKey = classmethod( calculateKey ) + def __str__(self): + """Give a friendly representation of the object""" + return """%s( %s.%s )"""%( + self.__class__.__name__, + self.selfName, + self.funcName, + ) + __repr__ = __str__ + def __nonzero__( self ): + """Whether we are still a valid reference""" + return self() is not None + def __cmp__( self, other ): + """Compare with another reference""" + if not isinstance (other,self.__class__): + return cmp( self.__class__, type(other) ) + return cmp( self.key, other.key) + def __call__(self): + """Return a strong reference to the bound method - If the target cannot be retrieved, then will - return None, otherwise returns a bound instance - method for our object and function. + If the target cannot be retrieved, then will + return None, otherwise returns a bound instance + method for our object and function. - Note: - You may call this method any number of times, - as it does not invalidate the reference. - """ - target = self.weakSelf() - if target is not None: - function = self.weakFunc() - if function is not None: - return function.__get__(target) - return None + Note: + You may call this method any number of times, + as it does not invalidate the reference. + """ + target = self.weakSelf() + if target is not None: + function = self.weakFunc() + if function is not None: + return function.__get__(target) + return None diff --git a/django/http/__init__.py b/django/http/__init__.py index 8fb4b293fc..06f6a106ee 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -1,3 +1,4 @@ +import os from Cookie import SimpleCookie from pprint import pformat from urllib import urlencode, quote @@ -37,6 +38,9 @@ class HttpRequest(object): def get_full_path(self): return '' + + def is_secure(self): + return os.environ.get("HTTPS") == "on" def parse_file_upload(header_dict, post_data): "Returns a tuple of (POST MultiValueDict, FILES MultiValueDict)" diff --git a/django/middleware/cache.py b/django/middleware/cache.py index 80c8626db8..08e77d1375 100644 --- a/django/middleware/cache.py +++ b/django/middleware/cache.py @@ -1,7 +1,6 @@ from django.conf import settings from django.core.cache import cache from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers -from django.http import HttpResponseNotModified class CacheMiddleware(object): """ @@ -10,6 +9,11 @@ class CacheMiddleware(object): Only parameter-less GET or HEAD-requests with status code 200 are cached. + If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests + (i.e., those node made by a logged-in user) will be cached. This is a + simple and effective way of avoiding the caching of the Django admin (and + any other user-specific content). + This middleware expects that a HEAD request is answered with a response exactly like the corresponding GET request. @@ -23,13 +27,17 @@ class CacheMiddleware(object): This middleware also sets ETag, Last-Modified, Expires and Cache-Control headers on the response object. """ - def __init__(self, cache_timeout=None, key_prefix=None): + def __init__(self, cache_timeout=None, key_prefix=None, cache_anonymous_only=None): self.cache_timeout = cache_timeout if cache_timeout is None: self.cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS self.key_prefix = key_prefix if key_prefix is None: self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX + if cache_anonymous_only is None: + self.cache_anonymous_only = getattr(settings, 'CACHE_MIDDLEWARE_ANONYMOUS_ONLY', False) + else: + self.cache_anonymous_only = cache_anonymous_only def process_request(self, request): "Checks whether the page is already cached and returns the cached version if available." @@ -37,6 +45,10 @@ class CacheMiddleware(object): request._cache_update_cache = False return None # Don't bother checking the cache. + if self.cache_anonymous_only and request.user.is_authenticated(): + request._cache_update_cache = False + return None # Don't cache requests from authenticated users. + cache_key = get_cache_key(request, self.key_prefix) if cache_key is None: request._cache_update_cache = True diff --git a/django/middleware/common.py b/django/middleware/common.py index a42c54751d..d63b71fed7 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -1,7 +1,7 @@ from django.conf import settings from django import http from django.core.mail import mail_managers -import md5, os +import md5 class CommonMiddleware(object): """ @@ -44,7 +44,7 @@ class CommonMiddleware(object): if new_url != old_url: # Redirect if new_url[0]: - newurl = "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', new_url[0], new_url[1]) + newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], new_url[1]) else: newurl = new_url[1] if request.GET: diff --git a/django/middleware/transaction.py b/django/middleware/transaction.py index 4128e012f2..96b1538d9d 100644 --- a/django/middleware/transaction.py +++ b/django/middleware/transaction.py @@ -1,4 +1,3 @@ -from django.conf import settings from django.db import transaction class TransactionMiddleware(object): diff --git a/django/template/__init__.py b/django/template/__init__.py index e898fc7636..a4c282f2ff 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -708,9 +708,9 @@ class DebugNodeList(NodeList): if not hasattr(e, 'source'): e.source = node.source raise - except Exception: + except Exception, e: from sys import exc_info - wrapped = TemplateSyntaxError('Caught an exception while rendering.') + wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) wrapped.source = node.source wrapped.exc_info = exc_info() raise wrapped @@ -817,7 +817,7 @@ class Library(object): self.filters[name] = filter_func return filter_func else: - raise InvalidTemplateLibrary, "Unsupported arguments to Library.filter: (%r, %r, %r)", (name, compile_function, has_arg) + raise InvalidTemplateLibrary, "Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func) def filter_function(self, func): self.filters[func.__name__] = func diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index bd9f55b1e9..c75f371ec8 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -438,7 +438,7 @@ def pluralize(value, arg='s'): the comma is used for the singular case. """ if not ',' in arg: - arg = ',' + arg + arg = ',' + arg bits = arg.split(',') if len(bits) > 2: return '' diff --git a/django/template/loader.py b/django/template/loader.py index ebca582ef9..60f24554f1 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -21,7 +21,7 @@ # installed, because pkg_resources is necessary to read eggs. from django.core.exceptions import ImproperlyConfigured -from django.template import Origin, StringOrigin, Template, Context, TemplateDoesNotExist, add_to_builtins +from django.template import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins from django.conf import settings template_source_loaders = None diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index e0d9a70a98..a8e76a1844 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -1,5 +1,5 @@ from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable -from django.template import Library, Context, Node +from django.template import Library, Node from django.template.loader import get_template, get_template_from_string, find_template_source from django.conf import settings diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 6718a0fbac..bf6497f9aa 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -1,8 +1,7 @@ -from django.template import Node, NodeList, Template, Context, resolve_variable +from django.template import Node, resolve_variable from django.template import TemplateSyntaxError, TokenParser, Library -from django.template import TOKEN_BLOCK, TOKEN_TEXT, TOKEN_VAR +from django.template import TOKEN_TEXT, TOKEN_VAR from django.utils import translation -import re, sys register = Library() @@ -228,7 +227,7 @@ def do_block_translate(parser, token): break if countervar and counter: if token.contents.strip() != 'plural': - raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags inside it" % tag + raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags inside it" while parser.tokens: token = parser.next_token() if token.token_type in (TOKEN_VAR, TOKEN_TEXT): diff --git a/django/utils/termcolors.py b/django/utils/termcolors.py index 3ce1d5bb6b..17a600f899 100644 --- a/django/utils/termcolors.py +++ b/django/utils/termcolors.py @@ -2,8 +2,6 @@ termcolors.py """ -import types - color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') foreground = dict([(color_names[x], '3%s' % x) for x in range(8)]) background = dict([(color_names[x], '4%s' % x) for x in range(8)]) diff --git a/django/views/debug.py b/django/views/debug.py index 6cbbde987b..6934360afd 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -3,8 +3,6 @@ from django.template import Template, Context, TemplateDoesNotExist from django.utils.html import escape from django.http import HttpResponseServerError, HttpResponseNotFound import os, re -from itertools import count, izip -from os.path import dirname, join as pathjoin HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD') @@ -124,7 +122,7 @@ def technical_500_response(request, exc_type, exc_value, tb): 'frames': frames, 'lastframe': frames[-1], 'request': request, - 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", + 'request_protocol': request.is_secure() and "https" or "http", 'settings': get_safe_settings(), 'template_info': template_info, 'template_does_not_exist': template_does_not_exist, @@ -149,7 +147,7 @@ def technical_404_response(request, exception): 'urlpatterns': tried, 'reason': str(exception), 'request': request, - 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", + 'request_protocol': request.is_secure() and "https" or "http", 'settings': get_safe_settings(), }) return HttpResponseNotFound(t.render(c), mimetype='text/html') diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index 5467ff501e..b04cc2340b 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -10,7 +10,6 @@ example, as that is unique across a Django project. Additionally, all headers from the response's Vary header will be taken into account on caching -- just like the middleware does. """ -import re from django.utils.decorators import decorator_from_middleware from django.utils.cache import patch_cache_control, add_never_cache_headers diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py index b5fdd3e4cc..27ba327ff5 100644 --- a/django/views/generic/create_update.py +++ b/django/views/generic/create_update.py @@ -4,7 +4,6 @@ from django import forms from django.db.models import FileField from django.contrib.auth.views import redirect_to_login from django.template import RequestContext -from django.core.paginator import ObjectPaginator, InvalidPage from django.http import Http404, HttpResponse, HttpResponseRedirect from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured @@ -20,7 +19,7 @@ def create_object(request, model, template_name=None, the form wrapper for the object """ if extra_context is None: extra_context = {} - if login_required and request.user.is_anonymous(): + if login_required and not request.user.is_authenticated(): return redirect_to_login(request.path) manipulator = model.AddManipulator(follow=follow) @@ -39,7 +38,7 @@ def create_object(request, model, template_name=None, # No errors -- this means we can save the data! new_object = manipulator.save(new_data) - if not request.user.is_anonymous(): + if request.user.is_authenticated(): request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name) # Redirect to the new object: first by trying post_save_redirect, @@ -86,7 +85,7 @@ def update_object(request, model, object_id=None, slug=None, the original object being edited """ if extra_context is None: extra_context = {} - if login_required and request.user.is_anonymous(): + if login_required and not request.user.is_authenticated(): return redirect_to_login(request.path) # Look up the object to be edited @@ -113,7 +112,7 @@ def update_object(request, model, object_id=None, slug=None, if not errors: object = manipulator.save(new_data) - if not request.user.is_anonymous(): + if request.user.is_authenticated(): request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name) # Do a post-after-redirect so that reload works, etc. @@ -162,7 +161,7 @@ def delete_object(request, model, post_delete_redirect, the original object being deleted """ if extra_context is None: extra_context = {} - if login_required and request.user.is_anonymous(): + if login_required and not request.user.is_authenticated(): return redirect_to_login(request.path) # Look up the object to be edited @@ -180,7 +179,7 @@ def delete_object(request, model, post_delete_redirect, if request.method == 'POST': object.delete() - if not request.user.is_anonymous(): + if request.user.is_authenticated(): request.user.message_set.create(message="The %s was deleted." % model._meta.verbose_name) return HttpResponseRedirect(post_delete_redirect) else: diff --git a/django/views/static.py b/django/views/static.py index 072a01671e..ac323944d0 100644 --- a/django/views/static.py +++ b/django/views/static.py @@ -1,5 +1,4 @@ from django.template import loader -from django.core.exceptions import ImproperlyConfigured from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified from django.template import Template, Context, TemplateDoesNotExist import mimetypes diff --git a/docs/admin_css.txt b/docs/admin_css.txt index 069012a84b..ec402f7142 100644 --- a/docs/admin_css.txt +++ b/docs/admin_css.txt @@ -118,8 +118,8 @@ additional class on the ``a`` for that tool. These are ``.addlink`` and Example from a changelist page:: <ul class="object-tools"> - <li><a href="/stories/add/" class="addlink">Add redirect</a></li> - </ul> + <li><a href="/stories/add/" class="addlink">Add redirect</a></li> + </ul> .. image:: http://media.djangoproject.com/img/doc/admincss/objecttools_01.gif :alt: Object tools on a changelist page diff --git a/docs/authentication.txt b/docs/authentication.txt index 68b9024a90..d10dda28ef 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -95,7 +95,11 @@ In addition to those automatic API methods, ``User`` objects have the following custom methods: * ``is_anonymous()`` -- Always returns ``False``. This is a way of - comparing ``User`` objects to anonymous users. + differentiating ``User`` and ``AnonymousUser`` objects. Generally, you + should prefer using ``is_authenticated()`` to this method. + + * ``is_authenticated()`` -- Always returns ``True``. This is a way to + tell if the user has been authenticated. * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``, with a space in between. @@ -219,6 +223,7 @@ the ``django.contrib.auth.models.User`` interface, with these differences: * ``id`` is always ``None``. * ``is_anonymous()`` returns ``True`` instead of ``False``. + * ``is_authenticated()`` returns ``False`` instead of ``True``. * ``has_perm()`` always returns ``False``. * ``set_password()``, ``check_password()``, ``save()``, ``delete()``, ``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``. @@ -254,12 +259,12 @@ Once you have those middlewares installed, you'll be able to access ``request.user`` in views. ``request.user`` will give you a ``User`` object representing the currently logged-in user. If a user isn't currently logged in, ``request.user`` will be set to an instance of ``AnonymousUser`` (see the -previous section). You can tell them apart with ``is_anonymous()``, like so:: +previous section). You can tell them apart with ``is_authenticated()``, like so:: - if request.user.is_anonymous(): - # Do something for anonymous users. + if request.user.is_authenticated(): + # Do something for authenticated users. else: - # Do something for logged-in users. + # Do something for anonymous users. .. _request objects: http://www.djangoproject.com/documentation/request_response/#httprequest-objects .. _session documentation: http://www.djangoproject.com/documentation/sessions/ @@ -323,19 +328,19 @@ The raw way ~~~~~~~~~~~ The simple, raw way to limit access to pages is to check -``request.user.is_anonymous()`` and either redirect to a login page:: +``request.user.is_authenticated()`` and either redirect to a login page:: from django.http import HttpResponseRedirect def my_view(request): - if request.user.is_anonymous(): + if not request.user.is_authenticated(): return HttpResponseRedirect('/login/?next=%s' % request.path) # ... ...or display an error message:: def my_view(request): - if request.user.is_anonymous(): + if not request.user.is_authenticated(): return render_to_response('myapp/login_error.html') # ... @@ -439,7 +444,7 @@ For example, this view checks to make sure the user is logged in and has the permission ``polls.can_vote``:: def my_view(request): - if request.user.is_anonymous() or not request.user.has_perm('polls.can_vote'): + if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')): return HttpResponse("You can't vote in this poll.") # ... @@ -605,10 +610,10 @@ Users The currently logged-in user, either a ``User`` instance or an``AnonymousUser`` instance, is stored in the template variable ``{{ user }}``:: - {% if user.is_anonymous %} - <p>Welcome, new user. Please log in.</p> + {% if user.is_authenticated %} + <p>Welcome, {{ user.username }}. Thanks for logging in.</p> {% else %} - <p>Welcome, {{ user.username }}. Thanks for logging in.</p> + <p>Welcome, new user. Please log in.</p> {% endif %} Permissions diff --git a/docs/cache.txt b/docs/cache.txt index 2ef3d6503f..62fec289b9 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -230,8 +230,13 @@ Then, add the following required settings to your Django settings file: collisions. Use an empty string if you don't care. The cache middleware caches every page that doesn't have GET or POST -parameters. Additionally, ``CacheMiddleware`` automatically sets a few headers -in each ``HttpResponse``: +parameters. Optionally, if the ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting is +``True``, only anonymous requests (i.e., not those made by a logged-in user) +will be cached. This is a simple and effective way of disabling caching for any +user-specific pages (include Django's admin interface). + +Additionally, ``CacheMiddleware`` automatically sets a few headers in each +``HttpResponse``: * Sets the ``Last-Modified`` header to the current date/time when a fresh (uncached) version of the page is requested. diff --git a/docs/django-admin.txt b/docs/django-admin.txt index 04d86aa3b4..eb7b2dccd6 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -192,6 +192,14 @@ documentation. .. _serving static files: http://www.djangoproject.com/documentation/static_files/ +Turning off auto-reload +~~~~~~~~~~~~~~~~~~~~~~~ + +To disable auto-reloading of code while the development server is running, use the +``--noreload`` option, like so:: + + django-admin.py runserver --noreload + shell ----- diff --git a/docs/faq.txt b/docs/faq.txt index b374abfbf3..ccf8906c41 100644 --- a/docs/faq.txt +++ b/docs/faq.txt @@ -535,6 +535,14 @@ If you're sure your username and password are correct, make sure your user account has ``is_active`` and ``is_staff`` set to True. The admin site only allows access to users with those two fields both set to True. +How can I prevent the cache middleware from caching the admin site? +------------------------------------------------------------------- + +Set the ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting to ``True``. See the +`cache documentation`_ for more information. + +.. _cache documentation: ../cache/#the-per-site-cache + How do I automatically set a field's value to the user who last edited the object in the admin? ----------------------------------------------------------------------------------------------- diff --git a/docs/model-api.txt b/docs/model-api.txt index c4d57bf8c4..c369508c65 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -1225,6 +1225,24 @@ A few special cases to note about ``list_display``: return self.birthday.strftime('%Y')[:3] + "0's" decade_born_in.short_description = 'Birth decade' + * If the string given is a method of the model, Django will HTML-escape the + output by default. If you'd rather not escape the output of the method, + give the method an ``allow_tags`` attribute whose value is ``True``. + + Here's a full example model:: + + class Person(models.Model): + first_name = models.CharField(maxlength=50) + last_name = models.CharField(maxlength=50) + color_code = models.CharField(maxlength=6) + + class Admin: + list_display = ('first_name', 'last_name', 'colored_name') + + def colored_name(self): + return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name) + colored_name.allow_tags = True + ``list_display_links`` ---------------------- diff --git a/docs/request_response.txt b/docs/request_response.txt index 0bcb3a7f5b..7480a6d3bb 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -106,12 +106,12 @@ All attributes except ``session`` should be considered read-only. A ``django.contrib.auth.models.User`` object representing the currently logged-in user. If the user isn't currently logged in, ``user`` will be set to an instance of ``django.contrib.auth.models.AnonymousUser``. You - can tell them apart with ``is_anonymous()``, like so:: + can tell them apart with ``is_authenticated()``, like so:: - if request.user.is_anonymous(): - # Do something for anonymous users. - else: + if request.user.is_authenticated(): # Do something for logged-in users. + else: + # Do something for anonymous users. ``user`` is only available if your Django installation has the ``AuthenticationMiddleware`` activated. For more, see @@ -134,21 +134,25 @@ Methods ------- ``__getitem__(key)`` - Returns the GET/POST value for the given key, checking POST first, then - GET. Raises ``KeyError`` if the key doesn't exist. + Returns the GET/POST value for the given key, checking POST first, then + GET. Raises ``KeyError`` if the key doesn't exist. - This lets you use dictionary-accessing syntax on an ``HttpRequest`` - instance. Example: ``request["foo"]`` would return ``True`` if either - ``request.POST`` or ``request.GET`` had a ``"foo"`` key. + This lets you use dictionary-accessing syntax on an ``HttpRequest`` + instance. Example: ``request["foo"]`` would return ``True`` if either + ``request.POST`` or ``request.GET`` had a ``"foo"`` key. ``has_key()`` - Returns ``True`` or ``False``, designating whether ``request.GET`` or - ``request.POST`` has the given key. + Returns ``True`` or ``False``, designating whether ``request.GET`` or + ``request.POST`` has the given key. ``get_full_path()`` - Returns the ``path``, plus an appended query string, if applicable. + Returns the ``path``, plus an appended query string, if applicable. - Example: ``"/music/bands/the_beatles/?print=true"`` + Example: ``"/music/bands/the_beatles/?print=true"`` + +``is_secure()`` + Returns ``True`` if the request is secure; that is, if it was made with + HTTPS. QueryDict objects ----------------- diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index c353e1ab4b..62db8ab842 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -346,6 +346,8 @@ Note the following: the SQL to the database. If you're interested, also run the following commands: + * ``python manage.py validate polls`` -- Checks for any errors in the + construction of your models. * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data required for Django's admin framework and your models. diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt index 3a830eb76f..248d234043 100644 --- a/docs/tutorial03.txt +++ b/docs/tutorial03.txt @@ -189,7 +189,7 @@ publication date:: from django.http import HttpResponse def index(request): - latest_poll_list = Poll.objects.all().order_by('-pub_date') + latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] output = ', '.join([p.question for p in latest_poll_list]) return HttpResponse(output) @@ -202,7 +202,7 @@ So let's use Django's template system to separate the design from Python:: from django.http import HttpResponse def index(request): - latest_poll_list = Poll.objects.all().order_by('-pub_date') + latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] t = loader.get_template('polls/index.html') c = Context({ 'latest_poll_list': latest_poll_list, @@ -288,7 +288,7 @@ exception if a poll with the requested ID doesn't exist. A shortcut: get_object_or_404() ------------------------------- -It's a very common idiom to use ``get_object()`` and raise ``Http404`` if the +It's a very common idiom to use ``get()`` and raise ``Http404`` if the object doesn't exist. Django provides a shortcut. Here's the ``detail()`` view, rewritten:: @@ -313,8 +313,8 @@ exist. foremost design goals of Django is to maintain loose coupling. There's also a ``get_list_or_404()`` function, which works just as -``get_object_or_404()`` -- except using ``get_list()`` instead of -``get_object()``. It raises ``Http404`` if the list is empty. +``get_object_or_404()`` -- except using ``filter()`` instead of +``get()``. It raises ``Http404`` if the list is empty. Write a 404 (page not found) view ================================= @@ -41,6 +41,7 @@ setup( 'locale/sl/LC_MESSAGES/*', 'locale/sr/LC_MESSAGES/*', 'locale/sv/LC_MESSAGES/*', + 'locale/ta/LC_MESSAGES/*', 'locale/uk/LC_MESSAGES/*', 'locale/zh_CN/LC_MESSAGES/*', 'locale/zh_TW/LC_MESSAGES/*'], diff --git a/tests/othertests/markup.py b/tests/othertests/markup.py index 3fa5a3a883..2b00a8c7a5 100644 --- a/tests/othertests/markup.py +++ b/tests/othertests/markup.py @@ -1,6 +1,7 @@ # Quick tests for the markup templatetags (django.contrib.markup) from django.template import Template, Context, add_to_builtins +import re add_to_builtins('django.contrib.markup.templatetags.markup') @@ -47,7 +48,8 @@ markdown_content = """Paragraph 1 t = Template("{{ markdown_content|markdown }}") rendered = t.render(Context(locals())).strip() if markdown: - assert rendered == """<p>Paragraph 1</p><h2>An h2</h2>""" + pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""") + assert pattern.match(rendered) else: assert rendered == markdown_content |
