要求登陆数据格式
# 使用用户名,手机号,邮箱,都可以登录#
# 前端需要传的数据格式
{ 用户名 / 手机号 / 邮箱
"username":"lqz/1332323223/33@qq.com",
"password":"lqz12345"
}
序列化类中 ser.py
from rest_framework import serializers
import re
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.utils import jwt_encode_handler, jwt_payload_handler
from api import models
class LoginModelSerializer(serializers.ModelSerializer):
username = serializers.CharField() # 重新覆盖username字段,数据中它是unique,post请求会认为你保存数据,自己有校验没过
# 或者你不想覆盖就把下面的fields里面的username改成别的名字 name
class Meta:
model = models.User
fields = ['username', 'password']
def validate(self, attrs):
username = attrs.get('username') # 用户名有三种格式
password = attrs.get('password')
# 在这写逻辑
# 通过判断,username数据不同,查询字段不一样
# 正则匹配,如果是手机号
if re.match('^1[3-9][0-9]{9}$', username):
user = models.User.objects.filter(phone=username).first()
# 如果是邮箱
elif re.match('^.+@.+$', username):
user = models.User.objects.filter(email=username).first()
# 否则就是用户名
else:
user = models.User.objects.filter(username=username).first()
if user:
# 用户存在 校验密码 因为密码是密文 要用check_password
if user.check_password(password):
# 签发token
payload = jwt_payload_handler(user) # 把user传入,得到payload
token = jwt_encode_handler(payload) # 把payload传入,得到token
self.context['token'] = token
self.context['username'] = user.username
return attrs
else:
raise ValidationError('密码错误')
else:
raise ValidationError('用户不存在')
视图函数 views.py
# 手动签发token,完成多方式登录
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSetMixin, ViewSet
from app02 import ser
# class Login2View(ViewSetMixin, APIView): # ViewSet(ViewSetMixin, views.APIView)
class Login2View(ViewSet): # 上面两个可以直接用内置的ViewSet代替
def login(self, request):
# 1 需要有个序列化的类
login_ser = ser.LoginModelSerializer(data=request.data) # 这里要注意写上data 不写默认传给instance 报错
# 2 生成序列化类对象
# 3 调用序列化类对象的
login_ser.is_valid(raise_exception=True)
# 4 return
token = login_ser.context.get('token')
username = login_ser.context.get('username')
return Response({'status': 100, 'msg': '登陆成功', 'token': token, 'username': username})