首页 > 其他 > 详细

模型类序列化器ModelSerializer的使用等相关内容-84

时间:2021-01-06 22:14:16      阅读:45      评论:0      收藏:0      [点我收藏+]

1 修改,删除接口

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

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

 

3 模型类序列化器

1 原来用的Serilizer跟表模型没有直接联系, 模型类序列化器ModelSerilizer,跟表模型有对应关系
?
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

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:就是原来的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,]

 

 

6 many=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

模型类序列化器ModelSerializer的使用等相关内容-84

原文:https://www.cnblogs.com/usherwang/p/14243498.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!