您的位置:首页 > 娱乐 > 明星 > 宿迁企业网站建设_公司创建网站多少钱_常用的seo工具推荐_免费网页在线客服系统代码

宿迁企业网站建设_公司创建网站多少钱_常用的seo工具推荐_免费网页在线客服系统代码

2024/10/11 10:20:21 来源:https://blog.csdn.net/weixin_43631940/article/details/142750884  浏览:    关键词:宿迁企业网站建设_公司创建网站多少钱_常用的seo工具推荐_免费网页在线客服系统代码
宿迁企业网站建设_公司创建网站多少钱_常用的seo工具推荐_免费网页在线客服系统代码

九、序列化器

9.1序列化

从数据库取QuerySet或数据对象转换成JSON

9.1.1序列化器的简易使用
#新建一张部门表
class Depart(models.Model):title=models.CharField(verbose_name='部门',max_length=32)order=models.IntegerField(verbose_name='顺序')count=models.IntegerField(verbose_name='人数')
#新建路由
urlpatterns = [  path('api/<str:version>/depart/',views.DepartView.as_view(),name='depart'),]
#创建一个序列化器
from rest_framework import serializers
class DepartSerializers(serializers.Serializer):#部门系列化器,字段需要和数据库中的字段相对应title=serializers.CharField()order=serializers.IntegerField()count=serializers.IntegerField()
#创建视图类
class DepartView(APIView):#无需认证authentication_classes = []#部门视图类def get(self,request,*args,**kwargs):#1、获取数据库中的数据depart_obj=models.Depart.objects.all().first()#2、序列化器转换成JSONser_obj=DepartSerializers(instance=depart_obj)#打印ser_obj.data类型print('ser_obj.data.type:',type(ser_obj.data))#3、返回给用户context={'status':True,'data':ser_obj.data}return Response(context)

使用postman发送get请求进行测试

在这里插入图片描述

打印输出ser_obj.data的类型,是一个字典

ser_obj.data.type: <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
9.1.2序列化QuerySet列表(多个数据对象)
#视图类
class DepartView(APIView):#无需认证authentication_classes = []#部门视图类def get(self,request,*args,**kwargs):#1、获取数据库中的数据#获取表中的所有记录(多个数据对象,是一个QuerySet列表)depart_objs=models.Depart.objects.all()#2、序列化器转换成JSON,many代表允许多个数据对象ser_obj=DepartSerializers(instance=depart_objs,many=True)print('ser_obj.data.type:',type(ser_obj.data))#3、返回给用户context={'status':True,'data':ser_obj.data}return Response(context)

使用postman发送GET请求进行测试

在这里插入图片描述

打印输出ser_obj.data的类型,是一个列表

ser_obj.data.type: <class 'rest_framework.utils.serializer_helpers.ReturnList'>
9.1.3ModelSerializer
#创建序列化器
from rest_framework import serializers
class DepartSerializers(serializers.ModelSerializer):#部门系列化器class Meta:model = models.Depart#获取数据库中的所有字段fields = "__all__"#指定字段# fields = ['title','order','count']#排除字段# exclude=['count']

这个效果同9.2.2中的效果

9.1.4特殊字段的处理
#表结构
class Depart(models.Model):#部门表title=models.CharField(verbose_name='部门',max_length=32)order=models.IntegerField(verbose_name='顺序')count=models.IntegerField(verbose_name='人数')class userInfo(models.Model):#员工信息表name=models.CharField(verbose_name='姓名',max_length=32)GENDER_CHOICES=((1,'男'),(2,'女'))#choices字段gender = models.SmallIntegerField(verbose_name='性别', choices=GENDER_CHOICES)#ForeignKey字段depart=models.ForeignKey(verbose_name='部门',to=Depart,on_delete=models.CASCADE)#DateTime字段ctime=models.DateTimeField(verbose_name='创建时间',auto_now=True)
#创建路由
urlpatterns = [   path('api/<str:version>/depart/',views.DepartView.as_view(),name='depart'),path('api/<str:version>/userinfo/',views.userInfoView.as_view(),name='userinfo'),  ]
#序列化器类
class UserInfoSerializers(serializers.ModelSerializer):#部门系列化器#新增一个choices字段,并获取choices中的文本gender_text=serializers.CharField(source='get_gender_display')#新增一个ForeignKey字段,并获取关联表中的文本depart_text=serializers.CharField(source='depart.title')#修改ctime类,并进行格式化ctime=serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")#新增一个数据库中不存在的字段xxx=serializers.SerializerMethodField()class Meta:model = models.userInfofields = ['name','gender','gender_text','depart','depart_text','ctime''xxx']def get_xxx(self,obj):#这个函数返回什么,xxx这个字段就等于什么。#obj代表当前数据对象,obj.name就是当前数据对象中的name字段值return 'I am {}'.format(obj.name)
#视图类
class userInfoView(APIView):# 用户视图类# 无需认证authentication_classes = []def get(self, request, *args, **kwargs):# 1、获取数据库中的数据# 多条数据userInfo_objs = models.userInfo.objects.all()# 2、序列化器转换成JSON,many代表允许多个数据对象ser_obj = UserInfoSerializers(instance=userInfo_objs, many=True)print('ser_obj.data.type:', type(ser_obj.data))# 3、返回给用户context = {'status': True,'data': ser_obj.data}return Response(context)

