首页 > 其他分享 >11111

11111

时间:2023-02-03 23:55:49浏览次数:39  
标签:HTTP 11111 self request 视图 序列化 data

昨日内容回顾

序列化类的常用字段

ListField

DictField

CharField

SerializerMethodField

字段参数

max_length

min_value

required,default,error_messages,validator

read_only,write_only

定制序列化字段(改名字)

方式1

source这个字段参数

如果是模型表自己的字段,直接写

不过是关联字段通过外键拿到

方式2

在序列化类中使用:SerializerMethodField,配合一个,get_字段名的方法,方法返回什么,这个字段就是什么–》这种字段以后不能用来做,反序列化

方式3

在模型表中使用,写方法的方式,方法返回什么,这个字段就是啥,序列化类中需要配合listField,DictField-》这种字段以后不能来,做反序列化,方法可以包装数据属性,也可以不包装

反序列化校验4层

1.字段自己的校验,序列化字段参数控制

2.validators=[方法,]

3.局部钩子

4.全局钩子

ModelSerializer:继承自Serializer

class BookSerializer(ModelSerializer):

如果字段是映射过来的,也会把字段属性【反序列化校验规则】,也会映射过来,有可能会校验失败,不能写入。

我们从写这个这段,不加任何规则,取消掉它

class BookSerializer(ModelSerializer):
        # 如果字段是映射过来的,也会把字段属性[反序列化校验规则],也会映射过来,有可能会校验失败,不能写入
        # 咱们重写这个字段,不加任何规则,取消掉它
        name = serializer.CharField()
        class Meta:
            model=Author
            # fields="__all__"
            # 只要是序列化的字段和反序列化的字段,都要在这注册
            # 序列化的字段,可能不是表模型的字段,是咱自己写的方法
            # 序列化的字段,可能是使用SerializerMethodField,也要注册
            fields=['name','photo','gender','addr'] 
            extra_kwargs={}  # 给字段类增加属性,read_only 和write_only用的多
        gender=serializer.CharField()
       addr=serializer.CharField()
       局部钩子,全局钩子完全一样
       SerializerMethodField也一样
       create
       update
     

只需要注册第一层的字段即可

{
    "name": "哈哈哈123123",
    "price": "1231312",
    "publish": "俄罗斯出版社"
    "authors":{"gender":"男","phone":"123"}
}
也就是只需要注册
fields=["name","price","publish","authors"]
即可,里面的字段可以由authors自己写局部钩子自己校验

反序列化的字段,不一定跟模型表的字段对应(记住)

image-20230203090927767

今日内容

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

反序列化校验,开始执行位置

在视图类种的ser.is_valid(),就会执行校验,校验通过返回True,不通过返回False

入口:ser.is_valid() 是序列化类的对象,假设序列化类是BookSerializer–》is_valid>找不到,找父类BaseSerializer中:【raise_exception:先注意】

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

        if not hasattr(self, '_validated_data'):
            try:
                # 校验入口,self是BookSerializer产生的对象,所有先从对象的名称空间找,在按照顺序找父类的
                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序列化类的对象

self._validated_data = self.run_validation(self.initial_data)

切记一定不要按住ctrl键点击

真正的执行顺序是,从下往上找,找不到,在往上

最终Serializer类中找到了
image-20230203192055379

而不是Field中的run_validation

    def run_validation(self, data=empty):
        """
        We override the default `run_validation`, because the validation
        performed by validators and the `.validate()` method should
        be coerced into an error dictionary with a 'non_fields_error' key.
        """
        # 字段的自己的校验与validators的校验
        (is_empty_value, data) = self.validate_empty_values(data)
        if is_empty_value:
            return data
		# 这里是局部钩子校验的验证
        value = self.to_internal_value(data)
        try:
            self.run_validators(value)
            #这里是全局钩子校验的函数
            value = self.validate(value)
            assert value is not None, '.validate() should return the validated data'
        except (ValidationError, DjangoValidationError) as exc:
            raise ValidationError(detail=as_serializer_error(exc))

        return value

