1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Django之使用自定义用户表(AbstractUser)/自定义登录验证(jwt)/获取当前登录用户

Django之使用自定义用户表(AbstractUser)/自定义登录验证(jwt)/获取当前登录用户

时间:2022-07-31 01:50:38

相关推荐

Django之使用自定义用户表(AbstractUser)/自定义登录验证(jwt)/获取当前登录用户

基本步骤:

一、自定义用户表:

1、自定义的用户表继承AbstractUser;

2、settings.py添加配置,指向用户表:AUTH_USER_MODEL = ‘myUser.Account’(子项目名称.用户表models名称);

3、python manage.py makemigrations

4、python manage.py migrate

二、自定义登录验证:

# 签发:jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER# 生成token:jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

三、获取当前登录用户:

# 通过headers获取token:token = request.META.get('HTTP_AUTHORIZATION')# 情况一:token的传参格式为JWT xxxxtoken = request.META.get('HTTP_AUTHORIZATION')[4:]# 情况二:token的传参格式为TOKEN xxxxtoken = request.META.get('HTTP_AUTHORIZATION')[7:]# 然后解析出user_id和username:jwt_decode_handler = api_settings.JWT_DECODE_HANDLER

基本目录结构

话不多说,直接上代码

models:

from django.db import modelsfrom django.contrib.auth.models import AbstractUser"""基类:可以把通用的字段定义这里,其他地方继承基类即可拥有"""class BaseModel(models.Model):updated_tm = models.DateTimeField(auto_now=True)created_tm = models.DateTimeField(auto_now_add=True)class Meta:abstract = True"""用户表:自定义的用户表想要使用自定义的用户表进行登录验证,需要满足下面的条件:1、需要继承AbstractUser;2、settings.py添加配置:AUTH_USER_MODEL = 'myUser.Account'(子项目名称.用户表models名称)"""class Account(AbstractUser, BaseModel):user_id = models.AutoField(help_text="用户id", primary_key=True)username = models.SlugField(max_length=128, help_text="用户名", unique=True)password = models.CharField(max_length=128, help_text="用户密码")nickname = models.CharField(max_length=128, help_text="用户昵称")# 指定数据库表信息class Meta:db_table = 'user'verbose_name = '用户基础信息'verbose_name_plural = verbose_name"""项目表:重点关注editor字段"""class ProjectList(BaseModel):"""项目基本信息"""project_id = models.AutoField(help_text="项目id", primary_key=True)project_name = models.SlugField(max_length=128, help_text="项目名", unique=True)editor = models.CharField(max_length=128, default='admin', help_text="编辑者")class Meta:db_table = 'project'verbose_name = '项目基本信息'verbose_name_plural = verbose_name

自定义用户数据库表 serializers

from rest_framework import serializersfrom myUser.models import BaseModel, Accountfrom myProject.models import ProjectListimport timeclass BaseSerializer(serializers.ModelSerializer):"""基类序列化器"""create_tm_format = serializers.DateTimeField(source="created_tm",format="%Y-%m-%d %H:%M:%S",required=False,read_only=True,help_text='创建时间(北京时间)')update_tm_format = serializers.DateTimeField(source="updated_tm",format="%Y-%m-%d %H:%M:%S",required=False,read_only=True,help_text='更新时间(北京时间)')created_tm = serializers.DateTimeField(required=False,read_only=True,help_text='创建时间(时间戳)')updated_tm = serializers.DateTimeField(required=False,read_only=True,help_text='更新时间(时间戳)')class Meta:model = BaseModelfields = ("created_tm", "updated_tm","create_tm_format", "update_tm_format")class UserSerializer(BaseSerializer):"""用户基本信息"""user_id = serializers.IntegerField(read_only=True)class Meta:model = Accountfields = ('username', 'password', 'user_id')class ProjectListSerializer(BaseSerializer):"""项目基本信息"""class Meta:model = ProjectListfields = ('project_id', 'project_name', 'editor','created_start_tm', 'created_end_tm',"created_tm", "updated_tm")

filter

import django_filtersfrom myUser.models import Accountfrom myProject.models import ProjectListclass UserFilter(django_filters.rest_framework.FilterSet):"""用户基本信息"""user_id = django_filters.NumberFilter(field_name='user_id', lookup_expr='exact')username = django_filters.CharFilter(field_name='username', lookup_expr='icontains')nickname = django_filters.CharFilter(field_name='nickname', lookup_expr='icontains')created_start_tm = django_filters.DateTimeFromToRangeFilter(field_name='创建开始时间')created_end_tm = django_filters.DateTimeFromToRangeFilter(field_name='创建结束时间')class Meta:model = Accountfields = ('user_id', 'username', 'created_start_tm', 'created_end_tm')class ProjectListFilter(django_filters.rest_framework.FilterSet):"""项目基本信息"""project_id = django_filters.NumberFilter(field_name='project_id', lookup_expr='exact')project_name = django_filters.CharFilter(field_name='project_name', lookup_expr='icontains')editor = django_filters.CharFilter(field_name='editor', lookup_expr='exact')created_start_tm = django_filters.DateTimeFromToRangeFilter(field_name='创建开始时间')created_end_tm = django_filters.DateTimeFromToRangeFilter(field_name='创建结束时间')class Meta:model = ProjectListfields = ('project_id', 'project_name', 'created_start_tm', 'created_end_tm')

