Django中rest_framework的十大组件作用及使用方法

参考链接:
1.https://blog.csdn.net/qq_41500222/article/details/87895643
2.https://zhuanlan.zhihu.com/p/54293336

Django后端开发

后端为前端提供URL(API接口)
返回json数据

反射

对象有几种方法用来操作自己的属性或方法:
getattr(object, name), 
hasattr(object, name), 
setattr(object, name, value), 
delattr(object, name)

1、有时我们要访问某个变量或是方法时并不知道到底有没有这个变量或方法,
所以就要做些判断。判断是否存在字符串对应的变量及方法。
2、我们知道访问变量时是不能加引号的,否则会被当成字符串处理。
如果要通过字符串找到对应的变量,

反射就是用于解决上面两个问题而产生的,所谓反射,
按我的理解就是反过来告诉我字符串是什么,是变量或方法
# 1. getattr()函数是Python自省的核心函数,具体使用大体如下:class A: def __init__(self): 
self.name = 'zhangjing'#self.age='24'def method(self): 
print"method print"
  Instance = A() 
print getattr(Instance , 'name, 'not find') #如果Instance 对象中有属性name则打印self.name的值,否则打印'not find'
print getattr(Instance , 'age', 'not find') #如果Instance 对象中有属性age则打印self.age的值,否则打印'not find'
print getattr(a, 'method', 'default') #如果有方法method,否则打印其地址,否则打印default 
print getattr(a, 'method', 'default')() #如果有方法method,运行函数并打印None否则打印default 

# 2. hasattr(object, name)

# 说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的)

# 3. setattr(object, name, value)

# 这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar = 123。

4. delattr(object, name)

# 与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar

Django中的视图函数分为 FBV和CBV其中CBV就是基于反射判断并执行对应方法接受返回值来实现的。

REST_FRAMEWORK 十大组件

首先导入from rest_framework.views import APIView
APIView类
对于rest_framework的全局设置, 可以写在setting.py中的REST_FRAMEWORK = {}, 这个字典中

这些属性既可以写在继承的视图类下面,也可以设置全局的, 它会在项目中的setting.py 文件中读取

认证

写认证类需要继承rest_framework中的认证基类
from rest_framework.authentication import BasicAuthentication,且必须实现authenticate方法
例如登录认证:

#创建一个我的认证类 继承BaseAuthentication方法
class MyAuthtication(BaseAuthentication):
	# 设置内置authenticate重写authenticate这个方法
    def authenticate(self, request):
    	# 将用户输入的token用变量接收
        token = request._request.GET.get("token")
        # 然后在数据库进行匹配
        token_obj = models.UserToken.objects.filter(token=token).first()
        # 如果认证失败
        if not token_obj:
        	#就返回失败
            raise exceptions.AuthenticationFailed("用户认证失败")
        # 在 rest framework内部 会将这两个字段赋值给request,以供后续操作使用
        #正确就返回用户和token
        return (token_obj.user, token)

权限

编写权限类需要继承rest_framework中的from rest_framework.permissions import BasePermission权限基类, 需要实现has_permission方法。

class MyPermission(BasePermission):
    # 这是一个判断用户权限的权限类
    message = '该章节为vip章节'
    def has_permission(self, request, view):
        section_id = int(view.kwargs.get('id')) if 'id' in view.kwargs else None
        if not section_id:
            return True
        # section是小说章节的model
        section = models.Section.objects.filter(id=section_id).first()

        if not section:
            return True
        # 用户的type属性1代表普通用户,2代表VIP;
        # 章节的is_vip属性1代表普通章节,2代表vip章节
        if request._request.user.type != 1 or section.is_vip != 2:
            return True
            # print(request._request.user.type)
            # print(type(request._request.user.type))
        return False

节流(用户访问频率限制)

简单的节流可以使用rest_framework中的
from rest_framework.throttling import SimpleRateThrottle
但是需要设置scope属性, 可以设置在节流类中,也可以设置在setting中。
例:

REST_FRAMEWORK = {
    ···
    'DEFAULT_THROTTLE_RATES': {'unlogin': '20/m'},
}
# s:秒,m:分,h:时,d:天

在这里插入图片描述在这里插入图片描述

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
import time
# 自定义节流类
class VisitThrottle(BaseThrottle):
    RECORD_VISITS = {}

    def __init__(self):
        self.history = []

    def allow_request(self, request, view):
        ip_addr = request._request.META.get('REMOTE_ADDR')
        key = ip_addr
        currenttime = time.time()
        if key not in self.RECORD_VISITS.keys():
            self.RECORD_VISITS[key] = [currenttime,]
            return True

        visit_history = self.RECORD_VISITS.get(key)
        self.history = visit_history

        while visit_history and visit_history[-1] < currenttime - 60:
            visit_history.pop()

        if len(visit_history) < 5:
            visit_history.insert(0, currenttime)
            return True
        else:
            return False


        # return True

    def wait(self):
        first_time = self.history[-1]
        return 60 - (time.time() - first_time)
# 自带的节流类
class MySimpleRateThrottle(SimpleRateThrottle):
    scope = 'unlogin'

    def get_cache_key(self, request, view):
        # 更具IP或者用户表示获取用户的访问记录
        return self.get_ident(request)
        raise NotImplementedError('.get_cache_key() must be overridden')

版本

from rest_framework.versioning import URLPathVersioning导入可直接使用,也可以配置在setting中,在全局使用版本控制

REST_FRAMEWORK = {
    # 全局使用版本控制时配置
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',

    # 以下三个配置可以自定义, 但url中  param关键字必须与  VERSION_PARAM  相同
    'ALLOWED_VERSIONS': ['v1', 'v2', 'v3'],
    'VERSION_PARAM': 'version',
    'DEFAULT_VERSION': 'v1',
}

url中的写法:

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 版本控制在url中的使用
    url(r'^api/(?P<version>[v1|v2]+)/', include('api_v1.urls')),
]

