Django rest framework之序列化组件、drf的请求与响应、通过配置,选择默认模板的显示形式(浏览器方式,json方式)及many=True源码分析,局部全局钩子源码解析

1、序列化组件

1.1、source用法
1、修改返回到前端的字段名
# 如果source=title字段名就不能再叫title
# 数据库中该表的字段是title,希望返回的字段是name
name = serializers.CharField(max_length=32,min_length=2,source='title')

2、表模型中存在方法
# 执行表模型中的test方法,并且把返回值赋值给xxx,数据库中可以没有test这个字段,返回的字段是xxx
# 在模型类中需要定义test方法
xxx = serializers.CharField(source='test')

3、sourc支持跨表操作,模型类中可以使用外键关联两个数据表
addr=serializers.CharField(source='publish.addr')
1.2、模型类序列化器
1.2.1、定义

原来用的serializer跟表模型没有直接联系, 模型类序列化器ModelSerializer,跟表模型有对应关系

1.2.2、简单使用
class BookModelSerializer(serializers.ModelSerializer):
     class Meta:
         model=表模型    # 跟哪个表模型建立关系
         fields=[字段,字段] # 序列化的字段,反序列化的字段
         fields='__all__' # 所有字段都序列化,反序列化
         exclude=[字段,字段] # 排除哪些字段(不能跟fields同时使用)
         read_only_fields=['price','publish']  # 序列化显示的字段
		 write_only_fields=['title']           # 反序列化需要传入的字段
         extra_kwargs ={'title':{'max_length':32,'write_only':True}}
         depth=1  # 跨表1查询,最多建议写3,该配置不建议使用
     # 重写某些字段
     publish = serializers.CharField(max_length=32,source='publish.name')
     # 局部钩子,全局钩子,跟原来完全一样

关于新增,修改: 统统不用重写create和update方法了,在ModelSerializer中重写了create和update方法
1.3、高级用法之SerializerMethodField
这个方法主要是想达到跟depth=1那样的效果,展出出来的效果如书籍多有数据(类似一个字典),然后书籍中包含出版社字段,这个出版社字段又对应类似一个字典,展示出所有出版社的详细信息

方式一: 基于serializers.Serializer中的使用
class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32,min_length=2,source='title')
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.SerializerMethodField()  # 在模型中是外键字段
    def get_publish(self,obj):
        dic={'name':obj.publish.name,'addr':obj.publish.addr}
        return dic

方式二: 基于serializers.ModelSerializer中的使用
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
    publish = serializers.SerializerMethodField()
    def get_publish(self,obj):
        dic={'name':obj.publish.name,'addr':obj.publish.addr}
        return dic

方式三: 使用序列化类的嵌套
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        # fields = '__all__'
        fields = ['name','addr']


class BookModelSerializer(serializers.ModelSerializer):
    publish = PublishSerializer()  # 指定PublishSerializer,当你查询的时候就会一起查询出publish中的详细数据

    class Meta:
        model = models.Book
        fields = '__all__'

2、drf的请求与响应

# Request
data: 前端以post请求提交的数据都在它中
FILES: 前端提交的文件
query_params: 就是原来的request.GET
重写了 __getattr__, 使用新的request.method其实取得就是原生request.method(通过反射实现)

# Response
from rest_framework.response import Response
data: 响应的字典
status: http响应的状态码
drf提供了所有的状态码,以及它的意思: from rest_framework from status 
template_name: 模板名字(一般不修改)
headers: 响应头,是字典类型
content_type: 响应的编码方式

# 自己封装一个Response对象
class CommonResponse:
     def __init__(self):
         self.code=100
         self.msg=''
         
     @property
     def get_dic(self):
         return self.__dict__

# 在视图函数中的使用:
    def post(self, request):
        res = CommonResponse()
        ser = xxxModelSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            res.msg = 'success'
            res.result = ser.data
        else:
            res.code = 101
            res.msg = 'error'
            res.result = ser.errors
        return Response(data=res.get_dic, status=201)

3、通过配置,选择默认模板的显示形式(浏览器方式,json方式)

3.1、全局配置
settings配置文件方式
如果没有配置,默认有浏览器和json
drf有默认配置文件

from rest_framework.settings import DEFAULTS

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
        'rest_framework.renderers.JSONRenderer',  # json渲染器
        'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
    )
}
3.2、局部配置
视图类中配置
粒度更小

from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer

class XXX(APIView):
    renderer_classes = [BrowsableAPIRenderer, JSONRenderer]  # 需要导入这两个类

4、many=True源码分析,局部全局钩子源码解析

1、many=True(查询结果是多个需要添加这个配置)
找__init__,通过类的继承方式开始查找 -----> 一路找到了BaseSerializer -----> __new__元类中决定了生成的对象是谁

2、全局局部钩子的解析,入口是is_valid() -----> 一路找到了BaseSerializer中定义的is_valid ----> self._validated_data = self.run_validation(self.initial_data)  # 需要明确当前这个self是谁,继续按照类的继承关系开始查找,最后找到了是Serializer这个类的self.run_validation

Serializer这个类的: self.run_validation
def run_validation(self, data=empty):
      value = self.to_internal_value(data)  # 局部字段自己的校验和局部钩子校验
      try:
          self.run_validators(value)
          value = self.validate(value)  # 全局钩子的校验
      except (ValidationError, DjangoValidationError) as exc:
          raise ValidationError(detail=as_serializer_error(exc))
      return value
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值