首页 > 其他分享 >drf-day8

drf-day8

时间:2023-09-06 17:33:07浏览次数:30  
标签:username day8 登录 request token user import drf

认证组件

1、登录功能

写登录的时候可以使用auth提供的user表,也可以自定义

写接口登录成功时,需要有一个标志,所以需要随机生成一个随机字符串,放在表中,以后只要携带这个随机字符串过来,我们就认为用户登录。

视图类

from rest_framework.viewsets import ViewSet
viewset继承from rest_framework.views import APIView和from rest_framework.viewsets import ViewSetMixin
class UserView(ViewSet):
    @action(methods=['POST'], detail=False) # /user/login/    post 请求就会执行
    def login(self, request, *args, **kwargs):
        # 前端传入用户名密码
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()

把随机字符串存到表中,方法一

 if user:
            # 生成一个随机字符串,返回给前端,并且要把随机字符串存到token表中
            # 随机字符串使用uuid生成
            token = str(uuid.uuid4())
 # 把随机字符串存到token表中会有两种情况(如果之前没有登录过就是新增,如果之前登录过修改)
 # 先去UserToken表中,根据user查,如果能查到,就修改,查不到就新增一条记录
 user_token=UserToken.objects.filter(user=user).first()
if user_token:
    user_token.name=name
    user_tokrn.save()
else:
    UserToken.objects.create(user=user,token=token)

方法二:

通过user去UserToken表中查,如果能查到用defaults的更新,如果查不到,就用user和defaults新增一条记录
UserToken.objects.update_or_create(defaults={'token': token}, user=user)
            return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username})

        else:
            return Response({'code': 101, 'msg': '用户名或密码错误'})

路由

#导入drf封装的路由类
from rest_framework.routers import SimpleRouter
#实例化类得到对像
router = SimpleRouter()
#对像调用register方法
router.register('user', UserView, 'user')
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),#导入include
]

认证组件

认证作用:限制某些接口登录后才能被访问,没有登陆就不能被访问

drf中,认证类如何使用

逻辑思维

1 写一个类,继承BaseAuthentication
2 类中重写 :authenticate方法
3在authenticate完成登录认证,如果登录了,返回两个值,如果没登录抛异常
4.在视图类中配置使用
 class BookView(ViewSet):
            authentication_classes = [LoginAuth]
5.之前在auth模块中,用到request.user,只要登录后再视图类中就能拿到request.user

第一步:写一个 LoginAuth类(创建一个auth.py文件)

# 导入longinauth要继承的类baseauthentication
from rest_framework.authentication import BaseAuthentication
class LoginAuth(BaseAuthentication):

第二步:在loginauth类中重写authenticate方法

# 导入longinauth要继承的类baseauthentication
from rest_framework.authentication import BaseAuthentication
#倒入数据库里面的usertoken
from .models import UserToken
class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
#如何知道当前请求是不是这个人登录的
# 拿到前端传入的token:当时给的随机字符串,去UserToken表中查,如果能查到,说明就是这个人在访问,如果查不到,说明这个人没有登录
# 前端传入的token,可以从 请求地址中 、  请求体中  、请求头中
#从请求地址中拿
token = request.query_params.get('token')

#查循表中数据
user_token = UserToken.objects.filter(token=token).first()

第三步:在authenticate完成登录认证,如果登录了,返回两个值,如果没登录抛异常

if user_token:  # 是登录状态
            return user_token.user, token  # 返回两个值,第一个是当前登录用户,第二个是前端token
        else:
            raise AuthenticationFailed('您没有登录')

第四步:在视图类中配置使用

from .auth import LoginAuth
lass BookView(ViewSet):
    authentication_classes = [LoginAuth]  # 这个认证类,管理了当前类下所有的方法

    def list(self, request):
        print(request.user.username)  # 当前登录用户
        return Response("你好:%s,你看到了好多书啊"%request.user.username)

视图类代码演示

# 路由自动生成吗?    自动生成继承:ViewSetMixin   我想
# 要不要序列化,要不要跟数据库打交道,继承GenericAPIView:查出所有数据(只要一条),还要写个序列化类()
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import ViewSetMixin, ViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import User, UserToken
import uuid

from .auth import LoginAuth


