django序列化组件

不用组件传值方式

views.py

    from rest_framework.views import APIView
    from app01 import models
    from app01.Myserializer import BookSerializer
    
    class BookView(APIview):
    	def get(self,request,*args,**kwargs):
    		    #获取所有图书数据
	    	response = {'status':100,'msg':'获取成功'}
			book_list = models.Book.objects.all()
			#列表推导式,结果为列表内元素为字典。
			book_ll = [{'id':book.pk,'name':book.name,'price':book.price} for book in book_list ]  
			response['data'] = book_ll
			#json不支持转列表,所有要传safe=False
			return JsonResponse(response,safe=False,ensure)
				

使用序列化组件

方式一:rest-framework序列化之Serializer(继承serializers.Serializer)

注:需要在Settings的INSTALLED_APPS中添加 rest_framework

urls.py

views.Bookview.as_view()

MySerializer.py

from res_framework import serializers

#这个类用于被实例化,多对多字段这么写
class AuthorSerializer(serializers.Serializer):
	id = serializers.Charfield()
	name = serializers.Charfield()
	age = serializers.Charfield()

#传给views.py的主类
class BookSerializer(serializers.Serializer):
	name = serializers.Charfield()
	#source 可以指定字段 ,  id是要序列化的表名。
	id  = serializers.CharField(source='nid') 
	#,source后字段用.的方式可以跨表查询。
	publish = serializer.CharField(source='publish.email')
	''' 
	如果在models.py的book类中定义一个test方法。
	def test(self): 
		return str(self.price)+self.name
   '''
   # 返回的结果就会有xx字段,souce不但可以指定表模型字段,还可以指定模型表方法,并且赋值给xx变量
   xx = serializers.Charfield(source='test')
   
   
   #外键的实现方法:
   #一对多字段
   #如果要通过外键字段返回出版社的所有信息,包括id,name,email...
   #obj是当前循环序列化到的数据对象
    publish = serializers.SerializerMethodField()
    	def get_publish(self,obj):
    		return {’id‘:obj.publish.pk,'name':obj.publish.name}
   
   #多对多字段
   #所有作者的详情,也展示出来
	authors = serializers.SerializermethodFiled()
	def get_authors(self,obj):
		author_list  = obj.authors.all()
		author_ser = AuthorSerializer(author_list,many=True)
		return author_ser.data

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models

class BookView(APIview):
	def get(self,request,*args,**kwargs):
		    #获取所有图书数据
    	response = {'status':100,'msg':'获取成功'}
		book_list = models.Book.objects.all()
		#实例化BookSerializer类,把要序列化的数据book_list传入
		#如果要序列化querySet对象,一定要加many = True
		book_ser = BookSerializer(book_list,many=True)
		#把序列化后的数据book_ser.data 拿出来放到response字典中返回给客户端
		response['data'] = book_ser.data 
		return Response(response)

访问 127.0.0.1/books

在这里插入图片描述

方式二:继承serialiazers.ModelSerializer(直接指定要序列化的表模型)

MySerializer.py

from app01 import models
class PublishSerializer(serializers.ModelSerializer): 
	class Meta: #固定写法
	# 指定要序列化Book表
	model = models.Book
	#指定要序列化的字段
	fields = ['nid','name']
	#序列化所有字段
	fileds ='__all__‘ 
	#要排除的字段(不能与fileds连用)
	# exclude = ['name','price'] 
	#深度判定
	depth = 1 
	#如果要不按照父类的来,想要自己定义显示的字段的话,自己定义一个,覆盖掉父类的字段属性。
    publish = serializers.SerializerMethodField()  #一对多字段
    	def get_publish(self,obj):
			return {’id‘:obj.publish.pk,'name':obj.publish.name}

views.py(不变)

from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models

class BookView(APIview):
	def get(self,request,*args,**kwargs):
		    #获取所有图书数据
    	response = {'status':100,'msg':'获取成功'}
		book_list = models.Book.objects.all()
		#实例化BookSerializer类,把要序列化的数据book_list传入
		#如果要序列化querySet对象,一定要加many = True
		book_ser = BookSerializer(book_list,many=True)
		#把序列化后的数据book_ser.data 拿出来放到response字典中返回给客户端
		response['data'] = book_ser.data 
		return Response(response)

获取单本图书的接口

urls.py

url(r'book/(?P<pk>\d+)',views.BookView.as_view())

MySerializer.py(参考上面的任意一种方式,最好是model)

views.py(有改动)

class BookView(APIView):
	def get(self,request,pk,*args,**kwargs):  # 有名分组,增加一个pk值更加方便
    	response = {'status':100,'msg':'获取成功'}
    	#取到pk =pk的这本书
    	book = models.Book.objects.all().filter(pk=pk).first()  
    	#要序列化单条,many = False ,queryset的话many 就传True
    	#注意,这里的book是book对象,而不是queryset对象
    	book_ser = BookSerializer(instance=book,many=False) 
    	#把序列化后的数据book_ser.data 拿出来放到response字典中返回给客户端
    	response['data'] = book_ser.data 
    	return Response(response) 

新增一本书、修改一本书、删除一本书

views.py

def post(self,request):
	response = {'status':100,'msg':'新增成功'}
	#取出每个字段(从request.data取出)
	#简便方式:采用序列化类的反序列化功能(之前把对象转化成字典,现在把字典转化为对象)。
	try:
    	book_ser = BookSerializer(data=request.data)
    	if book_ser.is_valid(): #校验通过
	    	book_ser.save()
	    	response['data'] = book_ser.data
	    else:
	    	response['msg'] = book_ser.errors
    	
    except Exception as e:
    	response['msg']=str(e)
    return Response(response)
def put(self,request,pk):
	response = {'status':100,'msg':'修改成功'}
	#取出书籍
	book = models.Book.objects.filter(pk=pk).first()
	#修改,需要指定instance实例,指定修改的对象。
	book_ser = BookSerializer(instance=book,data=request.data)
	if book_ser.is_valid():
		book_ser.save()
		response['data'] = book_ser.data
	else:
		response['msg'] = book_ser.errors
	return Response(response)

局部钩子函数对单个字段校验

全局钩子函数对全局字段校验

MySerializer.py

from app01 import models
class PublishSerializer(serializers.ModelSerializer): 
	class Meta: #固定写法
	# 指定要序列化Book表
	model = models.Book
	#指定要序列化的字段
	fields = ['nid','name']
	#序列化所有字段
	fileds ='__all__‘ 
	#要排除的字段(不能与fileds连用)
	# exclude = ['name','price'] 
	#深度判定
	depth = 1 
	#如果要不按照父类的来,想要自己定义显示的字段的话,自己定义一个,覆盖掉父类的字段属性。
    publish = serializers.SerializerMethodField()  #一对多字段
    	def get_publish(self,obj):
			return {’id‘:obj.publish.pk,'name':obj.publish.name}
	#--------------------------------------上面的都是复制的,一定要继承 serializers.ModelSerializer
	
	from rest_framework.exceptions import ValidationError
	
	#局部钩子
	#校验name字段不能以 ‘sb’ 开头
    def validate_name(self,value):
        if value.startswith('sb'):
            #不能让你过
            raise ValidationError('出版社名不能以sb开头')
        else:
            return value
    #全局钩子(attr为形参) ,如果不被局部校验拦截的话 attr为一个字典形式,打印出来的不是字典是因为重写了__str__方法。
	def validate(self,attr): 
		print(attr)
		name = attr.get('name')  #返回的是name的值。
		if name  != price:
			raise ValidationError('出错了')
		return attr 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值