序列化、认证、权限、视图回顾

回顾

基于django编写restful接口
APIView的流程分析
    重写了dispatch方法:包装了request,执行了认证,权限,频率
    
原生request对象:

​ 里面有个GET(以get形式提交的数据),以get形式提交的数据,都拆到environ内部,django把数据取出来转成了QueryDict的对象,而request.session不是原生request对象的属性,是在中间件中放进去的

1635178-20190704172332991-1397645520.png

drf的Request类:

​ data:post提交的数据,json格式,urlencoded,formdata编码方式的数据,data的类型并不是固定的,可能是QueryDict,也可能是字典

​ query_params:原生的GET

​ 重写了__getattr__:对象.属性,当属性不存在就会执行该方法,return getattr(self._requset,'属性'),这样就能通过封装后的request.属性也能拿到值

1635178-20190704172351773-1671998420.png

序列化源码分析

​ many = True的时候,生成的是列表中放了一个个序列化对象

​ many = False的时候,生成的是一个序列化对象

​ __new__控制的:返回什么样格式的就走什么样格式的init,比如返回的是字符串格式的就会走字符串格式的init,即实例化的时候就产生一个字符串

​ 校验源码部分:调用了bookser.is_valid方法才走校验,内部走了self.run_validation方法(要从根上找),在Serilaizer类中找到了run_validation方法

​ 重点:self.to_internal_value(局部钩子)/self.validate(全局钩子),Serializer类中找到了to_internal_value,去对象内部反射validate_字段名的方法,如果不为None,直接执行,于是就执行了咱们自己写的局部校验的函数

​ 序列化对象.data:执行Serializer内的data方法,又执行了父类(BaseSerializer)的data方法,执行self.to_representation(其实执行的是Serializer内的to_representation方法),最终执行的是每个字段对象的get_attribute方法,找字段对象的该方法,在Field中找到了该方法,执行了get_attribute(instance, self.source_attrs)

​ self.source_attrs:每个字段source后面指定的根据.切分后的列表(publish.name:就会被分成[publish,name]),如果是方法会执行方法,如果是字段,通过反射取出值

1635178-20190704172358663-1258681649.png

认证

​ 使用(必会):

​ 写一个认证类(继承BaseAuthentication)

​ 重写authenticate方法,把request对象传入

​ 能从request对象中取出用户携带的token,根据token判断是否登入,如果登入,返回两个值,user对象,token对象,如果没有登入就抛出异常raise AuthenticationFailed('您没有登录')

​ 局部使用、全局使用、局部禁用

​ update_or_create()有就更新,没有就创建models.Token.objects.update_or_create(user=user,defaults={'token':token})

​ uuid的使用:生成一个唯一的随机字符串

​ 源码分析:

​ APIVIew中的dispatch===>self.initial(认证,频率,权限)===>self.perform_authentication(认证)===>本质又调用了新的request对象的user方法

​ request.user内部执行了:self._authenticate(注意self是新的request对象),循环拿到一个个认证类的对象,执行对象的authenticate方法,传入request对象,一个个认证类的对象是在reuqest对象实例化的时候传入的,APIView中的get_authenticators,通过列表推导式生成一个个的认证类对象,然后传入request对象中

1635178-20190704172407064-1471680373.png

1635178-20190704172411390-1801249939.png

视图

基本写法:继承APIView

第二种写法

class PublishView(CreateModelMixin,ListModelMixin,GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializers
    def post(self,request,*args, **kwargs):
        return self.create(request, *args, **kwargs)
    def get(self,request,*args, **kwargs):
         return self.list(request, *args, **kwargs)
        
class PublishDetailView(RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin,GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializers
    def get(self,request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def put(self,request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self,request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

第三种写法

from rest_framework.generics import CreateAPIView,ListCreateAPIView,DestroyAPIView,RetrieveUpdateDestroyAPIView
class PublishView(ListCreateAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializers

class PublishDetailView(RetrieveUpdateDestroyAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = PublishSerializers

第四种写法

from django.views import View
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
    queryset=models.Publish.objects.all()
    serializer_class=PublishSerializers

ViewSetMixin重写了as_view方法,路由配置就改了,可以写成映射的形式{get:get_one}

as_view方法内部执行效果
通过反射的取值跟赋值,完成映射,根据请求方式执行对应的方法(比如:get请求执行get_one方法,在路由中配置{get:getone})

1635178-20190704172422378-1960417633.png

补充:

1.基于对象的跨表查询和基于双下划线的查询区别是什么?

​ 基于对象的跨表查询是子查询,基于双下划线是联表查询

2.left join/inner join/right join 区别是什么?

​ left join:基于左边的表连接(左表表字段齐全)

​ right join:基于右边的表连接(右表表字段齐全)

​ inner join:两张表有对应关系的连接

转载于:https://www.cnblogs.com/yanminggang/p/11133725.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值