Django实现的登录注册功能

这篇具有很好参考价值的文章主要介绍了Django实现的登录注册功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 前言

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

2 功能介绍

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

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

项目示例

1 账号密码登录
Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
2 短信验证码登录
Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
3 用户的注册
Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
4 用户退出
Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

3 申请容联云短信服务

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

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

3.1 创建应用

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

3.2 创建短信模板

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

3.3 填写测试号码

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

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")

运行脚本后手机会受到短信验证码,如下图
Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

4 注册

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

注册分为两个部分:

  • 点击获取验证码:前端通过ajax发送请求到后端,后端生成随机验证码随机保存到redis中,同时调用短信服务发送短信到用户手机。
  • 点击注册:用户输入用户信息和验证码之后,后端进行校验,没有问题时保存到数据库,同时跳转到登录页面。
    Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
    代码实现: 直截关键代码,完整代码跳转最后下载完整代码
# 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 models


class 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 username

    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.UserInfo.objects.filter(email=email).exists()
        if exists:
            raise ValidationError('邮箱已存在')
        return email

    def 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_phone

    def 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 code

        conn = 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 code


def 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 短信验证码登录

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
短信验证码登录也分为两个部分

  • 点击获取验证码: 这个过程和用户的注册获取验证码类似,可以复用注册获取手机验证的代码
  • 点击登录: 输入手机号码和验证码之后,后端校验数据的有效性,将用户的信息保存在session中,跳转主页
    Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
    代码实现: 直截关键代码,完整代码跳转最后下载完整代码
# 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_phone

    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code
        redis = 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 code


def 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 用户密码登录

Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql
用户密码登录也分为两个部分

  • 生成图像验证码: 加载网页时会请求后端生成图像验证码的接口,后端会根据pillow画出一张图片返回给前端,同时将验证码保存到session中, 图像验证码具体怎么生成的看生成随机图片验证码-CSDN博客
  • 点击登录: 填好信息后点击登录,请求端口登录接口后端会对数据进行验证,成功后跳转。
    Django实现的登录注册功能,Django,django,sqlite,数据库,redis,mysql

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

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 = request
        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"]
        if not models.UserInfo.objects.filter(username=username).exists():
            logger.warning("用户未注册")
            raise ValidationError("用户未注册")
        return username

    def clean_password(self):
        username = self.cleaned_data.get("username")
        if not username:
            logger.warning("用户名为空")
            return username
        password = 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_password

    def 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 code


def 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.id
            request.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博客文章来源地址https://www.toymoban.com/news/detail-853723.html

到了这里,关于Django实现的登录注册功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django实现注册及登录(附源码)

    目录 一、项目介绍 1、开发环境 2、注册功能介绍 3、登录功能介绍: 4、项目截图  二、数据迁移 1、建立自己的数据库 (1)通过命令行(win+R,输入cmd)进入自己的数据库,如下图所示表示进入成功  (2)创建自己的数据库 (3)配置数据库  (4)创建迁移文件 (5)进行数据

    2024年02月06日
    浏览(15)
  • 【Django】让SQLite数据库中表名支持重命名的方法

    修改了数据库表名之后,更新数据库时跳错: 意思就是 SQLite 数据库不支持重命名的操作,添加atomic = False即可: Migration 在 py36Libsite-packagesdjangodbmigrationsmigration.py 的位置 将 atomic = True 改成 atomic = False

    2024年02月10日
    浏览(28)
  • MVC框架实现用户登录注册功能(连接数据库)

    一、简单理解MVC框架 二、项目结构 三、项目源码 3.1 User 3.2 UserDao 3.3 RegisterDao 3.4 servletControll 3.5 servletControllRegister 3.6 web.xml 3.7 login.jsp 3.8 register.jsp 3.9 success.jsp 3.10 failure.jsp  四、实现效果 总结 本篇文章主要介绍利用MVC框架去实现一个简单的用户登录注册功能,内容主

    2024年02月06日
    浏览(24)
  • Flutter框架实现登录注册功能,不连接数据库

    要在Flutter框架中实现登录和注册功能,而不连接数据库,可以使用本地存储来存储用户信息。以下是一个简单的示例,演示如何使用本地存储来实现登录和注册功能。 首先,我们需要添加 shared_preferences 插件到 pubspec.yaml 文件中: 然后,在 lib 文件夹中创建一个新的文件夹

    2024年02月08日
    浏览(23)
  • Django用户认证: 利用Django Auth模块实现用户注册、登录与登出

    用户登录注册属于用户认证的一部分,Django内置了一套用户认证体系,使用起来比较方便,而且支持用户定制和拓展,足以满足任何复杂的业务需求。 Django框架中,用户权限管理被划分为三个层次: 用户 :系统使用者,拥有自己的权限。可被一个或多个用户组包含。 用户组

    2023年04月20日
    浏览(27)
  • JavaWeb实现简易的注册登录功能(与数据库连接)

    一、创建数据库表连接 这里我们创建一个数据库名为db_user,创建库的使用可视化工具很简单就不细说了,下面sql代码块是我们创建一个简易用户表为了方便我们后续进行登录注册操作。 下面就是建好的表: 1、建一个与数据库连接的file文件:db.properties 二、创建前端页面 1、

    2024年01月19日
    浏览(24)
  • java连接数据库实现登录与注册小功能(小白版)

    准备工作: 创建数据库stu;        create database stu charset=utf8; 使用数据库stu;            use stu; 创建用户表user(id,username,password,nick) create table user(id int primary key auto_increment,username varchar(50),password varchar(50),nick varchar(50));   1.开始创建springboot工程,勾选Web-spring Web,  SQL-MyBatis Frame

    2024年02月08日
    浏览(21)
  • Android Studio|使用SqLite实现一个简单的登录注册功能

    本学期学习了Android Studio这门课程,本次使用Android Studio自带的sqlite数据库实现一个简单的登录注册功能。 目录 一、了解什么是Android Studio? 二、了解什么是sqlite? 三、创建项目文件  四、创建活动文件和布局文件。 五、创建数据库,连接数据库  六、创建实体类,实现注

    2024年02月06日
    浏览(21)
  • 使用Pycharm配置Django后端程序实现登录和注册

    一、Django项目创建 在创建Django项目之前需要在本地安装Python 1、进入Pycham之后点击文件新建项目选择新建Django项目,创建templates文件夹用来存放登录所需要的HTML页面,注意选择正确的python解释器。然后点击创建,等待创建完成即可。 2、验证Django项目是否创建成功  在终端命

    2024年02月02日
    浏览(17)
  • Unity3D实现MySql数据库登录与注册功能

    1、界面布局如下: 2、界面控件 1、封装MySql 2、编写登录、注册功能脚本 挂载LoginPanel脚本,并将控件映射到公共属性如下: 有问题请指出,谢谢!

    2024年02月11日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包