修改删除接口,模型化序列化器,高级用法之source,SerializerMethodField,drf的请求与响应,many=True源码分析

day84一.昨日回顾二.今日内容1 修改,删除接口urls.pyviews.pyserializer.py2 高级用法之source3 模型化序列化器4 高级用法之SerializerMethodField5 drf的请求与响应7many=True源码分析,局部全局钩子源码解析扩展一.昨日回顾1 restful规范 -只是一个规范,规范了前后端交互的接口(api接口)格式 -10条 -https部署 -请求地址中有接口标识 -https://api.baidu.com -htt
摘要由CSDN通过智能技术生成

一.昨日回顾

1 restful规范
	-只是一个规范,规范了前后端交互的接口(api接口)格式
	-10-https部署
		-请求地址中有接口标识
			-https://api.baidu.com
			-https://www.baidu.com/api/
		-多版本共存
			-https://www.baidu.com/api/v1
		-请求资源名词表示,可以复数
			-一切皆资源
			-https://www.baidu.com/api/v1/books/
		-请求方式表示操作资源的方式
			-get:获取资源
			-post:新增资源
			-put:修改
			-patch:修改
			-delete:删除资源
		-响应中带状态码
			-{code:100}
		-响应中带错误信息
			-{code:100,msg:'错误'}
		-响应中带链接地址
		-响应数据遵循以下格式
			-多条数据  []
			-单条	{}
			-新增	新增的数据返回
			-修改	修改的数据返回
			-删除	空文档
		-请求中带过滤条件
2 序列化器
	-把对象--->序列化器--->字典--->Response--->json格式字符串给前端
	-把前端传过来的数据---Request->字典--->序列化器--->对象--->保存
	-数据校验
	-如何使用
		-写一个序列化类 继承Serializer
		-在类中写字段
			-字段类型:CharField...
			-字段属性参数:required...
		-在视图类中使用
			-实例化得到对象
				-序列化(对象-->字典)ser=XXSerializer(instance=对象,many=True)--->ser.data
				-反序列化(新增)(字典--->对象)ser=XXSerializer(data=字典)
	-反序列化的校验(三种方式)
		-字段自己的校验
		-validators=[函数内存地址,]
		-局部和全局钩子
			-validate_字段名(self,data)
			-validate(self,attrs)
	-write_only和read_only

二.今日内容

1 修改,删除接口

urls.py

re_path('^books/(?P<id>\d+)',views.BookDetail.as_view()),

views.py

def put(self, request, id):
        # 通过id取到对象
        res = {'code': 100, 'msg': ''}
        try:
            book = models.Book.objects.get(id=id)
            ser = BookSerializer(instance=book, data=request.data)
            ser.is_valid(raise_exception=True)
            ser.save()
            res['msg'] = '修改成功'
            res['result'] = ser.data

        except Exception as e:
            res['code'] = 101
            res['msg'] = str(e)

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

serializer.py

class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=32,min_length=2)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=32)

    def create(self, validated_data):
        res=models.Book.objects.create(**validated_data)
        print(res)
        return res

    def update(self, book, validated_data):
        book.title=validated_data.get('title')
        book.price=validated_data.get('price')
        book.publish=validated_data.get('publish')
        book.save()
        return book

2 高级用法之source

source:

①替换字段的显示名称。

②获取模型类方法的执行结果。

③可以写点跨表的查询语句。

1 修改返回到前端的字段名
	# source=title  字段名就不能再叫title
	name = serializers.CharField(max_length=32,min_length=2,source='title')
2 如果表模型中有方法
# 执行表模型中的test方法,并且把返回值赋值给xxx
xxx=serializers.CharField(source='test')
3 source支持跨表操作
addr=serializers.CharField(source='publish.addr')
# 可以看一下源码,内部如何实现的

3 模型化序列化器

如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。

ModelSerializer与常规的Serializer相同,但提供了:

基于模型类自动生成一系列字段
基于模型类自动为Serializer生成validators,比如unique_together
包含默认的create()和update()的实现

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

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')
        # 局部钩子,全局钩子,跟原来完全一样
3 新增,修改
	-统统不用重写create和update方法了,在ModelSerializer中重写了create和update

4 高级用法之SerializerMethodField

SerializerMethodField()的使用:需要有个配套方法,方法名为get_字段名,返回值就是显示值。

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


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()

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

5 drf的请求与响应

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

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

# 自己封装一个Response对象
class CommonResponse:
	def __init__(self):
		self.code=100
		self.msg=''
	@property
	def get_dic(self):
		return self.__dict__
# 自己封装一个response,继承drf的Response
# 通过配置,选择默认模板的显示形式(浏览器方式,json方式)
	-配置文件方式(全局)
        -如果没有配置,默认有浏览器和json
            -drf有默认配置文件
            from rest_framework.settings import DEFAULTS
            REST_FRAMEWORK = {
            'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
                'rest_framework.renderers.JSONRenderer',  # json渲染器
                'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
            )
        	}
    -在视图类中配置(局部)
    	-粒度更小
        -class BookDetail(APIView):
    		renderer_classes=[JSONRenderer,]

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

1 many=True
	-__init__--->一路找到了BaseSerializer--->__new__决定了生成的对象是谁
    
2 入口是is_valid()---》BaseSerializer--》is_valid---》self._validated_data = self.run_validation(self.initial_data)
	-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

扩展

1 接口幂等性,是什么,如何弄?
2 接口:统一字类的行为
	抛异常限制
    abc模块限制
    人为限制(鸭子类型)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值