Django AllAuth - 如何手动发送重置密码的电子邮件?

8
在我的应用程序中,我使用了Django Allauth。我没有为用户设置任何注册表单。管理员将通过上传包含用户信息的Excel文件来注册用户。我已经完成了所有这些工作,并通过自动生成密码将用户保存在用户表中。在上传用户列表并将其保存在数据库中之后,我希望向每个用户发送重置密码电子邮件。
在Allauth中重置密码,您首先需要转到重置页面account/password/reset/并输入您的电子邮件。然后会发送一封电子邮件,其中包含指引您更改密码的链接 account/password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/ 是否可能直接在应用程序中发送电子邮件?该URL包含一个我不知道如何生成的密钥!! 或者有更好的方法吗?
3个回答

15

可以实现。我的解决方案使用了一个User模型post_save信号,用来调用Allauth密码重置视图,该视图将向用户发送邮件。首先要考虑的是在管理用户创建表单中使用户电子邮件地址为必填项(如此处所述)。然后使用以下代码:

from allauth.account.views import PasswordResetView

from django.conf import settings
from django.dispatch import receiver
from django.http import HttpRequest
from django.middleware.csrf import get_token


@receiver(models.signals.post_save, sender=settings.AUTH_USER_MODEL)
def send_reset_password_email(sender, instance, created, **kwargs):

    if created:

        # First create a post request to pass to the view
        request = HttpRequest()
        request.method = 'POST'

        # add the absolute url to be be included in email
        if settings.DEBUG:
            request.META['HTTP_HOST'] = '127.0.0.1:8000'
        else:
            request.META['HTTP_HOST'] = 'www.mysite.com'

        # pass the post form data
        request.POST = {
            'email': instance.email,
            'csrfmiddlewaretoken': get_token(HttpRequest())
        }
        PasswordResetView.as_view()(request)  # email will be sent!

非常感谢。您的答案及时到位 :) 我之前实现得不是很好,但是您的解决方案很棒,而且运作良好。 - Marjan Kalanaki
我很高兴它有帮助 :) - davecaputo
这个可行。谢谢。我想要从ajax发送邮件(用户输入他/她的邮件并且我们可能会发现他/她有无法使用的密码),所以我可以(希望如此,但仅在本地主机:8000进行了测试)设置HTTP_HOST来自原始请求:fake_request.META['HTTP_HOST'] =(原始)request.get_host()。 - mirek
对于像我这样的愚蠢人:在我的情况下,我有一个ajax调用,并且我需要发送邮件+返回一些json作为ajax调用的响应。我使用了这个答案。当然,在ajax调用内部,我已经将请求作为PasswordResetView所需的参数。当我构造并发送一个虚假请求时,一切正常。但是:PasswordResetView的上下文管理器将接收不同的请求作为正确通过所有中间件的请求。因此,如果您在上下文管理器中依赖于请求中间件的更改,则会失败(稍后并带有困难的错误)。 - mirek

5
您可以尝试使用以下方式获取特定用户的URL:
from allauth.account.forms import EmailAwarePasswordResetTokenGenerator
from allauth.account.utils import user_pk_to_url_str

token_generator = EmailAwarePasswordResetTokenGenerator()
user = User.objects.get(email='example@example.com')
temp_key = token_generator.make_token(user)
path = reverse("account_reset_password_from_key", 
               kwargs=dict(uidb36=user_pk_to_url_str(user), key=temp_key))

0

接着@davecaputo的回答,你也可以直接提交表单而不是创建和调用视图:

from allauth.account.forms import ResetPasswordForm
from django.conf import settings
from django.http import HttpRequest


def send_password_reset(user: settings.AUTH_USER_MODEL):
    request = HttpRequest()
    request.user = user
    request.META["HTTP_HOST"] = "www.mysite.com"

    form = ResetPasswordForm({"email": user.email})
    if form.is_valid():
        form.save(request)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接