Django:新增用户时自动发送密码重置链接邮件的实现咨询
问题:管理员创建用户时直接发送密码重置链接
我正在开发一款应用,管理员负责创建新用户账号,添加用户时会自动生成随机密码。理想状态下,应该直接给新用户发送包含密码重置链接的邮件(不包含自动生成的密码)。目前我已经实现了发送引导用户输入邮箱获取重置链接的邮件,但想省去这一步,直接发送重置链接。请问该如何触发并发送这个链接?
现有代码
模型代码
from django.db import models from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import Group from django.contrib import admin from django.db.models import Count from django.db.models.signals import post_save class CustomUser(AbstractUser): full_name = models.CharField(max_length=250, null=True) age = models.PositiveIntegerField(null=True, blank=True) employee_type = models.ForeignKey(Group, null=True, on_delete=models.SET_NULL, default=1) employee_start_date = models.DateField(null=True, blank=True) is_active = models.BooleanField(null=False, default=True)
视图代码
class AddCompanyEmployee(CreateView): model = CustomUser template_name = 'manage/add_employee.html' form_class = BrowserCreateUserForm success_url = reverse_lazy('directory') def form_valid(self, form): password = CustomUser.objects.make_random_password() account = form.save(commit=False) account.password = make_password(password) account.save() return super().form_valid(form)
表单代码
class BrowserCreateUserForm(forms.ModelForm): class Meta: model = CustomUser fields = ['username','full_name', 'email', 'employee_type', 'employee_start_date', 'is_active'] widgets = { 'employee_start_date': forms.DateInput(attrs=dict(type='date')), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.layout = Layout( Div('username', css_class='form-group col-lg-6'), Div('full_name', css_class='form-group col-lg-6'), Div('email', css_class='form-group col-lg-6'), Div('employee_type', css_class='form-group col-lg-3'), Div('employee_start_date', css_class='form-group col-lg-3'), Div('is_active', css_class='form-group col-lg-3'), ) self.helper.add_input(Submit('submit', 'Submit'))
解决方案
直接复用Django内置的密码重置工具链,生成安全的重置链接并发送邮件,无需额外步骤。
1. 导入依赖模块
在视图文件顶部添加以下导入:
from django.contrib.auth.tokens import default_token_generator from django.core.mail import send_mail from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode from django.conf import settings from django.urls import reverse
2. 修改form_valid方法生成并发送重置链接
更新视图中的form_valid逻辑,在用户保存后直接生成重置链接并发送邮件:
def form_valid(self, form): # 生成随机密码并保存用户 password = CustomUser.objects.make_random_password() account = form.save(commit=False) account.password = make_password(password) account.save() # 生成密码重置所需的UID和Token uid = urlsafe_base64_encode(force_bytes(account.pk)) token = default_token_generator.make_token(account) # 构建绝对重置链接(自动适配当前域名) reset_url = self.request.build_absolute_uri( reverse('password_reset_confirm', kwargs={'uidb64': uid, 'token': token}) ) # 发送密码重置邮件 subject = "请设置你的账号密码" message = f"你好{account.full_name}:\n\n请点击下方链接设置你的账号密码:\n{reset_url}\n\n如果这不是你本人操作,请忽略此邮件。" send_mail( subject, message, settings.DEFAULT_FROM_EMAIL, [account.email], fail_silently=False, ) return super().form_valid(form)
3. 配置密码重置路由
确保项目URL配置中包含Django的密码重置确认和完成页面路由:
from django.contrib.auth import views as auth_views urlpatterns = [ # ... 其他现有路由 path('reset-password/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('reset-password/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'), ]
4. 完善邮件配置
在settings.py中配置邮件发送参数(以SMTP为例):
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.xxx.com' # 替换为你的SMTP服务器地址 EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = '你的发送邮箱账号' EMAIL_HOST_PASSWORD = '你的邮箱授权码/密码' DEFAULT_FROM_EMAIL = '你的发送邮箱账号'
关键说明
- 使用Django内置的
default_token_generator生成的Token会验证用户身份和密码状态,确保链接安全有效; - 生成的是绝对URL,用户点击邮件中的链接即可直接进入密码重置页面;
- 完全跳过引导用户输入邮箱的步骤,直接完成发送密码重置链接的需求。
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

