2、序列化(serializers.Serializer

    1)序列化(正向查找)

  1. from rest_framework import serializers
  2. from users.models import UserInfo
  3.  
  4. class UserInfoSerializer(serializers.Serializer):
  5. name = serializers.CharField(min_length=3,max_length=20) # 显示普通字段
  6. ut = serializers.CharField(source='ut.type_name',required=False) # 显示一对多字段名称
  7. gp = serializers.SerializerMethodField(read_only=True) # 自定义显示(显示多对多)
  8. xxx = serializers.CharField(source='name',required=False) # 也可以自定义显示字段名称
  9. ut_id = serializers.IntegerField(write_only=True) # 一对多关联字段定义(外键约束)
  10.  
  11. '''PrimaryKeyRelatedField和StringRelatedField:可以用对 一对多 和 多对多 关联对象序列化'''
  12. # gp = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
  13. # gp = serializers.StringRelatedField(read_only=True,many=True)
  14.  
  15. class Meta:
  16. model = UserInfo
  17.  
  18. # 自定义显示 多对多 字段
  19. def get_gp(self,row):
  20. '''row: 传过来的正是 UserInfo表的对象'''
  21. gp_obj_list = row.gp.all().values('id','group') # 获取用户所有组
  22. return gp_obj_list

   2)序列化(反向查找)

  1. ''' 一对多序列化(反向查找)'''
  2. class UserTypeSerializer(serializers.Serializer):
  3. type_name = serializers.CharField()
  4. # 法1一对多关联对象序列化:此字段将被序列化为关联对象的主键
  5. userinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
  6.  
  7. # 法2一对多关联对象序列化:此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值)
  8. # userinfo_set = serializers.StringRelatedField(read_only=True,many=True)
  9. # 法3一对多关联对象序列化:使用关联对象的序列化器
  10. # userinfo_set = UserInfoSerializer(many=True)

 3)视图函数中使用序列化

  1. class UserInfoViewSet(APIView):
  2. def get(self, request, *args, **kwargs):
  3. # 一对多、多对多查询都是一样的语法
  4. obj = users_model.UserInfo.objects.all()
  5. ser = serializers.UserInfoSerializer(instance=obj,many=True) # 关联数据多条
  6. # ser = serializers.UserInfoSerializer(instance=obj[0]) # 关联数据一条
  7. return Response(ser.data, status=200)

  

3、反序列化

    1)使用反序列化保存数据

  1. '''创建用户'''
  2. def post(self,request):
  3. ser = serializers.UserInfoSerializer(data=request.data)
  4. if ser.is_valid():
  5. ser.save()
  6. return Response(data=ser.data, status=201)
  7. return Response(data=ser.errors,status=400)

 2)反序列化定义创建和更新方法

  1. # 定义创建语法
  2. def create(self, validated_data):
  3. return UserInfo.objects.create(**validated_data)
  4.  
  5. # 定义更新方法
  6. def update(self, instance, validated_data):
  7. if validated_data.get('name'):
  8. instance.name = validated_data['name']
  9. if validated_data.get('ut_id'):
  10. instance.ut_id = validated_data['ut_id']
  11. instance.save()
  12. return instance
  13.  
  14. # 定义单一字段验证的方法
  15. def validate_name(self, value):
  16. if value == 'root':
  17. raise serializers.ValidationError('不能创建root管理员账号')
  18. return value
  19.  
  20. # 定义多字段验证方法
  21. def validate(self, attrs):
  22. if attrs['name'] == 'admin':
  23. raise serializers.ValidationError('不能创建admin用户')
  24. return attrs

  

