drf组件中,为我们提供了两个序列化类
- Serializer
- ModelSerializer
1.Serializer
2.ModelSerializer
- 跟ModelForm一样,可以通过model参数来获取某一个数据模型的类(就是数据库的表名)
下面以ModelSerializer做一个代码示例
1.models.py文件代码示例
##这里我定义了3歌数据模型,3张表,用户表与角色表是多对多的关系,与部门表是ForeignKey的关系(外键约束)
from django.db import models
class UserInfo(models.Model):
'''用户表'''
username = models.CharField(max_length=16,verbose_name="用户名")
password = models.CharField(max_length=32,verbose_name="密码")
email = models.CharField(max_length=32,verbose_name="邮箱")
sex_choices = ((1,"男"),(2,"女"))
sex = models.IntegerField(verbose_name='性别',choices=sex_choices)
roles = models.ManyToManyField(verbose_name="角色",to="Role")
depart = models.ForeignKey(verbose_name="部门",to="Depart",on_delete=models.CASCADE,null=True,blank=True)
def __str__(self):
return self.username
class Meta:
db_table = "db_userinfo"
class Role(models.Model):
'''角色表'''
name = models.CharField(max_length=16,verbose_name="角色名称")
def __str__(self):
return self.name
class Meta:
db_table = "db_role"
class Depart(models.Model):
'''部门表'''
title = models.CharField(max_length=16,verbose_name="部门名称")
def __str__(self):
return self.title
class Meta:
db_table = "db_depart"
2.序列化类的定义,serializers.py代码示例:
from rest_framework import serializers
from django.forms.models import model_to_dict
from student import models
class UserSerializer(serializers.ModelSerializer):
sex_text = serializers.CharField(source="get_sex_display") #该写法可以获取sex字段中的中文,而不是以数字展示
depart = serializers.CharField() # 将部门字段重新定义,在下面可以获取该部门字段的中文名称
#depart = serializers.CharField(source='depart.title') #这样写法也可以获取中文名称,下面单独写也可以获取
roles = serializers.SerializerMethodField()
class Meta:
model = models.UserInfo
fields = ["username","password",'email',"sex_text","roles","depart"]
extra_kwargs= {
"depart":{"source":"depart.title"}, #该写法也可以获取部门的中文名称
}
#当然,也可以通过示例化 roles的字段,来调用钩子函数,来自定义返回的内容
def get_roles(self,obj):
role_list = obj.roles.all()
return [model_to_dict(role,["id","name"]) for role in role_list] #该写法是调用的Django封装好的model_to_dict方法来生成字典的数据
#return [{"id":role.id,"title":role.name,} for role in role_list] #这样自己手动写也是可以的
3.视图函数views.py代码示例:
from rest_framework.views import APIView
from rest_framework.response import Response
from student.models import UserInfo
from student.serializers import UserSerializer
class UserViewSet(APIView):
def get(self,request):
queryset = UserInfo.objects.all()
ser = UserSerializer(instance=queryset,many=True)
return Response(ser.data)
最后,访问设置好的api路径接口,会返回设置好的数据,如图:
![]()
关于多表的序列类嵌套
- 因为多张表存在,也可以每张表定义一个序列化类,进行多个序列化类的嵌套
示例代码:
class RolesSerializer(serializers.ModelSerializer):
'''角色表序列化类'''
class Meta:
model = models.Role
fields = "__all__" # "__all__"代表展示该表的所有字段,不想展示所有,也可以自己定制
class DepartSerializer(serializers.ModelSerializer):
'''部门表序列化类'''
class Meta:
model = models.Depart
#fields = "__all__"
fields = ["title"]
class UserSerializer(serializers.ModelSerializer):
'''用户表序列化类'''
sex_text = serializers.CharField(source="get_sex_display")
#通过实例化两个写好的序列化类,将字段加入到fields列表中,就可以获取该类中定义的所有字段
depart = DepartSerializer()
roles = RolesSerializer(many=True) # 对于多对多的表关系,一定要加上many=True
class Meta:
model = models.UserInfo
fields = ["username","password",'email',"sex_text","roles","depart"]
序列化类嵌套的方式,接口返回的数据也是差不多的,如图:
![]()