05-Django REST framwork 板块(06-序列化)

6. 序列化

两大功能:
1. 对请求数据的验证
2. 对querset进行序列化

一.序列化:

利用ser.data获得经过序列化得到的数据,ser为经过数据库查询得到的query对象(ret = models.Role.objects.all())

1.写类

两种基本写法:from rest_framework.serializers import ...

一种继承自Serializer,
第二种继承自ModelSerializer,自动数据库表里边,自动生成Serializer的字段

class RolesSerializer(serializers.Serializer):
	id = serializers.IntegerField()
	title = serializers.CharField()

class UserInfoSerializer(serializers.ModelSerializer):
	class Meta:
		model = models.UserInfo
		# fields = "__all__"  # 可以自动生成所有字段,但是默认拿的都是最基本的
		fields = ['id','username','password',]  # 写数据库的字段
2.字段

a.

title = serializers.CharField(source="xxx.xxx.xx.xx")
重点:获取choice字段显示
  1. source为对应数据库的字段名称,这样前边的title就可以随便定义了

  2. source针对如含choice等字段,可以执行get_字段名_display 方法 进行显示,如source='get_usertype_display'

  3. source针对外键等情况,可以使用 xx.属性名,进行调用,如:source='group.id'

  4. 当要查的不只是一个数据,可以用SerializerMethodField进行自定义显示,可以定义一个
    get_ 开头的方法/函数,函数返回什么,就显示什么(如下:get_rls

b.


  title = serializers.SerializerMethodField()
  class UserInfoSerializer(serializers.ModelSerializer):
	rls = serializers.SerializerMethodField()  # 自定义显示
	haha = serializers.CharField(source='get_usertype_display')
	class Meta:
		model = models.UserInfo
		# fields = "__all__"  # 可以自动生成多有字段,但是默认拿的都是最基本的
		# 可以跟自定义的字段,混合着中。对于额外数据也可以depth进行深度提取,拿到更多数据
		# 对于有格外操作的,可以定义上边单独字段,然后添加到files中
		fields = ['id','username','password','rls','haha'] 
	 
	# 自定义方法
	def get_rls(self, row):
		role_obj_list = row.roles.all()

		ret = []
		for item in role_obj_list:
			ret.append({'id':item.id,'title':item.title})
		return ret

c. 自定义类

  • 可以继承CharFiled等字段,进行自己的再封装。用的不多
3. 自动序列化连表、深度depth
class UserInfoSerializer(serializers.ModelSerializer):
	class Meta:
		model = models.UserInfo
		# fields = "__all__"
		fields = ['id','username','password','group','roles']  #可对应添加含字段的字段名称
		depth = 1 # 官方建议0 ~ 10(取数据的深度,如果只拿到数据ID,可以再往深的取对应的描述文字)
		# 层数越深,数据越多,检索越多,影响性能,平时到3已经很大了  
4. 生成链接(反向解析)

url(r'^(?P<version>[v1|v2])/group/(?P<xxx>\d+)$',views.GroupView.as_view(),name='gp')

class UserInfoSerializer(serializers.ModelSerializer):
	group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx')
		# view_name   >>   url处的别名
		# lookup_field  >>  url中的xxx匹配的内容,针对数据库中所要查询字段的索引值
		# lookup_url_kwarg  >>  取url中正则匹配的名字
	class Meta:
		model = models.UserInfo
		# fields = "__all__"
		fields = ['id','username','password','group','roles']
		depth = 0 

class UserInfoView(APIView):
	def get(self,request,*args,**kwargs):

		users = models.UserInfo.objects.all()

		ser = UserInfoSerializer(instance=users,many=True,context={'request': request})
		ret = json.dumps(ser.data, ensure_ascii=False)
		return HttpResponse(ret)
		

源码:

对象, Serializer类处理;
QuerySet,ListSerializer类处理;
# serializer.data

2.请求数据校验:

对request请求过来的数据进行验证,比如不允许传空值,然后根据校验规则进行相应。如:发{"pwd":""},经过验证返回{"pwd":["标题不能为空"]}


class XXValidator(object):
	def __init__(self, base):
		self.base = base

	def __call__(self, value):
		if not value.startswith(self.base):
			message = '标题必须以 %s 为开头。' % self.base
			raise serializers.ValidationError(message)

	def set_context(self, serializer_field):
		"""
		This hook is called by the serializer instance,
		prior to the validation call being made.
		"""
		# 执行验证之前调用,serializer_fields是当前字段对象
		pass

class UserGroupSerializer(serializers.Serializer):
    # 基于title这个字段名进行,验证;
    # 就是说请求数据,必须需包含'title',并且不能为空
	title = serializers.CharField(error_messages={'required':'标题不能为空'},validators=[XXValidator('老男人'),])
		# error_messages={'required':'标题不能为空'}  #自定义出错的信息
		# validators=[XXValidator('老男人'),]  #自定义验证规则(上边的XXValidator)
class UserGroupView(APIView):

	def post(self,request,*args,**kwargs):

		ser = UserGroupSerializer(data=request.data)  #做校验时,传入请求数据
		if ser.is_valid():
			print(ser.validated_data['title'])
		else:
			print(ser.errors)

		return HttpResponse('提交数据')
		

问: 自定义验证规则时,需要钩子函数?请问钩子函数如何写?

答:从is_vaild()方法开始找源码,注意self要先从自己定义的类进行查找,然后在一步步深入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值