作用:
当请求来的时候在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