模型类:
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
结果: