经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
django框架之drf:04、序列化器常用字段及参数,序列化器高级用法之source、定制字段数据的两种方法、多表关联反序列化的保存、ModelSerializer的使用
来源:cnblogs  作者:kngk  时间:2023/2/3 8:42:34  对本文有异议

Django框架之drf

一、序列化器常用字段及参数

  1. # 序列化类---》字段类 CharField,除此之外还有哪些其他的
  2. # 序列化类---》字段类,字段类上,传属性的 ,序列化类上,也可以写属性
  3. models.CharField(max_length=32)

1、常用字段

字段 字段构造方式
BooleanField BooleanField()
NullBooleanField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
SlugField SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
URLField URLField(max_length=200, min_length=None, allow_blank=False)
UUIDField UUIDField(format=’hex_verbose’) format: 1) ‘hex_verbose’ 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) ‘hex’ 如 “5ce0e9a55ffa654bcee01238041fb31a” 3)‘int’ - 如: “123456789012312313134124512351145145114” 4)‘urn’ 如: “urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a”
IPAddressField IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
IntegerField IntegerField(max_value=None, min_value=None)
FloatField FloatField(max_value=None, min_value=None)
DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
DurationField DurationField()
ChoiceField ChoiceField(choices) choices与Django的用法相同
MultipleChoiceField MultipleChoiceField(choices)
FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ListField ListField(child=, min_length=None, max_length=None)
DictField DictField(child=)

2、常用字段参数

选项参数

参数名 说明
max_length 最大长度
min_lenght 最小长度
allow_blank 是否允许为空
trim_whitespace 是否截断空白字符
max_value 最大值
min_value 最小值

通用参数

参数名称 说明
read_only 表明该字段仅用于序列化输出,默认False
write_only 表明该字段仅用于反序列化输入,默认False
required 表明该字段在反序列化时必须输入,默认True
default 反序列化时使用的默认值
allow_null 表明该字段是否允许传入None,默认False
validators 该字段使用的验证器
error_messages 包含错误编号与错误信息的字典
label 用于HTML展示API页面时,显示的字段名称
help_text 用于HTML展示API页面时,显示的字段帮助提示信息

3、字段参数针对性分类

  1. 选项参数:
  2. # CharField及其子类的(EmailField) ---》反序列化的校验,字段自己的规则
  3. max_length 最大长度
  4. min_lenght 最小长度
  5. allow_blank 是否允许为空
  6. trim_whitespace 是否截断空白字符
  7. # IntegerField
  8. max_value 最小值
  9. min_value 最大值
  10. # 所有字段类都有的
  11. required 表明该字段在反序列化时必须输入,默认True
  12. default 反序列化时使用的默认值
  13. allow_null 表明该字段是否允许传入None,默认False
  14. validators 该字段使用的验证器
  15. ----看一眼忘掉-----
  16. error_messages 包含错误编号与错误信息的字典
  17. label 用于HTML展示API页面时,显示的字段名称
  18. help_text 用于HTML展示API页面时,显示的字段帮助提示信息
  19. # 重点:
  20. read_only 表明该字段仅用于序列化输出,默认False
  21. write_only 表明该字段仅用于反序列化输入,默认False
  22. ## 反序列化校验执行流程
  23. -1 先执行字段自己的校验规则----》最大长度,最小长度,是否为空,是否必填,最小数字。。。。
  24. -2 validators=[方法,] ----》单独给这个字段加校验规则
  25. name=serializers.CharField(validators=[方法,])
  26. -3 局部钩子校验规则
  27. -4 全局钩子校验规则

二、序列化器高级用法之source

准备工作

  1. ### 创建关联表
  2. class Book(models.Model):
  3. name = models.CharField(max_length=32)
  4. price = models.CharField(max_length=32)
  5. publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
  6. authors = models.ManyToManyField(to='Author')
  7. class Publish(models.Model):
  8. name = models.CharField(max_length=32)
  9. addr = models.CharField(max_length=32)
  10. class Author(models.Model):
  11. name = models.CharField(max_length=32)
  12. phone = models.CharField(max_length=11)
  13. # 迁移,录入数据

