2014-02-15 2 views
6

Приложение Django в настоящее время настроено на использование собственного регистрационного пакета для обработки аутентификации пользователей и управления ими.Как сделать Django Password Reset Email Красивым HTML?

Я создал несколько файлов в myApp/templates/registration, которые используются для отправки маркера сброса пароля, как описано в these docs.

Он отлично работает. Кроме того, что пароль для сброса пароля является уродливым текстовым монстром. Я хотел бы, чтобы это соответствовало внешнему виду и другим сообщениям, отправляемым моим приложением. IE: Я хочу, чтобы он был HTML и содержал изображения, стили и ссылки. Как мне это сделать?

Я следовал подробным инструкциям here. Однако в этом коде есть ошибка, в которой я не знаю, что делать: 'CustomPasswordResetForm' object has no attribute 'users_cache'

Может ли кто-нибудь показать мне подробный рабочий пример, как это сделать? Мне жаль, что это было не так сложно.

ответ

1

Вы пытались отредактировать этот шаблон? registration/password_reset_email.html

Вы можете добавить файл password_reset_email.html в свои шаблоны/папку регистрации в своем проекте, а затем добавить соответствующие разделы/HTML для получения хорошего шаблона. Шаблон по умолчанию пуст.

+0

Да. Я попробовал это. Но когда вы помещаете HTML в этот файл, код HTML отображается в теле письма. –

+0

См. Ответ Burhan Halid ниже - вам нужно переопределить функцию для поддержки отправки multipart/html – johnbarr

0

Вам необходимо переопределить html по умолчанию. Для этого перейдите в папку django istallation в libs/site-packages/django и скопируйте password_reset_email.html из шаблонов django и вставьте его в [templates]/registration/password_reset_email.html. Затем определите свой CSS и отредактируйте html по умолчанию, и если ваш код HTML появится в теле, отключите автоматическое экранирование менеджера шаблонов django, но оно не рекомендуется.

+0

Шаблон находится в django/contrib/admin/templates/registration/... Я думаю, что ответы должны быть более объяснительными .. – ratata

6

По умолчанию хелперные представления для проверки подлинности django не могут отправлять многостраничные (HTML) электронные письма, потому что базовый метод send_mail не поддерживает HTML-письма еще.

Это будет исправлено в следующей версии, добавив флаг html_message.

Самый простой способ исправить это - создать свою собственную форму сброса пароля и использовать EmailMultiAlternatives для отправки вашего сообщения, что позволит вашему HTML правильно отображать в почтовом клиенте.

Вы можете использовать existing form, и внесите необходимые изменения:

