【DRF配置管理】如何使用序列化:验证码、注册和登录

news2024/11/25 4:48:42

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。

DRF应用和管理

【DRF配置管理】Django安装DRF框架并生成openapi风格文档
【DRF配置管理】如何实现JWT身份验证
【DRF配置管理】如何使用序列化:验证码、注册和登录
【DRF配置管理】如何实现RBAC页面菜单和按钮权限
【DRF配置管理】如何在视图类使用get_objects()
【DRF配置管理】如何建立coreapi风格api接口文档
【DRF配置管理】如何建立swagger风格api接口文档


文章目录

  • DRF应用和管理
  • 前言
  • 一、drf序列化
    • 1.serializer.py文件和样例
    • 2.字段系列化
      • 1.ModelSerializer序列化
      • 2.serializers序列化
    • 3.错误验证信息和国际化
    • 4.Meta参数
    • 5.验证


前言

通常使用drf框架,都会使用序列化能力,尤其是ModelSerializer序列化。通过序列化我们可以实现字段的验证、文档的注释、异常获取等。


一、drf序列化

1.serializer.py文件和样例

在这里插入图片描述

样例内容

class RegisterSerializer(ModelSerializer):
    """注册账户"""
    password = serializers.CharField(write_only=True)
    password2 = serializers.CharField(write_only=True)
    code = serializers.IntegerField(write_only=True)

    default_error_messages = {
        "username_error": _('用户名必须以字母开头,且包含3~15个字母、数字'),
        "username_registered_error": _('用户名已存在'),
        'password_error': _('两次输入密码不一致'),
        "phone_error": _('手机号格式有误,请重填'),
        "phone_registered_error": _('手机号已注册'),
        'code_error': _('验证码不正确'),
        "email_error": _('电子邮箱格式有误,请重填'),
        "email_registered_error": _('邮箱已注册'),
    }

    class Meta:
        model = LoginUser
        fields = ['username', 'phone', 'password', 'password2', 'code']

    def validate_username(self, username):
        """单字段验证:名字"""
        # 1.用户名格式
        if not re.match(r'^[a-zA-z]\w{2,15}$', username):
            raise serializers.ValidationError(self.error_messages['username_error'])
        # 2.用户名是否存在
        if LoginUser.objects.filter(username=username).exists():
            raise serializers.ValidationError(self.error_messages['username_registered_error'])
        return username

    def validate_phone(self, phone):
        """单字段验证:手机号"""
        # 1.验证手机号码是否合法
        rs = r'^([+]?0?\d{2,3}-?|\([+]?0?\d{2,3}\)|\([+]?0?\d{2,3}\))?\d+$|^([+]?0?\d{2,3}-?|\([+]?0?\d{2,3}\)|\([+]?0?\d{2,3}\))?[1-9]\d{4,10}(-\d{1,10})?$'
        if not re.match(r'1[0-9]\d{9}$', str(phone)) and not re.match(rs, str(phone)):
            raise serializers.ValidationError(self.error_messages['phone_error'])
        # 2.手机是否注册
        if LoginUser.objects.filter(phone=str(phone)).exists():
            raise serializers.ValidationError(self.error_messages['phone_registered_error'])
        return phone

    # def validate_code(self, code):
    #     """单字段验证:验证码"""
    #     phone =
    #     if cache.has_key(phone):
    #         old_code = cache.get(phone)
    #         print(str(code))
    #         print(1111)
    #         print(str(old_code))
    #         if str(old_code) != str(code):
    #             raise serializers.ValidationError(self.error_messages['code_error'])

    def validate_email(self, email):
        """单字段验证:邮箱"""
        # 1.邮箱格式
        rs = '^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'
        if not re.match(rs, email):
            raise serializers.ValidationError(self.error_messages['email_error'])
        # 2.邮箱是否存在
        if LoginUser.objects.filter(email=email).exists():
            raise serializers.ValidationError(self.error_messages['email_registered_error'])
        return email

    def validate(self, attrs):
        """组合字段验证"""
        password = attrs.get('password')
        password2 = attrs.get('password2')
        if password and password2 and password != password2:
            raise serializers.ValidationError(self.error_messages['password_error'])
        attrs['password'] = make_password(attrs['password2'])  # 还可以通过重写create方法加密密码
        # 验证码
        phone = attrs.get('phone')
        code = attrs.get('code')
        if cache.has_key(phone):
            old_code = cache.get(phone)
            if str(old_code) != str(code):
                raise serializers.ValidationError(self.error_messages['code_error'])
        else:
            raise serializers.ValidationError(self.error_messages['code_error'])
        del attrs['password2']
        del attrs['code']
        return attrs

