一:django自带序列化组件
Django内置的serializers(把对象序列化成json字符串) from django.core import serializers def test(request): book_list = models.Book.objects.all() ret = serializers.serialize('json', book_list) return HttpResponse(ret)
二: rest-framework序列化之Serializer
Serializer各种方法即单表查询
from django.db import models # Create your models here. class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField() publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name def test(self): return self.email
在app01中创建一个新的py文件,mySer.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from rest_framework import serializers class BookSerializer(serializers.Serializer): # 重命名 thisname = serializers.CharField(source='name') price = serializers.CharField() # 在source不光能指定字段的名字,还能指定函数的名字 test = serializers.CharField(source='publish.test') # 在source后这样写,能拿到表中的任意字段 # publish = serializers.CharField(source='publish.city') # source加.内容,判断点后面的是一个字段还是一个可执行的函数, # 是函数就加括号执行,是字段,取出对应的值给publish # SerializerMethodField可以制定一个方法 publish = serializers.SerializerMethodField() #方法名:叫get_字段名,要传参数,参数是:当前book对象 def get_publish(self, obj): dic = {'name': obj.publish.name,'email':obj.publish.email} return dic
详解如下
来到视图对象
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from app01 import models from app01.mySer import BookSerializer from django.http import JsonResponse # Create your views here. # Django内置的serializers(把对象序列化成json字符串) # from django.core import serializers # def test(request): # book_list = models.Book.objects.all() # ret = serializers.serialize('json', book_list) # return HttpResponse(ret) class Books(APIView): def get(self, request, *args, **kwargs): ret = models.Book.objects.all() # queryset对象 # 生成一个序列化对象,传参数 # 序列化多条,记住many=True book_ser = BookSerializer(ret, many=True) return JsonResponse(book_ser.data, safe=False)
总结以上内容
-1 重命名:用source:xx = serializers.CharField(source='name') -2 取出出版社名字: 方式一: -在模型表中重写__str__方法 -publish=serializers.CharField() 方式二: -用source -拿出出版社的城市 -publish=serializers.CharField(source='publish.city') *****如果不指定source,字段必须对应起来,如果指定了source,字段可以任意命名 -source 可以指定字段,也可也指定方法 publish.test这是个方法,会执行该方法,并拿到返回结果 test = serializers.CharField(source='publish.test') -3 SerializerMethodField,可以指定一个方法 publish=serializers.SerializerMethodField() # 方法名:叫get_字段名,要传参数,参数是:当前book对象 def get_publish(self,obj): # obj 是当前book对象 dic={'name':obj.publish.name,'email':obj.publish.email} return dic -方法内部可以继续用其他的序列化类 -ModelSerializer -必须在类中写 class Meta: model=指定表 # fields = '__all__' # 指定只取这两个字段 fields = ['nid','name'] # 去掉指定的字段 # exclude=['publish','authors'] # fields,跟exclude不能连用 # 指定深度,就是跨几个表(官方建议小于10,我给你的建议小于3) # depth = 2
Serializer序列化的跨表查询
在postman中的运行效果
效果不好的话将代码复制到www.json.cn中,可以折叠,看起来更清晰,即
如果不想写for循环,还有一种方法
在mySer中写上
# 作者的序列化的类 class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField()
在图书序列化的类下面 写方法
# 通过上面的作者的序列化的类来实现 def get_authors(self, obj): auths = obj.authors.all()
#可以继续用序列化来处理
auth_ser=AuthorSerializer(auths,many=True) return auth_ser.data
这样,在视图函数中一样能拿到图书的作者们
三:serializers.ModelSerializer序列化方法
第一种方式(类中类)
在mySer.py中
from app01.models import Book class BookSerializer(serializers.ModelSerializer): # 不用按字段,直接序列化到表模型 #必须写一个内部内,名字必须交Meta class Meta: model=Book fields='__all__' #闹出book表的所有字段
postman运行结果会出现这样,publish和authors都是id
那么在
#重写属性 publish=serializers.CharField(source='publish.name')
在mySer中写
authors=serializers.SerializerMethodField() def get_authors(self,book): auths=book.authors.all() auth_ser=AuthorSerializer(auths,many=True) return auths.data
第二种方式:depth=? 深度(跨表查询,可控性查,效率低)
ModelSerializer -必须在类中写 class Meta: model=指定表 # fields = '__all__' # 指定只取这两个字段 fields = ['nid','name'] # 去掉指定的字段 # exclude=['publish','authors'] # fields,跟exclude不能连用 # 指定深度,就是跨几个表(官方建议小于10,我给你的建议小于3) # depth = 2