Я столкнулся с проблемой, когда мне пришлось загрузить более 200 новых пользователей в мое приложение django и сразу же отправить им электронное письмо для сброса пароля. Это должно было произойти только один раз, сделано только мной и тихо работало на бэкенде. Серфинг в Интернете привел меня только к одному более или менее правильному ответу: Trigger password сбросить электронную почту в django без браузера?. Единственная проблема заключалась в том, что этому посту было около 4 лет, и, конечно, когда я попробовал решение, оно не сработало...
Как программно вызвать электронную почту для сброса пароля в django 1.7.6?
Ответы (2)
Два наиболее ценных пункта из ссылки, которую я упомянул:
- В самой последней версии Django нам нужно вызвать
form.is_valid()
- Отправка электронной почты осуществляется после
save()
.
Вот как я опросил нужных мне пользователей и отправил каждому из них ссылку для сброса пароля:
def find_users_and_send_email():
from django.http import HttpRequest
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
import logging
logger = logging.getLogger(__name__)
users = User.objects.filter(date_joined__gt = '2015-04-16')
for user in users:
try:
if user.email:
logger.info("Sending email for to this email:", user.email)
form = PasswordResetForm({'email': user.email})
assert form.is_valid()
request = HttpRequest()
request.META['SERVER_NAME'] = 'help.mydomain.com'
request.META['SERVER_PORT'] = '443'
form.save(
request= request,
use_https=True,
from_email="[email protected]",
email_template_name='registration/password_reset_email.html')
except Exception as e:
logger.warning(str(e))
continue
return 'done'
- Обычно
PasswordResetForm
работает с запросом от фронтенда, которого у меня не было. Поэтому я просто создал его. - Когда я следовал примеру в ссылке, это не удалось. Не удалось найти имя сервера в запросе. (Имеет смысл, потому что я создал свой запрос из ниоткуда)
- Когда я исправил имя сервера, он запросил порт сервера. Поскольку я использовал https, мой порт — 443, в противном случае используйте порт по умолчанию.
- Если вы используете https, не забудьте указать его при сохранении формы
use_https=True
domain_override
в form.save()
на то, что вы хотите отображать в качестве своего домена в электронном письме сброса (это будет использоваться как для ссылки, так и для темы электронного письма по умолчанию)
- person Fasand; 30.07.2019
Я счел полезным обернуть ответ @chabislav в настраиваемую команду управления, которую затем можно повторно использовать по мере необходимости. Обратите внимание, что я исключил фильтр пользовательских объектов, так как знал, что хочу отправить инструкции по сбросу пароля всем пользователям.
# myproject/myapp/management/commands/send_password_reset_emails.py
from django.core.management.base import BaseCommand, CommandError
# I use a custom user model, so importing that rather than the standard django.contrib.auth.models
from users.models import User
from django.http import HttpRequest
from django.contrib.auth.forms import PasswordResetForm
class Command(BaseCommand):
help = 'Emails password reset instructions to all users'
def handle(self, *args, **kwargs):
users = User.objects.all()
for user in users:
try:
if user.email:
print("Sending email for to this email:", user.email)
form = PasswordResetForm({'email': user.email})
assert form.is_valid()
request = HttpRequest()
request.META['SERVER_NAME'] = 'www.example.com'
request.META['SERVER_PORT'] = 443
form.save(
request= request,
use_https=True,
from_email="[email protected]",
email_template_name='registration/password_reset_email.html'
)
except Exception as e:
print(e)
continue
return 'done'
Затем это можно легко запустить с помощью python manage.py send_password_reset_emails
.
Обратите внимание, что я получил сообщение об ошибке (550, b'5.7.1 Relaying denied')
, которое оказалось проблемой из-за того, как был настроен мой почтовый сервер localhost, но как только это было очищено, это сработало довольно хорошо. Наличие его в команде управления также хорошо, потому что оно не засоряет код, который вы используете на регулярной основе (представления).