Django12:序列化Django对象

本文介绍了Django REST framework在序列化和反序列化方面的应用,包括RESTful规范的解释,API设计的重要性,以及Django中序列化数据的示例,如序列化数据、反序列化数据以及支持的序列化格式。

1、简介

        Django REST framework (DRF)是用于构建Web API 的强大而灵活的工具包。它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架。而Django中自带的序列化框架提供了一种将 Django 模型“翻译”为其他格式的机制。

(1)RESTful

  • REST是一种标准,restful是一种规范,根据产品需求需要定出一份方便前后端的规范,与协议(如HTTP协议)不同,不是所有的标准要求都需要遵循。
  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
  • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
  • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

(2)API设计规范

        首先我们要知道,API并不是必须的,如果整个项目只有你一个人或者很少的人完成,完全可以直接用Django的模板引擎渲染发送到前端后直接操作。API的使用主要是为了解决多人开发,特别是前后端分离的情况。因为前端人员在制作页面时必然会需要向后端要数据,但是假如前后端是分离的,就不能用Django的render了,大部分情况前端会用ajax发送请求,后端人员则发送JSON字符串给前端,前端再反序列化后进行使用。这个时候其实我们设计一套API出来,就能使我们的任务轻松很多。所以,RestFramework就应运而生了。使用RestFramework设计API有一套规范,即RESTful。

(3)序列化

        api接口开发最核心最常见的一个代码编写过程就是序列化,所谓序列化就是把数据转换格式。常见序列化方式:json、pickle、base64、struct,…

序列化可分为两个阶段:

(i)序列化

        把我们识别的数据转换成指定的格式提供给别人。例如在django中获取到的数据默认是模型对象,但模型对象数据无法直接提供给前端或别的平台使用,所有需要把数据进行序列化,变成字符串或者json数据,提供给别人。

(ii)反序列化

        把别人提供的数据转换/还原成我们需要的格式。例如前端js提供过来的json数据,对于python而已json就是字符串,需要我们进行反序列化换成字典,然后接着字典再进行转换成模型对象,这样才能把数据保存到数据库中。

2、Django序列化

(1)序列化数据:

例1、序列化数据:

from django.core import serializers

data = serializers.serialize("xml", SomeModel.objects.all())

serialize :该函数的参数是数据序列化的目标格式 (查看 序列化格式)和用来序列化的 QuerySet。(实际上,第二个参数可以是任何生成 Django 模型实例的迭代器,但它几乎总是一个QuerySet)。

例2、使用序列化器对象

XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()

例3、序列化字段的子集

from django.core import serializers

data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))

        此例中将仅序列化每个模型的 name 和 size 属性。主键总是序列化为结果输出中的 pk 元素;它永远不会出现在 fields 部分。

(2)继承来的模型

        如果你有一个使用 抽象基类 定义的模型,那么你不必做任何特殊的事情来序列化该模型。对要序列化的一个(或多个)对象调用序列化程序,输出将是序列化对象的完整表示形式。但是,如果你有一个使用 多表继承 的模型, 则还需要序列化该模型的所有基类。这是因为只有在模型上本地定义的字段才会被序列化。例如,考虑以下模型:

例:

class Place(models.Model):
    name = models.CharField(max_length=50)

class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)

如果要序列化Restaurant及Place:
all_objects = [*Restaurant.objects.all(), *Place.objects.all()]
data = serializers.serialize('xml', all_objects)

3、反序列化数据

        序列化使用serialize,反序列化使用deserialize。

例:反序列化

for obj in serializers.deserialize("xml", data):
    do_something_with(obj)

        deserialize 函数与 serialize 函数采用相同的格式参数,字符串或数据流,并返回一个迭代器。deserialize 迭代器返回的对象 不是 常规的 Django 对象。相反,它们是特殊的 DeserializedObject 实例,实例封装了一个已创建 -- 但未保存 -- 的对象和任何相关联的数据。调用 DeserializedObject.save() 保存对象到数据库。

注意,如果序列化数据中的 pk 属性不存在或为 null,则会将新实例保存到数据库中。这可以确保反序列化是一个非破坏性操作,即使序列化表示中的数据与数据库中当前的数据不匹配。

例:反序列化后保存到数据库

for deserialized_object in serializers.deserialize("xml", data):
    if object_should_be_saved(deserialized_object):
        deserialized_object.save()

        Django 对象本身可以被像 deserialized_object.object 一样检查。如果模型中不存在序列化字段,将引发 DeserializationError 错误,除非将 ignorenonexistent 参数为 True 传入:

serializers.deserialize("xml", data, ignorenonexistent=True)

4、序列化格式

(1)可序列化格式

标识符

信息

xml

序列化和反序列化为一种简单地 XML 方言。

json

序列化和反序列化为 JSON

jsonl

Serializes to and from JSONL.

yaml

序列化为 YAML(YAML 不是标记语言)。此序列化器仅在 PyYAML 安装后可用。

例:

(i)models.py

from django.db import models


class Student(models.Model):
    name = models.CharField(verbose_name='姓名', max_length=20)
    age = models.IntegerField(verbose_name='年龄')

    class Meta:
        db_table = 'tb_student'
        verbose_name = '学生'
        verbose_name = verbose_name

(ii)view.py

from django.views import View
from django.http.response import JsonResponse
from .models import Student

class StudentView(View):
    # 获取数据
    def post(self, request):
        name = request.POST.get('name')
        age = request.POST.get('age')

         #保存数据
        instance = Student.objects.create(
            name = name,
            age = age,
        )

        # 返回结果
        return JsonResponse(data={
            'id':instance.pk,
            'name': instance.name,
            'age': instance.age,
        },status=201)

(iii)urls.py

1)app/urls.py

from django.urls import path
from .import views


urlpatterns = [
    path('students/', views.StudentView.as_view())
]

2)project/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('student.urls'))
]

调试:

http://192.168.28.128:8000/api/students/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值