Django Rest framework序列化流程


目錄

一 什么是序列化
二 Django REST framework配置流程之Serializer
三 Django REST framework配置流程之ModelSerializer

一 什么是序列化

序列化模型與序列化關系模型
序列化模型,顧名思義,即對 models 里的數據模型作序列化。
而序列化關系模型則是對 models 里數據模型中帶有關系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化。
Django Rest Framework 提供了靈活的序列化關系模型,讓開發者可以自由定制序列化數據模型。

二 Django REST framework配置流程之Serializer

1、GET請求

  1. 寫一個序列化的類,這個類需要繼承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")
  1. 視圖函數的配置
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)
  1. 啟動項目訪問url,可以看到多對多字段只能顯示object

  2. 處理多對多字段的顯示
    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請求

  1. 數據驗證配置
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'), ]
  1. 在視圖函數里面寫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 = 2

2、自定義簡單字段實例配置

class UserInfoSerializer(serializers.ModelSerializer):
    # 可以通過serializers自定義字段
    xxx = serializers.CharField(source="name")
    class Meta:
        # model表
        model = models.UserInfo
        fields = '__all__'
        # fields = []  # 可以指定字段
        # 遍歷的深度
        depth = 2

3、基於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'),
]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM