Django实现的登录注册功能

news/2024/4/30 3:22:29

1 前言

在Web开发中,用户登录和注册是最基本且必不可少的功能。Django,作为一个高级的Python Web框架,为我们提供了强大的工具和库来快速实现这些功能。下面,我将详细介绍如何使用Django来实现用户登录和注册功能。

2 功能介绍

该项目是使用django+bootstrp开发的项目,包含以下功能

  • 注册: 手机获取验证码、ModelForm数据验证、验证码redis超时处理,
  • 登录:手机验证码登录、账号密码登录、生成随机图片验证码、用户信息seesion处理

项目示例

1 账号密码登录
在这里插入图片描述
2 短信验证码登录
在这里插入图片描述
3 用户的注册
在这里插入图片描述
4 用户退出
在这里插入图片描述

3 申请容联云短信服务

登录和注册都需要一个短信的验证码,但是阿里、腾讯的短信服务申请太麻烦了,所有就申请了容联云短信服务,新用户有8元的免费额度只要项目不正式上线本地测试的话申请还是没有什么问题的,

容联云,全球智能通讯云服务商 (yuntongxun.com)

3.1 创建应用

在这里插入图片描述

3.2 创建短信模板

在这里插入图片描述

3.3 填写测试号码

在这里插入图片描述

3.4 安装sdk

 pip install ronglian_sms_sdk

3.5 发送短信的python代码

import json
from ronglian_sms_sdk import SmsSDK# 容联云创建的应用中获取
accId = "应用的id"
accToken = "应用的token"
appId = "appid"def send_sms(mobile, sms_code):"""发送短信"""sdk = SmsSDK(accId, accToken, appId)tid = "1"try:resp = sdk.sendMessage(tid, mobile, (sms_code, ))res_json = json.loads(resp)if res_json.get("statusCode") == "000000":logger.info(f"向mobile[{mobile}]发送短信验证码[{sms_code}]成功")else:logger.info(f"发送短信失败:{resp}")except Exception as e:logger.error(f"发送短信失败:{e}")if __name__ == '__main__':send_sms("平台测试手机号码", "9991")

运行脚本后手机会受到短信验证码,如下图
在这里插入图片描述

4 注册

在这里插入图片描述

注册分为两个部分:

  • 点击获取验证码:前端通过ajax发送请求到后端,后端生成随机验证码随机保存到redis中,同时调用短信服务发送短信到用户手机。
  • 点击注册:用户输入用户信息和验证码之后,后端进行校验,没有问题时保存到数据库,同时跳转到登录页面。
    在这里插入图片描述
    代码实现: 直截关键代码,完整代码跳转最后下载完整代码
# setting.py  django 使用redis
# 安装
pip install django-redis
# setting
CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://192.168.1.200:6379","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient","CONNECTION_POOL_KWARGS": {"max_connections": 100, "encoding": "utf-8"}# "PASSWORD": "123",}}
}from django_redis import get_redis_connection
def test_django_redis(request):# 可以直接从连接池中拿到连接redis=get_redis_connection()age = str(conn.get('age'), encoding='utf-8')# 设置过期时间redis.set('name','xiaoming',4)  redis.set('xxx',test_redis)
# view.py
from django.shortcuts import render
from django.http.response import JsonResponse
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django import forms
from django_redis import get_redis_connection
from users import modelsclass RegisterModelForm(forms.ModelForm):mobile_phone = forms.CharField(label="手机号",validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])password = forms.CharField(label="密码",min_length=8,max_length=64,error_messages={'min_length': "密码长度不能小于8个字符",'max_length': "密码长度不能大于64个字符"},widget=forms.PasswordInput())confirm_password = forms.CharField(label="重复密码",min_length=8,max_length=64,error_messages={'min_length': "重复密码长度不能小于8个字符",'max_length': "重复密码长度不能大于64个字符"},widget=forms.PasswordInput())code = forms.CharField(label="验证码", widget=forms.TextInput())class Meta:model = models.UserInfo# fields = "__all__"fields = ["username", "email", "password", "confirm_password", "mobile_phone", "code"]def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)for name, field in self.fields.items():field.widget.attrs['class'] = 'form-control'field.widget.attrs['placeholder'] = '请输入%s' % (field.label,)def clean_username(self):username = self.cleaned_data['username']exists = models.UserInfo.objects.filter(username=username).exists()if exists:raise ValidationError('用户名已存在')return usernamedef clean_email(self):email = self.cleaned_data['email']exists = models.UserInfo.objects.filter(email=email).exists()if exists:raise ValidationError('邮箱已存在')return emaildef clean_confirm_password(self):pwd = self.cleaned_data.get('password')confirm_pwd = self.cleaned_data['confirm_password']if pwd != confirm_pwd:raise ValidationError('两次密码不一致')def clean_mobile_phone(self):mobile_phone = self.cleaned_data['mobile_phone']exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()if exists:raise ValidationError('手机号已注册')return mobile_phonedef clean_code(self):code = self.cleaned_data['code']# mobile_phone = self.cleaned_data['mobile_phone']mobile_phone = self.cleaned_data.get('mobile_phone')if not mobile_phone:return codeconn = get_redis_connection()redis_code = conn.get(mobile_phone)if not redis_code:raise ValidationError('验证码失效或未发送,请重新发送')redis_str_code = redis_code.decode('utf-8')if code.strip() != redis_str_code:raise ValidationError('验证码错误,请重新输入')return codedef register(request):"""用户注册视图"""if request.method == "GET":form = RegisterModelForm()return render(request, "users/register.html", {"form": form})elif request.method == "POST":form = RegisterModelForm(data=request.POST)if form.is_valid():form.save()logger.info(f"用户[{form.username}]注册成功")return JsonResponse({"status": True})logger.warning(f"用户[{form.username}]注册失败")return JsonResponse({"status": False, "error": form.errors})

主要是用Django的ModeForm对数据格式进行验证,以及注册时候的一些逻辑判断

5 短信验证码登录

在这里插入图片描述
短信验证码登录也分为两个部分

  • 点击获取验证码: 这个过程和用户的注册获取验证码类似,可以复用注册获取手机验证的代码
  • 点击登录: 输入手机号码和验证码之后,后端校验数据的有效性,将用户的信息保存在session中,跳转主页
    在这里插入图片描述
    代码实现: 直截关键代码,完整代码跳转最后下载完整代码
# view,py 中数据校验和逻辑处理
class LoginSMSForm(forms.Form):"""短信验证码登录模板"""mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误'), ])code = forms.CharField(label='验证码',widget=forms.TextInput())def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)for name, field in self.fields.items():field.widget.attrs['class'] = 'form-control'field.widget.attrs['placeholder'] = '请输入%s' % (field.label,)def clean_mobile_phone(self):mobile_phone = self.cleaned_data['mobile_phone']exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()if not exists:raise ValidationError('用户未注册')return mobile_phonedef clean_code(self):code = self.cleaned_data['code']mobile_phone = self.cleaned_data.get('mobile_phone')if not mobile_phone:return coderedis = get_redis_connection()redis_code = redis.get(mobile_phone)  # 根据手机号去获取验证码if not redis_code:raise ValidationError('验证码失效或未发送,请重新发送')real_code = redis_code.decode('utf-8')if code.strip() != real_code:raise ValidationError('验证码错误,请重新输入')return codedef login_sms(request):"""短信验证码登录"""if request.method == "GET":form = LoginSMSForm()return render(request, "users/login_sms.html", context={"form": form})elif request.method == "POST":form = LoginSMSForm(data=request.POST)if form.is_valid():logger.info(f"用户登录成功")return JsonResponse({"status": True})logger.warning(f"用户登录失败")return JsonResponse({"status": False, "error": form.errors})

主要是用Django的ModeForm对数据格式进行验证,以及登录时候的一些逻辑判断

6 用户密码登录

在这里插入图片描述
用户密码登录也分为两个部分

  • 生成图像验证码: 加载网页时会请求后端生成图像验证码的接口,后端会根据pillow画出一张图片返回给前端,同时将验证码保存到session中, 图像验证码具体怎么生成的看生成随机图片验证码-CSDN博客
  • 点击登录: 填好信息后点击登录,请求端口登录接口后端会对数据进行验证,成功后跳转。
    在这里插入图片描述

代码实现: 直截关键代码,完整代码跳转最后下载完整代码

