问题
Good day, I am trying to override the password_reset_email of Django allauth. the issue is that it successfully overrides but I get the html code just sent to the user instead of the html representation.
I was expecting a styled email just like I got for my confirmation email, but this does not seem to be the case.
In my templates/registration/password_reset_email.html
{% load i18n %}
{% autoescape off %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Confirm Your E-mail</title>
<style>
.body {
background-color: #f6f6f6;
padding: 30px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.content {
background-color: #FFFFFF;
color: #4d4d4d;
max-width: 400px;
padding: 20px;
margin: auto;
}
.title {
font-size: 20px;
font-weight: 600;
margin: 10px 0;
text-align: center
}
.intro {
font-size: 15px;
align-self: flex-start;
color: #4d4d4d;
margin-bottom: 15px;
}
.main-body {
font-size: 15px;
color: #4d4d4d;
margin-bottom: 15px;
}
.alt-body {
width: 100%;
display: flex;
flex-direction: row !important;
justify-content: center !important;
}
.alt-body>a {
font-size: 17px;
font-weight: 500;
text-decoration: none;
color: #FFFFFF;
margin: auto;
margin-bottom: 15px;
}
.cta-button {
background-color: #525659;
padding: 9px 100px;
border: 2px solid #525659;
border-radius: 35px;
align-self: center;
}
.cta-button:hover {
background-color: #000000;
border: 2px solid #000000;
}
.sub-body {
font-size: 15px;
color: #4d4d4d;
margin-bottom: 15px;
margin-top: 0;
align-self: flex-start;
}
.sub-body a {
text-decoration: none;
color: #4d4d4d;
font-size: 15px;
}
.sub-body a:hover {
text-decoration: none;
color: #4d4d4d;
}
.outro {
margin: 20px 0;
}
.outro > p {
font-size: 15px;
margin-top: 3px;
margin-bottom: 3px;
}
.outro a {
text-decoration: none;
color: #4d4d4d;
font-size: 15px;
margin-top: 3px;
margin-bottom: 3px;
}
.outro a:hover {
text-decoration: none;
color: #4d4d4d;
}
</style>
</head>
<body class="body">
<div class="content">
{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}
<p class="title">Email Verification</p>
<p class="intro">Hello there,</p>
<p class="main-body">
Simply click on the button to verify your cre8ive-mart email.
</p>
<div class="alt-body">
<a href="{{ activate_url }}" class="cta-button">Verify Email</a>
</div>
<p class="sub-body">
if you have any questions, please contact <a href="mailto:opedoetester@gmail.com">opedoetester@gmail.com</a>
</p>
<div class="outro">
<p class="outro-greeting">Sincerely,</p>
<p class="outro-main">cre8ive-mart</p>
<a href="#" class="outro-website">cre8ivemart.com</a>
</div>
{% endblocktrans %}
</div>
</body>
</html>
{% endautoescape %}
but the email I get is like this
it is just the html representation i get back. instead of a styled component.
回答1:
I can't see the code you used but here is what works for me with django rest auth.
create a custom password reset serializer
from django.contrib.auth.forms import PasswordResetForm
from django.conf import settings
from django.utils.translation import gettext as _
from rest_framework import serializers
###### IMPORT YOUR USER MODEL ######
from .models import User
class PasswordResetSerializer(serializers.Serializer):
email = serializers.EmailField()
password_reset_form_class = PasswordResetForm
def validate_email(self, value):
self.reset_form = self.password_reset_form_class(data=self.initial_data)
if not self.reset_form.is_valid():
raise serializers.ValidationError(_('Error'))
###### FILTER YOUR USER MODEL ######
if not User.objects.filter(email=value).exists():
raise serializers.ValidationError(_('Invalid e-mail address'))
return value
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': 'account/email/password_reset_key.html',
'html_email_template_name': 'account/email/password_reset_key.html',
'request': request,
}
self.reset_form.save(**opts)
Then have the password reset email template as account/email/password_reset_key.html
Then in the settings, update your password reset serializer to point to the custom password reset serializer.
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER': '<path to >password_serializer.PasswordResetSerializer'
}
This should work, if it doesn't you will have to provide more context on how you setup this particular password reset flow so we can determine why it's sending it as text instead of the html representation
回答2:
With newer versions of django-rest-auth, we need less code to achieve what the OP wants:
Settings.py
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER': 'users.serializer.PasswordResetSerializer'
}
Serializer.py
from rest_auth.serializers import PasswordResetSerializer
class PasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
return {
'subject_template_name': 'account/email/password_reset_key_subject.txt',
'email_template_name': 'account/email/password_reset_key.txt',
# 'html_email_template_name': 'account/password_reset_key.html',
}
来源:https://stackoverflow.com/questions/60026522/overriding-restauth-password-reset-email-issues