用于字典列表的 Django REST Framework 序列化程序

Django REST Framework serializer for a list of dictionaries

我是 Django REST Framework 的新手,正在寻找一种序列化字典列表的方法。

目标数据是时间序列。每个字典包含每小时值,每个列表包含一天的每小时值。

class Hourly:
   hour = None
   value = None

   def __init__(self, hour, value):
      self.hour = hour
      self.value = value


class Daily:
   date = None
   vlist = None

   def __init__(self, date, vlist):
      self.date = date
      self.vlist = vlist

按照 Django REST Framework API guide.

可以很容易地为每小时 class 创建序列化程序
class HourlySerializer(serializers.Serializer):

    hour = serializers.IntegerField(required=True, min_value=0, max_value=23)
    value = serializers.FloatField(required=True)

    def create(self, validated_data):
        return Hourly(**validated_data)

    def update(self, instance, validated_data):
        instance.hour = validated_data.get('hour', instance.hour)
        instance.value = validated_data.get('value', instance.value)
        return instance

我的 objective 很简单:为每日数据创建序列化程序。 (1) 序列化器必须限制数据长度为 24。 (2) 它应该具有验证每个小时数据的能力。


#1。使用 ListField

在限制数据长度的情况下,ListField 有参数 min_lengthmax_length #.

我认为这种代码可能是可行的 #,但是,API 指南没有说明将 ListFieldchild 定义为序列化程序。

class DailySerializer(serializers.Serializer):
    date = serializers.DateField(required=True)
    vlist = serializers.ListField(child=HourlySerializer(), min_length=24, max_length=24)


#2。使用 ListSerializer

API guide 说可以像嵌套字段一样嵌套序列化器。如果嵌套值是一个项目列表,many=True可以用来发起ListSerializer。但是,没有关于限制数据长度的争论。

class DailySerializer(serializers.Serializer):
    date = serializers.DateField(required=True)
    vlist = HourlySerializer(many=True)


这是我的问题:

  1. 使用ListField的方法可以没有问题吗?或者,我可以用 many=True 传递 min_lengthmax_length 参数吗?
  2. API 指南没有说明为 ListFieldListSerializer 定义 create()update()。只有没有 many 选项 # and a ListSerializer without non-list field # 的嵌套序列化器的情况。有这方面的例子吗?

回答我自己的问题。

class DailySerializer(serializers.Serializer):
   date = serializers.DateField(required=True)
   vlist = serializers.ListField(child=HourlySerializer(), min_length=24, max_length=24)

   def create(self, validated_data):
      return Daily(**validated_data)

   def update(self, instance, validated_data):
      instance.date = validated_data.get('date', instance.date)
      instance.vlist = validated_data.get('vlist', instance.vlist)
      return instance

以上 ListField 基于 DailySerializer 使用以下输入进行测试。

[
{'date': '2000-01-01', 'vlist': [{'hour':'00', 'value': '012'}, {'hour':'01', 'value': '123'}, ...],
{'date': '2000-01-02', 'vlist': [{'hour':'00', 'value': '012'}, {'hour':'01', 'value': '123'}, ...],
...,
]

为了处理额外的多日嵌套,视图中的serializer定义为many=True

serializer = DailySerializer(data=data, many=True)

测试结果如下:

  1. 使用ListField方法在验证过程中不会出现任何问题。
    将某个小时值更改为任意字符串被检测为非整数值。
    还检测到长度不等于24的每日数据。

  2. 将天真的 create()update() 方法与 ListField 一起使用可能会有问题。

  • obj_list = serializer.validated_data returns OrderedDict 对象列表。
  • obj_list = serializer.save() returns Daily 对象的列表。
    但是,obj_list[0].vlist 是 OrderedDict 对象的列表,而不是 Hourly 个对象。