如何自定义此电子邮件的内容?您正在收到此电子邮件,因为您请求在 localhost:8000 上重置用户帐户的密码。
请转到以下页面并选择一个新密码:
http://localhost:8000/api/reset/Kih/89a-23809182347689312b123/
如果您忘记了用户名,请注意:test
感谢使用我们的网站!
localhost:8000 团队
如何自定义此电子邮件的内容?您正在收到此电子邮件,因为您请求在 localhost:8000 上重置用户帐户的密码。
请转到以下页面并选择一个新密码:
http://localhost:8000/api/reset/Kih/89a-23809182347689312b123/
如果您忘记了用户名,请注意:test
感谢使用我们的网站!
localhost:8000 团队
最近我需要在一个项目中实现同样的功能,但无法在任何地方找到详细的答案。
所以我在这里留下我的解决方案,供未来需要的人参考。
对mariodev的建议进行扩展:
1. 子类化PasswordResetSerializer
并覆盖save
方法。
yourproject_app/serializers.py
from django.conf import settings
from rest_auth.serializers import PasswordResetSerializer as _PasswordResetSerializer
class PasswordResetSerializer(_PasswordResetSerializer):
def save(self):
request = self.context.get('request')
opts = {
'use_https': request.is_secure(),
'from_email': getattr(settings, 'DEFAULT_FROM_EMAIL'),
###### USE YOUR TEXT FILE ######
'email_template_name': 'example_message.txt',
'request': request,
}
self.reset_form.save(**opts)
2. 配置AUTH_USER_MODEL
yourproject/settings.py
###### USE YOUR USER MODEL ######
AUTH_USER_MODEL = 'yourproject_app.ExampleUser'
3. 连接自定义的PasswordResetSerializer
以覆盖默认设置。
yourproject/settings.py
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':
'yourproject_app.serializers.PasswordResetSerializer',
}
4. 将您的自定义电子邮件消息文本文件所在目录的路径添加到TEMPLATES
中
yourproject/settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'yourproject/templates')],
...
}
]
5. 编写自定义电子邮件消息(默认从Django复制)
yourproject/templates/example_message.txt
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset
for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
更新:此解决方案适用于django-rest-auth的旧版本(v0.6.0)。从评论中可以看出,源软件包已进行了一些更新,更容易地处理自定义电子邮件模板。最好始终使用软件包中定义的方法,而不是像我的解决方案中覆盖它们。虽然曾经是必需的,但现在可能不再是这样。
PasswordResetSerializer
并重写 get_email_options
方法。例如:from rest_auth.serializers import PasswordResetSerializer
class CustomPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
return {
'subject_template_name': 'registration/password_reset_subject.txt',
'email_template_name': 'registration/password_reset_message.txt',
'html_email_template_name': 'registration/'
'password_reset_message.html',
'extra_email_context': {
'pass_reset_obj': self.your_extra_reset_obj
}
}
-templates
-registration
password_reset_email.html
您想要的内容是关于IT技术的:Django rest-auth 使用django.contrib.auth 模板。
对于 dj-rest-auth
,我是这样做的:
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.urls.base import reverse
from allauth.account import app_settings
from allauth.account.adapter import get_adapter
from allauth.account.utils import user_pk_to_url_str, user_username
from allauth.utils import build_absolute_uri
from dj_rest_auth.forms import AllAuthPasswordResetForm
from dj_rest_auth.serializers import PasswordResetSerializer
class CustomAllAuthPasswordResetForm(AllAuthPasswordResetForm):
def save(self, request, **kwargs):
current_site = get_current_site(request)
email = self.cleaned_data['email']
token_generator = kwargs.get('token_generator',
default_token_generator)
for user in self.users:
temp_key = token_generator.make_token(user)
# save it to the password reset model
# password_reset = PasswordReset(user=user, temp_key=temp_key)
# password_reset.save()
# send the password reset email
path = reverse(
'password_reset_confirm',
args=[user_pk_to_url_str(user), temp_key],
)
url = build_absolute_uri(None, path) # PASS NONE INSTEAD OF REQUEST
context = {
'current_site': current_site,
'user': user,
'password_reset_url': url,
'request': request,
}
if app_settings.AUTHENTICATION_METHOD != app_settings.AuthenticationMethod.EMAIL:
context['username'] = user_username(user)
get_adapter(request).send_mail('account/email/password_reset_key',
email, context)
return self.cleaned_data['email']
class CustomPasswordResetSerializer(PasswordResetSerializer):
@property
def password_reset_form_class(self):
return CustomAllAuthPasswordResetForm
# settings.py
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER':
'api.users.api.serializers.CustomPasswordResetSerializer',
}
request
替换为None
,而不是原始的request
,使用build_absolute_uri
函数时它将采用在django.contrib.sites
模块中定义的SITE_ID=1
的值作为域名。因此,在Django管理界面中定义的任何内容都可以作为密码重置链接URL中的域名。如果您想让密码重置URL指向前端(可能是在不同域上运行的React应用程序)时,这种方法很有意义。dj-rest-auth
文档,以了解您需要设置哪个设置。save
方法钩取你自己的重置密码序列化程序(PASSWORD_RESET_SERIALIZER
)。如果您想使用HTML电子邮件模板,则可以按照Brian的回答添加以下内容:
'html_email_template_name': 'account/email/example_message.html',
将其添加在
###### USE YOUR TEXT FILE ######
'email_template_name': 'account/email/example_message.txt',
下方即可,这样您就可以使用HTML模板发送电子邮件。
通过检查PasswordResetForm类的send_mail
方法,您可以了解到这是为什么发生的。
class PasswordResetForm(forms.Form):
email = forms.EmailField(label=_("Email"), max_length=254)
def send_mail(self, subject_template_name, email_template_name,
context, from_email, to_email, html_email_template_name=None):
"""
Send a django.core.mail.EmailMultiAlternatives to `to_email`.
"""
subject = loader.render_to_string(subject_template_name, context)
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
body = loader.render_to_string(email_template_name, context)
email_message = EmailMultiAlternatives(subject, body, from_email, [to_email])
if html_email_template_name is not None:
html_email = loader.render_to_string(html_email_template_name, context)
email_message.attach_alternative(html_email, 'text/html')
email_message.send()```
现在将django/contrib/admin/templates/registration/中的所有文件复制到您刚刚创建的目录中。您可以在安装django的位置找到此目录。在Linux中,可以在以下位置找到它:templates/admin/registration/
您需要root权限才能访问此目录。/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/registration
对于使用dj-rest-auth的用户,如果同时使用all-auth,请注意覆盖get_email_options()方法的解决方案将不起作用。因为当在设置中找到installed_apps时,dj-rest-auth会使用all-auth包中的AllAuthPasswordResetForm,该表单使用与dj-rest-auth发送邮件的不同代码,因此覆盖不会生效。相反,您需要覆盖all-auth表单中的'template_prefix'并/或根据需要更新url,以扩展表单,并覆盖序列化器以使用自定义表单。我发现这篇教程是一个很好的参考资料。希望能节省某些人的时间 :)
project/templates/emails/password-reset-email.html
下,并覆盖了get_email_options(self)
,现在返回'html_email_template_name': 'templates/emails/password-reset-email.html'
,但仍然没有变化...我的自定义密码序列化程序被使用了,我通过pycharm调试器进行了验证。所以设置应该是正确的,我的重写get_email_options也被调用了。有什么想法吗?谢谢! - ElectRocnic'password-reset-email.html'
而不是'templates/emails/password-reset-email.html'
,并确保在settings.py中指定了您的模板目录。此外,在我最初编写此代码时,get_email_options(self)
未包含在rest_auth软件包中。我的方法需要覆盖save(self)
。 - Brian K.