1、定制字段名

? 在我们编写序列化器的时候,序列化类中的字段名字对应的是模型层下表名内对应的字段名,但有的时候我们需要确保数据的安全,并不想直接将真实的字段名返回给前端用户查看,这个时候我们就可以利用source参数来将返回给前端的字段名进行修改

source参数:可以指定序列化字段的名字

  1. class BookSerializer(serializers.Serializer):
  2. # 自有字段: 直接写字段名
  3. book_name = serializers.CharField(source='name')
  4. book_price = serializers.CharField(source='price')
  5. # 外键字段:多对多,字段名字修改了,但是数据内容没办法显示
  6. book_author = serializers.CharField(source='author.all')
  7. # 外键字段:一对多,可以显示
  8. book_publish = serializers.CharField(source='publish.name')

三、定制字段数据的两种的方法

定制关联字段的显示形式

  • 一对多:显示字典
  • 多对多:显示列表内套字典

1、在序列化器类中定制

使用:SerializerMethodField字段定制

  1. from rest_framework import serializers
  2. class BookSerializer(serializers.Serializer):
  3. # 自有字段
  4. book_name = serializers.CharField(source='name')
  5. book_price = serializers.CharField(source='price')
  6. # 外键字段
  7. book_publish = serializers.SerializerMethodField()
  8. def get_book_publish(self, obj):
  9. return {'name': obj.publish.name, 'address': obj.publish.address}
  10. book_author = serializers.SerializerMethodField()
  11. def get_book_author(self, obj):
  12. book_data_list = [{'name': author_obj.name, 'phone': author_obj.phone} for author_obj in obj.author.all()]
  13. return book_data_list

2、在模型表中定制

在models.py文件下表的类中定制

  1. ### models.py 表的类中编写方法
  2. from django.db import models
  3. class Book(models.Model):
  4. name = models.CharField(max_length=32)
  5. price = models.CharField(max_length=32)
  6. publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
  7. def publish_detail(self):
  8. return {'name': self.publish.name, 'phone': self.publish.address}
  9. author = models.ManyToManyField(to='Author')
  10. def author_list(self):
  11. book_data_list = [{'name': author_obj.name, 'phone': author_obj.phone} for author_obj in self.author.all()]
  12. return book_data_list
  13. ### Serialiaer.py 序列化器中编写方法
  14. from rest_framework import serializers
  15. class BookSerializer(serializers.Serializer):
  16. # 自有字段
  17. book_name = serializers.CharField(source='name')
  18. book_price = serializers.CharField(source='price')
  19. # 外键字段
  20. publish_detail = serializers.DictField()
  21. author_list = serializers.ListField()

四、多表关联反序列化保存

前端传入数据格式

  1. # 前端传入的数据格式:
  2. {'name':'红楼梦','price':19,'publish':1,'authors':[1,2]}

1、新增接口

  1. ### view.py 视图类
  2. class BookView(APIView):
  3. # 新增
  4. def post(self, request):
  5. ser_obj = BookSerializer(data=request.data)
  6. if ser_obj.is_valid():
  7. ser_obj.save()
  8. return Response({'code': 100, 'msg': '新增图书成功', 'result': ser_obj.data})
  9. return Response({'code': 101, 'msg': ser_obj.errors})
  10. ### serializer.py 序列化器类
  11. class BookSerializer(serializers.Serializer):
  12. # 自有字段
  13. name = serializers.CharField()
  14. price = serializers.CharField()
  15. # 设置write_only参数,只作为反序列化使用
  16. publish = serializers.CharField(write_only=True)
  17. author = serializers.ListField(write_only=True)
  18. # 外键字段,设置read_only参数,只作为序列化使用
  19. publish_detail = serializers.DictField(read_only=True)
  20. author_list = serializers.ListField(read_only=True)
  21. # 新增
  22. def create(self, validated_data):
  23. # 使用反序列化后的数据创建新的图书
  24. new_book_obj = Book.objects.create(name=validated_data.get('name'), price=validated_data.get('price') , publish_id=validated_data.get('publish'))
  25. # 作者外键字段同步更新
  26. new_book_obj.author.add(*validated_data.get('author'))
  27. return new_book_obj

