# P10 Django Serialization 序列化的高级使用
  


**序列化器** `serializers`

**序列化器的作用**  
> Django 序列化是将 Python 对象转换为可在网络上传输或存储的数据格式的过程，以及将这些数据格式反序列化回 Python 对象的过程。序列化通常用于将数据转换为 JSON、XML 或其他格式，以便在应用程序之间进行数据交换或在不同部分之间进行数据传输。
  
- 序列化将 `queryset` 和 `instance` 转换为 `json/xml/yaml` 返回给前端  

- 反序列化与序列化则相反  


`Django` 提供了一个名为 `serializers` 的模块，其中包含用于序列化和反序列化数据的工具。下面是一些在 `Django` 中进行序列化的常见用法：

1. 使用 `Django` 内置的 `serializers` 模块进行序列化和反序列化。
  
```python
from django.core import serializers

# 序列化 QuerySet 为 JSON
data = serializers.serialize('json', MyModel.objects.all())

# 反序列化 JSON 数据并保存到数据库
for obj in serializers.deserialize('json', data):
    obj.save()  
```  

2. 使用 `Django` 的 `JsonResponse` 来将模型数据作为 `JSON` 响应返回给客户端。  
  
```python
from django.http import JsonResponse

def get_data(request):
    data = list(MyModel.objects.values())
    return JsonResponse(data, safe=False)  
```  

3. 使用第三方库如 `Django Rest Framework（DRF）` 来构建 `RESTful API` 并进行序列化。`DRF` 提供了强大的序列化和反序列化功能，以及视图、路由和其他 `API` 开发工具。  

```python
from rest_framework import serializers

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = '__all__'
```  

以上是一些基本的 `Django` 序列化概念和示例。根据需求和项目的复杂性，可以选择不同的序列化方法和工具。
  

**定义序列化器**

定义类，继承自 `Serializer`

通常新建一个 `serializers.py` 文件 撰写序列化内容

- `suah as`   目前只支持

- `read_only` 只读

- `label`     字段说明信息

- `max_length` 最大长度  

**serializer.py**

```python
# 定义产品序列化器
from rest_framework.serializers import *
from .models import *

# 产品分类序列化器
class GoodsCategorySerializer(ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ('name', 'remark')

# 产品序列化器
class GoodsSerializer(ModelSerializer):
    # 外键字段相关的数据 需要单独序列化
    category = GoodsCategorySerializer()

    class Meta:
        # 指定 model
        model = Goods

        # 序列化单个字段
        fields = ('name',)

        # 序列化多个字段
        fields = ('name','number',)

        # 序列化所有字段
        fields = '__all__'

```  

**views.py**

```python
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)
        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)
```

**urls.py**

```python
from django.contrib import admin
from django.urls import path
from apps.erp_test.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
    path('filtergoodscategory/', FilterGoodsCategory),
    path('filtergoodscategoryapi/', FilterGoodsCategoryAPI.as_view()),
    path('getgoods/', GetGoods.as_view()),
]
```

**a. 序列化单个对象**

- 获取对象  `data = Goods.objects.get(id=1)`  
- 创建序列化器 `serializer = GoodsSerializer(instance=data)`
- 转换数据 `print(serializer.data)`
- 注意点：

    `instance` 是一个参数，用于指定要序列化或反序列化的 `Python` 对象。具体来说，它是一个类实例 `(Class Instance)`,通常是指一个从数据库或其他数据源中检索出来的模型实例 `(Model Instance)`。

    当我们需要将一个模型实例转换为 `JSON` 或其他格式时，可以使用 `Django` 的序列化器 `(Serializer)` 来实现。
- 输出：

    ```json
        {'id': 1, 'number': '1', 'name': '第一个产品', 'purchase_price': 100.0, 'retail_price': 150.0, 'remark': '测试产品'}
    ```

**b. 序列化多个对象**

  ```python
  data = Goods.objects.all() # 获取对象

  # 创建序列化器，many表示序列化多个对象，默认为单个
  serializer = GoodsSerializer(instance=data,many=True)

  print(serializer.data) # 转换数据

  # 输出：
  [OrderedDict([('id', 1), ('number', '1'), ('name', '第一个产品'), ('purchase_price', 100.0), ('retail_price', 150.0), ('remark', '测试产品')]), OrderedDict([('id', 2), ('number', '123'), ('name', '产品2'), ('purchase_price', 123.0), ('retail_price', 4123.0), ('remark', '测试产品2')])]  
  ```
