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中找,找不到,再报错
原文地址:https://www.cnblogs.com/DEJAVU888/p/14893736.html