解析器

post请求时可能会接受到字典类型的数据,或者json类型的数据
取post请求的数据时,request.POST不一定能取到数据,request.body一定能取到。

解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己想要的数据类型的过程.

request.data
# 可以获取解析之后的数据

序列化

序列化有两大功能:请求数据的验证,

  • 对queryset的序列化
  • 创建URL

from rest_framework import serializers导入
编写序列化类继承serializers.Serializer与继承serializers.ModelSerializer的区别在于继承serializers.ModelSerializer不需要指定每个需要返回的字段。
下面列举两个例子。
继承serializers.Serializer

from rest_framework import serializers
class UserInfoSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

继承serializers.ModelSerializer

from rest_framework import serializers
from . import models
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
    	# 需要序列化的模型类
        model = models.UserInfo
        fields = ["username", "password"]

UserInfoSerializer在views中的使用

class RolesView(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()
        ser = UserInfoSerializer(instance=roles, many=True)
        import json
        return HttpResponse(json.dumps(ser.data))

分页

分页共有PageNumberPagination, LimitOffsetPagination, CursorPagination,访问时需要传入的参数不相同

class MyPageNumberPagination(PageNumberPagination):
    #每页显示多少个
    page_size = 3
    #默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数
    page_size_query_param = "size"
    #最大页数不超过10
    max_page_size = 10
    #获取页码数的
    page_query_param = "page"

class MyLimitOffsetPagination(LimitOffsetPagination):
    #默认显示的个数
    default_limit = 2
    #当前的位置
    offset_query_param = "offset"
    #通过limit改变默认显示的个数
    limit_query_param = "limit"
    #一页最多显示的个数
    max_limit = 10

#自定义分页类3 (加密分页)
class MyCursorPagination(CursorPagination):
    cursor_query_param = "cursor"
    page_size = 2     #每页显示2个数据
    ordering = 'id'   #排序
    page_size_query_param = None
    max_page_size = None

在视图中的使用

class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象
        pg = 分页类的类名()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response(ser.data)

路由系统

视图

渲染器

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值