# class UserView(ViewSetMixin,APIView):
class UserView(ViewSet):
    @action(methods=['POST'], detail=False)  # /user/login/    post 请求就会执行
    def login(self, request, *args, **kwargs):
        # 前端传入用户名密码
        username = request.data.get('username')
        password = request.data.get('password')
        user = User.objects.filter(username=username, password=password).first()

        if user:
            # 生成一个随机字符串,返回给前端,并且要把随机字符串存到token表中
            # 随机字符串使用uuid生成
            token = str(uuid.uuid4())
            # 把随机字符串存到token表中会有两种情况(如果之前没有登录过就是新增,如果之前登录过修改)
            # 先去UserToken表中,根据user查,如果能查到,就修改,查不到就新增一条记录
            ##### 方式一:麻烦方式
            # user_token=UserToken.objects.filter(user=user).first()
            # if user_token:
            #     user_token.token=token
            #     user_token.save()
            # else:
            #     UserToken.objects.create(user=user,token=token)

            ## 方式二:通过user去UserToken表中查,如果能查到用defaults的更新,如果查不到,就用user和defaults新增一条记录
            UserToken.objects.update_or_create(defaults={'token': token}, user=user)
            return Response({'code': 100, 'msg': '登录成功', 'token': token, 'username': user.username})

        else:
            return Response({'code': 101, 'msg': '用户名或密码错误'})


class BookView(ViewSet):
    authentication_classes = [LoginAuth]  # 这个认证类,管理了当前类下所有的方法

    def list(self, request):
        print(request.user.username)  # 当前登录用户
        return Response("你好:%s,你看到了好多书啊"%request.user.username)

路由

from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('user', UserView, 'user')
router.register('books', BookView, 'books')
urlpatterns = [
    path('', include(router.urls)),
]

总结

# 1 认证类写好,使用
配置在视图类上》》》局部使用
配置文件中配置》》》全局使用》》》所有接口都必须登录后才能用
        REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'app01.auth.LoginAuth'
            ],
        }
局部禁用:
    class UserView(ViewSet):
        authentication_classes = []
# 2 写的认证类:要重写authenticate方法,必须返回两个参数:当前登录用户:user_token.user,用户的 token----》后续再视图类中:request.user  就是认证类返回的第一个参数,request.auth 就是认证类返回的第二个参数

# 3 如果认证失败,抛异常AuthenticationFailed,会被drf捕获,处理,不会报错到前端

# 4 前端传入的token,从哪取?
    -后端定的,我们这个项目是从请求地址中取
    -还可以从请求头或请求体中取
# 5 UserToken.objects.update_or_create

权限组件

系统中:有普通用户,超级用户,超级管理员,他们都登录了,又分权限,有的人有权限,就能访问这个接口,没权限,就不能访问

使用步骤

1 写一个类,继承 BasePermission
2 重写 has_permission
3 在方法中校验用户是否有权限,如果有,就返回True,如果没有,就返回False
    -由于它的执行是在认证之后,所有从request.user中取出当前等用户,判断权限
4 在视图类中局部使用,在settings中全局使用,局部可以禁用
    class PublishView(ViewSet):
        permission_classes = [UserPermission] 

全局配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'app01.auth.LoginAuth'
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'app01.permissions.UserPermission',
    ],
}

第一步:创建一个permissions.py,写一个userpermision类,继承basepermission类

from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):

第二步:在userpermission中重写has_permission方法

def has_permission(self, request, view):

第三步:在方法中校验用户是否有权限,如果有,就返回True,如果没有,就返回False

# request 当次请求的request,  新的,它是在认证类之后执行的,如果认证通过了request.user 就是当前登录用户
        # 拿到当前登录用户,查看它的类型,确定有没有权限
        if request.user.user_type == 3:

            return True
        else:
            self.message = '您的用户类型是:%s,您没有权限操作' % (request.user.get_user_type_display())
            return False

django项目国际化

 配置文件中做一下处理以后所有英文都会转成中文
INSTALLED_APPS = [
    'rest_framework'
]

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

频率组件

 控制一个接口,访问频次,比如一分钟只能访问1次

对接口进行访问次数限制

使用步骤

1 写一个类,继承SimpleRateThrottle
2 重写get_cache_key,返回什么,就以什么做限制: IP地址,用户id限制
3 写一个类属性   scope = 'drf_day08'
4 配置文件中配置
 'DEFAULT_THROTTLE_RATES': {
            'drf_day08': '3/m',  # 一分钟访问三次   5/s,m,h,d
        },

局部使用

class PublishView(ViewSet):
        throttle_classes = [IPRateThrottle]

全局使用

 'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.IPRateThrottle'],

第一步:创建一个throttling.py文件,写一个ipratethrottle类,继承simpleratethrottlie

class IPRateThrottle(SimpleRateThrottle):

第二步:在ipratethrottle中定义类属性scope=‘根文件名’

 scope = 'drf_day08'  # 写一个类属性

