序列化器的基本使用
为什么需要序列化器
在项目中经常需要对数据库惊醒查询并将结果转化成json格式返还给用户,而django的orm获取数据库可能时可能获取到多个对象-->[对象1,对象2...],l类型是QuerySet,不能直接使用json.dumps()转换成json格式
#数据类型
depart_object = models.Depart.objects.first()
print(type(depart_object))
#<class 'api.models.Depart'>
depart_object = models.Depart.objects.all()
print(type(depart_object))
#<class 'django.db.models.query.QuerySet'>
序列化器的基本使用
from rest_framework import serializers
class DepartSerializer(serializers.Serializer):
title = serializers.CharField()
count = serializers.IntegerField()
class DepartView(APIView):
def get(self,request,*args,**kwargs):
#1.获取数据库中的数据{'id':xxx,'tittle:'xxx'}
depart_object = models.Depart.objects.all()
#print(type(depart_object))
#2.转换成json格式-->用json.dumps() 转换成json格式只支持 int/str/list/dict, 其他都不支持
ser = DepartSerializer(instance=depart_object,many=True)
print(ser.data)
#3.返回给用户
context = {'status':200,'data':ser.data}
return Response(context)
#models
class Depart(models.Model):
title = models.CharField(verbose_name='部门',max_length=20)
order = models.IntegerField(verbose_name='顺序')
count = models.IntegerField(verbose_name='人数')
当models中的定义的列比较多时,也可以继承ModelsSerializer更加简便的使用序列化器
class DepartSerializer(serializers.ModelSerializer):
class Meta:
model = models.Depart
fields = "__all__"
#指定返回的字段
fields = ['title','order',]
如果数据库中存的时各种疑难杂症类型,如下,的也是可以系列化的
#mdoels
class UserInfo(models.Model):
name = models.CharField(verbose_name='姓名',max_length=32)
gender = models.SmallIntegerField(verbose_name='性别',choices=((1,'男'),(2,'女')))
depart = models.ForeignKey(verbose_name='部门',to='Depart',on_delete=models.CASCADE)
ctime = models.DateTimeField(verbose_name='时间',auto_now_add=True)
对于获取choice的数字对应的值可以使用类似django的modelform的写法的
class UserSerializer(serializers.ModelSerializer):
gender = serializers.CharField(source='get_gender_display')
class Meta:
model = models.UserInfo
fields = "__all__"
'''
{
"status": 200,
"data": [
{
"id": 1,
"gender": "男",
"name": "nim",
"ctime": "2024-02-01T15:57:37.731296Z",
"depart": 1
},
{
"id": 2,
"gender": "女",
"name": "mm",
"ctime": "2024-02-01T15:57:37.731296Z",
"depart": 2
}
]
}
'''
#即想要数字又想要文本?
class UserSerializer(serializers.ModelSerializer):
gender_text = serializers.CharField(source='get_gender_display')
class Meta:
model = models.UserInfo
# fields = "__all__"
fields = ['name','gender','gender_text',]
'''
{
"status": 200,
"data": [
{
"name": "nim",
"gender": 1,
"gender_text": "男"
},
{
"name": "mm",
"gender": 2,
"gender_text": "女"
}
]
}
'''
外键想要显示具体的值:
class UserSerializer(serializers.ModelSerializer):
depart = serializers.CharField(source='depart.title')
class Meta:
model = models.UserInfo
# fields = "__all__"
fields = ['name','gender','gender_text','depart']
'''
{
"status": 200,
"data": [
{
"name": "nim",
"gender": 1,
"gender_text": "男",
"depart": "技术部"
},
{
"name": "mm",
"gender": 2,
"gender_text": "女",
"depart": "运营部"
}
]
}
'''
数据库的datetime类型,如果不想显示精确到年月日时分秒:
class UserSerializer(serializers.ModelSerializer):
gender_text = serializers.CharField(source='get_gender_display')
depart = serializers.CharField(source='depart.title')
ctime = serializers.DateTimeField(format="%Y-%m-%d")
class Meta:
model = models.UserInfo
# fields = "__all__"
fields = ['name','gender','gender_text','depart','ctime']
'''
{
"status": 200,
"data": [
{
"name": "nim",
"gender": 1,
"gender_text": "男",
"depart": "技术部",
"ctime": "2024-02-01"
},
{
"name": "mm",
"gender": 2,
"gender_text": "女",
"depart": "运营部",
"ctime": "2024-02-01"
}
]
}
'''
显示自定义字段
class UserSerializer(serializers.ModelSerializer):
gender_text = serializers.CharField(source='get_gender_display')
depart = serializers.CharField(source='depart.title')
ctime = serializers.DateTimeField(format="%Y-%m-%d")
#自定义
MyDefine = serializers.SerializerMethodField()
class Meta:
model = models.UserInfo
# fields = "__all__"
fields = ['name','gender','gender_text','depart','ctime','MyDefine']
#自定义值
def get_MyDefine(self,obj):
#会执行get_ firlds里的字段名的方法获取对应的值
return '123'
'''
{
"name": "nim",
"gender": 1,
"gender_text": "男",
"depart": "技术部",
"ctime": "2024-02-01",
"MyDefine": "123"
},
'''
#自定义格式
def get_MyDefine(self,obj):
return '{}-{}-{}'.format(obj.name,obj.gender,obj.id)
'''
{
"name": "nim",
"gender": 1,
"gender_text": "男",
"depart": "技术部",
"ctime": "2024-02-01",
"MyDefine": "nim-1-1"
}
'''
标签
#models
class Tag(models.Model):
caption = models.CharField(verbose_name='标签',max_length=32)
class UserInfo(models.Model):
name = models.CharField(verbose_name='姓名',max_length=32)
gender = models.SmallIntegerField(verbose_name='性别',choices=((1,'男'),(2,'女')))
depart = models.ForeignKey(verbose_name='部门',to='Depart',on_delete=models.CASCADE)
ctime = models.DateTimeField(verbose_name='时间',auto_now_add=True)
tags = models.ManyToManyField(verbose_name='标签',to='Tag')
想获取到标签,只能使用自定义的方法:
class UserSerializer(serializers.ModelSerializer):
gender_text = serializers.CharField(source='get_gender_display')
depart = serializers.CharField(source='depart.title')
ctime = serializers.DateTimeField(format="%Y-%m-%d")
tag = serializers.SerializerMethodField()
MyDefine = serializers.SerializerMethodField()
class Meta:
model = models.UserInfo
# fields = "__all__"
fields = ['tag','name','gender','gender_text','depart','ctime','MyDefine']
def get_tag(self,obj):
# queryset = obj.tags
#方式1 、使用列表推导式
res = [{'id':tag.id,'caption':tag.caption}for tag in obj.tags.all() ]
return res
针对foreign key 和many to many获取方法2:
嵌套
#用这个方法返回的可以从多个表里选择,可以返回任意的字段
class D1(serializers.ModelSerializer):
class Meta:
model = models.Depart
fields = ['id','title']
class D2(serializers.ModelSerializer):
class Meta:
model = models.Tag
fields = ['caption']
class UserSerializer(serializers.ModelSerializer):
depart = D1()
tags = D2(many=True)
class Meta:
model = models.UserInfo
fields = ['tags','depart',还可以加上Userinof的字段]
#其他自定义的字段还可以在D1和D2里面定义
继承
#可以使用父类中的字段
class base(serializers.Serializer):
xx = serializers.CharField(source='name')
class UserSerializer(serializers.ModelSerializer,base):
depart = D1()
tags = D2(many=True)
class Meta:
model = models.UserInfo
fields = ['tags','depart','xx']
对比
class ser2(serializers.Serializer):
#字段全部都需要自己写
pass
class ser1(serializers.ModelSerializer):
#可以使用class Meta: fields=[xx,xx,xxx]
#不能继承serializers.ModelSerializer,能继承serializers.Serializer
pass