序列化时如何在字段上应用转换?

How to apply a transformation on a field when serializing?

在 Django 中,如何在序列化字段时应用自定义转换?

例如,我有一个模型,它有一个 geometry 字段,它存储在一个特定的坐标系中。现在,对于这个序列化程序,我想执行将坐标转换为另一个坐标系的转换。这是怎么做到的?

序列化程序目前看起来像这样:

class LinkWithGeometrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Link
        fields = ['link_type',
                  'geometry',
                  ]

geometry 是应该对其应用转换的字段。

正如 Iklinac 指出的那样,您可以使用自定义字段,但只有在您可以重复使用它时才会有回报。

还有另外两种常见的方法:

将其保持在序列化程序级别:

class LinkWithGeometrySerializer(serializers.ModelSerializer):
    geometry = serializers.SerializerMethodField()
    class Meta:
        model = Link
        fields = ['link_type', 'geometry',]

    @staticmethod
    def get_geometry(obj: Link):
        # for example obtain srid from context, by passing it in via view or hardcode
        return obj.geometry.transform(srid=your_srid)

在模型层面(让数据库做转换):

在您看来:

from django.contrib.gis.db.models.functions import Transform
TARGET_SRID = 4326
class LinkView(RetrieveAPIVIew):
    queryset = Link.objects.annotate(transformed=Transform("geometry", TARGET_SRID))
    ...

或(srid 在 url 中作为路径组件传递):

from django.contrib.gis.db.models.functions import Transform
class LinkView(RetrieveAPIVIew):
    def get_queryset(self):
        return Link.objects.annotate(transformed=Transform("geometry", self.kwargs["srid"])

序列化器

class LinkWithGeometrySerializer(serializers.ModelSerializer):
    geometry = serializers.GeometryField(source='transformed') # [1]
    class Meta:
        model = Link
        fields = ['link_type', 'geometry',]

[1] https://github.com/openwisp/django-rest-framework-gis/blob/master/rest_framework_gis/fields.py#L13