使用postman发送GET请求进行测试

在这里插入图片描述

9.1.5通过序列化器的嵌套来处理m2m字段
#表结构:
class Auther(models.Model):#著作表name=models.CharField(verbose_name='作者',max_length=32)class Book(models.Model):#图书表title=models.CharField(verbose_name='书名',max_length=128)#auther为MToM类型,并关联到Auther#一个著作可以有多本书auther=models.ManyToManyField(verbose_name='作者',to=Auther,related_name='books')
#创建url
urlpatterns = [path('api/<str:version>/auther/',views.AutherView.as_view(),name='auther'),p]
#图书序列化器
class BookSerializers(serializers.ModelSerializer):#书系列化器class Meta:model = models.Bookfields = '__all__'
#著作序列化器
class AutherSerializers(serializers.ModelSerializer):#著者系列化器#books字段通过上面创建的图书序列化器来进行序列化books=BookSerializers(many=True)class Meta:model = models.Autherfields = ['name','books']
#视图类
class AutherView(APIView):# 用户视图类# 无需认证authentication_classes = []def get(self, request, *args, **kwargs):# 1、获取数据库中的数据# 多条数据auther_objs = models.Auther.objects.all()# 2、序列化器转换成JSON,many代表允许多个数据对象ser_obj = AutherSerializers(instance=auther_objs, many=True)# print('ser_obj.data.type:', type(ser_obj.data))# 3、返回给用户context = {'status': True,'data': ser_obj.data}return Response(context)

通过postman发送请求进行测试

在这里插入图片描述

9.1.6序列化器的继承
class BaseSerializers(serializers.Serializer):#基础序列化器#这里定义了一个xxx字段,数据来源是数据对象中的name属性xxx=serializers.CharField(source='name')
class BookSerializers(serializers.ModelSerializer):#书系列化器class Meta:model = models.Bookfields = '__all__'class AutherSerializers(serializers.ModelSerializer,BaseSerializers):#这个序列化器继承了BaseSerializers,所以也可以使用BaseSerializers中的xxx字段#著者系列化器books=BookSerializers(many=True)class Meta:model = models.Autherfields = ['name','books','xxx']

9.2使用序列化器校验数据

9.2.1基本校验
#创建url
urlpatterns = [   path('login/', views.LoginView.as_view()),   ]
#创建序列化器
class LoginSerializers(serializers.Serializer):#required=True代表不允许为空,默认值就是Truename=serializers.CharField(required=True)password=serializers.CharField(required=True)
#视图类
class LoginView(MyAPIView):#用户登入,不需要认证authentication_classes = []def post(self,request):#序列化用户传递过来的数据ser_obj=LoginSerializers(data=request.data)if ser_obj.is_valid():#如果数据有效,则将有效的数据返回给用户return Response(ser_obj.validated_data)#如果数据无效,则返回错误信息return Response(ser_obj.errors)

使用postman进行测试

在这里插入图片描述
在这里插入图片描述

