django中restframework中的序列化

模型類:

class UserInfo(models.Model):
    user_type_choice = (
        (1, '普通用戶'),
        (2, 'VIP'),
        (3, 'SVIP'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)
    group = models.ForeignKey('UserGroup', on_delete=models.CASCADE)
    roles = models.ManyToManyField('Role')

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

class UserGroup(models.Model):
    title = models.CharField(max_length=32)

總結:

     1. 寫類繼承ModelSerializer或者Serializer

     2. 字段:自定義字段,通過函數自定義字段

一。使用ModelSerializer序列化

   1. 獲取所有字段(關聯的字段或多選的字段只顯示數字)

class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"

  2. 獲取局部的字段(關聯的字段或多選的字段只顯示數字)

class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username']

 3. 自定義字段,並添加進去(這裏可以解決choice字段帶來的只顯示數字的問題和多對一的問題)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    ooo = serializers.CharField(source='get_user_type_display') # 自定義字段,解決choice問題
    group_title = serializers.CharField(source='group.title')  # 自定義字段,關聯group的title字段
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username', 'ooo']      # 這裏要加自定義的字段名稱

 4. 利用函數自定義字段(可以解決一對多的問題,還有其他自定義問題)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    ooo = serializers.CharField(source='get_user_type_display') #自定義字段
    rls = serializers.SerializerMethodField()
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username', 'ooo', 'rls']      # 這裏要加自定義的字段名稱

    def get_rls(self, row):                 # get開頭,字段名結尾,傳入row(這個是每一行)
        role_obj_list = row.roles.all()     # 角色對象
        ret = []                            # 要返回的值
        for item in role_obj_list:
            ret.append({'id':item.id, 'title':item.title})
        return ret

 結果:

 5. (重要)使用depth來獲取表的深度,深度是爲1時是當前表ForeignKey或ManyToManyField關聯的下一層的所有數據,深度爲2時是當前表關聯的表的所有ForeignKey或ManyToManyField的所有數據。(當然也可以和前面的情況一起使用)

from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = '__all__'      # 這裏要加自定義的字段名稱
        depth = 1  #0 ~ 10      # 深度爲1,獲取ForeignKey或ManyToManyField下的所有數據

 結果:

二。改變要顯示的字段的名稱(不是改變值),下面使用的是Serializer類,是ModelSerializer的父類

  1. 自定義一個序列化類,裏面寫要序列化的字段,如果不加source參數,則類的變量名就是字段的名稱。如果加了,則類的變量名是顯示的序列化的字段名稱。

from rest_framework import serializers
class UserInfoSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='user_type')   # source是顯示數據庫的那個字段,
    username = serializers.CharField()              # 用變量指定也可以,用source指定也可以,優先是變量指定,然後是source(這個可以變字段的名稱)
    password = serializers.CharField()

class Ser(APIView):
    authentication_classes = []
    permission_classes = []

    def get(self, request, *args, **kwargs):
        users = models.UserInfo.objects.all()
        ser = UserInfoSerializer(instance=users, many=True)

        ret = json.dumps(ser.data, ensure_ascii=False)
        return HttpResponse(ret)

 2. 顯示如圖

   

3. xxx,也就是user_type顯示的是數字而不是文字(普通用戶,vip等),那麼要顯示的話,就要讓source如下改變

    source = ‘get_字段名稱_display'        這裏字段是user_type,所以就是 get_user_type_display,其他的不變

from rest_framework import serializers
class UserInfoSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='get_user_type_display')   # source是顯示數據庫的那個字段,
    ooo = serializers.CharField(source='user_type')    #有choice的解決方案
    username = serializers.CharField()              # 用變量指定也可以,用source指定也可以,優先是變量指定,然後是source(這個可以變字段的名稱)
    password = serializers.CharField()

4, 顯示如圖

三。獲取關聯的字段:

1. 這個是多對一的解決方案,多的一方獲取一的一方的關聯字段,只要在source裏面寫入外鍵名稱,再通過外面名稱關聯其他表格

class UserInfoSerializer(serializers.Serializer):
    password = serializers.CharField() 
    # 有ForeignKey的解決方案
    gp = serializers.CharField(source='group.title') # 多的一方引用一的一方的關聯字段

結果:

 

2. 這個是一對多的解決方案,一的一方獲取多的一方的關聯字段,定義一個函數,這個函數以get開頭,以字段名稱結尾,然後傳入每一行的數據row,然後再裏面處理每一行的數據再返回。

class UserInfoSerializer(serializers.Serializer):
    username = serializers.CharField()              # 用變量指定也可以,用source指定也可以,優先是變量指定,然後是source(這個可以變字段的名稱)
    password = serializers.CharField()
    gp = serializers.CharField(source='group.title') # 多的一方引用一的一方的關聯字段
    rls = serializers.SerializerMethodField()

    def get_rls(self, row):             # get開頭,字段名結尾,傳入row(這個是每一行)
        role_obj_list = row.roles.all() # 角色對象
        ret = []                        # 要返回的值
        for item in role_obj_list:
            ret.append({'id':item.id, 'title':item.title})
        return ret

結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章