【Django | allauth】重写allauth重置密码方法

本文介绍了在Django项目中,如何重写allauth的密码重置功能,以适应中小型企业的需求。通过手机号验证而非邮箱,避免了SMTP限制,并详细阐述了重写表单模型、视图函数类以及配置项目的步骤,实现了通过身份证号重置密码的功能。
摘要由CSDN通过智能技术生成

在这里插入图片描述

🤵‍♂️ 个人主页: @计算机魔术师
👨‍💻 作者简介:CSDN内容合伙人,全栈领域优质创作者。

🌐 推荐一款找工作神器网站: 牛客网🎉🎉|笔试题库|面试经验|实习招聘内推
还没账户的小伙伴 速速点击链接跳转牛客网登录注册 开始刷爆题库,速速通关面试吧🙋‍♂️

该文章收录专栏
—【Django | 项目开发】从入门到上线 专栏—

一、场景需求

在allauth 中默认重置密码的方式是用户发送重置密码的请求后,发送重置密码的链接到用户的邮箱里面重置密码,如果使用QQ邮箱的SMTP服务,一天最多只能发送50封邮件,这样是明显不满足需求的,而如果为了实现此功能去部署一台邮件服务器或者申请一个企业邮箱,动辄几千一年的费用实在伤不起。所以在中小型的项目中,有一种折中的方法,即用户通过输入自己的身份证[这里已电话为例]即可重置对应的账号密码。

二、重写表单模型

  • form.py 添加表单模型 (处理手机号)
from django import forms

# 重写重置密码表单
class ResetPasswordForm(forms.Form):
    """
    重置密码表单,需要手机号验证
    """

    tel = forms.CharField(max_length=20, required=True, label='Telephone')

    # 获取电话号码
    def clean_identity_tel(self):
        tel = self.cleaned_data['tel']
        print(tel)
        """
        由于用get获取对象,如果获取不到会报错,所以这里使用filter
        获取失败返回空对象列表
        在UserProfile中筛选符合条件的用户,返回用户名
        """
        username = UserProfile.objects.filter(tel=tel)
        if not username:
            raise forms.ValidationError("手机号错误!!")

        return self.cleaned_data['tel']

    def save(self, request, **kwargs):
        return self.cleaned_data['tel']

三、重写view视图函数类

allauth中的重置密码的类视图位于allauth.account.views.PasswordResetView,我们需要在views.py中继承这个类并且重写它的post方法。

  • view.py 视图函数

注意!!这里的default_token_generator函数是allauth中的form.py的函数,不是django.contib,auth.token的,不然会报 bad token 错误,因为生成token的方法是不一样的(还有邮箱等)

from allauth.account.forms import default_token_generator,SignupForm  # 注意!! token生成实在allauth里面,不是django自带得token生成器
from allauth.account.utils import user_pk_to_url_str
from allauth.account.views import PasswordResetView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpRequest
from django.shortcuts import render, get_object_or_404, reverse, redirect, HttpResponseRedirect

from userprofile.forms import UseProfileForm, ResetPasswordForm
from userprofile.models import UserProfile


# 重写重置密码表单
class CustomPasswordResetView(PasswordResetView):

    def post(self, request, *args, **kwargs):
        reset_password_form = ResetPasswordForm(request.POST)
        if reset_password_form.is_valid():

            # 从电话筛选出 用户对象
            tel = reset_password_form.clean_identity_tel()
            # UseProfile 中由于user相同属性的 username
            username = UserProfile.objects.get(tel=tel)
            user = User.objects.get(username=username)
            # 查看传参有无 令牌
            token_generator = kwargs.get(
                "token_generator", default_token_generator)
            # 没有生成token
            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),
            )
            # 在根目录下建立绝对路径(self = request)
            url = HttpRequest.build_absolute_uri(request, path)
            # 重定向至修改密码链接
            return redirect(url)

        else:
            return render(request, 'account/telephone_error.html', {'content': "电话错误(表单格式错误)"})

# 注意 这里不能加上 login_required 的限制! 不然登录页面 忘记密码就会成功跳转页面!
password_reset = CustomPasswordResetView.as_view()
  • setting.py 添加配置(重写表单选项)
ACCOUNT_FORMS = ({
    'reset_password': 'Userprofile.forms.ResetPasswordForm'
})

五、配置项目路由

注意!!!: 在 引入 扩展模型应用路由时 allauth应用 和 userprofile 谁在上方一定要考虑好,不然路由覆盖等会出现页面失效或者报错的情况!!(一般默认allauth在上方),这里为了实现密码重置,要让 account/password/reset 不能走 allauth 的注册视图类,又不能修改allauth 源码,此时我们使用继承并在 项目 路由修改 优先级,优先进去扩展应用模型的 重写密码类。

  • 项目 urls.py
from django.contrib import admin
from django.urls import path, include

import userprofile.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', userprofile.views.profile),  # 首页 则为信息页(当未登录 自动跳转到login页)
    # 注意路由最后 一个 /
    path('accounts/password/reset/', userprofile.views.password_reset, name='account_reset_password'),
    path('accounts/', include('allauth.urls')),
    path('accounts/', include('userprofile.urls'))
]
  • 效果:
    在这里插入图片描述

参考文献:
Django的objects.get和objects.filter方法详解和区别
Python中的*(星号)和**(双星号)完全详解
raise 报异常异常用法
allauth 密码重置 *
as_view()解析

✨谢谢你的阅读,你的点赞和收藏是我创作的最大动力✨
本课程为Django第七季课程:用户登陆模块     本季课程主要实现图片的上传和展示,用户登陆账号的管理,用户账号的登陆、个人信息的修改、注销,使用邮箱地址找回密码。包含的主要知识点有:virtualenv虚拟环境、pip下载包、多app项目开发、templates模板的继承、font-awesome图标的使用、原生SQL语句和数据库交互、ORM模型和数据库交互、LayUI页面布局、jQuery实现用户交互、Ajax的异步请求、页面的块状展示数据、表格展示数据、表格的分页、数据的增改删改、Layer弹出层使用、表单的验证、照片的上传、照片的展示、图片展示的分页、照片的标准和放大、用户账号的增删改查、用户的登陆、Session和Cookie、Redis服务器的部署和基本配置、Django发送邮件等等知识点      本案例完整的演示了项目实现过程,虽然不复杂,但涉及的内容非常多,特别是前后端交互的时候,有诸多的坑等着你去踩,好在王老师全程代码呈现,带着大家一起填坑,大大提高学习效率的同时,也培养了大家良好的代码习惯,希望大家一致跟着王老师学习Python开发。 Django第八季课程课程预告:权限管理Django第九季课程课程预告:Web项目发布到阿里云 课程目标:本系列课程是从零基础开始并深入讲解Django,最终学会使用Django框架开发企业级的项目。课程知识点详细,项目实战贴近企业需求。本系列课程除了非常详细的讲解Django框架本身的知识点以外,还讲解了web开发中所需要用到的技术,学完本系列课程后,您将独立做出一个具有后台管理系统,并且前端非常优美实用的网站。对于从事一份Python Web开发相关的工作简直轻而易举。 
评论 50
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机魔术师

在校大二学生,请多多指教

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值