浏览代码

Fixed #12202 -- Removed hardcoded password reset subject and added a subject_template_name parameter to the password_reset view. Thanks, Ramiro Morales, Claude Paroz and agabel.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16438 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Jannis Leidel 13 年之前
父节点
当前提交
656360c240

+ 1 - 0
MANIFEST.in

@@ -17,6 +17,7 @@ recursive-include django/contrib/admin/templates *
 recursive-include django/contrib/admin/media *
 recursive-include django/contrib/admindocs/templates *
 recursive-include django/contrib/auth/fixtures *
+recursive-include django/contrib/auth/templates *
 recursive-include django/contrib/auth/tests/templates *
 recursive-include django/contrib/comments/templates *
 recursive-include django/contrib/databrowse/templates *

+ 1 - 1
django/contrib/auth/fixtures/authtestdata.json

@@ -31,7 +31,7 @@
             "groups": [], 
             "user_permissions": [], 
             "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", 
-            "email": "testclient@example.com", 
+            "email": "testclient2@example.com",
             "date_joined": "2006-12-17 07:03:31"
         }
     },

+ 10 - 5
django/contrib/auth/forms.py

@@ -120,8 +120,11 @@ class PasswordResetForm(forms.Form):
             raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?"))
         return email
 
-    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
-             use_https=False, token_generator=default_token_generator, from_email=None, request=None):
+    def save(self, domain_override=None,
+             subject_template_name='registration/password_reset_subject.txt',
+             email_template_name='registration/password_reset_email.html',
+             use_https=False, token_generator=default_token_generator,
+             from_email=None, request=None):
         """
         Generates a one-use only link for resetting password and sends to the user
         """
@@ -133,7 +136,6 @@ class PasswordResetForm(forms.Form):
                 domain = current_site.domain
             else:
                 site_name = domain = domain_override
-            t = loader.get_template(email_template_name)
             c = {
                 'email': user.email,
                 'domain': domain,
@@ -143,8 +145,11 @@ class PasswordResetForm(forms.Form):
                 'token': token_generator.make_token(user),
                 'protocol': use_https and 'https' or 'http',
             }
