I was trying to override templates/account/email/password_reset_key_message.html on my local project and i noticed a strange behavior.
Basically if i have both .html and .txt, allauth will prefer the overridden .txt. If i delete the .txt and leave the html only, for some reason this html will be ignored, and the default vanilla allauth .txt will be sent.
The only workaround i found so far to send it as .html was to override render_mail() in a new custom adapter as mentioned here and use the default allauth app_settings.TEMPLATE_EXTENSION.
example:
from allauth.account import app_settings
from allauth.account.adapter import DefaultAccountAdapter
from django.core.mail import EmailMultiAlternatives, EmailMessage
from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string
class AccountAdapter(DefaultAccountAdapter):
def render_mail(self, template_prefix, email, context):
"""
Renders an e-mail to `email`. `template_prefix` identifies the
e-mail that is to be sent, e.g. "account/email/email_confirmation"
"""
subject = render_to_string('{0}_subject.txt'.format(template_prefix),
context)
# remove superfluous line breaks
subject = " ".join(subject.splitlines()).strip()
subject = self.format_email_subject(subject)
from_email = self.get_from_email()
bodies = {}
for ext in [app_settings.TEMPLATE_EXTENSION]:
try:
template_name = '{0}_message.{1}'.format(template_prefix, ext)
bodies[ext] = render_to_string(template_name,
context).strip()
except TemplateDoesNotExist:
if ext == 'txt' and not bodies:
# We need at least one body
raise
if 'txt' in bodies:
msg = EmailMultiAlternatives(subject,
bodies['txt'],
from_email,
[email])
if 'html' in bodies:
msg.attach_alternative(bodies['html'], 'text/html')
else:
msg = EmailMessage(subject,
bodies['html'],
from_email,
[email])
msg.content_subtype = 'html' # Main content is now text/html
return msg
Not sure if there is a better way of doing this but if you want i can make a Pull Request.
Hmm, it will indeed fallback to the built-in allauth one, as the allauth app is in your INSTALLED_APPS. So, if Django won't find the template within your project, it will start looking into allauth/templates. Perhaps the best way forward is to simply drop allauth from the INSTALLED_APPS list...
馃憤 for this
If the PasswordResetView could be more custom, like set a different email template just overriding the view would be great.
I kind of reuse some of the PasswordResetView stuff for generating a migration email, like:
"we change our auth, please reset your pass using this link"
Reusing this view, I got the odd behavior of this PR and this sample code help me a lot thanks @psychok7
I'm having the same issue. I don't think dropping allauth is the best approach @pennersr . Any better solution?
I am trying to do the same thing.
But in my case, password reset requests seems to use the default django templates in templates/registration/, instead of the mentioned ones in templates/account/email/.
I overwrite the AccountAdapter and it works perfectly fine for customizing the URL in the confirmation email, but the password reset doesn't hit any of the functions in the AccountAdapter?
Also, I don't quite understand this? Are you saying we should stop using this project, or am I misunderstanding something? I'd recon that's not really a solution for everyone?
Any solution to the issue? I am also facing the same problem, I actually want to add a button with link.!
Most helpful comment
I'm having the same issue. I don't think dropping allauth is the best approach @pennersr . Any better solution?