首页 > 其他分享 >drf与视图类

drf与视图类

时间:2023-05-24 21:11:06浏览次数:39  
标签:return ser get self 视图 data Response drf

drf与视图类

模块与包的使用

# 模块与包
	模块:一个py文件,被别的py文件导入使用就是模块,直接右键运行就是脚本文件
    包:一个文件夹里面有__init__.py文件
# 模块与包的导入问题
	
'''
    导入模块有相对导入和绝对导入,绝对的路径是从环境变量开始的
    导入任何模块,如果使用绝对导入,都是从环境变量开始导入起
    脚本文件执行的路径,会自动加入环境变量
    相对导入的话,是从当前py文件开始计算的
    以脚本运行的文件,不能使用相对导入,只能用绝对导入
'''    

反序列化校验源码分析(了解)

# 序列化类的校验功能
	-局部钩子:必须validate_字段名
    -全局钩子: validate
    
# ser.is_valid,到这一步开始做校验,所以这是入口
BookSerializer---》Serializer——-》BaseSerializer---》is_valid---》继承了Field

# is_valid 方法
        def is_valid(self, *, raise_exception=False):
            # self中没有_validated_data,只有执行完后,才有
            if not hasattr(self, '_validated_data'):
                try:
                    # 核心---》这一句
                    # 想看它的源代码,按住ctrl+鼠标点击是不对的---》只能找当前类的父类
                    #但它真正的执行是,从根上开始找
                    self._validated_data = self.run_validation(self.initial_data)
                except ValidationError as exc:
                    self._validated_data = {}
                    self._errors = exc.detail
                else:
                    self._errors = {}

            if self._errors and raise_exception:
                raise ValidationError(self.errors)

            return not bool(self._errors)
    -self.run_validation(self.initial_data),不能按住ctrl+鼠标点点击,要从根上开始找
    -Serializer的run_validation
        def run_validation(self, data=empty):
             # 局部钩子
            value = self.to_internal_value(data)
            try:
                # 全局钩子
                value = self.validate(value) # BookSerializer只要写了,优先执行它的
            except (ValidationError, DjangoValidationError) as exc:
                raise ValidationError(detail=as_serializer_error(exc))

            return value
    
    -self.to_internal_value(data)---》Serializer类的方法
        def to_internal_value(self, data):
            for field in fields: #序列化类中写的一个个的字段类的对象列表
                # 一个field是name对象,field.field_name字符串 name
                # self是谁的对象:序列化类的对象,BookSerializer的对象  validate_name
                validate_method = getattr(self, 'validate_' + field.field_name, None)
                try:
                    # 字段自己的校验规则
                    validated_value = field.run_validation(primitive_value)
                    if validate_method is not None:
                        # 局部钩子
                        validated_value = validate_method(validated_value)
                except ValidationError as exc:
                    errors[field.field_name] = exc.detail
                except DjangoValidationError as exc:
                    errors[field.field_name] = get_error_detail(exc)
                except SkipField:
                    pass
                else:
                    set_value(ret, field.source_attrs, validated_value)

            if errors:
                raise ValidationError(errors)

            return ret
# 总结:
	-ser.is_valid---》走局部钩子的代码---》是通过反射获取BookSerializer中写的局部钩子函数,如果写了,就会执行----》走全局钩子代码---》self.validate(value)--->只要序列化类中写了,优先走自己的

断言

assert hasattr(self, 'initial_data'), (
            'Cannot call `.is_valid()` as no `data=` keyword argument was '
            'passed when instantiating the serializer instance.'
        )

# 声明这个就是对的,不对就报错返回括号中写的

drf之请求

# 视图类:APIView
# 序列化组件:Serializer,ModelSerializer
# drf:Request类的对象
# drf:Response

Request类对象的分析

1).data
    request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和 request.FILES属性,但提供如下特性:
    包含了解析之后的文件和非文件数据
    包含了对POST、PUT、PATCH请求方式解析后的数据
    利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
2).query_params
	request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而
3) 其他的属性用起来跟之前一样

请求,能够接受的编码格式

# urlencoded
# form-data
# json
三种都支持

可以通过限制只能接收某种或集中编码格式
# 方式一:
# 总共有三个:JSONParser, FormParser, MultiPartParser
	class BookView(APIView):
    	parser_classes = [JSONParser, FormParser]
# 方式二:
# 在配置文件写,drf的配置,统一写成它
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            # 'rest_framework.parsers.FormParser',
            # 'rest_framework.parsers.MultiPartParser',
        ],
    }
