drf_day06

books系列接口

查 单条和所有

        def get(self, request, *args, **kwargs):
        # 查单个 和所有 合在一起
        if kwargs.get('pk'):        # 如果 请求url中有 pk键值  代表是查单条记录
            book_list = models.Book.objects.all().filter(is_delete=False, pk=kwargs.get('pk'))
        else:                       # 否则就是查询所有记录
            book_list = models.Book.objects.all().filter(is_delete=False)       # 查询所有没有删除的书
        book_list_ser = BookModelSerializer(book_list, many=True)
        return Response(data=book_list_ser.data)

增单条


增单条
    def post(self, request, *args, **kwargs):
        if isinstance(request.data,dict):           # 判断request.data 是不是 dict类型  是的话意味着 是要操作增加一本书
            book_ser = BookModelSerializer(data=request.data)
            book_ser.is_valid(raise_exception=True)     # 视频里应该配置了全局异常处理  所有book_ser.save()是在正确的情况下保存 跟这种方法一致
            book_ser.save()
            return Response(data=book_ser.data)

增所有

		elif isinstance(request.data, list):        # 如果request.data 是 list类型 代表是要操作增加多本书
            book_ser = BookModelSerializer(data=request.data, many=True)    # 增多条 就是在增单条的基础上 加上 many = True
            book_ser.is_valid(raise_exception=True)  # 视频里应该配置了全局异常处理  所有book_ser.save()是在正确的情况下保存 跟这种方法一致
            print(book_ser.data)
            book_ser.save()
            return Response(data=book_ser.data)

单条修改

	    def put(self, request, *args, **kwargs):
	        if kwargs.get('pk', None):          # if 取不到pk 返回None   这是判断取到pk这样就是改一条的情况
	            book_obj = models.Book.objects.filter(pk=kwargs.get('pk')).first()
	            book_ser = BookModelSerializer(instance=book_obj, data=request.data, partial=True)      # 设置为True  后续修改的时候传部分要修改的数据也行
	            book_ser.is_valid(raise_exception=True)     # 配置了全局异常处理才能这样写 否则会报错
	            book_ser.save()
	            return Response(data=book_ser.data)

多条修改

	        else:
	            book_list = []
	            modify_data = []
	            for item in request.data:       # for循环遍历request.data(批量修改)的数据 然后添加到  modify_data列表中
	                pk = item.pop('id')         # 字典(item).pop('id')   有两个作用  1 是将id字段的值取出来赋值给pk   然后将item中的id字段移除掉(不允许用户更改id值)
	                book = models.Book.objects.get(pk=pk)
	                book_list.append(book)
	                modify_data.append(item)
	            # 第一种方法
	            # for i, si_data in enumerate(modify_data):         # for循环一个个保存
	            #     book_ser = BookModelSerializer(instance=book_list[i], data=si_data)
	            #     book_ser.is_valid(raise_exception=True)
	            #     book_ser.save()
	            # return Response(data='成功')
	            # 第二种方法                                     # 在序列化器里面进行
	            book_ser = BookModelSerializer(instance=book_list, data=modify_data, many=True)     # modify_data是列表 需要 many=True
	            book_ser.is_valid(raise_exception=True)
	            book_ser.save()
	            return Response(book_ser.data)


如果用来第二种方法  在序列化类里面加上这句话
    class Meta:
        list_serializer_class = BookListSerializer      # 上面
        
在定义一个类

class BookListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        # ll = []
        # for i, si_data in enumerate(validated_data):
        #     ret = self.child.update(instance[i], si_data)
        #     ll.append(ret)
        # return ll
        return [
            self.child.update(instance[i],attrs) for i,attrs in enumerate(validated_data)
        ]

批量删除

	    def delete(self, request, *args, **kwargs):
	        # 单个删除和批量删除
	        pk = kwargs.get('pk')
	        pks = []
	        if pk:
	            pks.append(pk)
	        # 不管是单条删除还是多条删除  都转换为列表的形式  当作为多条删除
	        else:
	            pks = request.data.get('pks')
	        # 把is_delete字段设置为true
	        # ret表示受影响的行数
	        ret = models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True)
	        if ret:
	            return Response(data={'msg':'删除成功'})
	        else:
	            return Response(data={'msg': '没有要删除的数据'})

分页器的使用 (三种分页方式)

from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
'''
设置每页数据条数的配置在 类PageNumberPagination中
    page_size: 每页显示条数
    可以在settings.py里面进行设置  或者在这里写个类继承它然后设置  page_size属性值
'''
###   三种分页方式

class MyPageNumberPagination(PageNumberPagination):
    page_size = 3                   # http://127.0.0.1:8000/api/books2/?aaa=1&size=6
    page_query_param = 'aaa'        # 设置get ? 后面的参数名称 默认是page  可以修改成自定义
    page_size_query_param = 'size'      # 虽然设置了每页 page_size = 3  如果配置上这句话 那么前端可以通过修改请求地址?后端的参数 加上 size = 4 让每页数据变成4条
    max_page_size = 5       # 这是来限制  page_size_query_param 的  避免它写无限大


