目录
一 什么是序列化
二 Django REST framework配置流程之Serializer
三 Django REST framework配置流程之ModelSerializer
一 什么是序列化
序列化模型与序列化关系模型
序列化模型,顾名思义,即对 models 里的数据模型作序列化。
而序列化关系模型则是对 models 里数据模型中带有关系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化。
Django Rest Framework 提供了灵活的序列化关系模型,让开发者可以自由定制序列化数据模型。
二 Django REST framework配置流程之Serializer
1、GET请求
- 写一个序列化的类,这个类需要继承Serializer,一对多字段可以直接通过指定source字段来查找。如果是多对多的字段则需要做进一步处理才能在页面显示 - from rest_framework import serializers class UserInfoSerializer(serializers.Serializer): name = serializers.CharField(max_length=32) pwd = serializers.CharField(max_length=128) # 多对多跨表查询,查询到的是所有对象 been_city = serializers.CharField(source="been_city.all")
- 视图函数的配置 - class IndexView(APIView): def get(self, request): user_list = models.UserInfo.objects.all() # 获取到的是一个serializer对象,如果user_list是一个对象则不需要many=True ser = UserInfoSe rializer(instance=user_list, many=True) # print(ser) """ UserInfoSerializer(instance=<QuerySet []>, many=True): name = CharField(max_length=32) pwd = CharField(max_length=128) been_city = CharField(source='city.name') """ # ser.data是一个有序字典 return Response(ser.data)
- 启动项目访问url,可以看到多对多字段只能显示object 
  
- 处理多对多字段的显示
a) 方法一:重写CharField的to_representation方法,这个方法就是用来显示最终数据的
class MyCharField(serializers.CharField):
    def to_representation(self, value):
        # value就是QuerySet对象列表
        data_list = []
        for row in value:
            data_list.append({'name': row.name, 'province': row.province.name})
        return data_list
class UserInfoSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    pwd = serializers.CharField(max_length=128)
    # 通过自定义的MyCharField中的to_representation处理多对多字段的QuerySet对象
    been_city = MyCharField(source="been_city.all")b) 方法二:通过ListField方法
class MyCharField(serializers.CharField):
    def to_representation(self, value):
        # value就是每个QuerySet对象
        return {‘id’:value.pk, "name": value.name, "province":value.province.name}
class UserInfoSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    pwd = serializers.CharField(max_length=128)
    # 通过自定义的MyCharField中的to_representation处理多对多字段的QuerySet对象
    been_city = serializers.ListField(child=MyCharField(),source="been_city.all")c) 方法三:通过定义serializers.SerializerMethodField()可以生成对象列表,然后通过get方法,可以接收对象,并返回需要的json数据
class UserInfoSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=32)
    pwd = serializers.CharField(max_length=128)
    # 多对多跨表查询,查询到的是所有city对象
    # been_city = serializers.CharField(source="been_city.all")
    # print(been_city)
    # provinse = serializers.CharField(source="been_city.province")
    been_city = serializers.SerializerMethodField()  # 获取到的是UserInfo对象
    def get_been_city(self, obj):
        print(obj)
        city_list = obj.been_city.all()
        data_list = []
        for row in city_list:
            data_list.append({'name': row.name, 'province': row.province.name})
        return data_list源码浏览

访问URL效果

2、POST请求
- 数据验证配置 - class PasswordValidator(object): def __init__(self, base): self.base = base def __call__(self, value): if value != self.base: message = '用户输入的值必须是 %s.' % self.base raise serializers.ValidationError(message) class UserInfoSerializer(serializers.Serializer): name = serializers.CharField(max_length=32) pwd = serializers.CharField(max_length=128, error_messages={'required': '密码不能为空'}, validators=[PasswordValidator('666'), ]
- 在视图函数里面写post方法,并且根据用户发送的数据做序列化操作 - class IndexView(APIView): def post(self, request): # 接收POST数据 data = request.POST # 序列化数据,基于Serializer和ModelSerializer都可以 # ser = UserInfoSerializer(data=data, many=True) ser = UserInfoModelSerializer(data=data, many=True) # 判断数据是否符合要求 if ser.is_valid(): print(ser.validated_data) # OrderedDict([('name', 'jack'), ('pwd', '123')]) # models.UserInfo.objects.create(**ser.validated_data) return Response('添加成功') return Response("POST测试")
三 Django REST framework配置流程之ModelSerializer
1、基础配置实例
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        # model表
        model = models.UserInfo
        fields = '__all__'
        # fields = []  # 可以指定字段
        # 遍历的深度
        depth = 22、自定义简单字段实例配置
class UserInfoSerializer(serializers.ModelSerializer):
    # 可以通过serializers自定义字段
    xxx = serializers.CharField(source="name")
    class Meta:
        # model表
        model = models.UserInfo
        fields = '__all__'
        # fields = []  # 可以指定字段
        # 遍历的深度
        depth = 23、基于HyperlinkedRelatedField实现url的实例配置
class UserInfoSerializer(serializers.ModelSerializer):
    #view_name是用来反向生成url的
    xxx = serializers.HyperlinkedRelatedField(view_name="detail")
    class Meta:
        # model表
        model = models.UserInfo
        fields = '__all__'
        # fields = []  # 可以指定字段
        # 遍历的深度
        depth = 2# urls.py配置
urlpatterns = [
    # 由于在class HyperlinkedRelatedField(RelatedField)中定义了lookup_field="pk",
    # 所以在url中必须使用pk字段
    url(r'xxx/(?P<pk>\d+)', views.UserView.as_view(), name='detail'),
]# UserView配置
class UserView(APIView):
    def get(self, request):
        user_list = models.UserInfo.objects.all()
        ser = UserSerializer(instance=user_list, many=True, content={"request":request})
        return Response(ser.data)4、全部生成url(serializers.HyperlinkedModelSerializer会把每个字段都成条url,默认的view_name是userinfo-detail
class ModelUserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = '__all__'  # 生成url
        # fields = ['name', 'pwd']  # 只显示字段
        # exclude = ['role',]# urls.py配置
urlpatterns = [
    url(r'^xxx/(?P<pk>\d+)', view.UserView.as_view(), name='userinfo-detail'),
    url(r'^xxx/(?P<pk>\d+)', view.UserView.as_view(), name='group-detail'),
    url(r'^xxx/(?P<pk>\d+)', view.UserView.as_view(), name='role-detail'),
]