# 方式三:
# 全局配置了只支持json,局部想支持3个
	-只需要在局部,视图类中,写3个即可
    class BookView(APIView):
    	parser_classes = [JSONParser, FormParser,MultiPartParser]
	
    
 # 总结:能够处理的请求方式编码
	-优先从视图类中找
    -再去项目配置文件找
    -再去drf默认的配置中找

drf之响应

响应类的对象Response

# return Response({code:100})
-data:响应体的内容,可以字符串,字典,列表
-status:http响应状态码  
	-drf把所有响应码都定义成了一个常量
	
template_name:模板名字,用浏览器访问,看到好看的页面,用postman访问,返回正常数据
	-自定制页面
    -根本不用
headers:响应头加数据(后面讲跨域问题再讲)
	-headers={'name':'lqz'}
content_type:响应编码,一般不用


# 三个重要的:data,status,headers

响应的格式

# 默认是两种:纯json,浏览器看到的样子

# 限制方式一:在视图类上写---》只是局部视图类有效
	# 总共有两个个:JSONRenderer,BrowsableAPIRenderer
	from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class BookView(APIView):
        renderer_classes = [JSONRenderer]
        
# 限制方式二:在配置文件中写---》全局有效
    # drf的配置,统一写成它
     REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            # 'rest_framework.renderers.BrowsableAPIRenderer',
        ],
    }
    
    
# 全局配置了只支持json,局部想支持2个
	-只需要在局部,视图类中,写2个即可
	from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class BookView(APIView):
        renderer_classes = [JSONRenderer,BrowsableAPIRenderer]

视图之两个视图基类

# 视图类:
	-APIView:之前用过
	-GenericAPIView:GenericAPIView继承了APIView
    
    
    
# GenericAPIView
	-类属性:
    	queryset:要序列化的所有数据
    	serializer_class:序列化类
        lookup_field = 'pk' :查询单条时的key值
     -方法:
    	-get_queryset():获取所有要序列化的数据【后期可以重写】
        -get_serializer  : 返回序列化类
        -get_object :获取单个对象
        
        
        
 #总结:以后继承GenericAPIView写接口
	1 必须配置类属性
    	queryset
        serializer_class
     2 想获取要序列化的所有数据
    	get_queryset()
     3 想使用序列化类:
    	get_serializer
     4 想拿单条
    	get_object
    	

使用APIView+序列化类+Response写接口

from rest_framework.views import APIView

from .serializer import BookSerialzier
from rest_framework.response import Response
from .models import Book

# class BookView(APIView):
#     def get(self, request):
#         qs = Book.objects.all()
#         ser = BookSerialzier(qs, many=True)
#         return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
#     def post(self, request):
#         ser = BookSerialzier(data=request.data)
#         if ser.is_valid():
#             ser.save()
#             return Response({'code': 100, 'msg': '成功'})
#         else:
#             return Response({'code': 100, 'msg': ser.errors})
#
#
# class BookDetailView(APIView):
#     def get(self, request, pk):
#         book = Book.objects.all().get(pk=pk)
#         ser = BookSerialzier(book)
#         return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
#     def put(self, request, pk):
#         book = Book.objects.get(pk=pk)
#         ser = BookSerialzier(data=request.data, instance=book)
#         if ser.is_valid():
#             ser.save()
#             return Response({'code': 100, 'msg': '更新成功'})
#         else:
#             return Response({'code': 100, 'msg': ser.errors})


####2 使用GenericAPIView+序列化类+Response写接口

# 咱们写的
# class GenericAPIView(APIView):
#     query_set=None
#     serialzier_class=None
#     def get_queryset(self):
#         return self.query_set
#     def get_serializer(self):
#         return self.serialzier_class
#     def get_object(self):
#         return self.query_set.filter(pk=pk)

# 人家写的
from rest_framework.generics import GenericAPIView


# class BookView(GenericAPIView):
#     queryset = Book.objects.all()
#     serializer_class = BookSerialzier
#
#     def get(self, request):
#         qs = self.get_queryset()
#         ser = self.get_serializer(qs, many=True)
#         return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
#     def post(self, request):
#         ser = self.get_serializer(data=request.data)
#         if ser.is_valid():
#             ser.save()
#             return Response({'code': 100, 'msg': '成功'})
#         else:
#             return Response({'code': 100, 'msg': ser.errors})
#
#
# class BookDetailView(GenericAPIView):
#     queryset = Book.objects.all()
#     serializer_class = BookSerialzier
#
#     def get(self, request, pk):
#         book = self.get_object()
#         ser = self.get_serializer(book)
#         return Response({'code': 100, 'msg': '成功', 'results': ser.data})
#
#     def put(self, request, pk):
#         book = self.get_object()
#         ser = self.get_serializer(data=request.data, instance=book)
#         if ser.is_valid():
#             ser.save()
#             return Response({'code': 100, 'msg': '更新成功'})
#         else:
#             return Response({'code': 100, 'msg': ser.errors})

