django djano支持嵌套或平面值为一个单一的字段使用单一的串行器

nkkqxpd9  于 2023-02-25  发布在  Go
关注(0)|答案(1)|浏览(129)

我有一个DateRangeSerializer序列化器,用于验证有效负载。

import rest_framework.serializers as serializer

from django.conf import settings

class ValueNestedSerializer(serializer.Serializer):
    lower = serializer.DateTimeField(input_formats=settings.DATETIME_INPUT_FORMATS, required=True)
    upper = serializer.DateTimeField(input_formats=settings.DATETIME_INPUT_FORMATS, required=True)
    

class DateRangeSerializer(serializer.Serializer):
    attribute = serializer.CharField(default="UPLOAD_TIME", allow_null=True)
    operator = serializer.CharField(default="between_dates")
    value = ValueNestedSerializer(required=True) <---- this could be set to `False` to address the issue
    # lower = serializer.DateTimeField()
    # upper = serializer.DateTimeField()
    timezone = serializer.CharField(default="UTC")
    timezoneOffset = serializer.IntegerField(default=0)

相应的有效载荷:

"date_range": {
        "attribute": "date_range",
        "operator": "between_dates",
        "value": {
            "lower": "2023-01-06T00:00:00Z",
            "upper": "2023-02-05T23:59:59Z"
        }
    }

这里value字段是nested,但是很少有lowerupperflat值并且没有嵌套的实现。
例如:

"date_range": {
        "lower": "2023-01-21T00:00:00Z",
        "upper": "2023-02-21T23:59:59Z"
    }

现在,我可以设置value required=False并将lower/upper添加为平面字段,就像我在上面的评论中提到的那样,但是我想更"正确"地执行它。
有没有其他方法可以同时处理nestedflat的上下值的有效负载?

pod7payv

pod7payv1#

您可以向序列化程序传递一个额外的上下文,指示您是否需要一个平面响应,并通过使用这样的键(我称之为flat)覆盖.to_representation钩子来修改响应:
serializers.py

class ValueNestedSerializer(serializer.Serializer):
    lower = serializer.DateTimeField(input_formats=settings.DATETIME_INPUT_FORMATS, required=True)
    upper = serializer.DateTimeField(input_formats=settings.DATETIME_INPUT_FORMATS, required=True)
    

class DateRangeSerializer(serializer.Serializer):
    attribute = serializer.CharField(default="UPLOAD_TIME", allow_null=True)
    operator = serializer.CharField(default="between_dates")
    value = ValueNestedSerializer(required=True)
    timezone = serializer.CharField(default="UTC")
    timezoneOffset = serializer.IntegerField(default=0)

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        flat = self.context.pop('flat', None)
        if flat:
            for key, value in representation['value'].items():
                representation[key] = value
            representation.pop('value')

        return representation

views.py 示例

class DateRangeAPIView(views.APIView):
    def get(self, request):
        value = {
            'lower': datetime.now(), 
            'upper': datetime.now() + timedelta(hours=1, minutes=42, seconds=42)
        }
        data = {'attribute': 'date_range', 'operator': 'between_dates', 'value': value}

        serializer = DateRangeSerializer(data=data, context={'flat': True})
        serializer.is_valid(raise_exception=True)
        
        return Response(serializer.data)

您只需省略context={'flat': True}即可获得正常响应,例如DateRangeSerializer(data=data)

相关问题