-            send_mail(_("Password reset on %s") % site_name,
-                t.render(Context(c)), from_email, [user.email])
+            subject = loader.render_to_string(subject_template_name, c)
+            # Email subject *must not* contain newlines
+            subject = ''.join(subject.splitlines())
+            email = loader.render_to_string(email_template_name, c)
+            send_mail(subject, email, from_email, [user.email])
 
 class SetPasswordForm(forms.Form):
     """

+ 47 - 51
django/contrib/auth/locale/en/LC_MESSAGES/django.po

@@ -4,7 +4,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Django\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-03-15 13:14-0400\n"
+"POT-Creation-Date: 2011-06-19 13:08+0200\n"
 "PO-Revision-Date: 2010-05-13 15:35+0200\n"
 "Last-Translator: Django team\n"
 "Language-Team: English <en@li.org>\n"
@@ -12,27 +12,27 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: admin.py:28
+#: admin.py:29
 msgid "Personal info"
 msgstr ""
 
-#: admin.py:29
+#: admin.py:30
 msgid "Permissions"
 msgstr ""
 
-#: admin.py:30
+#: admin.py:31
 msgid "Important dates"
 msgstr ""
 
-#: admin.py:31
+#: admin.py:32
 msgid "Groups"
 msgstr ""
 
-#: admin.py:113
+#: admin.py:116
 msgid "Password changed successfully."
 msgstr ""
 
-#: admin.py:123
+#: admin.py:126
 #, python-format
 msgid "Change password: %s"
 msgstr ""
@@ -49,7 +49,7 @@ msgstr ""
 msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
 msgstr ""
 
-#: forms.py:17 forms.py:67 forms.py:193
+#: forms.py:17 forms.py:67 forms.py:201
 msgid "Password"
 msgstr ""
 
@@ -65,7 +65,7 @@ msgstr ""
 msgid "A user with that username already exists."
 msgstr ""
 
-#: forms.py:37 forms.py:163 forms.py:205
+#: forms.py:37 forms.py:171 forms.py:213
 msgid "The two password fields didn't match."
 msgstr ""
 
@@ -89,154 +89,150 @@ msgstr ""
 msgid "E-mail"
 msgstr ""
 
-#: forms.py:117
+#: forms.py:120
 msgid ""
 "That e-mail address doesn't have an associated user account. Are you sure "
 "you've registered?"
 msgstr ""
 
-#: forms.py:143
-#, python-format
-msgid "Password reset on %s"
-msgstr ""
-
-#: forms.py:151
+#: forms.py:159
 msgid "New password"
 msgstr ""
 
-#: forms.py:152
+#: forms.py:160
 msgid "New password confirmation"
 msgstr ""
 
-#: forms.py:177
+#: forms.py:185
 msgid "Old password"
 msgstr ""
 
-#: forms.py:185
+#: forms.py:193
 msgid "Your old password was entered incorrectly. Please enter it again."
 msgstr ""
 
-#: forms.py:194
+#: forms.py:202
 msgid "Password (again)"
 msgstr ""
 
-#: models.py:76 models.py:104
+#: models.py:77 models.py:105
 msgid "name"
 msgstr ""
 
-#: models.py:78
+#: models.py:79
 msgid "codename"
 msgstr ""
 
-#: models.py:82
+#: models.py:83
 msgid "permission"
 msgstr ""
 
-#: models.py:83 models.py:105
+#: models.py:84 models.py:106
 msgid "permissions"
 msgstr ""
 
-#: models.py:108
+#: models.py:109
 msgid "group"
 msgstr ""
 
-#: models.py:109 models.py:216
+#: models.py:110 models.py:217
 msgid "groups"
 msgstr ""
 
-#: models.py:206
+#: models.py:207
 msgid "username"
 msgstr ""
 
-#: models.py:206
+#: models.py:207
 msgid ""
 "Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"
 msgstr ""
 
-#: models.py:207
+#: models.py:208
 msgid "first name"
 msgstr ""
 
-#: models.py:208
+#: models.py:209
 msgid "last name"
 msgstr ""
 
-#: models.py:209
+#: models.py:210
 msgid "e-mail address"
 msgstr ""
 
-#: models.py:210
+#: models.py:211
 msgid "password"
 msgstr ""
 
-#: models.py:210
+#: models.py:211
 msgid ""
 "Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
 "password form</a>."
 msgstr ""
 
-#: models.py:211
+#: models.py:212
 msgid "staff status"
 msgstr ""
 
-#: models.py:211
+#: models.py:212
 msgid "Designates whether the user can log into this admin site."
 msgstr ""
 
-#: models.py:212
+#: models.py:213
 msgid "active"
 msgstr ""
 
-#: models.py:212
+#: models.py:213
 msgid ""
 "Designates whether this user should be treated as active. Unselect this "
 "instead of deleting accounts."
 msgstr ""
 
-#: models.py:213
+#: models.py:214
 msgid "superuser status"
 msgstr ""
 
-#: models.py:213
+#: models.py:214
 msgid ""
 "Designates that this user has all permissions without explicitly assigning "
 "them."
 msgstr ""
 
-#: models.py:214
+#: models.py:215
 msgid "last login"
 msgstr ""
 
-#: models.py:215
+#: models.py:216
 msgid "date joined"
 msgstr ""
 
-#: models.py:217
+#: models.py:218
 msgid ""
 "In addition to the permissions manually assigned, this user will also get "
 "all permissions granted to each group he/she is in."
 msgstr ""
 
-#: models.py:218
+#: models.py:219
 msgid "user permissions"
 msgstr ""
 
-#: models.py:222
+#: models.py:223
 msgid "user"
 msgstr ""
 
-#: models.py:223
+#: models.py:224
 msgid "users"
 msgstr ""
 
-#: models.py:406
-msgid "message"
-msgstr ""
-
-#: views.py:91
+#: views.py:93
 msgid "Logged out"
 msgstr ""
 
-#: management/commands/createsuperuser.py:23
+#: management/commands/createsuperuser.py:24
 msgid "Enter a valid e-mail address."
 msgstr ""
+
+#: templates/registration/password_reset_subject.txt:2
+#, python-format
+msgid "Password reset on %(site_name)s"
+msgstr ""

+ 3 - 0
django/contrib/auth/templates/registration/password_reset_subject.txt

@@ -0,0 +1,3 @@
+{% load i18n %}{% autoescape off %}
+{% blocktrans %}Password reset on {{ site_name }}{% endblocktrans %}
+{% endautoescape %}

+ 13 - 0
django/contrib/auth/tests/forms.py

@@ -1,3 +1,7 @@
+from __future__ import with_statement
+import os
+from django.conf import settings
+from django.core import mail
 from django.contrib.auth.models import User
 from django.contrib.auth.forms import UserCreationForm, AuthenticationForm,  PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm
 from django.test import TestCase
@@ -251,6 +255,15 @@ class PasswordResetFormTest(TestCase):
         self.assertTrue(form.is_valid())
         self.assertEqual(form.cleaned_data['email'], email)
 
+    def test_custom_email_subject(self):
+        template_path = os.path.join(os.path.dirname(__file__), 'templates')
+        with self.settings(TEMPLATE_DIRS=(template_path,)):
+            data = {'email': 'testclient@example.com'}
+            form = PasswordResetForm(data)
+            self.assertTrue(form.is_valid())
+            form.save()
+            self.assertEqual(len(mail.outbox), 1)
+            self.assertEqual(mail.outbox[0].subject, u'Custom password reset on example.com')
 
     def test_bug_5605(self):
         # bug #5605, preserve the case of the user name (before the @ in the

+ 1 - 0
django/contrib/auth/tests/templates/registration/password_reset_subject.txt

@@ -0,0 +1 @@
+{% autoescape off %}Custom password reset on {{ site_name }}{% endautoescape %}

+ 2 - 0
django/contrib/auth/views.py

@@ -135,6 +135,7 @@ def redirect_to_login(next, login_url=None,
 def password_reset(request, is_admin_site=False,
                    template_name='registration/password_reset_form.html',
                    email_template_name='registration/password_reset_email.html',
+                   subject_template_name='registration/password_reset_subject.txt',
                    password_reset_form=PasswordResetForm,
                    token_generator=default_token_generator,
                    post_reset_redirect=None,
@@ -151,6 +152,7 @@ def password_reset(request, is_admin_site=False,
                 'token_generator': token_generator,
                 'from_email': from_email,
                 'email_template_name': email_template_name,
+                'subject_template_name': subject_template_name,
                 'request': request,
             }
             if is_admin_site:

+ 6 - 0
docs/topics/auth.txt

@@ -964,6 +964,12 @@ includes a few other useful built-in views located in
           generating the email with the new password. This will default to
           :file:`registration/password_reset_email.html` if not supplied.
 
+        * ``subject_template_name``: The full name of a template to use for
+          the subject of the email with the new password. This will default
+          to :file:`registration/password_reset_subject.txt` if not supplied.
+
+          .. versionadded:: 1.4
+
         * ``password_reset_form``: Form that will be used to set the password.
           Defaults to :class:`~django.contrib.auth.forms.PasswordResetForm`.