局部钩子self.to_internal_value(data)》》self是BookSerializer的对象,从跟本上找

image-20230203192417273

    def to_internal_value(self, data):
        """
        Dict of native values <- Dict of primitive datatypes.
        """
        if not isinstance(data, Mapping):
            message = self.error_messages['invalid'].format(
                datatype=type(data).__name__
            )
            raise ValidationError({
                api_settings.NON_FIELD_ERRORS_KEY: [message]
            }, code='invalid')

        ret = OrderedDict()
        errors = OrderedDict()
        fields = self._writable_fields
		# fields写在序列化类中一个个字段类的对象
        for field in fields:
            # self BookSerializer的对象,反射validate_name
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            primitive_value = field.get_value(data)
            try:
                # 在执行BookSerializer类中的validate_name方法,传入了要校验的数据
                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

image-20230203092941210

断言

源码中大量使用try和断言

关键字assert,的作用就是断定后面的为真,如果不是就抛异常

assert 0,('1231312',12312312)  # ,号后面断言失败错误的值信息,就不想下走了,断言成功猜想下执行
print(123)

image-20230203193128270

drf之请求

Request能够解析的前端传入的编码格式

需求是该接口只能接收json格式,不能接收其他格式

方式一,在继承自APIView及其子类的视图类中配置(局部配置)

总共有三个:

from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookView(APIView):
    parser_classes = [JSONParser,]
方式二,在配置文件中配置(影响所有,全局配置)

django有套默认配置,每个项目有个配置,项目的settins

drf有套默认配置,每个项目也有个配置》就在django的配置文件中

settings.py

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser',
    ],
}
方式三:全局配了1个,某个视图类响应3个

只需要在视图类中,配置3个即可

因为:先从视图类中找,找不到,取项目drf配置中找,在找不到,取drf默认的配置找,默认不写配置即可,因为drf默认配置就是三种都支持

Request类有哪些属性和方法

视图类方法中的request

data

_getattr_

query_parms

FILES

drf之响应

Response能够响应的编码格式

drf是django的一个app,所以需要注册

drf的响应,如果使用浏览器和postman访问同一个接口,返回格式是不一样的

drf做了个判断,如果是浏览器,好看一些,如果是postman只要json结果

方式一:在视图类中写(局部配置)

两个相应类》》找》》drf的配置文件中找》》两个类

from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class BookView(APIView):
    renderer_classes=[JSONRenderer,]
方式二:在项目配置文件中写(全局配置)

settings.py