class HTMLPasswordResetForm(forms.Form): 
    email = forms.EmailField(label=_("Email"), max_length=254) 

    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. 
     """ 
     # from django.core.mail import send_mail 
     from django.core.mail import EmailMultiAlternatives 
     UserModel = get_user_model() 
     email = self.cleaned_data["email"] 
     active_users = UserModel._default_manager.filter(
      email__iexact=email, is_active=True) 
     for user in active_users: 
      # Make sure that no email is sent to a user that actually has 
      # a password marked as unusable 
      if not user.has_usable_password(): 
       continue 
      if not domain_override: 
       current_site = get_current_site(request) 
       site_name = current_site.name 
       domain = current_site.domain 
      else: 
       site_name = domain = domain_override 
      c = { 
       'email': user.email, 
       'domain': domain, 
       'site_name': site_name, 
       'uid': urlsafe_base64_encode(force_bytes(user.pk)), 
       'user': user, 
       'token': token_generator.make_token(user), 
       'protocol': 'https' if use_https else 'http', 
      } 
      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) 

      msg = EmailMessage(subject, email, from_email, [user.email]) 
      msg.content_subtype = "html" # Main content is now text/html 
      msg.send() 

      #send_mail(subject, email, from_email, [user.email]) 

После того, как вы сделали это, изменить password_reset вызов метода и перейти в новый класс формы:

password_reset(request, password_reset_form=HTMLPasswordResetForm) 
+0

Burhan , Как изменить существующий вызов password_reset? Я не вижу, чтобы это называлось где угодно. Укажите мне имя файла. Я добавил вашу форму выше в мои формы.Но я все еще не уверен, что должно быть в моих view.py и в urls.py (Кстати, есть 2 urls.py, как вы знаете. Я внес изменения в приложение для своего приложения, а не глобальное) –

+0

Создайте свой собственный пользовательский режим для сброса паролей. –

+0

Работаю как шарм :) – Abdullah

6

[кросс -posted from Does Django password_reset support html email templates?]

После некоторого количества проб и ошибок я обнаружил гораздо более простой способ предоставить заказную templ который был отправлен в последнюю версию Django (1.8).

В вашем project/urls.py, добавьте эти импорт:

from django.contrib.auth import views as auth_views 
from django.core.urlresolvers import reverse_lazy 

И добавьте следующий маршрут в ваших urlpatterns раньше обычного Джанго CONTRIB URL аутентификации маршрут включения:

url(r'^accounts/password/reset/$', 
    auth_views.password_reset, 
    { 
    'post_reset_redirect': reverse_lazy('auth_password_reset_done'), 
    'html_email_template_name': 'registration/password_reset_html_email.html' 
    }, 
    name='auth_password_reset'), 


url('^', include('django.contrib.auth.urls')), 

А потом, в ваших приложения templates/registration, создайте password_reset_html_email.html с любым HTML-шаблоном, который вы хотите.

Причина этого, казалось, необходимое лежало в источнике для django/contrib/auth/views.py, который имеет функцию просмотра исходного маршрута URL отображается:

147 def password_reset(request, is_admin_site=False, 
148     template_name='registration/password_reset_form.html', 
149     email_template_name='registration/password_reset_email.html', 
150     subject_template_name='registration/password_reset_subject.txt', 
151     password_reset_form=PasswordResetForm, 
152     token_generator=default_token_generator, 
153     post_reset_redirect=None, 
154     from_email=None, 
155     current_app=None, 
156     extra_context=None, 
157     html_email_template_name=None): 
158 

html_email_template_name установлен в None как по умолчанию, и не сделал по-видимому, способ присвоить его значение, кроме того, что я перечислил этот конкретный маршрут для этого случая, как я упоминал выше.

Надеюсь, это поможет без необходимости скопировать вставку кучу почти идентичного кода, например, некоторые из других предложенных ответов - обратная связь приветствуется, конечно!

0

Вы можете сделать следующее.

Добавить как в password_reset:

html_email_template_name='YOUR TEMPLATE PATH', 
email_template_name='YOUR TEMPLATE PATH' 

Он работал для меня (Django 1,11)

0

Добавление моих выводов для Джанго версии 2.0, как я нашел остальные ответы на этот вопрос, чтобы быть вне -of-дата.

С 2,0, правильный способ добавления URL в ваш urls.py файла с помощью path():

from django.urls import path 
from django.contrib.auth import views as auth_views 

path('accounts/password_reset/', auth_views.PasswordResetView.as_view(
    html_email_template_name='registration/password_reset_html_email.html' 
)), 

Следующий фрагмент кода, чтобы выделить здесь является .as_view() функция. Django 2.0 реализует представления auth как классы. Вы можете узнать больше об этом в Authentication Views documentation

Вы затем «преобразуете» класс в представление с использованием `.as_view(), и вы можете передавать любые атрибуты класса, определенные в исходном коде как именованные параметры.

Передача html_email_template_name (по умолчанию None) автоматически отправляет html-адрес электронной почты.

Вы можете получить доступ исходный код для PasswordResetView следуя питона пути: django.contrib.auth.views

Здесь Вы можете увидеть другой класс атрибутов, которые можно передать в PasswordResetView и других AUTH взглядов. Это очень полезно для передачи extra_context в ваши шаблоны django.

Смежные вопросы