DRF 序列化
Django REST framework序列化
Django REST framework(DRF)框架文档齐全,社区较稳定,而且由于它是基于Django这个十分全面的框架而设计开发的,能够让开发者根据自己的业务需要,使用极少的代码量快速的开发一套符合RESTful风格的API,并且还支持自动生成API文档。
Django REST framework(DRF)官网:http://www.django-rest-framework.org/
中文文档 https://q1mi.github.io/Django-REST-framework-documentation/
起步
-
安装
pip install djangorestframework
-
注册APP(不是必须)
-
INSTALLED_APPS = [ ..., 'rest_framework', ]
-
-
导入APIView
from rest_framewor.views import APIView
, CBV继承它 -
自己写一个序列化的工具类
BookSerializer
-
from rest_framework import serializers class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) title = serializers.CharField(max_length=32) pub_date = serializers.DateField() CHOICES = ((1, 'Python'), (2, 'Go'), (3, 'Linux')) category = serializers.ChoiceField(choices=CHOICES)
-
-
使用queryset数据实例化得到一个 序列化对象 --》 ser_obj
-
使用
from rest_framework.response import Response
restframework提供的
Respoinse`返回上一步的 ser_obj.data-
from rest_framework.views import APIView from rest_framework.response import Response from bms.serializer import BookSerializer from bms import models class BookListView(APIView): def get(self, request): """以JSON格式返回书籍的所有信息""" # 1. 查出所有书籍信息 queryset = models.Book.objects.all() # 2. 使用serizlizer序列化 ser_boj = BookSerializer(queryset, many=True) return Response(ser_boj.data)
-
序列化
Django ORM对象 ---> JSON格式的数据 序列化
JSON格式的数据 ----> Django ORM数据 反序列化
两个工具
from rest_framework.serializers import Serializer
from rest_framework.serializers import ModelSerializer
类比Django中的form组件
from作用
Django form -----》 HTML表单
HTML表单 ----》 ORM数据
参数
-
many=True
参数- 序列化对象时添加,可以序列化多个对象,原理实现在APIView的 __new__方法中,循环序列化对象
-
read_only=True
和write_only=True
read_only=True
,仅序列化用- ``write_only=True`,仅反序列化用
-
source
-
将用于填充字段的属性的名称
-
category = serializers.CharField(source='get_category_display', read_only=True)
-
-
require=False
- 校验的时候,该字段可以不填
校验
校验规则由序列化对象的is_valid()
触发
-
局部校验方法
def validate_title(self, attrs): """类似于Form中的校验钩子""" # attrs就是需要检验的这个字段的值 if '最' in attrs: raise serializers.ValidationError('非法字段') else: return attrs
-
全局校验方法
-
def validate(self, attrs): """全局校验钩子""" return attrs
-
-
自定义校验函数
-
# 类似于Form组建中的自定义校验规则 title = serializers.CharField(max_length=32, validators=[my_validator, ])
-
ModelSerializer
和model一对一绑定的序列化类
-
SerializerMethodField
字段:-
class BookModelSerializer(serializers.ModelSerializer): # SerializerMethodField 会自动去找 get_字段名 的方法执行 category_info = serializers.SerializerMethodField(read_only=True) publisher_info = serializers.SerializerMethodField(read_only=True) authors_info = serializers.SerializerMethodField(read_only=True) def get_category_info(self, book_obj): # book_obj ==》 当前被序列化的那个书籍对象 return book_obj.get_category_display() def get_publisher_info(self, obj): return PublisherSerializer(obj.publisher).data def get_authors_info(self, obj): return AuthorSerializer(obj.authors.all(), many=True).data class Meta: model = models.Book fields = '__all__' # exclude = [] # 排除某个字段 # depth = 1 # 所有有关系的字段都变成 read_only extra_kwargs = { # 每个字段的一些额外参数 'publisher': {'write_only': True}, 'authors': {'write_only': True}, 'category': {'write_only': True}, }
-
终极修改序列化 字段
如果单API需要一个字段,但在model 不存在,需要自自己加,且复杂,直接加到 to_repreentation
def to_representation(self, instance):
# 调用父类的同名方法把序列化的结果拿到
data = super().to_representation(instance)
# 针对序列化的结果做一些自定制操作
# 判断当前这个课程是否有永久有效的价格
price_obj = instance.price_policy.all().filter(valid_period=999).first()
if price_obj:
# 有永久有效的价格
data['has_price'] = True
data['price'] = price_obj.price
else:
# 没有永久有效的价格策略
data['has_price'] = False
return data