• DAY 68 drf06


    1 drf入门
    -web开发模式:分离和混合
      -api接口:接口
       -postman的使用(http客户端)
       -restful-10条规范
       -drf是什么,能做什么(快速写符合resful规范的接口)
       -分析了执行流程:APIView
      -重写了dispatch
          -包装了新的request:drf的request
      -self.initial
          -请求格式处理,认证,权限,频率
      -处理了全局异常  
      -处理了响应
       -Request对象:data,取其他值和属性时跟原来一样
       
    2 序列化器
    -Serializer,ModelSerializer
       -写一个类继承Serializer
       -在类中写字段,
       -字段参数:read_only,write_only
       -视图类中使用:ser=Serilaizer(要序列化的对象,many=True)
       -ser.data
       -反序列化
       -ser=Serilaizer(data=字典)
       -ser.is_valid()
       -ser.save():Serializer需要重写update和create
       -反序列化的修改
       -ser=Serilaizer(instance=对象,data=字典)
       
       
       -ModelSerializer
       -class Meta:
      model=表模型
          fields='__all__'
      extra_kwargs={'name';{}}
       -重写字段
       name=serilaizer.CharField(source='xx')
       name=serilaizer.SerializerMethodField()
       def get_name(self,obj):
           return 'sb'+obj.name
       子序列化
       publish=PublishSerializer()
    2.1 序列化类的源码
    -many控制了谁
      -局部钩子和全局钩子
    -source为什么填publish.name  方法
       
    3 请求和响应
    -自己封装了一个响应对象(low,高级)
      -通过配置,配置请求和响应(全局配置,局部配置)
       
    4 视图
    -APIView,GenericAPIView
      -5个视图扩展类
    -9个视图子类
      -写一个删除接口(只需要继承DestroyAPIView,写上那两个类属性)
      -视图集
    -ViewSetMixin:路由就不一样了

    4.1 写一个删除接口,但是,删除后要记录日志

    5 自动生成路由
    -SimpleRouter
      -ViewSetMixin+9个子类视图才能自动生成路由
    6 action装饰器
    -自动生成路由后,使用action装饰器来继续让写在视图类的方法,可以被访问到

     

    1 认证类前奏登录功能,认证类编写

    1 认证类的使用流程
    -写一个类,继承BaseAuthentication
    -在类中写authenticate(self, request):
    -在方法中进行校验,如果校验通过,返回两个值(返回空)
    -使用认证类,在视图类上加
    authentication_classes = [LoginAuth,]

     

    1.1 登录功能

    1.1.1 写两个表

    ##先写两个表
    ##models.py
    class User(models.Model):
       name = models.CharField(max_length=32)
       password = models.CharField(max_length=32)


    class UserToken(models.Model):
       user = models.OneToOneField(to='User',on_delete=models.CASCADE)
       token=models.CharField(max_length=32)
       
       
    ###登录功能

    1.1.2 登录视图类

    class UserView(ViewSetMixin, CreateAPIView):
       queryset = models.User.objects.all()
       serializer_class = serializer.UserModelSerializer
       authentication_classes = []

       #基于原生session版
       @action(methods=['POST'], detail=False)
       def login(self, request):
           username = request.data.get('username')
           password = request.data.get('password')
           user = models.User.objects.filter(name=username, password=password).first()
           request.session['name'] = user.name
           request.session['id'] = user.id
           print(type(request.session))
           request.session.save()
           print(request.session.session_key)
           from  django.contrib.sessions.backends.db import SessionStore
           if user:
               return APIResponse(msg='登录成功', token=request.session.session_key)
           else:
               return APIResponse(status=101, msg='用户名或密码错误')

       # 基于自己写的UserToken表版
       # @action(methods=['POST'], detail=False)
       # def login(self, request):
       #     username = request.data.get('username')
       #     password = request.data.get('password')
       #     user = models.User.objects.filter(name=username, password=password).first()
       #     token = uuid.uuid4() # 生成一个uuid的随机字符串
       #     # 这个是错误的:user.usertoken是None
       #     # user.usertoken.user=user
       #     # user.usertoken.token=token
       #     # 如果每次都是新增,如果它登录过,这个地方会报错
       #     # models.UserToken.objects.create(user=user,token=token)
       #     # 如果有就更新,如果没有就创建
       #     # 根据user去查询,如果能查到,就修改token,如果查不到,就新增一条
       #     models.UserToken.objects.update_or_create(defaults={'token': token}, user=user)
       #     if user:
       #         return APIResponse(msg='登录成功', token=token)
       #     else:
       #         return APIResponse(status=101, msg='用户名或密码错误')

    1.1.3 路由

    router = SimpleRouter()
    router.register('user', views.UserView)

    urlpatterns = [
       path('admin/', admin.site.urls),
       path('api/', include(router.urls)),
    ]

    1.2 认证类

    1.2.1 认证类的编写

    ####基于自己写的UserToken表
    # class LoginAuth(BaseAuthentication):
    #     def authenticate(self, request):
    #         token = request.GET.get('token')
    #         user_token = models.UserToken.objects.filter(token=token).first()
    #         if user_token:
    #             # 登录了
    #             #返回两个值,第一个值,给了新的request对象的user属性,通常情况我们把当前登录用户给它
    #             return user_token.user, ''
    #         else:
    #             raise AuthenticationFailed('您没有登录')


    ####基于session的
    from django.contrib.sessions.models import Session
    from importlib import import_module
    from django.conf import settings
    class LoginAuth(BaseAuthentication):
       def authenticate(self, request):
           token = request.GET.get('token')

           #通过传入的token(session_key,取到当前key的session对象)
           engine = import_module(settings.SESSION_ENGINE)
           self.SessionStore = engine.SessionStore
           request.session = self.SessionStore(token)

           Session.objects.filter(session_key=token).first()
           # print(request.session['name'])
           if request.session.get('name',None):
               print(request.session['name'])
               print(request.session['id'])
               return '',''
           else:
               raise AuthenticationFailed('您没有登录')

    1.2.2 使用认证类(全局用,局部用)

    #全局用,setting中配置(所有接口都需要认证)
    REST_FRAMEWORK={
       "DEFAULT_AUTHENTICATION_CLASSES":["app01.auth.LoginAuth",]
    }
    # 登录功能需要局部禁用,在视图类中加入
    authentication_classes = []
       
    #只在局部使用,只在视图类中加
    authentication_classes = [LoginAuth,]

     

     

    2 认证的局部和全局使用

    看上面

     

    3 权限类编写和使用

    3.1 编写权限类

    class MyPermission(BasePermission):
    message='你没有权限'
    def has_permission(self, request, view):
    if request.user.user_type == 1:

    return True
    else:
    self.message='你是%s用户,你没有权限'%request.user.get_user_type_display()
    return False

    3.2 权限类的使用

    # 局部使用(在视图类中加)
    permission_classes = [MyPermission,]
    # 全局使用(在配置文件中配置)
    REST_FRAMEWORK={
    "DEFAULT_PERMISSION_CLASSES":["app01.auth.MyPermission",],
    }

     

    4 频率类的使用

    4.1 定义一个频率类

    from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
    class MyThrottle(SimpleRateThrottle):
    scope = 'ip_th'
    def get_cache_key(self, request, view):
    return self.get_ident(request)

    4.2 在配置文件中配置

    REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
    'ip_th': '5/m', #一分钟访问5次
    },
    }

    4.3 局部使用,全局使用

    # 局部用,在视图类中配置
    throttle_classes = [MyThrottle,]
    # 全局用,在配置文件中配置
    REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES": ["app01.auth.MyThrottle", ],
    'DEFAULT_THROTTLE_RATES': {
    'ip_th': '5/m', #一分钟访问5次
    },

    }

    补充

    1 魔法方法:类中以  __名字__的方法 
    2 魔法方法的作用:某种情况下,会触发它的执行
    -__init__,类实例化的时候
      -__call__,对象()
      -__getattr__,对象.属性
       新的request.method,通过反射区原来的request中取出来返回
       
       
       
    3 猴子补丁:动态的把对象替换掉,以后用的都是新对象
  • 相关阅读:
    android studio eclipse keymap theme 快捷键 主题风格设置
    android Observable api请求参数设置注解问题
    量化交易-外汇交易-MetaTrader5
    springboot maven项目,为什么build成功,build path也没错误,project-->clean 也没用,项目上面还是有个红x呢?
    springboot用@Autowired和@PostConstruct注解把config配置读取到bean变成静态方法
    深入剖析Kubernetes k8s
    android搜索框列表布局,流程及主要步骤思维导图
    php 当前时间 当前时间戳和数据库里取出的时间datetime格式进行比较大小
    android studio 自动导入包
    第三方统计分析埋点工具对比,神策、Ptmind、GrowingIO、国双,还有谷歌分析,谁更好?
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14893769.html
Copyright © 2020-2023  润新知