class LoginForm(forms.Form):username = forms.CharField(label='用户名',min_length=4,max_length=64,error_messages={'min_length': "密码长度不能小于4个字符",'max_length': "密码长度不能大于64个字符"})password = forms.CharField(label="密码",min_length=8,max_length=64,error_messages={'min_length': "密码长度不能小于8个字符",'max_length': "密码长度不能大于64个字符"},widget=forms.PasswordInput(render_value=True))code = forms.CharField(label='图片验证码',widget=forms.TextInput())def __init__(self, request,  *args, **kwargs):super().__init__(*args, **kwargs)self.request = requestfor name, field in self.fields.items():field.widget.attrs['class'] = 'form-control'field.widget.attrs['placeholder'] = '请输入%s' % (field.label,)def clean_username(self):username = self.cleaned_data["username"]if not models.UserInfo.objects.filter(username=username).exists():logger.warning("用户未注册")raise ValidationError("用户未注册")return usernamedef clean_password(self):username = self.cleaned_data.get("username")if not username:logger.warning("用户名为空")return usernamepassword = self.cleaned_data['password']encrypt_password = md5(password)if not models.UserInfo.objects.filter(username=username, password=encrypt_password).exists():logger.warning("用户名或者密码错误")raise ValidationError("用户名或者密码错误")return encrypt_passworddef clean_code(self):code = self.cleaned_data["code"]session_code = self.request.session.get("image_code")if not session_code:logger.warning("验证码已过期, 请求重新获取")raise ValidationError("验证码已过期, 请求重新获取")if code.strip().upper() != session_code.strip().upper():logger.warning(f"验证码输入错误,{code}:{session_code}")raise ValidationError("验证码输入错误")return codedef login(request):"""用户账号密码登录"""if request.method == "GET":form = LoginForm(request)else:form = LoginForm(request, data=request.POST)if form.is_valid():username = form.cleaned_data["username"]user_obj = models.UserInfo.objects.filter(username=username).first()request.session["user_id"] = user_obj.idrequest.session.set_expiry(settings.SESSION_EXPIRY)logger.info("用户登录成功")return redirect("home")logger.warning("用户登录失败")return render(request, "users/login.html", context={"form": form})

主要是用Django的ModeForm对数据格式进行验证,以及登录时候的一些逻辑判断

6 运行项目

完整代码一下链接下载

【免费】Django+bootstrp实现用户的注册和登录功能资源-CSDN文库

# 1 下载代码解压
# 2 安装依赖
pip install -r requirement.txt
# 3 迁移数据库
python manage.py makemigrations
python manage.py migrate
# 4 登录容联云获取accId、accToken、appId替换sms.py
# 5 在setting中修改redis中的地址
# 4 启动项目
python manage.py runserver

另外安装redis的教程也可以看::Docket常见的软件部署1-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/11787.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

OpenHarmony开发-连接开发板调试应用

在 OpenHarmony 开发过程中,连接开发板进行应用调试是一个关键步骤,只有在真实的硬件环境下,我们才能测试出应用更多的潜在问题,以便后续我们进行优化。本文详细介绍了连接开发板调试 OpenHarmony 应用的操作步骤。 首先&#xf…

vue3项目运行正常但vscode红色波浪线报错

以下解决办法如不生效,可尝试 重启 vscode 一、Vetur插件检测问题 vetur 是一个 vscode 插件,用于为 .vue 单文件组件提供代码高亮以及语法支持。但 vue 以及 vetur 对于 ts 的支持,并不友好。 1、原因 如下图:鼠标放到红色波浪…

数据挖掘中的PCA和KMeans:Airbnb房源案例研究

目录 一、PCA简介 二、数据集概览 三、数据预处理步骤 四、PCA申请 五、KMeans 聚类 六、PCA成分分析 七、逆变换 八、质心分析 九、结论 十、深入探究 10.1 第 1 步:确定 PCA 组件的最佳数量 10.2 第 2 步:使用 9 个组件重做 PCA 10.3 解释 PCA 加载和特…

【stm32】I2C通信协议

【stm32】I2C通信协议 概念及原理 如果我们想要读写寄存器来控制硬件电路,就至少需要定义两个字节数据 一个字节是我们要读写哪个寄存器,也就是指定寄存器的地址 另一个字节就是这个地址下存储寄存器的内容 写入内容就是控制电路,读出内容就…

ChatGPT 初学者指南

原文:ChatGPT for Beginners 译者:飞龙 协议:CC BY-NC-SA 4.0 介绍 如果您一直关注新闻和趋势,您可能已经在某个地方读到或听到过,Sam Altman 的生成式人工智能平台 ChatGPT 已经将人工智能推向了一个新的高度 - 许多…

Topaz Video AI for Mac v5.0.0激活版 视频画质增强软件

Topaz Video AI for Mac是一款功能强大的视频处理软件,专为Mac用户设计,旨在通过人工智能技术为视频编辑和增强提供卓越的功能。这款软件利用先进的算法和深度学习技术,能够自动识别和分析视频中的各个元素,并进行智能修复和增强&…