REST_FRAMEWORK = {
      'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}
方式三:使用顺序(一般就用内置的即可)

优先使用视图类中的配置,其次使用项目配置文件的配置,最后使用内置的

Response的源码属性或方法

drf的Response源码分析

from rest_framework.response import Response
    -视图类的方法返回时,retrun Response ,走它的__init__,init中可以传什么参数
    
    
# Response init可以传的参数
    def __init__(self, 
                 data=None, 
                 status=None,
                 template_name=None, 
                 headers=None,
                 exception=False, 
                 content_type=None)

    

data是之前写的ser.data可以是字典或列化,字符串》》序列化后返回给前端》》前端在响应体中看到的就是这个
status:http响应状态码,默认是200,可以改,在drf的status包下,把所有http响应状态码都写了一遍,常量

from rest_framework.status import HTTP_200_OK
HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_102_PROCESSING = 102
HTTP_103_EARLY_HINTS = 103
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_208_ALREADY_REPORTED = 208
HTTP_226_IM_USED = 226
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_308_PERMANENT_REDIRECT = 308
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_418_IM_A_TEAPOT = 418
HTTP_421_MISDIRECTED_REQUEST = 421
HTTP_422_UNPROCESSABLE_ENTITY = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_425_TOO_EARLY = 425
HTTP_426_UPGRADE_REQUIRED = 426
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_508_LOOP_DETECTED = 508
HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509
HTTP_510_NOT_EXTENDED = 510
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511
Response('dddd',status=status.HTTP_200_OK)

template_name:了解即可,修改响应模板的样子,BrowsableAPIRenderer定死的样子,后期公司可以自己定制

headers:响应头,http响应的响应头

原生django响应头加东西或修改

四件套
render,HttpResponse,readict,JsonResponse
            obj = HttpResponse('dddd')
            obj['xxc'] = 'yyc'
        	obj['server']='我自定义的不告诉你服务'
            return obj

content_type:响应编码格式,一般不动

重点:data,status,headers

视图组件介绍及两个视图基类

drf视图,视图类,学过APIView,drf的基类,drf提供的最顶层的类

APIView跟之前的View区别:传入到视图方法中的是RESTframework的Request对象,而不是jango的HttpRequest对象

视图方法可以返回REST framwork的Response对象

任何APIException异常都会被捕获到,并且处理成合适的响应信息

在进行dispatch()分发前,会对请求进行身份认证,权限检查、浏览控制

两个视图基类

APIView

类属性:

renderer_classes# 响应格式

parser_class#能够解析的请求格式

authentication_classes#认证类
throttle_classes#频率类
permission_classes#权限类

基于APIView+ModelSerializer+Response写5个接口

视图类

from .models import Book
from .serializer import BookSerializer


class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            # 咱们现在只有ser序列化类的对象,但是咱们想要,新增的对象---》序列化成字典---》大前提,序列化类中的create方法一定要返回新增的对象
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    def get(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books)
        return Response(ser.data)

    def put(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

序列化类

### ModelSerializer的使用
class BookSerializer(serializers.ModelSerializer):
    # 跟表有关联
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }

路由

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

基于GenericAPIView+5个视图扩展类

视图类

from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    ListModelMixin


# 基于GenericAPIView+5个视图扩展类写接口

class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    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)

视图类

class BookSerializer(serializers.ModelSerializer):
    # 跟表有关联
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }

路由

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

标签:HTTP,11111,self,request,视图,序列化,data
From: https://www.cnblogs.com/clever-cat/p/17090723.html

相关文章

  • 111111
    一不小心将注册表中的HKEY_CLASSES_ROOT\.exe删除,导致.exe文件全部打不开。本想重新添加一个值到注册表,却发现就连注册表都打不开。win+R,输入regedit都打不开。还好网上教......
  • 1111111
    1.参考文档见同目录下的.mhtml文件在第一步安装JDK那一步中我选择直接安装了jdk17,因为官网和国内镜像的OpenJDK始终都下载不下来。1.1.配置文件基本信息spring:data......
  • 【221225-1】数列求和:1+11+111+1111+11111+...
    ......
  • [vue项目] 后台管理 11111111111111111
    文章目录​​gitee地址​​​​登录业务解析​​​​退出登录​​​​模板结构图​​​​路由的搭建​​​​品牌管理​​​​table数据渲染​​​​分页器​​​​点击添加......
  • 111111111111111111
    测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测......
  • 11111
    文字少的博文不允许投稿到博客园首页文字少的博文不允许投稿到博客园首页文字少的博文不允许投稿到博客园首页文字少的博文不允许投稿到博客园首页文字少的博文不允许投稿......
  • 111111
    昨日数据回顾(自己方便记单词,别模仿)布尔值bollTrue,False意思是对的和错的所有的数据自带布尔值布尔值为Flase的有0None''[]{}元组......
  • wireshark 11111111111111111
     wireshark抓包过滤器语法及示例=====================================================================BPF语法(BerkeleyPacketFilter),基于libpcap/wincap库语句......
  • tcpdump 1111111111111111111111111
     tcpdump命令格式、参数====================================================================================================================tcpdump[-AdDe......