第三步:ipratethrottle中重写get_cache_key方法返回什么,就以什么做限制: IP地址,用户id限制

   def get_cache_key(self, request, view):
        # 返回ip,以ip地址限制
        print(request.META)
        return request.META.get('REMOTE_ADDR')

第四步:配置文件中配置

 'DEFAULT_THROTTLE_RATES': {
        'drf_day08': '3/m',  # 一分钟访问三次
    },

排序

只有5个接口中的查询所有,才涉及到排序

使用步骤

1 必须写在继承:GenericAPIView 类的视图类中才行
2 配置类属性:
        filter_backends = [OrderingFilter]
        ordering_fields=['id','user_type'] #可以排序的字段
        
3 使用
        http://127.0.0.1:8000/user/?ordering=user_type #用户类型升序排
        http://127.0.0.1:8000/user/?ordering=-user_type #用户类型降序排
        http://127.0.0.1:8000/user/?ordering=user_type,-id#先按用户类型升序排,如果用户类型一样,再按id降序排

 

标签:username,day8,登录,request,token,user,import,drf
From: https://www.cnblogs.com/shanghaipudong/p/17682932.html

相关文章

  • DRF----限流、序列化、视图、条件搜索
    1.4djangorestframework(中)drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的封装版本管理认证权限限流序列化视图条件搜索分页路由解析器 6.限流限流,限制用户访问频率,例如:用户1分钟最多访问100次......
  • DRF----分页、路由、解析器
    1.5djangorestframework(下)drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的封装版本管理认证权限限流序列化视图条件搜索分页路由解析器  10.分页在查看数据列表的API中,如果数据量比较大,肯定......
  • DRF01---快速上手,请求的封装,版本管理,认证,权限
    1.3djangorestframework(上)djangorestframework(简称drf)本质上其实就是一个别人编写好的app,里面集成了很多编写restfulAPI的功能功能,接下里咱们就来学习drf并用他来开发restfulAPI。drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的......
  • drf-ModelViewSet
    9个视图子类CreateAPIView--继承-->CreateModelMixin、GenericAPIViewListAPIView--继承-->ListModelMixin、GenericAPIViewRetrieveAPIView--继承-->RetrieveModelMixin、GenericAPIViewDestroyAPIView--继承-->DestroyModelMixin、GenericAPIViewUpdateAPIView--......
  • 9个视图子类,视图类,视图集,ViewSetMixin, drf之路由
    1.9个视图子类fromrest_framework.genericsimportListAPIView,CreateAPIView,ListCreateAPIViewfromrest_framework.genericsimportRetrieveAPIView,DestroyAPIView,UpdateAPIViewfromrest_framework.genericsimportRetrieveUpdateDestroyAPIView,RetrieveDes......
  • 9个视图子类、视图集、drf之路由
    9个视图子类fromrest_framework.genericsimportListAPIView,CreateAPIView,ListCreateAPIViewfromrest_framework.genericsimportRetrieveAPIView,DestroyAPIView,UpdateAPIViewfromrest_framework.genericsimportRetrieveUpdateDestroyAPIView,RetrieveDestroy......
  • drf-day7
    九个视图子类以后想写5个接口中的某一个或某几个或所有,只需要选择继承不同的类即可,类中只需要配置两个类属性queryset=Publish.objects.all()serializer_class=PublishSerialize使用九个视图子类两个综合类来写五个接口fromrest_framework.genericsimportListCrea......
  • drf之请求,drf 之响应,drf之响应格式,两个视图基类,基于GenericAPIView,5个视图扩展类
    drf之请求1.1之请求Request类#data#query_params#用起来跟之前一样了解: request._request视图类的方法中:self是咱们写的视图类的对象,self.request是新的request,self.request是一个HttpRequest对象,它提供了许多属性和方法来访问和处理请求的信息.1.2......
  • drf-视图组件
    一、视图DjangoRESTframwork提供的视图的主要作用:控制序列化器的执行(检验、保存、转换数据)控制数据库查询的执行RESTframework提供了众多的通用视图基类与扩展类,以简化视图的编写。1. 两个视图基类1.1APIViewfromrest_framework.viewsimportAPIViewAPIView......
  • drf请求和响应、GenericAPIView封装、5个视图扩展类
    一、drf之请求1、drf之请求Request类视图类继承APIView后多了-0去除了csrf认证-1新的request-request.data-request.query_params-request.其他跟之前一样-request._request是老的-2三大认证-3全局异常2、控制前端请求的编码格式fromrest_fra......