DRF的serializer中如何使用validators和信号量完成用户注册

作用:
当请求来的时候在serializer中对数据的校验,然后返回相应的错误,比如在用户注册的时候就就可以使用validators来对用户名做限制
效果:
在这里插入图片描述
首先在相应的app下创建serializer.py文件
创建一个serializer类继承ModelSerializer,就使用用户注册来举例:

import re
from datetime import datetime,timedelta
from rest_framework import serializers

from vueshop.settings import REGEX_MOBILE
from .models import VerifyCode
from rest_framework.validators import UniqueValidator

#自定义了User表需要在settings中配置,调用user的时候就需要按以下来:
from django.contrib.auth import get_user_model
User=get_user_model()


class UserRegSerializer(serializers.ModelSerializer):
    """
    验证手机验证码
    """
	# 验证验证码是否符合要求,error_messages:当出现错误后返回的错误信息,不写也有默认的,
	#label:显示的名字,write_only=True不会被序列化
    code=serializers.CharField(required=True,max_length=4,min_length=4,help_text="验证码",label="验证码",write_only=True
                               error_messages={
                                   "required":"验证格式不对",
                                   "max_length":"最长只有四位",
                                   "min_length":"最少要四位",
                                   "blank":"不能为空"
                               })
    # validators:验证用户名是否已经存在,write_only=True不会被序列化
    username=serializers.CharField(required=True,allow_blank=False,
                                   validators=[UniqueValidator(queryset=User.objects.all(),message="用户已存在")],help_text="用户名")
    # style密码在输入框以密文的样式展现
  	password=serializers.CharField(style={'input_type':'password'},write_only=True)
  	
    # 将密码加密
    def create(self, validated_data):
        user=super(UserRegSerializer,self).create(validated_data=validated_data)
        user.set_password(validated_data["password"])
        user.save()
        return user

	#校验code
    def validate_code(self,code):
    
        verify_code= VerifyCode.objects.filter(mobile=self.initial_data["mobile"]).order_by("-add_time")
        if verify_code:
            last_code=verify_code[0]

            if last_code != code:
                raise serializers.ValidationError("验证码不正确")

            five_minits_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)

            if five_minits_ago<last_code.add_time:
                raise serializers.ValidationError("验证码过期了")

        else:
            raise serializers.ValidationError("验证码不正确")
            
    # 作用于所有的字段
    def validate(self, attrs):
        attrs["mobile"] = attrs["username"]
        # 删除code,因为不需要存入数据库
        del attrs["code"]
        return attrs

    class Meta:
        model=User
        fields=["username","mobile","code"]

下面代码中将密码加密我们可以使用django的信号量来完成
在这里插入图片描述
view:
用户创建成功如何返回token:

class UserViewSet(CreateModelMixin,viewsets.GenericViewSet):
    serializer_class = UserRegSerializer
    queryset = User.objects.all()
    # 返回token,重写CreateModelMixin里面的create函数
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 获得serializer里的user模型
        user=self.perform_create(serializer)

        re_dict=serializer.data
        # 获得token
        payload=jwt_payload_handler(user)
        # 构造要返回的数据
        re_dict["token"]=jwt_encode_handler(payload)
        re_dict["name"]= user.name if user.name else user.username

        headers = self.get_success_headers(serializer.data)
        return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

urls:

from rest_framework.routers import DefaultRouter
router=DefaultRouter()
router.register('user',UserViewSet,basename='user')
urlpatterns = [
    # restframework urls配置
    url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

django的信号量:

django的某些操作发生时,会发出signals,可以截获signals,并进行一些操作
下面代码是在创建新用户完成时,截获signals,把保存的明文密码修改为密文

在app下创建signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model

User = get_user_model()

@receiver(post_save, sender=User)
def create_user(sender, instance=None, created=False, **kwargs):
    if created:
        password = instance.password
        instance.set_password(password)
        instance.save()

在这里插入图片描述
然后在apps.py文件中写入:

from django.apps import AppConfig


class UserConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'apps.user'
    verbose_name = "用户管理"

    def ready(self):
        import user.signals

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值