2、修改接口

  1. ### view.py 视图类:
  2. class BookDetailView(APIView):
  3. # 修改
  4. def put(self, request, pk):
  5. # 获取指定图书
  6. target_book_obj = Book.objects.filter(pk=pk).first()
  7. if target_book_obj:
  8. ser_obj = BookSerializer(data=request.data, instance=target_book_obj)
  9. if ser_obj.is_valid():
  10. ser_obj.save()
  11. return Response(ser_obj.data)
  12. return Response({'code': 101, 'msg': ser_obj.errors})
  13. return Response({'code': 101, 'msg': '图书不存在'})
  14. ### serializer.py 序列化器类:
  15. class BookSerializer(serializers.Serializer):
  16. # 自有字段
  17. name = serializers.CharField()
  18. price = serializers.CharField()
  19. # 设置write_only参数,只作为反序列化使用
  20. publish = serializers.CharField(write_only=True)
  21. author = serializers.ListField(write_only=True)
  22. # 外键字段,设置read_only参数,只作为序列化使用
  23. publish_detail = serializers.DictField(read_only=True)
  24. author_list = serializers.ListField(read_only=True)
  25. # 修改
  26. def update(self, instance, validated_data):
  27. instance.name = validated_data.get('name')
  28. instance.price = validated_data.get('price')
  29. instance.publish_id = validated_data.get('publish')
  30. instance.author.clear()
  31. instance.author.add(*validated_data.get('author'))
  32. instance.save()
  33. return instance

五、反序列化字段校验(总结)

反序列化字段校验(共四层)

  1. 1、自有字段:可直接在字段后方参数填写校验规则
  2. 2validators参数:同样在字段后方参数内填写,通过绑定函数体代码进行校验
  3. 3、局部钩子
  4. 4、全局钩子

六、ModelSerializer的使用

ModelSerializer继承自Serializer,帮助我们完成了很多操作

特点

  • 和表模型强关联
  • 帮助我们完成很多请求,不用再create和update

使用方法

  1. class BookSerializer(serializers.ModelSerializer):
  2. # 控制字段的校验
  3. class Meta:
  4. # 与表进行关联
  5. model = Book
  6. # 填写__all__默认序列全部字段,如果Meta写了__all__ ,就相当于,复制了表模型中的所有字段,放在了这里,做了个映射
  7. # fields = '__all__'
  8. # 填写列表是校验部分字段
  9. fields = ['name', 'price', 'publish', 'author', 'publish_detail', 'author_list']
  10. # 给字段添加校验或限制
  11. extra_kwargs = {
  12. 'name': {'max_length': 3},
  13. 'price': {'min_length': 2},
  14. 'publish': {'write_only': True},
  15. 'author': {'write_only': True},
  16. 'author_list': {'read_only': True},
  17. 'publish_detail': {'read_only': True},
  18. }
  19. # 假如Meta类中已经对字段进行校验,任然可以在外部(内部的校验失效)重写校验,优先级高于Meta内部的校验
  20. name = serializers.CharField(max_length=8)
  21. # 同理,针对外键字段的方法也可以在外部重写
  22. # book_publish = serializers.SerializerMethodField()
  23. #
  24. # def get_book_publish(self, obj):
  25. # return {'name': obj.publish.name, 'address': obj.publish.address}
  26. #
  27. # book_author = serializers.SerializerMethodField()
  28. #
  29. # def get_book_author(self, obj):
  30. # book_data_list = [{'name': author_obj.name, 'phone': author_obj.phone} for author_obj in obj.author.all()]
  31. # return book_data_list
  32. # 钩子函数(不会影响,正常编写即可)
  33. def validate_name(self, name):
  34. if name.startswith('sb'):
  35. raise ValidationError('不能sb')
  36. else:
  37. return name

原文链接:https://www.cnblogs.com/kangssssh/p/17087423.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号