Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用

  本文根据datawhale开源Djiango后端开发入门( https://github.com/Joe-2002/sweettalk-django4.2 )Task04:序列化器serializers及其应用做的学习笔记

一、学习目标

  序列化器 serializers的使用
  (1)序列化单个对象
  (2)序列化多个对象
  (3)序列关联对象(有外键)

二、serializers序列化器的理解

1 功能意义

  在前后端分离的设计模式中,后端只负责返回前端需要的数据。后端开发的每个视图都称为一个接口(API),前端通过接口进行数据增删改查。因此,需要将操作数据库将模型类对象转换成响应数据,比如Json(或者xml、yaml)的格式以及请求的数据(如json\xml、yaml格式的数据)转换成模型类对象。
   将 Django数据库中的数据(queryset 或者instance )转换为 json/xml/yaml数据格式,返回给前端过程称为序列化,相反过程称为反序列化。而实现这一过程运用的工具称为称为序列化器。Django提供的强大序列化工具叫做serializers(序列化器)。
  在开发REST API 接口时,视图中要频繁进行序列化和反序列化的编写,因此掌握serializers的使用非常重要

2 语法架构

  (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’))

3 执行过程

  ● 获取对象
data = Goods.objects.get(id=1);
data = Goods.objects.all() # 获取对象
  ● 创建序列化器
sberializer = GoodsSerializer(instance=data) #序列化单个对象
serializer = GoodsSerializer(instance=data,many=True) #序列化多个对象。many表示序列化多个对象,默认为单个。
  ● 输出数据 print(serializer.data)

4 应用举例–序列化转化的可视化表示

4.1 编程思路
     (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)之间的映射
4.2 编程实现

以下程序来源于datawhale开源Djiango后端开发入门( https://github.com/Joe-2002/sweettalk-django4.2

(1)models.py
    # 导包
    
    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='备注')
(2)serializer.py
       # 导包
       
       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任意选一,或者编程实现多选一)
(3) views.py
##导包

	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)
(4)urls.py
# 导包

	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()),
	]

4.3 输出结果

  (1) fields = (‘name’,) # 序列化不是外键的单个字段

Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用_第1张图片

  (2)fields = (‘name’,‘number’,> # 不带外键的多个字段

Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用_第2张图片

   (4) fields = (‘name’,‘number’,’ category ')# 序列化带外键的多个字段

Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用_第3张图片

  (5) fields = ‘all’# 序列化所有字段(注释了class里面的语句: category = GoodsCategorySerilizer())测试结果如下:

Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用_第4张图片

  (6) fields = ‘all’# 序列化所有字段,class类定义中,加上 category = GoodsCategorySerilizer() ,测试行结果如下:

Djiango后端开发入门学习之task04--serializers(序列化器,准确说是数据类型转化器)及应用_第5张图片

结论:对于有外键的,在全部字段序列化时要单独定义。否则虽然无报错提示,会有遗漏发生。

你可能感兴趣的:(学习,sqlite,数据库)