[Django 0-1] Core.Serializers 模块

发布于:2024-05-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

Core.Serializers 模块

Django 序列化模块

模块结构

.
├── __init__.py
├── base.py
├── json.py
├── jsonl.py
├── python.py
├── pyyaml.py
└── xml_serializer.py

1 directory, 7 files

自定义序列化器

通过继承django.core.serializers.base.Serializer类,可以自定义序列化器。


    def serialize(
        self,
        queryset,
        *,
        stream=None,
        fields=None,
        use_natural_foreign_keys=False,
        use_natural_primary_keys=False,
        progress_output=None,
        object_count=0,
        **options,
    ):
        """
        Serialize a queryset.
        """
        self.options = options

        self.stream = stream if stream is not None else self.stream_class()
        self.selected_fields = fields
        self.use_natural_foreign_keys = use_natural_foreign_keys
        self.use_natural_primary_keys = use_natural_primary_keys
        progress_bar = self.progress_class(progress_output, object_count)

        self.start_serialization()
        self.first = True
        for count, obj in enumerate(queryset, start=1):
            self.start_object(obj)
            # Use the concrete parent class' _meta instead of the object's _meta
            # This is to avoid local_fields problems for proxy models. Refs #17717.
            concrete_model = obj._meta.concrete_model
            # When using natural primary keys, retrieve the pk field of the
            # parent for multi-table inheritance child models. That field must
            # be serialized, otherwise deserialization isn't possible.
            if self.use_natural_primary_keys:
                pk = concrete_model._meta.pk
                pk_parent = (
                    pk if pk.remote_field and pk.remote_field.parent_link else None
                )
            else:
                pk_parent = None
            for field in concrete_model._meta.local_fields:
                if field.serialize or field is pk_parent:
                    if field.remote_field is None:
                        if (
                            self.selected_fields is None
                            or field.attname in self.selected_fields
                        ):
                            self.handle_field(obj, field)
                    else:
                        if (
                            self.selected_fields is None
                            or field.attname[:-3] in self.selected_fields
                        ):
                            self.handle_fk_field(obj, field)
            for field in concrete_model._meta.local_many_to_many:
                if field.serialize:
                    if (
                        self.selected_fields is None
                        or field.attname in self.selected_fields
                    ):
                        self.handle_m2m_field(obj, field)
            self.end_object(obj)
            progress_bar.update(count)
            self.first = self.first and False
        self.end_serialization()
        return self.getvalue()

start_serialization方法

序列化开始,可以在这个方法内定义一些初始化操作,或者日志或者提前的数据准备工作。

start_object方法

每个对象序列化开始时调用。

end_object方法

每个对象序列化结束时调用。

handle_field方法

对象字段序列化时调用。

handle_fk_field方法

处理外键字段时调用。

handle_m2m_field方法

处理多对多字段时调用。

getvalue方法

返回序列化结果。

总结

Django 提供了一系列格式的序列化器使用,包括json,jsonl,yaml,xml,python等。
通过继承Serializer类,可以自定义序列化器。自定义后的序列化器可以通过在settings.py配置 SERIALIZATION_MODULES 变量将自定义的序列化器注册到 Django serializers 工作流中,而无需使用时自己调用。

# settings.py
SERIALIZATION_MODULES = {
    "msgpack": "path.to.msgpack.Serializer",
}

# other.py
from django.core import serializers

serializers.serialize("msgpack", queryset) # 避免了项目中直接导入自定义序列化器使用

网站公告

今日签到

点亮在社区的每一天
去签到