4、序列化使用举例(serializers.ModelSerializer

      1. ModelSerializer本质是继承了Serielizer类添加了部分功能

      2. 在使用上ModelSerializer可以使用     fields = '__all__'     定义要显示的字段

  1. '''users/serializers/userinfo_serializers.py'''
  2.  
  3. from rest_framework import serializers
  4. from users.models import UserInfo
  5.  
  6. class UserInfoSerializer(serializers.ModelSerializer):
  7. # name = serializers.CharField() # 显示普通字段
  8. ut = serializers.CharField(source='ut.type_name') # 显示一对多字段
  9. gp = serializers.SerializerMethodField() # 自定义显示(显示多对多)
  10. xxx = serializers.CharField(source='name') # 也可以自定义显示字段名称
  11.  
  12. class Meta:
  13. model = UserInfo
  14. # fields = "__all__"
  15. fields = ["name",'ut','gp','xxx'] # 定义显示那些字段
  16.  
  17. def get_gp(self,row):
  18. '''row: 传过来的正是 UserInfo表的对象'''
  19. gp_obj_list = row.gp.all() # 获取用户所有组
  20. ret = []
  21. for item in gp_obj_list:
  22. ret.append({'id':item.id,'gp':item.group})
  23. return ret
  24.  
  25. serializers.ModelSerializer使用

5、使用serializers.ModelSerializer 进行数据验证

  1. from rest_framework.views import APIView
  2. from users.serializers.userinfo_serializers import UserInfoSerializer
  3. from users.models import UserInfo
  4.  
  5. class UserInfoViewSet(APIView):
  6. def get(self, request, *args, **kwargs):
  7. obj = UserInfo.objects.all()
  8. ser = UserInfoSerializer(instance=obj,many=True)
  9. ret = json.dumps(ser.data,ensure_ascii=False)
  10. return HttpResponse(ret)
  11.  
  12. def post(self, request, *args, **kwargs):
  13. ser = UserInfoSerializer(data=request.data) # 验证,对请求发来的数据进行验证
  14. if ser.is_valid():
  15. print(ser.validated_data) # post请求数据字典
  16. else:
  17. print(ser.errors) # form验证错误信息
  18. return HttpResponse(json.dumps({'status':True}))
  19.  
  20. users/views.py

  

  1. '''users/serializers/userinfo_serializers.py'''
  2.  
  3. from rest_framework import serializers
  4. from django.core.exceptions import ValidationError
  5. from users.models import UserInfo
  6.  
  7. class UserInfoSerializer(serializers.ModelSerializer):
  8. name = serializers.CharField(min_length=10, error_messages={'required': '该字段必填'}) # 显示普通字段
  9. ut = serializers.CharField(source='ut.type_name',required=False) # 显示一对多字段
  10. gp = serializers.SerializerMethodField(required=False) # 自定义显示(显示多对多)
  11. xxx = serializers.CharField(source='name', required=False) # 也可以自定义显示字段名称
  12.  
  13. class Meta:
  14. model = UserInfo
  15. # fields = "__all__"
  16. fields = ["name",'ut','gp','xxx'] # 定义显示那些字段
  17.  
  18. # 局部钩子:
  19. def validate_name(self, value): # value 是name字段提交的值
  20. if value.startswith('sb'): # 不能以sb开头
  21. raise ValidationError('不能以sb开头')
  22. else:
  23. return value
  24.  
  25. # 全局钩子找到了
  26. def validate(self, value): # value是所有校验通过数据的字典
  27. name = value.get('name')
  28. if False:
  29. raise ValidationError('全局钩子引发异常')
  30. return value
  31.  
  32. users/serializers/userinfo_serializers.py
  1. '''1、ser.is_valid()'''
  2. # 验证post请求中数据是否合法
  3.  
  4. '''2、全局校验钩子'''
  5. def validate(self, value): # value是所有校验通过数据的字典
  6.  
  7. '''3、局部钩子'''
  8. def validate_name(self, value): # value 是name字段提交的值

1、分页中基本语法

  1. '''1、实例化一个Paginator对象'''
  2. paginator = Paginator(objs, page_size) # paginator对象
  3.  
  4. '''2、获取总数量&总页数'''
  5. total_count = paginator.count # 总数量
  6. total = paginator.num_pages # 总页数
  7.  
  8. '''3、使用objs对象获取指定页数内容'''
  9. objs = paginator.page(page)
  10.  
  11. '''4、对分页后的数据进行序列化操作'''
  12. serializer = Serializer(objs, many=True) # 序列化操作

  

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. from django.conf import settings
  4. from rest_framework import status
  5. from django.core.paginator import EmptyPage, Paginator, PageNotAnInteger
  6. from rest_framework.views import Response
  7.  
  8. def Paginators(objs, request, Serializer):
  9. """
  10. objs : 实体对象, queryset
  11. request : 请求对象
  12. Serializer : 对应实体对象的类
  13. page_size : 每页显示多少条数据
  14. page : 显示第几页数据
  15. total_count :总共有多少条数据
  16. total :总页数
  17. """
  18. try:
  19. page_size = int(request.GET.get('page_size', settings.REST_FRAMEWORK['PAGE_SIZE']))
  20. page = int(request.GET.get('page', 1))
  21. except (TypeError, ValueError):
  22. return Response(status=400)
  23.  
  24. paginator = Paginator(objs, page_size) # paginator对象
  25. total_count = paginator.count
  26. total = paginator.num_pages # 总页数
  27. try:
  28. objs = paginator.page(page)
  29. except PageNotAnInteger:
  30. objs = paginator.page(1)
  31. except EmptyPage:
  32. objs = paginator.page(paginator.num_pages)
  33. serializer = Serializer(objs, many=True) # 序列化操作
  34. return Response(
  35. data={
  36. 'detail': serializer.data,
  37. 'page': page,
  38. 'page_size': page_size,
  39. 'total': total,
  40. 'total_count': total_count
  41. }
  42. )
  43.  
  44. common/utils/api_paginator.py 自定义分页模块
  1. # 分页
  2. REST_FRAMEWORK = {
  3. # 全局分页
  4. 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
  5. # 关闭api root页面展示
  6. 'DEFAULT_RENDERER_CLASSES': (
  7. 'rest_framework.renderers.JSONRenderer',
  8. ),
  9. 'UNICODE_JSON': False,
  10. # 自定义异常处理
  11. 'EXCEPTION_HANDLER': (
  12. 'common.utils.custom_exception_handler'
  13. ),
  14. 'PAGE_SIZE': 10
  15. }
  16.  
  17. settings.py
  1. '''users/serializers/userinfo_serializers.py'''
  2.  
  3. from rest_framework import serializers
  4. from users.models import UserInfo
  5.  
  6. class UserInfoSerializer(serializers.Serializer):
  7. name = serializers.CharField() # 显示普通字段
  8. ut = serializers.CharField(source='ut.type_name') # 显示一对多字段
  9. gp = serializers.SerializerMethodField() # 自定义显示(显示多对多)
  10. xxx = serializers.CharField(source='name') # 也可以自定义显示字段名称
  11.  
  12. class Meta:
  13. model = UserInfo
  14.  
  15. def get_gp(self,row):
  16. '''row: 传过来的正是 UserInfo表的对象'''
  17. gp_obj_list = row.gp.all() # 获取用户所有组
  18. ret = []
  19. for item in gp_obj_list:
  20. ret.append({'id':item.id,'gp':item.group})
  21. return ret
  22.  
  23. users/serializers/userinfo_serializer.py

  

  1. ''' users/views.py'''
  2.  
  3. from rest_framework.views import APIView
  4. from rest_framework.views import Response
  5. from users.serializers.userinfo_serializers import UserInfoSerializer
  6. from users.models import UserInfo
  7. from common.utils.api_paginator import Paginators
  8.  
  9. class UserInfoViewSet(APIView):
  10. queryset = UserInfo.objects.all().order_by('id')
  11. serializer_class = UserInfoSerializer
  12.  
  13. def get(self, request, *args, **kwargs):
  14. self.queryset = self.queryset.all()
  15. ret = Paginators(self.queryset, request, self.serializer_class)
  16. print(json.dumps(ret.data)) # ret.data 返回的是最终查询的json数据
  17. return Response(ret.data)
  18.  
  19. # http://127.0.0.1:8000/users/info/?page_size=1
  20. '''
  21. {
  22. "detail": [
  23. {
  24. "name": "zhangsan",
  25. "ut": "学生",
  26. "gp": [
  27. {
  28. "id": 1,
  29. "gp": "group01"
  30. },
  31. {
  32. "id": 2,
  33. "gp": "group02"
  34. }
  35. ],
  36. "xxx": "zhangsan"
  37. }
  38. ],
  39. "page": 1,
  40. "page_size": 1,
  41. "total": 3,
  42. "total_count": 3
  43. }
  44. '''
  45.  
  46. users/views.py

  

 

  

 

ser 序列化的使用的更多相关文章

  1. 一: DRF web应用框架基础,及序列化器的使用

    ---恢复内容开始--- 一: web 应用模式(有两种) 1: 前后端不分离(前端从后端直接获取数据) 2: 前后端分离 二: api 接口 原因一: 为了在团队内部形成共识.防止个人习惯差异引起的 ...

  2. 066.Python框架DRF之序列化器Serializer

    一 序列化器-Serializer 作用: 1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 2. 反序列化,把客户端发送过来的数据,经过request以后变成 ...

  3. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  4. IO流

    流的概念和作用 学习JavaIO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特 ...

  5. io流操作大全

    JAVA 中的IO流 一.流的概念        流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部 ...

  6. javaIO整理

    写在前面:本文章基本覆盖了java IO的全部内容,java新IO没有涉及,因为我想和这个分开,以突出那个的重要性,新IO哪一篇文章还没有开始写,估计很快就能和大家见面.照旧,文章依旧以例子为主,因为 ...

  7. java中的IO整理

    写在前面:本文章基本覆盖了java IO的全部内容,java新IO没有涉及,因为我想和这个分开,以突出那个的重要性,新IO哪一篇文章还没有开始写,估计很快就能和大家见面.照旧,文章依旧以例子为主,因为 ...

  8. Java IO流详尽解析

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  9. Java开发之File类

    File类 File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹. File类保存文件或目录的各种元数据信息,包括文件名.文件长度.最后修改时间.是否可读.获取当 ...

随机推荐

  1. SpringBoot系列——MyBatis-Plus整合封装

    前言 MyBatis-Plus是一款MyBatis的增强工具(简称MP),为简化开发.提高效率,但我们并没有直接使用MP的CRUD接口,而是在原来的基础上封装一层通用代码,单表继承我们的通用代码,实现 ...

  2. mybatis逆向工程介绍

    项目的model一旦多了起来,复杂了起来,我们很自然的想到使用mybatis的逆向工程来生成相应的pojo和mapper,能节省很多精力. MyBatis Generator(MBG)是 MyBati ...

  3. 专为seo新手准备的百度分享工具教程

    http://www.wocaoseo.com/thread-178-1-1.html 百度分享工具是目前seo站长最为常用的工具之一,主要用来让用户分享来提高网站的流量,同时他也有很多实际有效的方式 ...

  4. 4300 字Python列表使用总结,用心!

    今天列表专题的目录如下: 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这 ...

  5. 合并模拟器和真机的静态库动态库aggregate

    创建Aggregate的target 在Build Phases 添加Run Script,内容为 scriptFile=${SRCROOT}/universalA.shsh ${scriptFile ...

  6. [PyTorch 学习笔记] 5.1 TensorBoard 介绍

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson5/tensorboard_methods.py http ...

  7. P2414 [NOI2011]阿狸的打字机 AC自动机

    题意 给定n个模式串,有m个询问,每次询问第X个模式串在第Y个模中出现了多少次 解题思路 以fail树相反的方向建一棵树T,问题转化为X的子树中有多少个y的终止节点.跑出T的dfs序,X的子树就可以表 ...

  8. (高难度SQL)从产品表中找出相同前缀 (都云作者痴 谁解其中味)

    --期盼值 找出AA,3;PDST,3;QPL-,3;TP-,2; --基本表 create table tb_product( id number(9,0) primary key, name nv ...

  9. ZT:如果有来生,要做一棵树

    出处:https://zhidao.baidu.com/question/393644025.html 原以为是三毛所作,想不到还有争议. 如果有来生,要做一棵树, 站成永恒.没有悲欢的姿势, 一半在 ...

  10. Java得到指定日期的时间

    //得到指定日期(几天前/几天后)整数往后推,负数往前移动private Date getAppointDay(int num) throws ParseException { DateFormat ...