rest-framework之序列化组件
一 Django自带序列化组件
二 rest-framework序列化组件之Serializer
三 rest-framework序列化之ModelSerilizer
四 生成hy.permedialink(极少数)
五 序列化组件之请求数据校验和保存功能
一 Django自带序列化组件
class PublishView(View): def get(self,request): # 方式一 publish_list = list(Publish.objects.all().values('name','email')) return HttpResponse(json.dumps(publish_list)) # 方式二 from django.forms.models import model_to_dict publish_list = Publish.objects.all() temp = [] for obj in publish_list: temp.append(model_to_dict(obj)) return HttpResponse(json.dumps(temp)) # 方式三 from django.core import serializers publish_list = Publish.objects.all() temp = serializers.serialize("json",publish_list) return HttpResponse(temp)
二 rest-framework序列化之Serializer
models部分:
from django.db import models # Create your models here. class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name
view部分:
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from django.core import serializers from rest_framework import serializers class BookSerializers(serializers.Serializer): title=serializers.CharField(max_length=32) price=serializers.IntegerField() pub_date=serializers.DateField() publish=serializers.CharField(source="publish.name") #authors=serializers.CharField(source="authors.all") authors=serializers.SerializerMethodField() def get_authors(self,obj): temp=[] for author in obj.authors.all(): temp.append(author.name) return temp #此处可以继续用author的Serializers, # def get_authors(self,obj): # ret=obj.authors.all() # ss=AuthorSerializer(ret,many=True) # return ss.data class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # import json # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse("ok") # 序列化方式2: # data=serializers.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) #many=True代表有多条数据,如果只有一条数据,many=False return Response(bs.data) # 序列化方式4: # ret=models.Book.objects.all().values('nid','title') # dd=list(ret) # return HttpResponse(json.dumps(dd))
注意:
source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))
如在模型中定义一个方法,直接可以在在source指定执行
三 rest-framework序列化之ModelSerializer
class BookSerializers(serializers.ModelSerializer): class Meta: model = models.Book # fields = "__all__" fields=['nid','title','authors','publish'] # exclude=('nid',) #不能跟fields同时用 # depth = 1 #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层 publish=serializers.SerializerMethodField() def get_publish(self,obj): return obj.publish.name authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=obj.authors.all() ss=AuthorSerializer(ret,many=True) return ss.data
四 生成hypermedialink(极少数)
class BookSerializers(serializers.ModelSerializer): class Meta: model = models.Book fields = "__all__" # 生成连接,直接查看出版社详情 publish = serializers.HyperlinkedIdentityField(view_name='ttt', lookup_field='publish_id', lookup_url_kwarg='pkk') authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=obj.authors.all() ss=AuthorSerializer(ret,many=True) return ss.data #-------------- res=BookSerializers(ret,many=True,context={'request': request}) #-------------- class Publish(APIView): def get(self,request,pkk): print(pkk) return HttpResponse('ok') #----路由--- url(r'^publish/(?P<pkk>\d+)$', views.Publish.as_view(),name='ttt'),
五 序列化组件之请求数据校验和保存功能
class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" #———————— class BookView(APIView): def post(self, request): # 添加一条数据 print(request.data) bs=BookSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成记录 return Response(bs.data) else: return Response(bs.errors)
通过源码查看校验字段的钩子函数:
#is_valid---->self.run_validation-(执行Serializer的run_validation)-->self.to_internal_value(data)---(执行Serializer的run_validation:485行) def validate_title(self, value): from rest_framework import exceptions raise exceptions.ValidationError('看你不顺眼') return value #全局 def validate(self, attrs): from rest_framework import exceptions if attrs.get('title')== attrs.get('title2'): return attrs else: raise exceptions.ValidationError('不想等啊')
图书的增删查改restful接口:
视图层:
class BookSerializers(serializers.ModelSerializer): class Meta: model=models.Book fields='__all__' class BookView(APIView): def get(self, request): book_list = models.Book.objects.all() bs = BookSerializers(book_list, many=True) # 序列化数据 return Response(bs.data) def post(self, request): # 添加一条数据 print(request.data) bs=BookSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成记录 return Response(bs.data) else: return Response(bs.errors) class BookDetailView(APIView): def get(self,request,pk): book_obj=models.Book.objects.filter(pk=pk).first() bs=BookSerializers(book_obj,many=False) return Response(bs.data) def put(self,request,pk): book_obj = models.Book.objects.filter(pk=pk).first() bs=BookSerializers(data=request.data,instance=book_obj) if bs.is_valid(): bs.save() # update return Response(bs.data) else: return Response(bs.errors) def delete(self,request,pk): models.Book.objects.filter(pk=pk).delete() return Response("")
路由:
url(r'^books/$', views.BookView.as_view()), url(r'^books/(?P<pk>\d+)$', views.BookDetailView.as_view()),