REST_FRAMEWORK之序列化 serializer

本文介绍了Django REST FRAMEWORK中序列化器Serializer的使用,包括ModelSerializer的运用,如何通过Source指定字段,以及ModelSerializer的Hypermedia特性,返回结果以链接形式展示。同时探讨了Serializers的验证功能,类似于表单验证,用于确保数据的正确性。

6.序列化器(Serializer)

  1. 假设有一张表格Cos,表格里面有一个title字段写角色名。利用json.dump()进行序列化。
方式一:

Class Cosview(APIview):
	def get(self,request,*args,**kwargs):
		cos=models.Cos.objects.all().values('id','title')
		cos=list(cos)
		ret=json.dumps(cos,ensure_ascii=False)
		return HttpResponse(ret)
		
(json.dumps())只能处理Python类型的数据。
第一个cos返回的是Queryset对象,通过list转化。
方式二:

from rest_framework import serializer.Serializer
Class CosSerializer(Serializer):
	title=Serializer.CharFields()   #对应Cos表格字段,表格中不设id字段,系统都会自动加上去
	id=Serializer.IntegerFields()

Class Cosview(APIview):
	def get(self,request,*args,**kwargs):
		cos=models.Cos.objects.all()
		ser=CosSerializer(instance=cos,many=True)   #many代表的是多条数据
		ret=json.dumps(ser.data,ensure_ascii=False)  #ensure_ascii=False 表示不翻译
		return HttpResponse(ret)

问题回顾:
1.

  1. 在当初额Userinfo表格中 User_type_choice=((1,"普通用户"),(2,“VIP”),(3,"SVIP"))
  2. 当初在model模型中的语句user_type=models.IntegerField(choice=User_type_choice)
  3. 第一个问题:用数字和中文显示用户登录时的等级。
Class UserinfoSerializer(serializer.Serializer):
	1.user_type=serializer.IntegerField()  #利用integer类型去序列化,回显的一定是'1,2,3'的数字
	2.user_type=serializer.CharField(source='user_type') #回显的还是‘1,2,3’
	3.user_type=serializer.CharField(source='get_user_type_display') #回显中文 

2.

  1. 之前有一个Usergroup的表格,为User所在的分组,字段名为title字段,分A/B组
  2. 在model类中Userinfo 和Usergroup进行了一对一的连表
group=models.ForeignKey("Usergroup")

UserinfoSerializer(serializer.Serializer):
	group=serializer.CharField(Source="group.title")   #当表与表建立起连接时,可以逐层往下查
  1. 一对一,一对多的连表示,可以利用Source来进行指定字段。
  2. 当Userinfo与其他表为ManytoMany关系时,就不能用source。
  3. roles=models.ManyToManyField("Role") #例子,人和角色之间可以多对多关系
Class UserinfoSerializer(serializer.Serializer):
	roles=serializer.SerializerMethodField() #自定义显示,自定义一个以字段名为后缀的函数,
	                                          参数为(self,row)
	def get_roles(self,row):
		role_list=row.roles.all()
		ret=[]
		for item in role_list:
			ret.append({'id':item.id,'title':item.title})
	    return ret
#Role表里面一个‘id’,一个'title',相当于作为了userinfo的外键。

ModelSerializer------>继承于Serializer

1.正常流程:

Class UserinfoSerializer(serializer.ModelSeriliazer):
	user_type=serializer.CharField(source="get_user_type_display")
	roles=serializer.SerializerMethodField()   #自定义显示
	
	Class Meta:
		model=models.Userinfo  #说明使用的是Userinfo表格
		fields=['id','username','password','user_type','roles']
		
	   #fields='__all__'  #即显示所有字段
		
	def get_roles(self,row):      #自定义的方法为get_mehodname
		role_list=row.roles.all()
		ret=[]
		for item in role_list:
			ret.append({'id':item.id,'title':item.title})
	    return ret
这里重点就是一对一、一对多、中文显示和连表查询的操作。	    