用户登录views

from drf_yasg.utils import swagger_auto_schemafrom myUser.models import Accountfrom rest_framework import mixinsfrom rest_framework.generics import GenericAPIViewfrom serializers import UserSerializerfrom render_response import APIResponsefrom rest_framework_jwt.settings import api_settings# 签发jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER# 生成tokenjwt_encode_handler = api_settings.JWT_ENCODE_HANDLER# Create your views here.class LoginView(mixins.UpdateModelMixin, GenericAPIView):authentication_classes = ()permission_classes = ()queryset = Account.objects.all()serializer_class = UserSerializerordering = ['-created_tm']tag = ['用户']@swagger_auto_schema(tags=tag,operation_id="login",operation_summary='用户登录',operation_description='明文密码',responses={400010: "账号密码错误", 200: UserSerializer})def post(self, request, *args, **kwargs):"""post: 用户登录400010:账号密码错误"""username = str(request.data.get('username'))password = str(request.data.get('password'))try:Account.objects.get(username=username)except Account.DoesNotExist:return APIResponse(400010, '账号密码错误', success=False)try:Account.objects.get(password=password, username=username)except Account.DoesNotExist:return APIResponse(400010, '账号密码错误', success=False)user = Account.objects.filter(username=username, password=password).first()if user:# 登录成功,签发token,通过当前登录用户获取荷载(payload)payload = jwt_payload_handler(user)# 通过payload生成token串(三段:头,payload,签名)token = jwt_encode_handler(payload)response = {"user_id": user.user_id, "username": username, "token": token}return APIResponse(200, '登录成功', response)

项目创建views

from drf_yasg.utils import swagger_auto_schemafrom myProject.models import ProjectListfrom rest_framework import mixinsfrom rest_framework.viewsets import GenericViewSetfrom serializers import ProjectListSerializerfrom render_response import APIResponsefrom rest_framework.response import Responsefrom get_login_user_info import GetLoginUser# Create your views here.class AddProjectViews(mixins.CreateModelMixin, GenericViewSet):authentication_classes = []permission_classes = ()queryset = ProjectList.objects.all().order_by("-created_tm")serializer_class = ProjectListSerializertag = ['项目']@swagger_auto_schema(tags=tag,operation_summary='创建项目',operation_id="project_create",operation_description='项目名称必填',responses={400014: "参数错误", 200: ProjectListSerializer,400013: "请检查输入字段是否正确(必填字段、未定义字段)", 500001: "项目名称长度需要1到20位", 500002: "项目已存在", 500003: "项目创建失败", })def create(self, request, *args, **kwargs):"""新增项目"""try:project_name = request.data.get("project_name")project_desc = request.data.get("project_desc")except Exception:return APIResponse(400014, '参数错误', success=False)field_list = {}if project_name:field_list["project_name"] = project_nameif project_desc:field_list["project_desc"] = project_desc# 获取当前登录用户信息user = GetLoginUser().get_login_user(request)if user["code"] == 200:field_list["editor"] = user["username"]else:return Response(user)# 检查账号密码是否有填写if "project_name" not in list(field_list.keys()):return APIResponse(400013, '请检查输入字段是否正确(必填字段、未定义字段)', success=False)else:if len(field_list["project_name"]) > 20 or len(field_list["project_name"]) < 1:return APIResponse(500001, '项目名称长度需要1到20位', success=False)try:ProjectList.objects.get(project_name=field_list["project_name"])return APIResponse(500002, '项目已存在', success=False)except ProjectList.DoesNotExist:try:ProjectList.objects.create(**field_list)return APIResponse(200, '项目创建成功')except Exception as e:print(e)return APIResponse(500003, '项目创建失败', success=False)

token的传参 返回我是这么定义的(来自网友)

"""自定义返回处理"""from rest_framework.response import Responseclass APIResponse(Response):def __init__(self, code=200, msg='请求成功', data=None, status=None, headers=None, success=True, **kwargs):dic = {'code': code, 'message': msg, 'success': success, 'data': None}if data:dic['data'] = datadic.update(kwargs) # 可以灵活的添加,需要返回的键值对super().__init__(data=dic, status=status, headers=headers)

获取当前登录用户信息我是这么写的(原创)

from myUser.models import Accountfrom jwt import ExpiredSignatureErrorfrom render_response import APIResponsefrom rest_framework_jwt.settings import api_settings# 解析tokenjwt_decode_handler = api_settings.JWT_DECODE_HANDLERclass GetLoginUser:@staticmethoddef get_login_user(request):try:token = request.META.get('HTTP_AUTHORIZATION')except Exception:return APIResponse(400014, '参数错误', success=False)if token:try:# 解密token,提取user_iduser_id = jwt_decode_handler(token)["user_id"]username = Account.objects.filter(user_id=user_id).values('username').first()return {"user_id": user_id, "username": username["username"], "code": 200}except ExpiredSignatureError:return APIResponse(4031, 'token已过期', success=False)else:return APIResponse(403, '无访问权限,请重新登录或稍后再试!', success=False)

简易的swagger文档

用户登录

项目创建

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。