2.字段系列化

1.ModelSerializer序列化

	class RegisterSerializer(ModelSerializer):
	    """注册账户"""
	    password = serializers.CharField(write_only=True)
	    password2 = serializers.CharField(write_only=True)
	    code = serializers.IntegerField(write_only=True)
	
	    class Meta:
	        model = LoginUser
	        fields = ['username', 'phone', 'password', 'password2', 'code']

2.serializers序列化

使用serializers时,必须重写create和update方法

class BitableRecordsSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
        return True

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        return instance

3.错误验证信息和国际化

    default_error_messages = {
        "username_error": _('用户名必须以字母开头,且包含3~15个字母、数字'),
        "username_registered_error": _('用户名已存在'),
        'password_error': _('两次输入密码不一致'),
        "phone_error": _('手机号格式有误,请重填'),
        "phone_registered_error": _('手机号已注册'),
        'code_error': _('验证码不正确'),
        "email_error": _('电子邮箱格式有误,请重填'),
        "email_registered_error": _('邮箱已注册'),
    }

4.Meta参数

class Meta:
    model = LoginUser
    fields = ['username', 'phone', 'password', 'password2', 'code']
    read_only_fields = ['pic_id',]
	# extra_kwargs = {'password': {'write_only': True}}

5.验证

第一种:序列化字段验证

password = serializers.CharField(write_only=True)

第二种:单字段方法验证

    def validate_email(self, email):
        """单字段验证:邮箱"""
        # 1.邮箱格式
        rs = '^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'
        if not re.match(rs, email):
            raise serializers.ValidationError(self.error_messages['email_error'])
        # 2.邮箱是否存在
        if LoginUser.objects.filter(email=email).exists():
            raise serializers.ValidationError(self.error_messages['email_registered_error'])
        return email

第三种:组合字段方法验证

    def validate(self, attrs):
        """组合字段验证"""
        password = attrs.get('password')
        password2 = attrs.get('password2')
        if password and password2 and password != password2:
            raise serializers.ValidationError(self.error_messages['password_error'])
        attrs['password'] = make_password(attrs['password2'])  # 还可以通过重写create方法加密密码
        # 验证码
        phone = attrs.get('phone')
        code = attrs.get('code')
        if cache.has_key(phone):
            old_code = cache.get(phone)
            if str(old_code) != str(code):
                raise serializers.ValidationError(self.error_messages['code_error'])
        else:
            raise serializers.ValidationError(self.error_messages['code_error'])
        del attrs['password2']
        del attrs['code']
        return attrs

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

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

相关文章

如何设计正确的SpringBoot接口访问频率?

最近在基于SpringBoot做一个面向普通用户的系统&#xff0c;为了保证系统的稳定性&#xff0c;防止被恶意攻击&#xff0c;我想控制用户访问每个接口的频率。为了实现这个功能&#xff0c;可以设计一个annotation&#xff0c;然后借助AOP在调用方法之前检查当前ip的访问频率&am…

SpringBoot——对于属性中的时间和文件的单位进行设置