2.简单流程,利用depth做一个深度的权限放宽:

Class UserinfoSerializer(serializer.Serializer):
	Class Meta:
		model=model.Userinfo
		fields='__all__'
		depth=1           #depth默认为0,最大为10

depth:深度,为0表示第一层,即id层。可以显示一对多,多对多之间的关系。

ModelSerializer.Hypermedia

  1. Hypermedia是返回结果以链接的形式,点击链接进行url的跳转,然后触发view。
  2. url(r'^(?p<version>[v1][v2]+)/userinfo/$',userinfo.view.as_view())
  3. url(r'^(?p<version>[v1][v2]+)/group/(?p<pk>\d+)$',groupview.as_view()),name='gp'
Class UserinfoSerializer(seriializer.ModelSerializer):
	group=Serializer.HyperlinkIdentityField(view_name='gp',lookup_field='group_id,lookup_url_kwarg='pk'')
	Class Meta:
		model=models.Userinfo
		fields=['id','username'.'password','group','roles']
		depth=0                 #group返回一个链接地址对象
		
Class Userinfo(APIview):
	def get(self,request,*args,**kwargs):
		users=models.Userinfo.objects.all()
	#	pk=kwargs.get('pk') #可以从url中获取pk的值、然后object.filter()进行数据的筛选、
		Ser=UserinfoSerializer(instance=users,many=True,Contect={'request':request})
		ret=json.dumps(ser.data,ensure_ascii=False)
		return HttpResponse(ret)
		

Serializers序列化验证(类似于表单验证)

  1. 表单验证
1.request.POST.get <--------> forms=forms(request.POST)

2.Django 自带的form表单是验证前段字段数据合法性的一个好途径。

3.在APP中编写form.py文件,继承forms.Form,在文件中的字段必须和前段发来的字段一致。比如:
from django.core import validators
email=Forms.CharField(validators=[validators.Emailvalidators(mess='  ')])

表单中的错误信息提示可以为:error_message={"invalid":"____"}
from django.views.generic import view 
Class Index(view):
	def get(self,request,*args,**kwargs):
		pass
	def post(self,request,*args,**kwargs):
		form=form(request.POST)    #将request.POST的数据放到form类中去验证、
		if form.is_valid():        #如果数据验证通过了,就用相应的字段将干净的数据提取出来、
			price=form.cleaned_data.get('price') 
		else:
			print(form.error.get_json_data())  #数据类型出错,显示出错信息、

2.利用Form的实例在前端生成表格,利用context渲染html{‘form’:form},前端{{form.as_table}}。

Views

from .forms import form
Class Index(View):
	def get(self,request,*args,**kwargs):  #前端get请求实际上是在向服务器请求数据,所以直接将form渲染返回
		return render(request,'index.html',{'form':form})
	def post(self,request,*args,**kwargs):
		pass

Index.html

<table>
{{form.as_table}}
<input text='submit',name='提交'>
</table>

3.Serializers序列验证

  1. 获取字段值,不仅可以用request._request.GET/POST.get(),也可以使用parser的request.data
Class SerializerUsergroup(serializers.Serializer):
	title=Serializers.Charfield(error_message={'required':'标题不能为空'})
Class Usergroupview(APIView):
	def post(self,request,*args,**kwargs):
		ser=SerializerUsergroup(data=request.data)
		if ser.is_valid():
			print(validated_data)  #大致和form表单一致,利用is_valid进行判断
		else:
			print(ser.errors)
		return HttpResponse('ok')
Serializer.CharField(除了error_message 还可以用自定义的Validators=[abcValidators('abc'),])
abcValidators类 ,自定义了类内容,必须以abc为开头的类
Class abcValidators(object):
	def __init__(self,base):
		self.base=base
	def __call__(self,value): #value--->的值就是request.data 值
		if not value.startwith(self.base):
			message="标题必须以%s 开头“%self.base
			raise Serializer.ValidationError(message)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值