DRF组件--2

DRF组件--权限功能

自己定义一个权限类,其中必须包含has_permission方法

class MyPermission(object):     #创建一个权限类。里面写具体的权限划分
    def has_permission(self,request,view):
        if request.user.usertype == 3:
            return True             #如果返回ture,则说明拥有该权限
        return False

然后再视图函数中,配置permission_classes = [MyPermission,]列表。方法同认证功能一样,如果想要配置为全局,也是同认证一样,再settings里配置

BasePermission内置权限类。

 

 

节流(访问控制)

自定义一个访问控制类,其中必须包含allow_request方法和wait方法

#访问频率控制
import time
VISIT_RECORD={}     #存储用户的访问记录,将用户的ip作为key
class VisitThrottle(object):
    def __init__(self):
        self.history = None

    def allow_request(self,request,view):
        #获取用户ip
        remote_addr = request._request.META.get('REMOTE_ADDR')
        ctime = time.time()
        if remote_addr not in VISIT_RECORD:
            VISIT_RECORD[remote_addr] = [ctime,]
            return True
        history = VISIT_RECORD.get(remote_addr)
        self.history = history
        while history and history[-1] < ctime - 60:
            history.pop()
        if len(history) < 3:
            history.insert(0,ctime)
            return True
    #返回true说明可以正常访问
    #返回false说明访问频率过高

    def wait(self):
        ctime = time.time()
        wait_time = 60 - (ctime - self.history[-1])
        #此处返回的值,就会再频率过高的时候提示还剩多少秒
        return wait_time

然后再视图函数中配置throttle_classes=[VisitThrottle,]方法同认证一样,如果想要配置为全局,也同认证一样,在settins里配置

 

版本

版本在url中get传参,例如127.0.0.1:8001/app02/users/?version=v1,但是不常用.

 

url携带版本号,例如127.0.0.1:8001/app02/v1/users/

采用内置的版本类,URLPathVersioning,可以解决该问题

class UserView(APIView):
    authentication_classes=[]
    permission_classes=[]
    throttle_classes=[]
    # versioning_class = URLPathVersioning     #使用内置的版本控制类,此处可以写在全局配置文件中
    def get(self,request,*args,**kwargs):
        res = {'code':200, 'data':None}
        url = request.versioning_scheme.reverse(viewname='xxx',request=request)     #反向生成url,不过需要配套urls路由别名使用
        print(url)
        print(request.version)              #在添加后,直接在request中带有version
        return JsonResponse(res)

还需要在urls配置相应的正则

urlpatterns = [
    re_path('^(?P<version>[v1|v2]+)/users/$', views.UserView.as_view(),name='xxx'),
]

settings里全局的版本配置

    'default_version': 'v1',                    #表示默认的版本
    'allowed_versions': ['v1','v2'],            #表示允许的版本
    'version_param': 'version',                 #表示传入的关键字-key
    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',       #全局配置版本

 

 

 

解析器(parse)

当请求过来时,解释器会根据content-type字段,选择相应的解释器,然后并将数据封装的request.data中。一般我们都是直接采用rest里面内置的解析器,无需自己定义

class ParseView(APIView):
#接口地址 127.0.0.1:8002/app02/v1/parse/            #使用内置的解释器
    authentication_classes=[]
    permission_classes=[]
    throttle_classes=[]
    parser_classes = [JSONParser,FormParser]
#此处可以写进全局变量中。当请求过来时,解释器会根据content-type字段,选择相应的解释器,然后并将数据封装的request.data中
    def post(self,request,*args,**kwargs):
        print(request.data)             #根据解析器,将数据封装到这
        res = {'code': 200, 'data': None}
        return JsonResponse(res)

 

 

序列化

序列化:由于我们在数据库中获取的数据是queryset类型,无法向前端返回json,这一部分需要自己转换,rest的序列化可以提供这个关系转化。

class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserGroupModel
        fields = '__all__'
        # fields = ['id','username','password']
        depth = 2       #该配置表示,如果字段是外键,那么是可以点出来的,这个数字就代表可以点出几层

class Group(APIView):
    #api;http://127.0.0.1:8002/app02/v1/group/3
    authentication_classes=[]
    permission_classes=[]
    throttle_classes=[]
    def get(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        groupinfo = UserGroupModel.objects.filter(id=pk).first()
        ser = GroupSerializer(instance=groupinfo,many=False)
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)

对想要的字段进行序列号,不想要的可以不写

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()  # 与模型层字段类型对应
    price = serializers.IntegerField()  # 与模型层字段类型对应

 常用的字段

BooleanField()
NullBooleanField()
CharField()
EmailField()
RegexField()
SlugField()
URLField()
UUIDField()
IPAddressField()
IntegerField()
FloatField()
DecimalField()
DateTimeField()
DateField()
TimeField()
ChoiceField()
FileField()
ImageField()

 

 

分页

一般使用内置三种分页

看第m页,每页n条数据

在第m个数据的位置上,向后看n条数据

加密分页,只看上一页和下一页:为了防止用户将页码手动修改,比如直接将页码修改9999,这样会造成数据库查询压力大,所以rest提供将页码进行加密处理。如果数据量大,这种效率高

 https://www.cnblogs.com/yume-zbh/p/16406434.html

 

路由

router自动给生成路由

from rest_framework import routers
router = routers.DefaultRouter
router.register(r'xxx',views.UserView)
url(r'(?P<version>[v1|v2]+)/users/',include(router.urls)),

 

 

 

视图**

GenricAPIView

由于GenericViewSet中ViewSetMixin重写了as_view方法,所以需要在urls里面传参

    re_path('^(?P<version>[v1|v2]+)/users/$', views.UserView.as_view({'get':'list','post':'create'})),

其中get请求会转换为list,所以在视图类中,需要填list方法

 

渲染器

将返回的数据在页面进行渲染,在页面进行美化

    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]  #将返回的数据在页面进行渲染

 

posted @ 2022-11-27 23:52  powfu  阅读(25)  评论(0)    收藏  举报