• DAY 65 drf03


    1 cbv执行流程
    -路由里写的是  类名.as_view(),
       -as_view()执行完是一个闭包函数的内存地址
       -当请求来了,路由匹配上就会调用 闭包函数(request)
       -self.dispatch(requset)
       -通过反射,去类中根据请求方式取方法,执行,把参数传入
    2 APIView的执行流程
    -以后写drf,最顶层都是APIView
       -类名.as_view()是APIView,内部调用了父类的view
       -在后加了去除csrf
       -self.dispatch(requset)是APIView的
      -包装新的request
           -执行了权限,频率,认证
           -处理了全局异常
           -处理了响应
    4 drf的Request类
    -重写了__getattr__ :新的request用起来,跟之前一模一样
       -drf的reqeust._request 是原来的request
       -request.data :post,put,patch,请求的body体中的数据,都从data中取
    5 序列化,反序列化
    -对象----》json
       -json---》对象
    6 序列化器
    -定义一个类,继承Serializer
       -在类内些字段(常用字段,和非常用字段)(字段参数)
       -在视图类中,实例化得到一个序列化类的对象,传入要序列化的数据
       -对象.data---》就是字典
       -source

     

    1 反序列化,局部钩子,全局钩子

    1 如果要反序列化,继承了Serializer,必须重写create方法

    2 使用
    #视图类
    def post(self, request):
       publish_ser = serializer.PublishSerializer(data=request.data)
       if publish_ser.is_valid():
           # 直接保存,保存到哪个表里?需要重写save
           publish_ser.save()
           return Response(publish_ser.data)
       else:
           print(publish_ser.errors)
           return Response('数据有问题啊')
       
    # 序列化类
    def create(self, validated_data):
       res = models.Publish.objects.create(**validated_data)
       return res

    1.3 局部和全局钩子

        def validate_name(self, data):
           # data就是当前字段的值
           if data.startswith('sb'):
               raise ValidationError('不能以sb开头')
           else:
               return data

       def validate(self, attrs):
           if attrs.get('name') == attrs.get('city'):
               raise ValidationError('city和名字不能一样')
           else:
               return attrs

     

    2 序列化类常用字段属性

    2.1 常用和非常用字段

    http://www.liuqingzheng.top/python/Django-rest-framework%E6%A1%86%E6%9E%B6/2-drf-%E5%BA%8F%E5%88%97%E5%8C%96%E7%BB%84%E4%BB%B6/

    2.2 字段参数

    # 针对charfield
    max_length 最大长度
    min_lenght 最小长度
    allow_blank 是否允许为空
    # 针对interfield
    max_value 最小值
    min_value 最大值

    # 通用的,大家都有
    #这两个最重要
    read_only 表明该字段仅用于序列化输出,默认False(序列化)
    write_only 表明该字段仅用于反序列化输入,默认False(反序列化)


    required 表明该字段在反序列化时必须输入,默认True
    default 反序列化时使用的默认值
    allow_null 表明该字段是否允许传入None,默认False
    error_messages 包含错误编号与错误信息的字典

    validators 该字段使用的验证器(了解)

     

    3 模型序列化器

    2.1 视图类

    class BookView(APIView):
       def get(self,request):
           qs=models.Book.objects.all()
           ser=serializer.BookModelSerializer(instance=qs,many=True)
           return Response(ser.data)

       def post(self,request):
           ser = serializer.BookModelSerializer(data=request.data)
           if ser.is_valid():
               ser.save()
               return Response(ser.data)
           else:
               return Response(ser.errors)


    class BookDetailView(APIView):
       def get(self,request,id):
           book = models.Book.objects.filter(pk=id).first()
           ser = serializer.BookModelSerializer(instance=book)
           return Response(ser.data)
       def put(self,request,id):
           book = models.Book.objects.filter(pk=id).first()
           ser = serializer.BookModelSerializer(instance=book,data=request.data)
           if ser.is_valid():
               ser.save()
               return Response(ser.data)
           else:
               return Response(ser.errors)

       def delete(self,request,id):
           res = models.Book.objects.filter(pk=id).delete()
           if res[0] > 0:
               return Response('')
           else:
               return Response('要删的不存在')

    3.2 序列化类

    class BookModelSerializer(serializers.ModelSerializer):
       class Meta:
           model = models.Book
           fields = '__all__'
           extra_kwargs = {
               'publish': {'required': True, 'write_only': True},
               'authors': {'required': True, 'write_only': True},
          }
       publish_detail = PublishSerializer(source='publish',read_only=True)
       author_list=serializers.ListField(read_only=True)
       # 字段自己的校验,全局钩子,局部钩子

    3.3 表模型

    class Book(models.Model):
       nid = models.AutoField(primary_key=True)
       name = models.CharField(max_length=32)
       price = models.DecimalField(max_digits=5, decimal_places=2)
       publish_date = models.DateField()

       publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
       authors=models.ManyToManyField(to='Author')
       def __str__(self):
           return self.name


       # def publish_name(self):
       #     return self.publish.name

       def publish_name(self):
           return {'name':self.publish.name,'city':self.publish.city}

       @property
       def author_list(self):
           return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]

    3.4 路由

    path('books/',views.BookView.as_view()),
    path('books/<int:id>/',views.BookDetailView.as_view()),

     

    4 请求对象

    1 Request:新的request
    2 常用属性

    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相同,只是更换了更正确的名称而已

     

    5 响应对象属性

    #一直会用
    data: 为响应准备的序列化处理后的数据(字典)
    #偶尔会用
    headers: 用于存放响应头信息的字典;
    status: 状态码,默认200;(http请求的状态码)

    # 基本不用
    template_name: 模板名称,如果使用HTMLRenderer 时需指明;
    content_type: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。

     

    补充

    1 django项目,app中有templates,找模板优先从项目的templates中找,找不到,去相应的app中找,找不到,再报错
  • 相关阅读:
    JS 提交表单
    [ZJOI 2010]base 基站选址
    [ZJOI 2013]丽洁体
    [Codeforces 176B]Word Cut
    [SDOI 2013]方程
    [AtCoder agc021D]Reversed LCS
    [BZOJ 4361]isn
    [SDOI 2011]黑白棋
    [ZJOI 2010]Perm 排列计数
    [Codeforces 297E]Mystic Carvings
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14893736.html
Copyright © 2020-2023  润新知