创新互联Django4.0教程:Django4.0迁移-序列化值

迁移是包含模型旧定义的 Python 文件,因此,要编写它们,Django 必须获取模型的当前状态并将它们序列化到一个文件中。

创新互联服务项目包括鹤壁网站建设、鹤壁网站制作、鹤壁网页制作以及鹤壁网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,鹤壁网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到鹤壁省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

虽然 Django 可以序列化大多数内容,但有些内容我们无法序列化为有效的 Python 表示形式——对于如何将值转换回代码,没有 Python 标准(​repr()​ 只适用于基本的值,而且没有指定导入路径)。

Django 可以序列化以下内容:

  • int​,​float​,​bool​,​str​,​bytes​,​None​,​NoneType
  • list​,​set​,​tuple​,​dict​,​range​。
  • datetime.date​,​datetime.time​ 和 ​datetime.datetime​ 实例(包括可识别时区的实例)
  • decimal.Decimal​ 实例
  • enum.Enum​ 实例
  • uuid.UUID​ 实例
  • functools.partial()​ 和具有可序列化 ​func​、​args ​和 ​keywords ​值的 ​functools.partialmethod​ 实例。
  • 来自 ​pathlib ​的具体的路径对象。 具体路径被转换为它们的纯路径等价物,例如 ​pathlib.PosixPath​ 到 ​pathlib.PurePosixPath​。
  • os.PathLike​ 实例,例如 ​os.DirEntry​,使用 ​os.fspath()​ 将其转换为 ​str ​或 ​bytes​。
  • 包含可序列化值的 ​LazyObject ​实例。
  • 枚举类型(例如 ​TextChoices ​或 ​IntegerChoices​)实例。
  • 任何 Django 字段
  • 任何函数或方法引用(如 ​datetime.datetime.today​)(必须在模块的顶层范围内)
  • 在类主体内部使用的未绑定方法
  • 任何类引用(必须在模块的顶层范围内)
  • 具有自定义 ​deconstruct() ​方法的任何东西(见下文)

Django 不能序列化:

  • 嵌套类
  • 任何类实例(例如 MyClass(4.3, 5.7))
  • 匿名函数

自定义序列化

你可以通过编写一个自定义的序列化器来序列化其他类型。例如,如果 Django 默认没有序列化 ​Decimal ​你可以这样做:

from decimal import Decimal

from django.db.migrations.serializer import BaseSerializer
from django.db.migrations.writer import MigrationWriter

class DecimalSerializer(BaseSerializer):
    def serialize(self):
        return repr(self.value), {'from decimal import Decimal'}

MigrationWriter.register_serializer(Decimal, DecimalSerializer)

MigrationWriter.register_serializer()​ 的第一个参数想要使用序列化器的程序类型或类型的可迭代对象。
序列化器的 ​serialize()​ 方法必须返回一个字符串,说明该值在迁移中应如何显示以及迁移中需要的一组导入。

添加 deconstruct() 方法

你可以通过给类一个 ​deconstruct()​ 方法来让Django序列化你的自定义类实例。它不带任何参数,应该返回一个三个项目组成的元组​ (path, args, kwargs)​:

  • path ​应该是该类的 Python 路径,并且类名作为最后一部分包括在内(例如,​myapp.custom_things.MyClass​)。如果你的类在模块的顶层不可用,那么它就不能被序列化。
  • args ​应该是一个位置参数的列表,用来传递给你的类的 ​__init__​ 方法。这个列表中的所有内容本身应该是可序列化的。
  • kwargs ​应该是一个关键字参数的字典,用来传递给你的类的 ​__init__​ 方法。每个值本身应该是可序列化的。

此返回值与自定义字段的 ​deconstruct()​ 方法不同,后者返回四个项组成的元组。

Django 会用给定的参数将值作为你的类的实例化写出来,类似于它写出对 Django 字段的引用的方式。
为了防止每次运行 ​makemigrations ​时都会创建一个新的迁移,你还应该在装饰类中添加一个 ​__eq__()​ 方法。这个函数将被 Django 的迁移框架调用,以检测状态之间的变化。
只要类构造函数的所有参数本身都是可序列化的,就可以使用 ​django.utils.deconstruct​ 的 ​@deconstructible​ 类装饰器添加 ​deconstruct()​ 方法:

from django.utils.deconstruct import deconstructible

@deconstructible
class MyCustomClass:

    def __init__(self, foo=1):
        self.foo = foo
        ...

    def __eq__(self, other):
        return self.foo == other.foo

装饰器添加逻辑以捕获并保留进入构造函数的参数,然后在调用 ​deconstruct()​ 时准确返回这些参数。

当前文章:创新互联Django4.0教程:Django4.0迁移-序列化值
网址分享:http://www.shufengxianlan.com/qtweb/news41/492091.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联