基本步骤:
一、自定义用户表:
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 xxxx
token = request.META.get(\'HTTP_AUTHORIZATION\')[4:]
# 情况二:token的传参格式为TOKEN xxxx
token = request.META.get(\'HTTP_AUTHORIZATION\')[7:]
# 然后解析出user_id和username:
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
- 基本目录结构
话不多说,直接上代码
- models:
from django.db import models
from 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 serializers
from myUser.models import BaseModel, Account
from myProject.models import ProjectList
import time
class 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 = BaseModel
fields = (\"created_tm\", \"updated_tm\",
\"create_tm_format\", \"update_tm_format\")
class UserSerializer(BaseSerializer):
\"\"\"用户基本信息\"\"\"
user_id = serializers.IntegerField(read_only=True)
class Meta:
model = Account
fields = (\'username\', \'password\', \'user_id\')
class ProjectListSerializer(BaseSerializer):
\"\"\"项目基本信息\"\"\"
class Meta:
model = ProjectList
fields = (\'project_id\', \'project_name\', \'editor\',
\'created_start_tm\', \'created_end_tm\',
\"created_tm\", \"updated_tm\")
- filter
import django_filters
from myUser.models import Account
from myProject.models import ProjectList
class 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 = Account
fields = (\'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 = ProjectList
fields = (\'project_id\', \'project_name\', \'created_start_tm\', \'created_end_tm\')
- 用户登录views
from drf_yasg.utils import swagger_auto_schema
from myUser.models import Account
from rest_framework import mixins
from rest_framework.generics import GenericAPIView
from serializers import UserSerializer
from render_response import APIResponse
from rest_framework_jwt.settings import api_settings
# 签发
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
# 生成token
jwt_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 = UserSerializer
ordering = [\'-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_schema
from myProject.models import ProjectList
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from serializers import ProjectListSerializer
from render_response import APIResponse
from rest_framework.response import Response
from 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 = ProjectListSerializer
tag = [\'项目\']
@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_name
if 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 Response
class 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\'] = data
dic.update(kwargs) # 可以灵活的添加,需要返回的键值对
super().__init__(data=dic, status=status, headers=headers)
- 获取当前登录用户信息我是这么写的(原创)
from myUser.models import Account
from jwt import ExpiredSignatureError
from render_response import APIResponse
from rest_framework_jwt.settings import api_settings
# 解析token
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
class GetLoginUser:
@staticmethod
def get_login_user(request):
try:
token = request.META.get(\'HTTP_AUTHORIZATION\')
except Exception:
return APIResponse(400014, \'参数错误\', success=False)
if token:
try:
# 解密token,提取user_id
user_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文档
-
用户登录
-
项目创建
来源:https://www.cnblogs.com/lsc-blog/p/16827761.html
本站部分图文来源于网络,如有侵权请联系删除。