模型類:
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
結果: