from rest_framework import serializers
前后端交互主要有get
,post
,puch
,put
,deleter
其中用到序列化的get
用到反序列化的剩下四中
二.序列化的使用1.首先我们要根据我们定义的模型一一对应定义一个继承serializers.Serializer
的类class UserSerializer(serializers.Serializer): username = serializers.CharFIEld() #不需要的字段=serializers.CharFIEld(write_only=True) sex = serializers.IntegerFIEld() gender = serializers.SerializerMethodFIEld() def get_gender(self,user_obj): return user_obj.get_sex_display() icon = serializers.SerializerMethodFIEld() #SerializerMethodFIEld为自定义字段 def get_icon(self,user_obj): icon_url = 'http://127.0.0.1:8000{}{}'.format(settings.MEDIA_URL,user_obj.icon) return icon_url
自定义字段,拿gander
字段举例在models中是
SEX_CHOICES = [ (0,'男'),#choices选择中,括号里前者表示填写的值,后者表示对应的值 (1,'女'),]# 为choices的字段,获取值后的映射关系 get_字段名_display()sex = models.IntegerFIEld(choices=SEX_CHOICES,default=0)
def get_gender(self,user_obj): return user_obj.get_sex_display()
基于GET请求的get_固定写法def get_model类中有字段(self,obj): #逻辑处理 return 修改后的代码
需要序列化字段
在不做任何处理的情况下
我们定义的类里面的字段必须在model类中必须存在该字段参与序列化的属性名必须与model类的属性相同只出现在序列化中不出现在反序列化中我们要加只读属性read_only=True
如果我们Serializer类中定义字段类型为SerializerMethodFIEld
及自定义字段类型不用遵守类里面的字段必须在model类中必须存在该字段
不需要序列化字段
write_only=True
2.在vIEws视图中from rest_framework.vIEws import APIVIEwclass UserAPIVIEw(APIVIEw): def get(self,request,*args,**kwargs): user_obj = models.User.objects.all().frist user_obj_data = '''我们自定义的Serializer类'''(user_obj).data return APIResponse(0,'ok',results=user_obj_data)
获取models中的对象我们自定义的Serializer类传入models中的对象然后.data
如果models中对象为多个Serializer传入models中的对象以外many=True
还需传入这个参数many
这个参数默认是False所有我们序列化单个参数时候不需要传入many
序列化数据可以为状态User类的多个对象的单列集合
,不能是多列集合注
:
[a,b,c.....]
|{a,c.....}
|(a,c.....)
|querySet
多列集合{k1:v1,k2:v2.......}
三反序列化的使用1.首先我们要根据我们定义的模型一一对应定义一个继承serializers.Serializer
的类class UserDeserializer(serializers.Serializer): username = serializers.CharFIEld( min_length=3,error_messages={ 'min_length': '用户名太短' } ) password = serializers.CharFIEld( min_length=3,error_messages={ 'min_length': '密码太短' } ) re_password = serializers.CharFIEld( min_length=3,required=True,error_messages={ 'min_length': '确认密码太短','required': '确认密码不能为空' } )
相较于序列化定义
反序列化中增加了条件的筛选
注意点
:如果类的字段值应用在反序列化,我们可以在他的字段的属性上加上write_only=True
里面所提及的字段必须传入
常用的约数条件与django中from组件约数条件有点类似
:
error_messages
错误信息的属性required
是否为空max_length
最长min_length
最短invalID
格式局部钩子class UserDeserializer(serializers.Serializer): ....... def valIDate_字段名称(self,value): #代码块 if 情况不满足: raise serializers.ValIDationError('异常信息') #抛出异常 return value #也就是对字段数据进行二次处理
全局钩子 class UserDeserializer(serializers.Serializer): ....... def valIDate(self,attrs): #attrs是所有字段的一个类似字典的集合 #我们要其中某个字段 attrs.get('字段名') return attrs # 最终结果抛出异常或者返回attrs
2.内容新增使用我们如果想自定义create的相关内容我们可以Serializer类中
再加个create
方法
class UserDeserializer(serializers.Serializer): ....... def create(self,valIDated_data): try: return modles中的类.objects.create(**valIDated_data) except: raise IOError('数据库入库失败')
我们更具需求可以先自定义一个APIResponse,继承rest_framework中的Response也可以直接使用他自带的
自定义APIResponse,建议自定义
from rest_framework.response import Response"""Response({ 'status': 0,'msg': 'ok','results': [],'token': ''},headers={},status=200,content_type="")APIResponse(0,results,status,headers,content_type)"""class APIResponse(Response): def __init__(self,data_status,data_msg,results=None,status=None,headers=None,content_type=None,**kwargs): data = { 'status': data_status,'msg': data_msg } if results is not None: data['results'] = results data.update(kwargs) super().__init__(data=data,status=status,headers=headers,content_type=content_type)
在视图函数中的设置
class UserAPIVIEw(APIVIEw): def post(self,**kwargs): #一般都是post请求 request_data = request.data user_ser = '''我们自定义的Serializer类'''(data=request_data) #传入request.data if user_ser.is_valID(): # 自定义处理校验成功的逻辑 user_obj = user_ser.save() return APIResponse(0,results=serializers.UserSerializer(user_obj).data ) else: # 自定义返回错误信息 return APIResponse(1,'Failed',results=user_ser.errors)
3.内容修改使用我们如果想自定义update的相关内容我们可以Serializer类中
再加个update
方法
class UserDeserializer(serializers.Serializer): ....... def update(self,instance,valIDated_data): # instance自定义传入的要更新的原数据(pk | obj | queryset) # valIDated_data校验通过后的新数据 # instance的值外部反序列化传入要更新的自定义标识决定 instance.update(**valIDated_data) return instance.first()
在视图函数中的设置
单整体改
class UserV2APIVIEw(APIVIEw): def put(self,**kwargs): pk = kwargs.get('pk') if not pk: return APIResponse(1,'pk error') user_query = models.User.objects.filter(pk=pk,is_delete=False) if not user_query: return APIResponse(1,'user error') # 第一种:user_query完成数据的更新 # user_query = models.User.objects.filter(pk=pk) # user_query.update(**kwargs) # 第二种:user_obj完成数据的更新 # user_obj = models.User.objects.filter(pk=pk).first() # type: models.User # user_obj.username = 'new_username' # ... # user_obj.save() #这里的instance必须传参(pk | obj | queryset) request_data = request.data user_ser = serializers.UserV2Serializer(instance=user_query,data=request_data) if user_ser.is_valID(): # save的返回值是由update内部自定义的返回值决定 user_obj = user_ser.save() return APIResponse(0,results=serializers.UserV2Serializer(user_obj).data ) else: return APIResponse(1,user_ser.errors)
单删
或单体修改
现在数据都是很重要的一般情况下不会吧数据删除只会做个标记字段其本质还是局部更新
def delete(self,'pk error') user_obj = models.User.objects.filter(pk=pk,is_delete=False).first() if not user_obj: return APIResponse(1,'删除失败') user_obj.is_delete = True user_obj.save() return APIResponse(0,'删除成功')
四.model字段修订与时区修改model.py
create_time = models.DateTimeFIEld(auto_Now_add=True,null=True) is_delete = models.BooleanFIEld(default=False)
setting.py
时区相关设置
LANGUAGE_CODE = 'zh-hans' #其中 zh-Hans是简体中文 zh-Hant是繁体中文TIME_ZONE = 'Asia/Shanghai' #上海时间USE_I18N = True #国际化支持 I18NUSE_L10N = TrueUSE_TZ = False #USE_TZ设置为True,Django会使用系统默认设置的时区即America/Chicago,此时的TIME_ZONE不管有没有设置都不起作用。
注意点:
USE_TZ为True
,TIME_ZONE
不管有没有设置都不起作用
以上是内存溢出为你收集整理的drf框架序列化和返序列化全部内容,希望文章能够帮你解决drf框架序列化和返序列化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)