9.2.2内置检验和正则表示式检验
#创建序列化器
from rest_framework import serializers
from django.core.validators import RegexValidator
class LoginSerializers(serializers.Serializer):name=serializers.CharField(required=True)#password字段最大长度为32,最小长度为8password=serializers.CharField(required=True,max_length=32,min_length=8)#order字段最大值为100,最小值为10order=serializers.IntegerField(required=False,max_value=100,min_value=10)#gender只允许为1或2gender=serializers.ChoiceField(choices=((1,'男'),(2,'女')))#EmailField必须输入Email格式的数据email=serializers.EmailField(required=True)#手机号字段使用正则表达式检验,必须满足正则表达式的规则才能通过校验mobilePhone=serializers.CharField(validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误')])

使用postman进行测试

在这里插入图片描述

9.2.3钩子校验
#序列化器
from rest_framework import serializers
from rest_framework import exceptions
class LoginSerializers(serializers.Serializer):name=serializers.CharField(required=True)password=serializers.CharField(required=True,max_length=32,min_length=6)def validate_name(self,value):#对某个字段进行钩子检验user_obj=models.User.objects.filter(name=value).first()if not user_obj:#如果用户名不存在,则抛出错误信息raise exceptions.ValidationError("用户名不存在")return valuedef validate(self, attrs):#全局中钩子检验name=attrs.get('name')password=attrs.get('password')user_obj=models.User.objects.filter(name=name,password=password).first()if not user_obj:#如果密码错误不存在,则抛出错误信息raise exceptions.ValidationError('密码错误')return attrs
9.2.4ModelSerializer进行数据校验
#创建Model序列化器(用于数据校验)
class RegisterModelSerializers(serializers.ModelSerializer):confirm_password=serializers.CharField(required=True)class Meta:model=models.Userfields=['name','password','confirm_password','depart']extra_kwargs={#为各个字段添加参数'name': {'max_length':32,'min_length':2},'password': {'validators':[RegexValidator(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$')]},}def validate_confirm_password(self, value):#确认密码钩子校验password=self.initial_data.get('password',None)if password != value:raise exceptions.ValidationError('两次输入密码不一致')return value
#创建Model序列化器(用于序列化返回给用户的数据)
class UserSerializers(serializers.ModelSerializer):#role是chioces字段,这里可以获取它的文本内容role=serializers.CharField(source='get_role_display')#depart是ForeignKey字段,这里可以获取它的文本内容depart=serializers.CharField(source='depart.title')class Meta:model=models.Userfields=["name","role","depart"]
#视图类
class RegisterViews(APIView):# 用户登入,不需要认证authentication_classes = []def post(self,request):#通过序列化器校验用户传递过来的数据ser_obj=RegisterModelSerializers(data=request.data)#判断校验是否通过if ser_obj.is_valid():#如果校验通过,则删除数据库中不存在的字段,添加数据库中存在但用户未传递的字段ser_obj.validated_data.pop("confirm_password")instance=ser_obj.save(role=3)#通过序列化器序列化存入数据库中的数据,并返回给用户data = UserSerializers(instance=instance).datareturn Response(data)return Response(ser_obj.errors)

使用postman进行测试

在这里插入图片描述

9.2.5使用一个序列化器既做校验又做序列化
#创建序列化器
class RegisterModelSerializers(serializers.ModelSerializer):#write_only=True代表只做校验,不做序列化confirm_password=serializers.CharField(required=True,write_only=True)#read_only=True代表只做序列化,不做校验role_text = serializers.CharField(source='get_role_display',read_only=True)depart_text=serializers.CharField(source='depart.title',read_only=True)class Meta:model=models.Userfields=['name','password','confirm_password','role_text','depart','depart_text']extra_kwargs={#为各个字段添加参数'name': {'max_length':32,'min_length':2},#write_only=True代表只做校验,不做序列化'password': {"write_only":True,'validators':[RegexValidator(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$')]},#write_only=True代表只做校验,不做序列化'depart':{"write_only":True}}def validate_confirm_password(self, value):#确认密码钩子校验password=self.initial_data.get('password',None)if password != value:raise exceptions.ValidationError('两次输入密码不一致')return value
#视图类
class RegisterViews(APIView):# 用户登入,不需要认证authentication_classes = []def post(self,request):ser_obj=RegisterModelSerializers(data=request.data)if ser_obj.is_valid():ser_obj.validated_data.pop("confirm_password")ser_obj.save(role=3)return Response(ser_obj.data)return Response(ser_obj.errors)

使用postman测试

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com