简单介绍&#xff1a; 在之前我们编写配置文件的时候&#xff0c;有时候多种技术的配置的属性值的默认属性的单位不同&#xff0c;比如在Tomcat中&#xff0c;对于最大连接时间就是以毫秒为单位&#xff0c;但是对于session的过期时间就是以分钟为单位&#xff0c;像这种单位不…

java线程池ThreadPoolExecutor使用

文章目录 一、简介1. 背景2. Executor接口介绍 二、使用Executors工厂创建线程池1. 简介2. 使用newCachedThreadPool()方法创建无界线程池3. 验证newCachedThreadPool()方法创建的线程池和线程复用特性4. 使用newCachedThreadPool(ThreadFactory)定制线程工厂5. 使用newCachedT…

怎么把音乐的伴奏提取出来?分享几个音乐伴奏提取的方法!

在这个数字时代&#xff0c;人人都有机会成为视频创作者。如果你也想发布自己剪辑的短视频&#xff0c;就需要了解视频编辑的相关操作。其中一个重要的操作是提取人声&#xff0c;将音频中人物的声音从杂音中分离出来&#xff0c;使声音更加清晰。那么&#xff0c;如何从音频中…

GPT时代,最令人担心的其实是“塔斯马尼亚效应”

目录 教育到底教什么&#xff1f; 过度依赖GPT可能导致文明退化 GPT可以帮助人类破解“学海无涯极限”悖论 春季学期伊始&#xff0c;全球各地的老师们如临大敌&#xff0c;因为学生们带着ChatGPT杀过来了。Study.com的调研显示&#xff0c;每10个学生中就有超过9个知道Chat…

基于FPGA的超声波测距——数码管显示

文章目录 前言一、超声波模块介绍1、产品特点2、超声波模块的时序图 二、系统设计1、系统框图2、源码3、RTL视图4、效果 三、总结四、参考资料 前言 环境&#xff1a; 1、Quartus18.1 2、vscode 3、板子型号&#xff1a;EP4CE6F17C8N 4、超声波模块&#xff1a;HC_SR04 要求&am…

【持续集成CI/持续部署CD】二、Docker安装Maven私服Nexus

本文是关于通过 Docker 进行安装部署 Nexus3 私服的快速入门和简单使用案例。 一、安装 1. 通过 docker 获取最新版本的 nexus3 镜像 docker pull sonatype/nexus3创建 docker 镜像到宿主机的磁盘映射目录Linux:mkdir -p /home/nexus/datachmod 777 -R /home/nexus/dataWind…

ThingsBoard的Actor系统如何初始化

1、概述 大家都知道ThingsBoard中使用了Actor,使用这个可以避免多线程并发问题,上一篇我查询资料总结了一下关于Actor的内容,actor不是通过new 一个对象来创建,而是通过一个ActorSystem来创建,下面我将带领大家来学习ThingsBoard启动时Actor如何创建。 2、ThingsBoard的…

【建议收藏】|某大型金融集团内部数据治理实战总结

对于你喜欢的事想去做的事,你必须付出百分之一千的努力你知道这一路可能会有很多困难&#xff0c;会有坚持不下去想要放弃的时候也有时候&#xff0c;你不一定会得到你想要的结果,但你—定要相信。 公众号&#xff1a;857Hub 转发领取PDF全集一份~~~ 数据治理 数字转型&…

传输层协议

目录 传输层 端口号 端口号范围划分 认识知名端口号(Well-Know Port Number) netstat pidof UDP协议UDP协议端格式​编辑 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 确认应答(ACK)机制 超时重传机制 连…

LDR6020 Type-C PD显示器方案简介

笔记本的视频输出接口一般有VGA、HDMI、DP、Type-C四种。 自从战66一代之后&#xff0c;VGA就基本上已经销声匿迹了&#xff0c;所以目前还是以HDMI和DP接口更为常见。 如果你的笔记本只支持HDMI1.4&#xff0c;那么你外接显示器的上限就只能是2K60或者是1080P144&#xff0c;…