class MyPageNumberPagination(LimitOffsetPagination):
    default_limit = 2                   # 默认每次拿几条  http://127.0.0.1:8000/api/books2/?limit=4&offset=1 从1开始拿四条数据
    limit_query_param = 'limit'         # 每次从offset位置取   取 limit条
    offset_query_param = 'offset'
    max_limit = 5       # 限制limit的数量


class MyPageNumberPagination(CursorPagination):     # 数据量大的时候查询效率高  但是出来的前端效果是只能上一页 和下一页 不支持跳页
    cursor_query_param = 'cursor'       # 每页查询的key
    page_size = 2                       # 每页显示的条数
    ordering = '-id'                    # 排序字段


class BookView(ListAPIView):
    queryset = models.Book.objects.all().filter(is_delete=False)
    serializer_class = BookModelSerializer
    # 配置分页
    pagination_class = MyPageNumberPagination       # 因为MyPageNumberPagination继承了PageNumberPagination 且改了页数 所以继承这个

如果使用APIView分页
from app01.throttling import MyThrottle
class BookView(APIView):
    throttle_classes = [MyThrottle,]
    def get(self, request, *args, **kwargs):
        book_list = models.Book.objects.all()
        # 实例化得到一个分页器对象
        page_cursor = MyPageNumberPagination()

        book_list = page_cursor.paginate_queryset(book_list, request, view=self)
        next_url = page_cursor.get_next_link()
        pr_url = page_cursor.get_previous_link()
        print(next_url)
        print(pr_url)
        book_ser = BookModelSerializer(book_list, many=True)
        return Response(data=book_ser.data)

根据ip限制用户频率

创建一个throttling.py文件 在里面书写一下代码
from rest_framework.throttling import ScopedRateThrottle,SimpleRateThrottle


class MyThrottle(SimpleRateThrottle):
    scope = 'luffy'         # 这个要跟settings.py 里面的频率限制 对应
    def get_cache_key(self, request, view):
        return request.META.get('REMOTE_ADDR')      # 获取 访问该服务器的用户ip

然后在settings.py中配置以下信息

REST_FRAMEWORK={
    # 'PAGE_SIZE': 2
    'DEFAULT_THROTTLE_RATES': {                     # 与上面连起来用 具体限制次数
        'luffy': '5/m'      # key要跟类中的scop对应		一分钟最多访问5次
    },
}

JWT的概念

jwt = Json Web token
# 原理
'''
1	jwt分三段式: 头 体  签名(head.payload.sgin)
2	头和体是可逆加密, 让服务器可以反解出user对象; 签名是不可逆加密, 保证整个token的安全性
3	头体签名三部分, 都是采用json格式的字符串,进行加密,可逆加密一般采用base64算法, 不可逆加密一般采用hash(md5)算法
4	头中的内容是基本信息: 公司信息	项目组信息	token采用的加密方式信息
{
	"company": "公司信息”,
	...
}
5	体中的内容是关键性信息: 用户主键, 用户名, 	签发时客户端信息(设备号,地址),过期时间
{
	“user_id": 1,
	...
}
6 签名中的内容时安全信息: 头的加密结果 + 体的加密结果  + 服务器不对外公共的安全码  进行md5加密
{
	"head": "头的加密字符串",
	"payload":  "体的加密字符串”,
	"secret_key": "安全码"

'''

校验
'''
1	将token按 .拆分为三段字符串,第一段  头加密字符串 一般不需要做任何处理
2	第二段  体加密字符串, 要反解出用户主键, 通过主键从user表中就能得到登录用户, 过期时间和设备信息都是安全信息	,确保token没过期, 且是同一设备
3	再用第一段  +  第二段 + 服务器安全码  不可逆md5加密, 与第三段 签名字符串  进行碰撞校验 , 通过后才能代表第二段校验得到的user对象就是合法的登录用户
'''

drf 项目的jwt认证开发流程(重点)
'''
1	用账号密码访问登录接口 , 登录接口逻辑中调用  签发token算法 ,得到token ,返回给客户端 ,客户端自己存到cookies中
2	校验token的算法应该写在认证类中(在认证类中调用), 全局配置给认证组件, 所有视图类请求, 都会进行认证校验, 所有请求带了token, 就会反解user对象, 在视图类中用request.user就能访问用户

注: 登录接口需要做  认证 + 权限  两个局部禁用
'''

第三方写好的  django-rest-framework-jwt
安装  pip install djangorestframework-jwt

新建一个项目, 继承AbstractUser表()

创建超级用户

简单使用
	urls.py
		from rest_framework_jwt.views import JSONWebTokenAPIView, obtain_jwt_token
		
		urlpatterns = [
		    path('admin/', admin.site.urls),
		    path('login/', obtain_jwt_token),
		]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值