【补充】用户多方式登陆
【模型表】
from django.db import models
# Create your models here.
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32)
【序列化类】
# -*-coding: Utf-8 -*-
# @File : user_serializer .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/1
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from rest_framework.exceptions import ValidationError
from app01.models import UserInfo
import re
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
class UserSerializer(serializers.ModelSerializer):
username = serializers.CharField(max_length=32)
class Meta:
model = UserInfo
# 继承 ModelSerializer 后,字段是映射过来的
# 但是username字段是唯一的
# 反序列化校验的时候,字段自己的规则,会去数据库查询有没有和这个用户,如果有则报错
# 解决方式:重写 username 字段
fields = ["username", "password"] # 只做反序列化的校验
def validate(self, attrs):
# attrs : 前端传入的校验过的数据,字段自己的局部钩子
# (1)获取前端传入的数据
username = attrs.get('username') # 拿到的参数可能是手机号/邮箱/用户名
password = attrs.get('password')
# (2)校验用户是否存在
# (2.1)先查找用户
if re.match(r'^1(3[0-9]|5[0-3,5-9]|7[1-3,5-8]|8[0-9])\d{8}$', username):
user = UserInfo.objects.filter(phone=username).first()
elif re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$', username):
user = UserInfo.objects.filter(email=username).first()
else:
user = UserInfo.objects.filter(username=username).first()
# 校验密码
if user and user.check_password(password):
# (3)签发token
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.user = user
self.token = token
return attrs
else:
raise ValidationError("用户名或密码错误")
【视图】
from django.shortcuts import render
# Create your views here.
from rest_framework.viewsets import ViewSet
from app01 import models
from app01.serializers.user_serializer import UserSerializer
from rest_framework.response import Response
class UserView(ViewSet):
back_dict = {"code": 200, "msg": ""}
def login(self, request):
# (1)得到序列化类
user_ser = UserSerializer(data=request.data)
if user_ser.is_valid():
user = user_ser.user
token = user_ser.token
self.back_dict["token"] = token
self.back_dict["msg"] = "登陆成功"
self.back_dict["username"] = user.username
return Response(self.back_dict)
else:
self.back_dict["code"] = 101
self.back_dict["msg"] = user_ser.errors
return Response(self.back_dict)
【路由】
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.UserView.as_view({
"post": "login"
})),
]
【配置文件】
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'rest_framework'
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
AUTH_USER_MODEL = 'app01.UserInfo'
标签:username,补充,self,用户,django,dict,user,import,登陆
From: https://www.cnblogs.com/dream-ze/p/17596112.html