From f8217026f9618adb65ab2d517025e87b98ed2fbe Mon Sep 17 00:00:00 2001 From: Jason Pellerin Date: Wed, 29 Nov 2006 20:16:50 +0000 Subject: [PATCH] [multi-db] Merge trunk to [3850]. Some tests still failing. git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@4142 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/conf/global_settings.py | 4 +- django/conf/locale/de/LC_MESSAGES/django.mo | Bin 37271 -> 37729 bytes django/conf/locale/de/LC_MESSAGES/django.po | 49 ++++++++++++++---- .../conf/locale/zh_CN/LC_MESSAGES/django.mo | Bin 30798 -> 30798 bytes .../conf/locale/zh_CN/LC_MESSAGES/django.po | 4 +- .../conf/locale/zh_CN/LC_MESSAGES/djangojs.mo | Bin 1513 -> 1505 bytes .../conf/locale/zh_CN/LC_MESSAGES/djangojs.po | 28 +++++----- django/contrib/auth/decorators.py | 4 +- django/contrib/auth/forms.py | 11 ++-- django/core/management.py | 2 +- django/core/servers/basehttp.py | 2 +- django/core/validators.py | 4 +- django/db/backends/ansi/sql.py | 2 +- django/db/models/fields/__init__.py | 4 +- django/db/models/fields/related.py | 2 +- django/db/models/manipulators.py | 4 +- django/db/models/query.py | 14 ++--- django/forms/__init__.py | 3 +- django/middleware/common.py | 4 +- django/views/generic/create_update.py | 6 +-- docs/apache_auth.txt | 2 +- docs/authentication.txt | 32 ++++++++---- docs/contributing.txt | 6 +-- docs/db-api.txt | 10 +++- docs/django-admin.txt | 8 +-- docs/forms.txt | 19 ++++--- docs/model-api.txt | 2 +- docs/serialization.txt | 22 ++++---- docs/settings.txt | 7 ++- tests/modeltests/basic/models.py | 4 ++ tests/modeltests/custom_pk/models.py | 4 ++ tests/modeltests/one_to_one/models.py | 14 +++++ 33 files changed, 172 insertions(+), 106 deletions(-) diff --git a/AUTHORS b/AUTHORS index 3c2542cb0d..9621fd8252 100644 --- a/AUTHORS +++ b/AUTHORS @@ -82,6 +82,7 @@ answer newbie questions, and generally made Django that much better: Espen Grindhaug Brant Harris heckj@mac.com + Joel Heenan hipertracker@gmail.com Ian Holsman Kieran Holland diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 920ff9657c..cc168034ce 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -277,8 +277,8 @@ CACHE_MIDDLEWARE_KEY_PREFIX = '' COMMENTS_ALLOW_PROFANITIES = False # The profanities that will trigger a validation error in the -# 'hasNoProfanities' validator. All of these should be in lower-case. -PROFANITIES_LIST = ['asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit'] +# 'hasNoProfanities' validator. All of these should be in lowercase. +PROFANITIES_LIST = ('asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit') # The group ID that designates which users are banned. # Set to None if you're not using it. diff --git a/django/conf/locale/de/LC_MESSAGES/django.mo b/django/conf/locale/de/LC_MESSAGES/django.mo index 768c859ad24444b328bcae759ddff05c454b9b4a..aef68099d31c60505f1b2b69b9eb48d6ac10ef9f 100644 GIT binary patch delta 10060 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 diff --git a/django/conf/locale/de/LC_MESSAGES/django.po b/django/conf/locale/de/LC_MESSAGES/django.po index 2da39e2253..614ea69247 100644 --- a/django/conf/locale/de/LC_MESSAGES/django.po +++ b/django/conf/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Django 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-09-25 15:39+0200\n" +"POT-Creation-Date: 2006-09-25 16:04+0200\n" "PO-Revision-Date: 2005-10-08 00:03+0200\n" "Last-Translator: Georg Bauer \n" "MIME-Version: 1.0\n" @@ -586,6 +586,7 @@ msgid "view:" msgstr "Ansicht:" #: contrib/admin/views/doc.py:164 +#, python-format msgid "App %r not found" msgstr "Anwendung %r nicht gefunden" @@ -826,6 +827,7 @@ msgid "Models available in the %(name)s application." msgstr "Modelle, die in der Anwendung %(name)s vorhanden sind." #: contrib/admin/templates/admin/index.html:18 +#, python-format msgid "%(name)s" msgstr "%(name)s" @@ -873,6 +875,7 @@ msgid "Delete" msgstr "Lschen" #: contrib/admin/templates/admin/delete_confirmation.html:14 +#, python-format msgid "" "Deleting the %(object_name)s '%(escaped_object)s' would result in deleting " "related objects, but your account doesn't have permission to delete the " @@ -883,18 +886,20 @@ msgstr "" "folgenden abhngigen Daten zu lschen:" #: contrib/admin/templates/admin/delete_confirmation.html:21 +#, python-format msgid "" "Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? " "All of the following related items will be deleted:" msgstr "" -"Sind Sie sicher, das Sie %(object_name)s \"%(escaped_object)s\" lschen wollen? Es " -"werden zustzlich die folgenden abhngigen Daten mit gelscht:" +"Sind Sie sicher, das Sie %(object_name)s \"%(escaped_object)s\" lschen " +"wollen? Es werden zustzlich die folgenden abhngigen Daten mit gelscht:" #: contrib/admin/templates/admin/delete_confirmation.html:26 msgid "Yes, I'm sure" msgstr "Ja, ich bin sicher" #: contrib/admin/templates/admin/filter.html:2 +#, python-format msgid " By %(filter_title)s " msgstr " Nach %(filter_title)s " @@ -962,9 +967,9 @@ msgid "" "database tables have been created, and make sure the database is readable by " "the appropriate user." msgstr "" -"Irgendetwas ist falsch mit der Datenbankkonfiguration. Bitte sicherstellen, das " -"die richtigen Datenbanktabellen angelegt wurden und bitte sicherstellen, das die " -"Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist." +"Irgendetwas ist falsch mit der Datenbankkonfiguration. Bitte sicherstellen, " +"das die richtigen Datenbanktabellen angelegt wurden und bitte sicherstellen, " +"das die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist." #: contrib/admin/templates/admin/auth/user/add_form.html:6 msgid "" @@ -1252,8 +1257,8 @@ msgid "" "Example: 'flatpages/contact_page.html'. If this isn't provided, the system " "will use 'flatpages/default.html'." msgstr "" -"Beispiel: 'flatpages/contact_page.html'. Wenn dieses Feld nicht gefllt ist, wird " -"'flatpages/default.html' als Standard gewhlt." +"Beispiel: 'flatpages/contact_page.html'. Wenn dieses Feld nicht gefllt ist, " +"wird 'flatpages/default.html' als Standard gewhlt." #: contrib/flatpages/models.py:14 msgid "registration required" @@ -1350,8 +1355,8 @@ msgid "" "Designates whether this user can log into the Django admin. Unselect this " "instead of deleting accounts." msgstr "" -"Gibt an, ob der Benutzer sich an der Administrationsseite anmelden kann. Anstelle " -"Benutzer zu lschen, kann das hier auch einfach abgeschaltet werden." +"Gibt an, ob der Benutzer sich an der Administrationsseite anmelden kann. " +"Anstelle Benutzer zu lschen, kann das hier auch einfach abgeschaltet werden." #: contrib/auth/models.py:97 msgid "superuser status" @@ -1425,6 +1430,22 @@ msgstr "" msgid "This account is inactive." msgstr "Dieser Benutzer ist inaktiv." +#: contrib/auth/forms.py:84 +msgid "" +"That e-mail address doesn't have an associated user acount. Are you sure " +"you've registered?" +msgstr "" +"Die Email-Adresse hat keinen Benutzer zugeordnet. Sicher, das die Adresse " +"hier angemeldet ist?" + +#: contrib/auth/forms.py:116 +msgid "The two 'new password' fields didn't match." +msgstr "Die zwei Passwrter sind nicht gleich." + +#: contrib/auth/forms.py:123 +msgid "Your old password was entered incorrectly. Please enter it again." +msgstr "Das alte Passwort war falsch. Bitte neu eingeben." + #: contrib/contenttypes/models.py:20 msgid "python model class name" msgstr "Python Model-Klassenname" @@ -1872,6 +1893,7 @@ msgid "Year must be 1900 or later." msgstr "Das Jahr muss 1900 oder spter sein." #: core/validators.py:142 +#, python-format msgid "Invalid date: %s." msgstr "Ungltiges Datum: %s" @@ -1895,7 +1917,8 @@ msgstr "Bitte eine g #: core/validators.py:172 core/validators.py:401 forms/__init__.py:661 msgid "No file was submitted. Check the encoding type on the form." -msgstr "Es wurde keine Datei geschickt. Eventuell ist das Formular-Encoding falsch." +msgstr "" +"Es wurde keine Datei geschickt. Eventuell ist das Formular-Encoding falsch." #: core/validators.py:176 msgid "" @@ -2007,6 +2030,7 @@ msgstr[0] "Bitte eine g msgstr[1] "Bitte eine gltige Dezimalzahl mit maximal %s Ziffern eingeben." #: core/validators.py:381 +#, python-format msgid "" "Please enter a valid decimal number with a whole part of at most %s digit." msgid_plural "" @@ -2111,14 +2135,17 @@ msgstr "" "beginnt mit \"%(start)s\"." #: views/generic/create_update.py:43 +#, python-format msgid "The %(verbose_name)s was created successfully." msgstr "%(verbose_name)s wurde erfolgreich angelegt." #: views/generic/create_update.py:117 +#, python-format msgid "The %(verbose_name)s was updated successfully." msgstr "%(verbose_name)s wurde erfolgreich aktualisiert." #: views/generic/create_update.py:184 +#, python-format msgid "The %(verbose_name)s was deleted." msgstr "%(verbose_name)s wurde gelscht" diff --git a/django/conf/locale/zh_CN/LC_MESSAGES/django.mo b/django/conf/locale/zh_CN/LC_MESSAGES/django.mo index 9fc04b9395f1b130baf7c390706c64e409a8a7f8..0d6bf90c0ee6f3de4ac035c8640733427dbc1031 100644 GIT binary patch delta 37 tcmX^2f$`i2#tl4vT$Z{9h6+YTRtBb<#r(pB*`Cd9emQf(=HkTLVgLzh4wL`@ delta 37 tcmX^2f$`i2#tl4vT&B8)<_d5 diff --git a/django/conf/locale/zh_CN/LC_MESSAGES/django.po b/django/conf/locale/zh_CN/LC_MESSAGES/django.po index 7718514299..2552b677bd 100644 --- a/django/conf/locale/zh_CN/LC_MESSAGES/django.po +++ b/django/conf/locale/zh_CN/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: django v1.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2006-05-16 10:10+0200\n" -"PO-Revision-Date: 2006-05-17 13:47+0800\n" +"PO-Revision-Date: 2006-09-01 22:05+0800\n" "Last-Translator: limodou \n" "Language-Team: Simplified Chinese \n" "MIME-Version: 1.0\n" @@ -1167,7 +1167,7 @@ msgstr "个人信息" #: contrib/auth/models.py:77 msgid "Permissions" -msgstr "许可" +msgstr "权限" #: contrib/auth/models.py:78 msgid "Important dates" diff --git a/django/conf/locale/zh_CN/LC_MESSAGES/djangojs.mo b/django/conf/locale/zh_CN/LC_MESSAGES/djangojs.mo index 983a8a7154e7e138dcde32216d80c155ef1253c9..ec7580a8629f346ef84074a06bd51e93dd549820 100644 GIT binary patch delta 435 zcmaFK{g8XYnR+Wm1_m2u1_mw$28MDL1_m}D-2|jLfpjO7KN(8T0@6Z2@r6+S79h<7 zDA_&Fe*0OVhV^37N$YcWdcN&|(0SQ!}Pfpi{_b_LRXKpJG_6)1fhN*wf!{ax`;rN~Eh}kgl)4u8X6BhrgAtr*@RTpDUM7VsVLX zNKs;5aZX}Mevy@eTd0qZf}f+WtAb5#VueF$MSgi|l3reFi5*aFUV3R_da7, YEAR. # -#, fuzzy msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: Django 0.95\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2006-03-21 18:43+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" +"PO-Revision-Date: 2006-09-25 08:35+0800\n" +"Last-Translator: limodou \n" +"Language-Team: limodou \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: contrib/admin/media/js/SelectFilter2.js:33 msgid "Available %s" -msgstr "可行 %s" +msgstr "可用 %s" #: contrib/admin/media/js/SelectFilter2.js:41 msgid "Choose all" @@ -30,34 +29,32 @@ msgstr "增加" #: contrib/admin/media/js/SelectFilter2.js:48 msgid "Remove" -msgstr "移出" +msgstr "删除" #: contrib/admin/media/js/SelectFilter2.js:53 msgid "Chosen %s" -msgstr "选择 %s" +msgstr "选中的 %s" #: contrib/admin/media/js/SelectFilter2.js:54 msgid "Select your choice(s) and click " -msgstr "挑选你的选择并且点击 " +msgstr "选择并点击 " #: contrib/admin/media/js/SelectFilter2.js:59 msgid "Clear all" -msgstr "清除所有" +msgstr "清除全部" #: contrib/admin/media/js/dateparse.js:32 #: contrib/admin/media/js/calendar.js:24 -msgid "" -"January February March April May June July August September October November " -"December" +msgid "January February March April May June July August September October November December" msgstr "一月 二月 三月 四月 五月 六月 六月 七月 八月 九月 十月 十一月 十二月" #: contrib/admin/media/js/dateparse.js:33 msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" -msgstr "星期天 星期一 星期二 星期三 星期四 星期五 星期六" +msgstr "星期日 星期一 星期二 星期三 星期四 星期五 星期六" #: contrib/admin/media/js/calendar.js:25 msgid "S M T W T F S" -msgstr "日 月 火 水 木 金 土" +msgstr "日 一 二 三 四 五 六" #: contrib/admin/media/js/admin/DateTimeShortcuts.js:45 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:80 @@ -105,3 +102,4 @@ msgstr "昨天" #: contrib/admin/media/js/admin/DateTimeShortcuts.js:164 msgid "Tomorrow" msgstr "明天" + diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 8164d8314e..37e948f8fe 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -29,8 +29,8 @@ login_required.__doc__ = ( def permission_required(perm, login_url=LOGIN_URL): """ - Decorator for views that checks if a user has a particular permission - enabled, redirectiing to the log-in page if necessary. + Decorator for views that checks whether a user has a particular permission + enabled, redirecting to the log-in page if necessary. """ return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url) diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index ad8d423ebf..6fd583dcc0 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -4,6 +4,7 @@ from django.contrib.sites.models import Site from django.template import Context, loader from django.core import validators from django import forms +from django.utils.translation import gettext_lazy as _ class UserCreationForm(forms.Manipulator): "A form that creates a user, with no privileges, from the given username and password." @@ -13,7 +14,7 @@ class UserCreationForm(forms.Manipulator): validator_list=[validators.isAlphaNumeric, self.isValidUsername]), forms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True), forms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True, - validator_list=[validators.AlwaysMatchesOtherField('password1', "The two password fields didn't match.")]), + validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]), ) def isValidUsername(self, field_data, all_data): @@ -21,7 +22,7 @@ class UserCreationForm(forms.Manipulator): User.objects.get(username=field_data) except User.DoesNotExist: return - raise validators.ValidationError, 'A user with that username already exists.' + raise validators.ValidationError, _('A user with that username already exists.') def save(self, new_data): "Creates the user." @@ -81,7 +82,7 @@ class PasswordResetForm(forms.Manipulator): try: self.user_cache = User.objects.get(email__iexact=new_data) except User.DoesNotExist: - raise validators.ValidationError, "That e-mail address doesn't have an associated user acount. Are you sure you've registered?" + raise validators.ValidationError, _("That e-mail address doesn't have an associated user acount. Are you sure you've registered?") def save(self, domain_override=None, email_template_name='registration/password_reset_email.html'): "Calculates a new password randomly and sends it to the user" @@ -113,14 +114,14 @@ class PasswordChangeForm(forms.Manipulator): forms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True, validator_list=[self.isValidOldPassword]), forms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True, - validator_list=[validators.AlwaysMatchesOtherField('new_password2', "The two 'new password' fields didn't match.")]), + validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]), forms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True), ) def isValidOldPassword(self, new_data, all_data): "Validates that the old_password field is correct." if not self.user.check_password(new_data): - raise validators.ValidationError, "Your old password was entered incorrectly. Please enter it again." + raise validators.ValidationError, _("Your old password was entered incorrectly. Please enter it again.") def save(self, new_data): "Saves the new password." diff --git a/django/core/management.py b/django/core/management.py index bd162a1e8d..09db6e5c01 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -1128,7 +1128,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None): parser.add_option('--verbosity', action='store', dest='verbosity', default='2', type='choice', choices=['0', '1', '2'], help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), - parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Lets you manually specify the directory to serve admin media from when running the development server.'), + parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Specifies the directory from which to serve admin media for runserver.'), options, args = parser.parse_args(argv[1:]) diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index fe534d5da0..a16b8b675a 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -594,7 +594,7 @@ class AdminMediaHandler(object): Use this ONLY LOCALLY, for development! This hasn't been tested for security and is not super efficient. """ - def __init__(self, application, media_dir = None): + def __init__(self, application, media_dir=None): from django.conf import settings self.application = application if not media_dir: diff --git a/django/core/validators.py b/django/core/validators.py index f2f3f44914..4c3f59143e 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -249,7 +249,7 @@ def hasNoProfanities(field_data, all_data): Watch your mouth! The words "f--k" and "s--t" are not allowed here. """ field_data = field_data.lower() # normalize - words_seen = [w for w in settings.PROFANITIES_LIST if field_data.find(w) > -1] + words_seen = [w for w in settings.PROFANITIES_LIST if w in field_data] if words_seen: from django.utils.text import get_text_list plural = len(words_seen) > 1 @@ -377,7 +377,7 @@ class IsValidFloat(object): if len(data) > max_allowed_length: raise ValidationError, ngettext("Please enter a valid decimal number with at most %s total digit.", "Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits - if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places)) or ('.' in data and len(data) > (self.max_digits - (self.decimal_places - len(data.split('.')[1])) + 1)): + if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places - 1)) or ('.' in data and len(data) > (max_allowed_length - (self.decimal_places - len(data.split('.')[1])))): raise ValidationError, ngettext( "Please enter a valid decimal number with a whole part of at most %s digit.", "Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places) if '.' in data and len(data.split('.')[1]) > self.decimal_places: diff --git a/django/db/backends/ansi/sql.py b/django/db/backends/ansi/sql.py index affe77a41f..a6c50298e6 100644 --- a/django/db/backends/ansi/sql.py +++ b/django/db/backends/ansi/sql.py @@ -73,7 +73,7 @@ class SchemaBuilder(object): table_output = [] for f in opts.fields: - if isinstance(f, models.ForeignKey): + if isinstance(f, (models.ForeignKey, models.OneToOneField)): rel_field = f.rel.get_related_field() data_type = self.get_rel_data_type(rel_field) else: diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 1c85b5b68a..7534a634cc 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -367,8 +367,8 @@ class BooleanField(Field): def to_python(self, value): if value in (True, False): return value - if value in ('t', 'True'): return True - if value in ('f', 'False'): return False + if value in ('t', 'True', '1'): return True + if value in ('f', 'False', '0'): 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/fields/related.py b/django/db/models/fields/related.py index 6276c55f69..dc2ae69fa7 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -618,7 +618,7 @@ class ManyToManyField(RelatedField, Field): msg = gettext_lazy('Separate multiple IDs with commas.') else: msg = gettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.') - self.help_text = string_concat(self.help_text, msg) + self.help_text = string_concat(self.help_text, ' ', msg) def get_manipulator_field_objs(self): if self.rel.raw_id_admin: diff --git a/django/db/models/manipulators.py b/django/db/models/manipulators.py index b0ce48dec5..faf453b86b 100644 --- a/django/db/models/manipulators.py +++ b/django/db/models/manipulators.py @@ -215,8 +215,8 @@ class AutomaticManipulator(forms.Manipulator): # Save many-to-many objects. for f in related.opts.many_to_many: if child_follow.get(f.name, None) and not f.rel.edit_inline: - was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.attname]) - if self.change and was_changed: + setattr(new_rel_obj, f.name, f.rel.to.objects.filter(pk__in=rel_new_data[f.attname])) + if self.change: self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) # If, in the change stage, all of the core fields were blank and diff --git a/django/db/models/query.py b/django/db/models/query.py index 78179244e6..f16e6869e3 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -732,14 +732,10 @@ def parse_lookup(kwarg_items, opts): # Extract the last elements of the kwarg. # The very-last is the lookup_type (equals, like, etc). # The second-last is the table column on which the lookup_type is - # to be performed. - # The exceptions to this are: - # 1) "pk", which is an implicit id__exact; - # if we find "pk", make the lookup_type "exact', and insert - # a dummy name of None, which we will replace when - # we know which table column to grab as the primary key. - # 2) If there is only one part, or the last part is not a query - # term, assume that the query is an __exact + # to be performed. If this name is 'pk', it will be substituted with + # the name of the primary key. + # If there is only one part, or the last part is not a query + # term, assume that the query is an __exact lookup_type = path.pop() if lookup_type == 'pk': lookup_type = 'exact' @@ -789,7 +785,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column): name = path.pop(0) # Has the primary key been requested? If so, expand it out # to be the name of the current class' primary key - if name is None: + if name is None or name == 'pk': name = current_opts.pk.name # Try to find the name in the fields associated with the current class diff --git a/django/forms/__init__.py b/django/forms/__init__.py index 759a32ba81..5f47059f03 100644 --- a/django/forms/__init__.py +++ b/django/forms/__init__.py @@ -54,6 +54,7 @@ class Manipulator(object): def get_validation_errors(self, new_data): "Returns dictionary mapping field_names to error-message lists" errors = {} + self.prepare(new_data) for field in self.fields: errors.update(field.get_validation_errors(new_data)) val_name = 'validate_%s' % field.field_name @@ -638,7 +639,7 @@ class CheckboxSelectMultipleField(SelectMultipleField): if str(value) in str_data_list: checked_html = ' checked="checked"' field_name = '%s%s' % (self.field_name, value) - output.append('
  • ' % \ + output.append('
  • ' % \ (self.get_id() + escape(value), self.__class__.__name__, field_name, checked_html, self.get_id() + escape(value), choice)) output.append('') diff --git a/django/middleware/common.py b/django/middleware/common.py index 4f060b8590..8392fb0e5f 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -64,9 +64,9 @@ class CommonMiddleware(object): is_internal = referer and (domain in referer) path = request.get_full_path() if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer): - ua = request.META.get('HTTP_USER_AGENT','') + ua = request.META.get('HTTP_USER_AGENT', '') mail_managers("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain), - "Referrer: %s\nRequested URL: %s\nUser Agent: %s\n" % (referer, request.get_full_path(), ua)) + "Referrer: %s\nRequested URL: %s\nUser agent: %s\n" % (referer, request.get_full_path(), ua)) return response # Use ETags, if requested. diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py index 034253a549..3a03fa59e4 100644 --- a/django/views/generic/create_update.py +++ b/django/views/generic/create_update.py @@ -102,7 +102,7 @@ def update_object(request, model, object_id=None, slug=None, except ObjectDoesNotExist: raise Http404, "No %s found for %s" % (model._meta.verbose_name, lookup_kwargs) - manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.name), follow=follow) + manipulator = model.ChangeManipulator(getattr(object, object._meta.pk.attname), follow=follow) if request.POST: new_data = request.POST.copy() @@ -142,7 +142,7 @@ def update_object(request, model, object_id=None, slug=None, else: c[key] = value response = HttpResponse(t.render(c)) - populate_xheaders(request, response, model, getattr(object, object._meta.pk.name)) + populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname)) return response def delete_object(request, model, post_delete_redirect, @@ -196,5 +196,5 @@ def delete_object(request, model, post_delete_redirect, else: c[key] = value response = HttpResponse(t.render(c)) - populate_xheaders(request, response, model, getattr(object, object._meta.pk.name)) + populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname)) return response diff --git a/docs/apache_auth.txt b/docs/apache_auth.txt index 72e0841305..b85057924b 100644 --- a/docs/apache_auth.txt +++ b/docs/apache_auth.txt @@ -6,7 +6,7 @@ Since keeping multiple authentication databases in sync is a common problem when dealing with Apache, you can configuring Apache to authenticate against Django's `authentication system`_ directly. For example, you could: - * Serve media files directly from Apache only to authenticated users. + * Serve static/media files directly from Apache only to authenticated users. * Authenticate access to a Subversion_ repository against Django users with a certain permission. diff --git a/docs/authentication.txt b/docs/authentication.txt index 31a894512a..6d345adaec 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -456,9 +456,9 @@ As a shortcut, you can use the convenient ``user_passes_test`` decorator:: # ... my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) -We are using this particular test as a relatively simple example, however be -aware that if you just want to test if a permission is available to a user, -you can use the ``permission_required()`` decorator described below. +We're using this particular test as a relatively simple example. However, if +you just want to test whether a permission is available to a user, you can use +the ``permission_required()`` decorator, described later in this document. Here's the same thing, using Python 2.4's decorator syntax:: @@ -495,20 +495,30 @@ Example in Python 2.4 syntax:: The permission_required decorator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Since checking whether a user has a particular permission available to them is a -relatively common operation, Django provides a shortcut for that particular -case: the ``permission_required()`` decorator. Using this decorator, the -earlier example can be written as:: +**New in Django development version** + +It's a relatively common task to check whether a user has a particular +permission. For that reason, Django provides a shortcut for that case: the +``permission_required()`` decorator. Using this decorator, the earlier example +can be written as:: from django.contrib.auth.decorators import permission_required - + def my_view(request): # ... - my_view = permission_required('polls.can_vote')(my_view) Note that ``permission_required()`` also takes an optional ``login_url`` -parameter. +parameter. Example:: + + from django.contrib.auth.decorators import permission_required + + def my_view(request): + # ... + my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view) + +As in the ``login_required`` decorator, ``login_url`` defaults to +``'/accounts/login/'``. Limiting access to generic views -------------------------------- @@ -633,7 +643,7 @@ The currently logged-in user, either a ``User`` instance or an``AnonymousUser`` instance, is stored in the template variable ``{{ user }}``:: {% if user.is_authenticated %} -

    Welcome, {{ user.username }}. Thanks for logging in.

    +

    Welcome, {{ user.username }}. Thanks for logging in.

    {% else %}

    Welcome, new user. Please log in.

    {% endif %} diff --git a/docs/contributing.txt b/docs/contributing.txt index 7ecda7425c..6ff0b038a3 100644 --- a/docs/contributing.txt +++ b/docs/contributing.txt @@ -259,10 +259,10 @@ The tests cover: We appreciate any and all contributions to the test suite! The Django tests all use the testing infrastructure that ships with Django for -testing applications. See `Testing Django Applications`_ for an explanation of +testing applications. See `Testing Django applications`_ for an explanation of how to write new tests. -.. _Testing Django Applications: http://www.djangoproject.com/documentation/testing/ +.. _Testing Django applications: http://www.djangoproject.com/documentation/testing/ Running the unit tests ---------------------- @@ -273,7 +273,7 @@ To run the tests, ``cd`` to the ``tests/`` directory and type:: Yes, the unit tests need a settings module, but only for database connection info -- the ``DATABASE_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD``. -You will also need a ``ROOT_URLCONF`` setting (it's value is ignored; it just +You will also need a ``ROOT_URLCONF`` setting (its value is ignored; it just needs to be present) and a ``SITE_ID`` setting (any integer value will do) in order for all the tests to pass. diff --git a/docs/db-api.txt b/docs/db-api.txt index 7800ff324a..0d1f049601 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -1140,7 +1140,7 @@ The pk lookup shortcut ---------------------- For convenience, Django provides a ``pk`` lookup type, which stands for -"primary_key". This is shorthand for "an exact lookup on the primary-key." +"primary_key". In the example ``Blog`` model, the primary key is the ``id`` field, so these three statements are equivalent:: @@ -1149,6 +1149,14 @@ three statements are equivalent:: Blog.objects.get(id=14) # __exact is implied Blog.objects.get(pk=14) # pk implies id__exact +The use of ``pk`` isn't limited to ``__exact`` queries -- any query term +can be combined with ``pk`` to perform a query on the primary key of a model:: + + # Get blogs entries with id 1, 4 and 7 + Blog.objects.filter(pk__in=[1,4,7]) + # Get all blog entries with id > 14 + Blog.objects.filter(pk__gt=14) + ``pk`` lookups also work across joins. For example, these three statements are equivalent:: diff --git a/docs/django-admin.txt b/docs/django-admin.txt index ed162f0520..7f9682b443 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -392,10 +392,10 @@ and `2` is verbose output. Example usage:: django-admin.py manage.py --adminmedia=/tmp/new-admin-style/ -Tell Django where to find the various stylesheets and Javascript files for the -admin interface when running the development server. Normally these files are -served out of the Django source tree, but since some designers change these -files for their site, this option allows you to test against custom versions. +Tells Django where to find the various CSS and JavaScript files for the admin +interface when running the development server. Normally these files are served +out of the Django source tree, but because some designers customize these files +for their site, this option allows you to test against custom versions. Extra niceties ============== diff --git a/docs/forms.txt b/docs/forms.txt index 0ffb0bdcb7..2b00cb67d6 100644 --- a/docs/forms.txt +++ b/docs/forms.txt @@ -337,8 +337,8 @@ The only real differences are: object being edited. * We set ``new_data`` based upon ``flatten_data()`` from the manipulator. - ``flatten_data()`` takes the data from the original object under - manipulation, and converts it into a data dictionary that can be used + ``flatten_data()`` takes the data from the original object under + manipulation, and converts it into a data dictionary that can be used to populate form elements with the existing values for the object. * The above example uses a different template, so create and edit can be @@ -404,7 +404,7 @@ Here's a simple function that might drive the above form:: errors = new_data = {} form = forms.FormWrapper(manipulator, new_data, errors) return render_to_response('contact_form.html', {'form': form}) - + ``FileField`` and ``ImageField`` special cases ============================================== @@ -481,13 +481,13 @@ the data being validated. Also, because consistency in user interfaces is important, we strongly urge you to put punctuation at the end of your validation messages. -When Are Validators Called? +When are validators called? --------------------------- After a form has been submitted, Django first checks to see that all the required fields are present and non-empty. For each field that passes that test *and if the form submission contained data* for that field, all the -validators for that field are called in turn. The emphasised portion in the +validators for that field are called in turn. The emphasized portion in the last sentence is important: if a form field is not submitted (because it contains no data -- which is normal HTML behaviour), the validators are not run against the field. @@ -497,18 +497,17 @@ This feature is particularly important for models using ``forms.CheckBoxField``. If the checkbox is not selected, it will not contribute to the form submission. -If you would like your validator to *always* run, regardless of whether the -field it is attached to contains any data, set the ``always_test`` attribute -on the validator function. For example:: +If you would like your validator to run *always*, regardless of whether its +attached field contains any data, set the ``always_test`` attribute on the +validator function. For example:: def my_custom_validator(field_data, all_data): # ... - my_custom_validator.always_test = True This validator will always be executed for any field it is attached to. -Ready-made Validators +Ready-made validators --------------------- Writing your own validator is not difficult, but there are some situations diff --git a/docs/model-api.txt b/docs/model-api.txt index c6c4200239..5524c76654 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -545,7 +545,7 @@ The default value for the field. If ``False``, the field will not be editable in the admin or via form processing using the object's ``AddManipulator`` or ``ChangeManipulator`` -classes. Default is ``True``. +classes. Default is ``True``. ``help_text`` ~~~~~~~~~~~~~ diff --git a/docs/serialization.txt b/docs/serialization.txt index 694e2d25db..aee1b9a3bb 100644 --- a/docs/serialization.txt +++ b/docs/serialization.txt @@ -3,12 +3,12 @@ Serializing Django objects ========================== .. note:: - + This API is currently under heavy development and may change -- perhaps drastically -- in the future. - + You have been warned. - + Django's serialization framework provides a mechanism for "translating" Django objects into other formats. Usually these other formats will be text-based and used for sending Django objects over a wire, but it's possible for a @@ -21,7 +21,7 @@ At the highest level, serializing data is a very simple operation:: from django.core import serializers data = serializers.serialize("xml", SomeModel.objects.all()) - + The arguments to the ``serialize`` function are the format to serialize the data to (see `Serialization formats`_) and a QuerySet_ to serialize. (Actually, the second argument can be any iterator that yields Django objects, @@ -34,7 +34,7 @@ You can also use a serializer object directly:: xml_serializer = serializers.get_serializer("xml") xml_serializer.serialize(queryset) data = xml_serializer.getvalue() - + This is useful if you want to serialize data directly to a file-like object (which includes a HTTPResponse_):: @@ -50,7 +50,7 @@ Deserializing data is also a fairly simple operation:: for obj in serializers.deserialize("xml", data): do_something_with(obj) - + As you can see, the ``deserialize`` function takes the same format argument as ``serialize``, a string or stream of data, and returns an iterator. @@ -69,7 +69,7 @@ something like:: for deserialized_object in serializers.deserialize("xml", data): if object_should_be_saved(deserialized_object): obj.save() - + In other words, the usual use is to examine the deserialized objects to make sure that they are "appropriate" for saving before doing so. Of course, if you trust your data source you could just save the object and move on. @@ -89,22 +89,22 @@ Django "ships" with a few included serializers: bundled with Django). ``python`` Translates to and from "simple" Python objects (lists, dicts, - strings, etc.). Not really all that useful on its own, but + strings, etc.). Not really all that useful on its own, but used as a base for other serializers. ========== ============================================================== .. _json: http://json.org/ .. _simplejson: http://undefined.org/python/#simplejson -Notes For Specific Serialization Formats +Notes for specific serialization formats ---------------------------------------- json ~~~~ -If you are using UTF-8 (or any other non-ASCII encoding) data with the JSON +If you're using UTF-8 (or any other non-ASCII encoding) data with the JSON serializer, you must pass ``ensure_ascii=False`` as a parameter to the -``serialize()`` call. Otherwise the output will not be encoded correctly. +``serialize()`` call. Otherwise, the output won't be encoded correctly. For example:: diff --git a/docs/settings.txt b/docs/settings.txt index 6764f01513..57483cbef3 100644 --- a/docs/settings.txt +++ b/docs/settings.txt @@ -606,8 +606,11 @@ See also ``APPEND_SLASH``. PROFANITIES_LIST ---------------- -A list of profanities that will trigger a validation error when the -``hasNoProfanities`` validator is called. +A tuple of profanities, as strings, that will trigger a validation error when +the ``hasNoProfanities`` validator is called. + +We don't list the default values here, because that would be profane. To see +the default values, see the file ``django/conf/global_settings.py``. ROOT_URLCONF ------------ diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py index acbea0d1e0..5638865f31 100644 --- a/tests/modeltests/basic/models.py +++ b/tests/modeltests/basic/models.py @@ -86,6 +86,10 @@ DoesNotExist: Article matching query does not exist. >>> Article.objects.get(pk=1) +# pk can be used as a shortcut for the primary key name in any query +>>> Article.objects.filter(pk__in=[1]) +[] + # Model instances of the same type and same ID are considered equal. >>> a = Article.objects.get(pk=1) >>> b = Article.objects.get(pk=1) diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py index ca788f6aa5..fd0901da3c 100644 --- a/tests/modeltests/custom_pk/models.py +++ b/tests/modeltests/custom_pk/models.py @@ -51,6 +51,10 @@ DoesNotExist: Employee matching query does not exist. >>> Employee.objects.get(employee_code__exact='ABC123') +# pk can be used as a substitute for the primary key. +>>> Employee.objects.filter(pk__in=['ABC123','XYZ456']) +[, ] + # Fran got married and changed her last name. >>> fran = Employee.objects.get(pk='XYZ456') >>> fran.last_name = 'Jones' diff --git a/tests/modeltests/one_to_one/models.py b/tests/modeltests/one_to_one/models.py index 8afa74454d..7488204ff1 100644 --- a/tests/modeltests/one_to_one/models.py +++ b/tests/modeltests/one_to_one/models.py @@ -30,6 +30,14 @@ class Waiter(models.Model): def __str__(self): return "%s the waiter at %s" % (self.name, self.restaurant) +class ManualPrimaryKey(models.Model): + primary_key = models.CharField(maxlength=10, primary_key=True) + name = models.CharField(maxlength = 50) + +class RelatedModel(models.Model): + link = models.OneToOneField(ManualPrimaryKey) + name = models.CharField(maxlength = 50) + __test__ = {'API_TESTS':""" # Create a couple of Places. >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton') @@ -151,4 +159,10 @@ DoesNotExist: Restaurant matching query does not exist. # Delete the restaurant; the waiter should also be removed >>> r = Restaurant.objects.get(pk=1) >>> r.delete() + +# One-to-one fields still work if you create your own primary key +>>> o1 = ManualPrimaryKey(primary_key="abc123", name="primary") +>>> o1.save() +>>> o2 = RelatedModel(link=o1, name="secondary") +>>> o2.save() """}