zoukankan      html  css  js  c++  java
  • drf—— 编写登录接口,用同一个接口既可以不登录访问,又可以登录访问

    要求:

    编写登录接口,一个接口既可以不登录访问,又可以登录访问(匿名用户一分钟访问1次,登录用户一分钟访问3次)
    #需要用到student和user表

    1.models.py

    from django.db import models
    
    class Student(models.Model):
        name = models.CharField(max_length=32)
        sex = models.SmallIntegerField(choices=((1, ''), (2, ''), (3, '未知')), default=1)
        age = models.IntegerField()
    
    class User(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
        user_type = models.IntegerField(choices=((1, '超级用户'), (2, '普通用户'), (3, '二笔用户')),default=1)
    #此表完全可以与User表合为一个,但这样解耦合,可扩展性高
    class UserToken(models.Model):
        user = models.OneToOneField(to='User',on_delete=models.CASCADE)
        token = models.CharField(max_length=64)

    2.数据迁移,两条命令;然后连接数据库,在user和student表中写入测试数据

    3.serializer.py

    from rest_framework import serializers
    from app01.models import Student
    
    
    class StudentSerializer(serializers.ModelSerializer):
        sex = serializers.CharField(source='get_sex_display')
    
        class Meta:
            model = Student
            fields = '__all__'

    4.auth.py

    from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
    
    from app01 import models
    #from rest_framework.exceptions import AuthenticationFailed
    
    from rest_framework.authentication import BaseAuthentication
    
    class LoginAuth(BaseAuthentication):
        def authenticate(self, request):
            token = request.GET.get('token')
            res = models.UserToken.objects.filter(token=token).first()
            if res:
                return (res.user, token)
            else:
                return None
    
    
    class MySimpleThrottle(SimpleRateThrottle):
        scope = 'xxx'
    
        def get_cache_key(self, request, view):
            if not request.user.id:  # 没有登录用户
                return self.get_ident(request)  # 根据ip限制
            else:
                return None
    
    class MyLoginThrottle(SimpleRateThrottle):
        scope = 'login'
        def get_cache_key(self, request, view):
            return request.user.pk

    5.views.py

    from rest_framework.views import APIView
    from app01 import models
    import uuid
    from app01.auth import LoginAuth,MyLoginThrottle,MySimpleThrottle
    class LoginView(APIView):
        authentication_classes = []
        def post(self, request):
            res = {'code': 100, 'msg': '登录成功'}
            username = request.data.get('username')
            password = request.data.get('password')
            # 查询数据库
            user = models.User.objects.filter(username=username, password=password).first()
    
            if user:
                token = uuid.uuid4()  # 生成一个随机字符串
                # 把token存到UserToken表中(如果是第一次登录:新增,如果不是第一次:更新)
                models.UserToken.objects.update_or_create(defaults={'token': token}, user=user)
                res['token'] = token
                return Response(res)
            else:
                res['code'] = 101
                res['msg'] = '用户名或密码错误'
    
                return Response(res)
    
    
    from app01.models import Student
    from app01.serializer import StudentSerializer
    
    from rest_framework.mixins import ListModelMixin
    from rest_framework.viewsets import GenericViewSet
    from rest_framework.response import Response
    from rest_framework.mixins import CreateModelMixin
    class StudentView(GenericViewSet, ListModelMixin, CreateModelMixin):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
        authentication_classes = [LoginAuth,]
        throttle_classes = [MyLoginThrottle,MySimpleThrottle,]

    6.urls.py

    from django.urls import path
    from app01 import views
    #自动生成路由
    from rest_framework.routers import SimpleRouter
    router=SimpleRouter()
    router.register('students',views.StudentView)
    
    urlpatterns = [
        path('login/', views.LoginView.as_view()),
    ]
    urlpatterns+=router.urls
    print(router.urls)

    7.settings.py

    INSTALLED_APPS = [
        ...
        'rest_framework'
    ]
    
    REST_FRAMEWORK = {
        # 'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],
        'DEFAULT_THROTTLE_RATES' : {
            'xxx':'1/m',
            'login':'3/m'
        }
    }

    后续:

    如果要写两个接口,一个接口不登陆访问1次,一个接口登录访问3次,可以用以下的方式:(推荐使用写两个接口,这样解耦合,不需要写那么多判断麻烦)
    -方式一:
            -写两个频率类(一个是根据ip限制,另一个根据userid)
    -方式二:
            -使用内置的,如果可以,就没问题就可以,如果又问题需要继承重写get_cache_key方法
  • 相关阅读:
    IBM openblockchain学习(五)--consensus源码分析
    Linux内核抢占机制
    IBM openblockchain学习(四)--crypto源码分析
    IBM openblockchain学习(三)--Ledger源码分析
    IBM openblockchain学习(二)--chaincode源码分析
    瞎谈“认知计算”
    IBM openblockchain学习(一)--obc-peer环境搭建
    10G数据不用框架快速去重
    Spark学习笔记(一)--Spark架构
    HDU2255 【模板】KM算法
  • 原文地址:https://www.cnblogs.com/guojieying/p/13964272.html
Copyright © 2011-2022 走看看