Reputation: 569
I'm trying to send a resetting password email with gmail. The resetting functions below work and redirect to the "success" page after filling in a valid email adress and submitting it for sending, but there is no mail sent. All registration templates are stored in the same dir; myapp/registration.
in settings
import smtplib
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587 #465
EMAIL_HOST_PASSWORD = 'yourpassword'
EMAIL_HOST_USER = '[email protected]'
#EMAIL_SUBJECT_PREFIX = 'something'
EMAIL_USE_TLS = True
in urls
url(r'^password/change/$',
auth_views.password_change,
{'post_change_redirect': reverse_lazy('auth_password_change_done')},
name='password_change'),
url(r'^password/change/done/$',
auth_views.password_change_done,
name='password_change_done'),
url(r'^password/reset/$',
auth_views.password_reset,
{'post_reset_redirect': reverse_lazy('auth_password_reset_done')},
name='password_reset'),
url(r'^password/reset/done/$',
auth_views.password_reset_done,
name='password_reset_done'),
url(r'^password/reset/complete/$',
auth_views.password_reset_complete,
name='password_reset_complete'),
url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
auth_views.password_reset_confirm,
{'post_reset_redirect': reverse_lazy('auth_password_reset_complete')},
name='password_reset_confirm'),
#and now add the registration urls
url(r'', include('registration.backends.default.urls')),
in views
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,
from_email=None,
current_app=None,
extra_context=None,
html_email_template_name=None):
if post_reset_redirect is None:
post_reset_redirect = reverse('password_reset_done')
else:
post_reset_redirect = resolve_url(post_reset_redirect)
if request.method == "POST":
form = password_reset_form(request.POST)
if form.is_valid():
opts = {
'use_https': request.is_secure(),
'token_generator': token_generator,
'from_email': from_email,
'email_template_name': email_template_name,
'subject_template_name': subject_template_name,
'request': request,
'html_email_template_name': html_email_template_name,
}
if is_admin_site:
opts = dict(opts, domain_override=request.get_host())
form.save(**opts)
return HttpResponseRedirect(post_reset_redirect)
else:
form = password_reset_form()
context = {
'form': form,
'title': _('Password reset'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
def password_reset_done(request,
template_name='registration/password_reset_done.html',
current_app=None, extra_context=None):
context = {
'title': _('Password reset successful'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
@sensitive_post_parameters()
@never_cache
def password_reset_confirm(request, uidb64=None, token=None,
template_name='registration/password_reset_confirm.html',
token_generator=default_token_generator,
set_password_form=SetPasswordForm,
post_reset_redirect=None,
current_app=None, extra_context=None):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
assert uidb64 is not None and token is not None # checked by URLconf
if post_reset_redirect is None:
post_reset_redirect = reverse('password_reset_complete')
else:
post_reset_redirect = resolve_url(post_reset_redirect)
try:
uid = urlsafe_base64_decode(uidb64)
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None
if user is not None and token_generator.check_token(user, token):
validlink = True
title = _('Enter new password')
if request.method == 'POST':
form = set_password_form(user, request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(post_reset_redirect)
else:
form = set_password_form(user)
else:
validlink = False
form = None
title = _('Password reset unsuccessful')
context = {
'form': form,
'title': title,
'validlink': validlink,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
def password_reset_complete(request,
template_name='registration/password_reset_complete.html',
current_app=None, extra_context=None):
context = {
'login_url': resolve_url(settings.LOGIN_URL),
'title': _('Password reset complete'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
def password_change(request,
template_name='registration/password_change_form.html',
post_change_redirect=None,
password_change_form=PasswordChangeForm,
current_app=None, extra_context=None):
if post_change_redirect is None:
post_change_redirect = reverse('password_change_done')
else:
post_change_redirect = resolve_url(post_change_redirect)
if request.method == "POST":
form = password_change_form(user=request.user, data=request.POST)
if form.is_valid():
form.save()
# Updating the password logs out all other sessions for the user
# except the current one if
# django.contrib.auth.middleware.SessionAuthenticationMiddleware
# is enabled.
update_session_auth_hash(request, form.user)
return HttpResponseRedirect(post_change_redirect)
else:
form = password_change_form(user=request.user)
context = {
'form': form,
'title': _('Password change'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
@login_required
def password_change_done(request,
template_name='registration/password_change_done.html',
current_app=None, extra_context=None):
context = {
'title': _('Password change successful'),
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
UPDATE
my email is now sent to gmail but gmail delivers the following errormessage;
Delivery to the following recipient failed permanently:
[email protected]
Technical details of permanent failure:
Google tried to deliver your message, but it was rejected by the server for the recipient domain gmail.com by gmail-smtp-in.l.google.com. [2a00:1450:4010:c04::1b].
The error that the other server returned was:
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://support.google.com/mail/bin/answer.py?answer=6596 ok4si3174885lbb.110 - gsmtp
----- Original message -----
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=from:content-type:mime-version:content-transfer-encoding:subject:to
:date:message-id;
bh=XIT/LAmN67IRi9HrLcISdd0LCPh/Bo8BtcnOZ3a1r2M=;
b=jIlBIOhiXVxumR9TmTigQTJL23bh5NiaGHVZr7zOdIbVaQ/o3Ud3F7S7xlYdgrdF7X
f8kZwMY59Q405rfxv5dmkDm5cAu7XTHJANpbhdMgk0zDySh9ohxJSPDNZ53fMDMubPZN
Y2HAYFGrB51nyld/wSfBJ/tOgxZ25kA//g/1wLhfCZOiU5zOVlMhl/T38W7bIRXpgSuy
MwPWeUWJ7HfLOaCbuXNcizVvUxzieq5aKrIw5I16TmNfkp40oCR3oBnBR1hx8gvPim4x
6IR+GhAwo5Zj9XNmFhnIp/EjxU4DV9OsgUelAqfyPRQ80M4RWE/qaWXqxJs2HGJ6+2gI
bc/w==
X-Received: by 10.112.61.136 with SMTP id p8mr23610717lbr.107.1429696044965;
Wed, 22 Apr 2015 02:47:24 -0700 (PDT
)
I think it might have to do with that the resetting views are bound to the Django admin views so I've tried with changing the registration - templates by extending it with my own base.html as is done in this blog http://garmoncheg.blogspot.se/2012/07/django-resetting-passwords-with.html but it doesn't work with. I've also added the following change_password function in views.
in urls.py
url(r'^password/change/$',
auth_views.password_change,
{'post_change_redirect': reverse_lazy('auth_password_change_done')},
name='my_password_change'),
url(r'^password/change/done/$',
auth_views.password_change_done,
name='password_change_done'),
url(r'^password/reset/$',
auth_views.password_reset,
{'post_reset_redirect': reverse_lazy('auth_password_reset_done')},
name='password_reset'),
url(r'^password/reset/done/$',
auth_views.password_reset_done,
name='password_reset_done'),
url(r'^password/reset/complete/$',
auth_views.password_reset_complete,
name='password_reset_complete'),
url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
auth_views.password_reset_confirm,
{'post_reset_redirect': reverse_lazy('auth_password_reset_complete')},
name='password_reset_confirm'),
#and now add the registration urls
url(r'', include('registration.backends.default.urls')),
in views
from django.contrib.auth.views import password_change
def my_password_change(request):
return password_change(template_name='password_change_form.html', extra_context={'my_var1': my_var1})
def password_change(request,
template_name='registration/password_change_form.html',
post_change_redirect=None,
password_change_form=PasswordChangeForm,
current_app=None, extra_context=None):
if post_change_redirect is None:
post_change_redirect = reverse('django.contrib.auth.views.password_change_done')
if request.method == "POST":
form = password_change_form(user=request.user, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(post_change_redirect)
else:
form = password_change_form(user=request.user)
context = {
'form': form,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
Upvotes: 1
Views: 2397
Reputation: 6122
This is my working configuration for sending mail in django via gmail smtp:
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'yourpassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Upvotes: 0
Reputation: 51988
Here unfortunately I don't see any mail sending code(i.e. send_mail(...)
) in the view function you have written, which should be probably in password_reset
or in password_reset_form
. You need to add that to send email(for example) like this:
from django.core.mail import send_mail
send_mail('subject', 'email_body', '[email protected]' , ['[email protected]'], fail_silently=False)
Upvotes: 1
Reputation: 1768
Have you tried logging in to the Gmail account after running your code?
You might have to allow your app to send emails using your Gmail.
https://support.google.com/accounts/answer/6010255?hl=en
Upvotes: 0