20230522-win11删除文件失败-需要SYSTEM提供的权限

20230522-win11删除文件失败-需要SYSTEM提供的权限 一、软件环境 标签&#xff1a;win11 SYSTEM权限分栏&#xff1a;windows编译器&#xff1a;VS2019 二、问题描述 删除D:\WindowsApps\36186RuoFan.USB_5.8.1.0_x64__q3e6crc0w375t目录下的文件时&#xff0c;提示【文件访…

网络安全合规-数据分类分级具体操作

数据的安全防护&#xff0c;前提在于数据的分级分类。不同类别&#xff0c;不同安全等级的数据&#xff0c;防护手段和要求也是不尽相同的。 数据分类分级整体工作内容&#xff1a; 基础数据资产盘点 通过业务调研及技术探测&#xff0c;对企业的数据库进行全面扫描&#xff0c…

【leetcode】989.数组形式的整数加法

在刷题过程中&#xff0c;遇到此题&#xff0c;自己水平有限做不出来&#xff0c;查看众多题解&#xff0c;找到一个通俗易懂的思路&#xff0c;在此我将分享给大家这个解题过程&#xff01; 题目描述&#xff1a; 整数的 数组形式 num 是按照从左到右的顺序表示其数字的数组…

探索Java面向对象编程的奇妙世界(一)

现实世界中&#xff0c;随处可见的一种事务就是对象&#xff0c;对象是事务存在的实体&#xff0c;如人、书桌、计算机、高楼大厦等。人类解决问题的方式总是将复杂的事务简单化&#xff0c;于是就会思考这些对象都是由哪些部分组成的。下面我来带大家了解面向对象吧。 ⭐ 面向…

Anaconda安装与Python环境搭建

这篇文章介绍了如何安装Anaconda&#xff0c;及Python环境如何配置&#xff0c;你是否还在为难以寻找一篇讲述全面的环境配置博客而苦恼&#xff0c;稍安勿躁&#xff0c;你找对啦&#xff0c;照着本篇文章做下去&#xff0c;你就会发现没那么难呢&#xff01; Anaconda安装 …

记一次 .NET 某汽贸店 CPU 爆高分析

一&#xff1a;背景 1. 讲故事 上周有位朋友在 github 上向我求助&#xff0c;说线程都被卡住了&#xff0c;让我帮忙看下&#xff0c;截图如下&#xff1a; 时隔两年 终于有人在上面提 Issue 了&#xff0c;看样子这块以后可以作为求助专区来使用&#xff0c;既然来求助&…

gulimall-商城业务-商品上架

商城业务 前言一、商品上架1.1 商品 Mapping1.2 商品信息保存到es1.3 es数组的扁平化处理1.4 构造基本数据 前言 本文继续记录B站谷粒商城项目视频 P128-135 的内容&#xff0c;做到知识点的梳理和总结的作用&#xff0c;接口文档地址&#xff1a;gulimall接口文档 一、商品上…

面了个字节拿 30K 出来的测试,让我见识到了什么是测试的天花板

人人都有大厂梦&#xff0c;对于软件测试人员来说&#xff0c;BATJ 为首的一线互联网公司肯定是自己的心仪对象&#xff0c;毕竟能到这些大厂工作&#xff0c;不仅薪资高待遇好&#xff0c;而且能力技术都能够得到提升&#xff0c;最关键的是还能够给自己镀上一层金&#xff0c…

jenkins pipline 拉取git历史版本

声明&#xff0c;本文是基于&#xff1a;jenkins流水线&#xff08;jenkinsfile&#xff09;详解&#xff0c;保姆式教程_我认不到你的博客-CSDN博客&#xff0c;以下内容介绍通过 Commit ID 拉取 git 历史版本 Commit ID &#xff08;节点号&#xff09;是什么&#xff1f;&a…