drf 之序列化组件
序列化
把Python中对象转换为json格式字符串
反序列化
把json格式转为为Python对象。
用orm查回来的数据都是都是一个一个的对象, 但是前端要的是json格式字符串。
序列化两大功能:
对请求数据进行验证
对Queryset对象进行序列化
一、Django自带序列化组件
略
二、rest framework序列化之Serializer
使用方式如下:
建表 models.py
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
views
写一个restframework接口拿到数据(所有图书)
方式一:如果没有序列化组件的话,要先转成字典,然后再用json.dumps()再转。
方式二:用序列化组件。
首先你要序列化谁,先写一个类。这个类继承一个东西,然后用的时候,在视图类中直接用这个类生成一个对象。
from django.shortcuts import render,HttpResponse from rest_framework.views import APIView from rest_framework.response import Response # Create your views here. from api import models # 想用这个类,需要导入 from api.MySerializer import BookSerializer class BookView(APIView): def get(self,request,*args,**kwargs): ret = { 'code':100, 'msg':'成功了' } books = models.Book.objects.all() # 第一个参数是要序列化的对象,如果序列化多条,必须指定many=True books_ser = BookSerializer(instance=books,many=True) # 当序列化的对象是单个对象的时候many=False book = models.Book.objects.all().first() # books_ser.data 就是序列化后的结果 是个字典 print(books_ser.data) ret['books']=books_ser.data # return Response(books_ser.data) return Response(ret)
写的格式化的类在另外的文件夹或文件:
# 自己写一个序列化的类 from rest_framework import serializers class BookSerializer(serializers.Serializer): # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写 id = serializers.CharField() title = serializers.CharField() price = serializers.CharField()
在线格式化json
https://www.json.cn
获取一本id为3的书 http://127.0.0.1:8000/book/3
路由:
from api import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^books/$', views.BookView.as_view()), url(r'^book/(?P<id>\d+)$', views.Book.as_view()), ]
视图:
from django.shortcuts import render,HttpResponse from rest_framework.views import APIView from rest_framework.response import Response # Create your views here. from api import models # 想用这个类,需要导入 from api.MySerializer import BookSerializer class BookView(APIView): def get(self,request,*args,**kwargs): ret = { 'code':100, 'msg':'成功了' } books = models.Book.objects.all() # 第一个参数是要序列化的对象,如果序列化多条,必须指定many=True books_ser = BookSerializer(instance=books,many=True) # 当序列化的对象是单个对象的时候many=False book = models.Book.objects.all().first() # books_ser.data 就是序列化后的结果 是个字典 print(books_ser.data) ret['books']=books_ser.data # return Response(books_ser.data) return Response(ret) class Book(APIView): def get(self,requst,id): ret = { 'code': 100, 'msg': '成功了' } book = models.Book.objects.filter(pk=id).first() book_ser = BookSerializer(instance=book,many=False) ret['book']=book_ser.data return Response(book_ser.data)
如果序列化加个publish字段 (外键关联的)
拿到的是 "publish": "Publish object"
如果想显示出版社的名字,拿到出版社的id
可以通过source来改名!
变量名和source指定的值不能一样。
source还支持继续点(字段)还支持方法
序列化的类:
# 自己写一个序列化的类 from rest_framework import serializers class BookSerializer(serializers.Serializer): # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写 id = serializers.CharField() # title = serializers.CharField() name = serializers.CharField(source='title') price = serializers.CharField() publish_name = serializers.CharField(source='publish.name') publish_id = serializers.CharField(source='publish.pk')
拿出出版社所有的东西:SerializerMethodField()
意思是支持SerializerMethodField()这个方法,并且把返回值赋值给字段
固定写法:get_这个字段名字,里面有个参数obj,这个obj就是当前对象。
# 自己写一个序列化的类 from rest_framework import serializers class BookSerializer(serializers.Serializer): # 序列化哪个字段,必须跟数据库字段一样,都想序列化就一个一个排着写 publish_dic = serializers.SerializerMethodField() def get_publish_dic(self, obj): #意思是支持SerializerMethodField()这个方法,并且把返回值赋值给publish_dic return {'id':obj.publish.pk,'name':obj.publish.name,'email':obj.publish.email}
多对多的表关系: