Django_rest_framework_Serializer

 序列化Serializer

序列化用于对用户请求数据进行验证和数据进行序列化(为了解决queryset序列化问题)。

那什么是序列化呢?序列化就是把对象转换成字符串,反序列化就是把字符串转换成对象

 models部分

models.py

from django.db import models

# Create your models here.
class Group(models.Model):
    title = models.CharField(max_length=32)
    mu = models.ForeignKey(to='Menu',default=1)

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)
    group = models.ForeignKey(to="Group")

    roles = models.ManyToManyField(to="Role")
class Menu(models.Model):
    name = models.CharField(max_length=21)

class Role(models.Model):
    name = models.CharField(max_length=32)

基本操作

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from app03 import models
class UsersSerializer(serializers.Serializer):
    name = serializers.CharField()  #字段名字
    pwd = serializers.CharField()

class UserView(APIView):
    def get(self,request,*args,**kwargs):
        # 方式一实现
        # user_list = models.UserInfo.objects.values('name','pwd','group__mu','group__title')
        # print(type(user_list))
        # return Response(user_list)

        # 方式二之多对象
        # user_list = models.UserInfo.objects.all()  #直接这样查会报错,借助他提供的系列化
        # ser = UsersSerializer(instance=user_list,many=True) #可允许多个
        # # print(type(ser))  #<class 'rest_framework.serializers.ListSerializer'>
        # print(ser.data)  #返回的是一个有序字典

        #方式三之单对象
        user = models.UserInfo.objects.all().first()
        ser = UsersSerializer(instance=user,many=False)

        return Response(ser.data)
views.py

跨表

x1 = serializers.CharField(source='group.mu.name') 
   如果你想跨表拿你任何需要的数据,都可以用上面的这种操作,内部做判断,如果可用内部就加括号调用了
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from app03 import models
class UsersSerializer(serializers.Serializer):
    name = serializers.CharField()  #字段名字
    pwd = serializers.CharField()
    # group = serializers.CharField()  #会显示对象
    # group_id = serializers.CharField()  #会显示id
    x1 = serializers.CharField(source='group.mu.name')
    roles = serializers.CharField(source='roles.all') #多对多关系的这样查出的是queryset对象

class UserView2(APIView):
    '''跨表操作'''
    def get(self,request,*args,**kwargs):

        user = models.UserInfo.objects.all()
        ser = UsersSerializer(instance=user,many=True)

        return Response(ser.data)
Views.py

复杂序列化

解决方案一

class MyCharField(serializers.CharField):

    def to_representation(self, value): ##打印的是所有的数据
        data_list = []
        for row in value:
            data_list.append(row.name)
        return data_list

class UsersSerializer(serializers.Serializer):
    name = serializers.CharField() # obj.name
    pwd = serializers.CharField()  # obj.pwd
    group_id = serializers.CharField() # obj.group_id
    xxxx = serializers.CharField(source="group.title") # obj.group.title
    x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
    # x2 = serializers.CharField(source="roles.all") #  多对多关系的这样查出的是queryset对象
    x2 = MyCharField(source="roles.all") # obj.mu.name
Views.py

解决方案二

class MyCharField(serializers.CharField):
    def to_representation(self, value):
        return {'id':value.pk, 'name':value.name}

class UsersSerializer(serializers.Serializer):
    name = serializers.CharField() # obj.name
    pwd = serializers.CharField()  # obj.pwd
    group_id = serializers.CharField() # obj.group_id
    xxxx = serializers.CharField(source="group.title") # obj.group.title
    x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
    # x2 = serializers.CharField(source="roles.all") # obj.mu.name
    x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name
Views.py

解决方案三(推荐使用)

class UsersSerializer(serializers.Serializer):
    name = serializers.CharField() # obj.name
    pwd = serializers.CharField()  # obj.pwd
    group_id = serializers.CharField() # obj.group_id
    xxxx = serializers.CharField(source="group.title") # obj.group.title
    x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
    # x2 = serializers.CharField(source="roles.all") # obj.mu.name
    # x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name
    x2 = serializers.SerializerMethodField()

    def get_x2(self,obj):  #get_字段名
        print(obj)   ##UserInfo object
        obj.roles.all()
        role_list = obj.roles.filter(id__gt=1)
        data_list = []
        for row in role_list:
            data_list.append({'pk':row.pk,'name':row.name})
        return data_list
    
Views.py

基于models

class UsersSerializer(serializers.ModelSerializer):
x1 = serializers.CharField(source='name')
group = serializers.HyperlinkedIdentityField(view_name='detail')
class Meta:
    
    model = models.UserInfo
    # fields = "__all__"
    fields = ['name','pwd','group','x1']  #自定义字段的时候注意要指定source,scource里面的数据必须是数据库有的数据
    depth = 1 #表示深度


class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        self.dispatch
        # 方式一:
        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
        # return Response(user_list)

        # 方式二之多对象
        user_list = models.UserInfo.objects.all()
        # [obj1,obj2,obj3]
        ser = UsersSerializer(instance=user_list,many=True)
        return Response(ser.data)
Views.py

生成url

class UsersSerializer(serializers.ModelSerializer):  #
    group = serializers.HyperlinkedIdentityField(view_name='detail')
    class Meta:
        model = models.UserInfo
        fields = "__all__"
        fields = ['name', 'pwd','group']
        depth = 1


class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        self.dispatch
        # 方式一:
        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
        # return Response(user_list)

        # 方式二之多对象
        user_list = models.UserInfo.objects.all()
        # [obj1,obj2,obj3]
        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
        return Response(ser.data)
views.py
from django.conf.urls import url,include
from django.contrib import admin
from app03 import views
urlpatterns = [

    url(r'^users4/', views.UserView4.as_view(), name='xxx'), #吧users4的group的值反向生成users5的url
    url(r'^users5/(?P<pk>.*)', views.UserView5.as_view(), name='detail'),  #必须叫pk
    # url(r'^users4/(?P<pk>.*)', views.UserView4.as_view(), name='detail'),
]
urls.py

全局生成url

class UsersSerializer(serializers.HyperlinkedModelSerializer): #继承他自动生成
    class Meta:
        model = models.UserInfo
        fields = "__all__"

        # fields = ['id','name','pwd']  

class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        self.dispatch
        # 方式一:
        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
        # return Response(user_list)

        # 方式二之多对象
        user_list = models.UserInfo.objects.all()
        # [obj1,obj2,obj3]
        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
        return Response(ser.data)
views.py

 

数据验证

自定义

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)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass

class UsersSerializer(serializers.Serializer):
        name = serializers.CharField(min_length=6)
        pwd = serializers.CharField(error_messages={'required': '密码不能为空'}, validators=[PasswordValidator('666')])
views.py

基于models

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)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass

class UsersSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"
        #自定义验证规则
        extra_kwargs = {
            'name': {'min_length': 6},
            'pwd': {'validators': [PasswordValidator(666), ]}
        }
views.py

使用

class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        self.dispatch
        # 方式一:
        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
        # return Response(user_list)

        # 方式二之多对象
        user_list = models.UserInfo.objects.all()
        # [obj1,obj2,obj3]
        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
        return Response(ser.data)

    def post(self,request,*args,**kwargs):
        ser = UsersSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
        else:
            print(ser.errors)
        return Response('...')
views.py

钩子函数

def validate_字段(self,validated_value):
       raise ValidationError(detail='xxxxxx')
       return validated_value
                        

 

参考or转发

http://www.cnblogs.com/haiyan123/p/8427997.html#lable3

posted @ 2018-09-11 22:26  fat39  阅读(295)  评论(0编辑  收藏  举报