使用GenericAPIView+序列化类+Response写接口

class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier

    def get(self, request):
        qs = self.get_queryset()
        ser = self.get_serializer(qs, many=True)
        return Response({'code': 100, 'msg': '成功', 'results': ser.data})

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '成功'})
        else:
            return Response({'code': 100, 'msg': ser.errors})


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier

    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(book)
        return Response({'code': 100, 'msg': '成功', 'results': ser.data})

    def put(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(data=request.data, instance=book)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '更新成功'})
        else:
            return Response({'code': 100, 'msg': ser.errors})

标签:return,ser,get,self,视图,data,Response,drf
From: https://www.cnblogs.com/juzixiong/p/17429532.html

相关文章

  • django配置文件作用,drf 登录功能,drf认证组件,drf权限组件,drf频率组件
    django配置文件作用:    drf登录功能:view内:from.modelsimportUserInfo,UserTokenfromrest_framework.viewsetsimportViewSetimportuuidfromrest_framework.responseimportResponsefromrest_framework.decoratorsimportactionclassUser......
  • drf频率的使用
    频率,按ip地址,用户id,限制1写一个类,继承SimpleRateThrottle2写一个方法,get_cache_key-可以返回ip或者用户idreturnrequest.META.get("REMOTE_ADDR")-返回什么,就用什么做频率限制3写一个类属性scope='lqz'4在配置文件中配置'DEFAULT_THROTTLE_RATES':{......
  • drf配置文件和三大认证
    0django转换器,配置文件作用#django转换器:django2.x以后,为了取代re_path -intpath('books/<str:name>')---->/books/1----》name=1---》当参数传入视图类的方法中-str-path-slug-uuid#django配置文件 1djagno项目要运行,优先执行配置文......
  • drf——5个视图扩展类、9个视图子类、视图集、drf之路由
    5个视图扩展类#写5个类(不叫视图类视图拓展类需要配合GenericAPIView一起用)每个类有一个方法以后想写哪个接口就继承哪个类即可fromrest_framework.responseimportResponse####自己封装的5个视图拓展类classListModelMixin:deflist(self,request):......
  • 视图(Views)- Yii2 权威指南
    视图 ¶创建视图渲染视图布局使用视图组件视图事件渲染静态页面最佳实践视图是 MVC 模式中的一部分。它是展示数据到终端用户的代码,在网页应用中,根据视图模板来创建视图,视图模板为PHP脚本文件,主要包含HTML代码和展示类PHP代码,通过yii\web\View应用组件来管理,该组......
  • iOS UIView如何管理它的子视图
    didMoveToWindow 通知接收者它一斤给添加到窗口中 -(void)didMoveToWindow 讨论 默认实现不做任何事情;子类可以重写这个方法来做特殊的实现 窗口的属性有可能是nil当这个方法调用的时候,这表明接收者并不属于当然任何一个窗口。这个只发生在接收者从它的父视图上移......
  • drf——自定义权限
    第一步:创建自定义权限首先,需要创建自定义权限类以实现企业黑名单功能。在你的permissions.py文件中创建一个新的类,例如:fromrest_frameworkimportpermissionsclassBlacklistPermission(permissions.BasePermission):message='Youraccounthasbeenblacklisted.'......
  • drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类
    1.模块与包#模块与包 模块:一个py文件被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件包:一个文件夹下有__init__.py#模块与包的导入问题'''1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的2.导入任何模块,如果......
  • drf自动生产路由
    自动生产路由#ReadOnlyModelViewSet:两个接口,list和retrievefromrest_framework.viewsetsimportReadOnlyModelViewSetclassBookLIstretrieveView(ReadOnlyModelViewSet):queryset=Book.objects.all()serializer_class=Bookserializers#ViewSetMixin:魔......
  • 5个视图扩展类,9个视图子类,视图集,drf之路由
    5个视图扩展类:1from.modelsimportBook2from.serializerimportBookSerialzier3fromrest_framework.responseimportResponse4fromrest_framework.genericsimportGenericAPIView56fromrest_framework.mixinsimportListModelMixin,CreateModelMixi......