本文根据datawhale开源Djiango后端开发入门( https://github.com/Joe-2002/sweettalk-django4.2 )Task04:序列化器serializers及其应用做的学习笔记
序列化器 serializers的使用
(1)序列化单个对象
(2)序列化多个对象
(3)序列关联对象(有外键)
在前后端分离的设计模式中,后端只负责返回前端需要的数据。后端开发的每个视图都称为一个接口(API),前端通过接口进行数据增删改查。因此,需要将操作数据库将模型类对象转换成响应数据,比如Json(或者xml、yaml)的格式以及请求的数据(如json\xml、yaml格式的数据)转换成模型类对象。
将 Django数据库中的数据(queryset 或者instance )转换为 json/xml/yaml数据格式,返回给前端过程称为序列化,相反过程称为反序列化。而实现这一过程运用的工具称为称为序列化器。Django提供的强大序列化工具叫做serializers(序列化器)。
在开发REST API 接口时,视图中要频繁进行序列化和反序列化的编写,因此掌握serializers的使用非常重要
(1)导入
from django.core import serializers #从djang.core导入它
(2)调用
serializers.serialize("json/xml/yaml", SomeModel.objects.all(),**kawg)
这个方法至少接收两个参数:要序列化成为的数据格式(如"/xml",“/yaml”,或者"xml等);要序列化的数据对象(如QuerySet,instance等)。如果你不想序列化模型对象所有字段的内容,只想序列化某些指定的字段,可以使用fields参数=序列化指定字段
如下所示:data = serializers.serialize(‘xml’, SomeModel.objects.all(), fields=(‘name’,‘size’))
● 获取对象
data = Goods.objects.get(id=1);
data = Goods.objects.all() # 获取对象
● 创建序列化器
sberializer = GoodsSerializer(instance=data) #序列化单个对象
serializer = GoodsSerializer(instance=data,many=True) #序列化多个对象。many表示序列化多个对象,默认为单个。
● 输出数据 print(serializer.data)
(1)编写models.py,提供序列化的数据源
(2)编写serializer.py,定义序列化类
(3)编写view.py, 实现序列化及其可视化功能
(4)编写urls.py,构建url和view.py功能函数之间链接
对应的功用描述表如下:
模块 | 功用 |
---|---|
models.py | 创建服务器里的Django数据表,提供数据源,供视图函数(存放在view.py)调用 |
serializer.py | 定义序列化器,提供给序列化函数(存放在view.py)调用 |
view.py | 编写调用apiview和创建序列化函数,实现序列化转换和可视化结果输出 |
urls.py | 建立URL请求和处理该请求的视图函数(存放在view.py)之间的映射 |
以下程序来源于datawhale开源Djiango后端开发入门( https://github.com/Joe-2002/sweettalk-django4.2
# 导包
from django.db.models import *
# 创建数据表
class GoodsCategory(Model): #产品分类表
name = CharField(max_length=64, verbose_name='名称')
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
class Goods(Model): #产品明细表
number = CharField(max_length=64,null=True, blank=True,verbose_name='编号')
name=CharField(max_length=64,null=True,blank=True,default=0,verbose_name='名称')
barcode = CharField(max_length=32,null=True, blank=True, default=None,verbose_name='条码')
category = ForeignKey(GoodsCategory, on_delete=SET_NULL, ull=True,blank=True,
default=None,related_name='goods_set', verbose_name='产品分类')
spec = CharField(max_length=64, null=True, blank=True, verbose_name='规格')
shelf_life_days = IntegerField(null=True, blank=True, verbose_name='保质期天数')
purchase_price = FloatField(default=0,null=True,blank=True,verbose_name='采购价')
retail_price = FloatField(default=0,null=True,blank=True,verbose_name='零售价')
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
# 导包
from rest_framework.serializers import *
from .models import *
#定义产品分类序列化器
class GoodsCategorySerializer(ModelSerializer):# 产品分类序列化器
class Meta:
model = GoodsCategory
fields = ('name', 'remark')
class GoodsSerializer(ModelSerializer):# 产品序列化器
category = GoodsCategorySerilizer() #外键字段相关的数据 需要单独序列化
class Meta:
model = Goods
fields = ('name',)# 序列化单个字段
fields = ('name','number',)# 序列化多个字段
fields = ('name','number',' category ')# 序列化多个字段
fields = '__all__'# 序列化所有字段
(上述fileds任意选一,或者编程实现多选一)
##导包
from django.shortcuts import render
from rest_framework.response import Response
from .models import *
from rest_framework.decorators import api_view
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from .serializer import *
##数据获取、序列化转化及其可视化
class GetGoods(APIView):
def get(self, request):
data = Goods.objects.all()
serializer = GoodsSerializer(instance=data, many=True)
# serializer = GoodsSerializer(instance=data, name=电影)
print(serializer.data)
return Response(serializer.data)
def post(self, request): # 从请求数据中提取字段
request_data = {
"category": request.data.get("Goodscategory"),
"number": request.data.get("number"),
"name": request.data.get("name"),
"barcode": request.data.get("barcode"),
"spec": request.data.get("spec"),
"shelf_life_days": request.data.get("shelf_life_days"),
"purchase_price": request.data.get("purchase_price"),
"retail_price": request.data.get("retail_price"),
"remark": request.data.get("remark"),
}
# 使用 create() 方法创建新的商品对象
new_goods = Goods.objects.create(**request_data)
# 对创建的对象进行序列化,并作为响应返回
serializer = GoodsSerializer(instance=new_goods)
return Response(serializer.data)
# 导包
from django.contrib import admin
from django.urls import path
from apps.erp_test.views import *
# url与view.py里函数映射表
urlpatterns = [
path('admin/', admin.site.urls),
path('getgoods/', GetGoods.as_view()),
]
(1) fields = (‘name’,) # 序列化不是外键的单个字段
![]() |
(2)fields = (‘name’,‘number’,> # 不带外键的多个字段
![]() |
(4) fields = (‘name’,‘number’,’ category ')# 序列化带外键的多个字段
![]() |
(5) fields = ‘all’# 序列化所有字段(注释了class里面的语句: category = GoodsCategorySerilizer())测试结果如下:
![]() |
(6) fields = ‘all’# 序列化所有字段,class类定义中,加上 category = GoodsCategorySerilizer() ,测试行结果如下:
![]() |
结论:对于有外键的,在全部字段序列化时要单独定义。否则虽然无报错提示,会有遗漏发生。