【问题标题】:Posting multiple values to a single field in django rest framework?将多个值发布到 django rest 框架中的单个字段?
【发布时间】:2020-10-26 23:39:45
【问题描述】:

我正在使用 Django Rest Framework,并尝试将多个值类型发布到我的序列化程序类中的单个字段。例如,我想在“value”字段下发布“Temp (C)”、“Humidity(%)”、“Pyra(WPM)”的值。

我在我的序列化程序类中使用 extra_kwargs 来告诉我的“值”字段接受我发布到它的不同值类型。但是,当我尝试使用 Postman 发布时,只会发布第一个匹配字段的值(在这种情况下为“Temp (C)”),而不是所有其他字段的值。我想知道是否有办法发布所有字段类型,这样我就不必为我需要的每个值类型都发出新的发布请求?

我知道我可以将这些值名称硬编码到我的 models.py 和 serializer.py 中,但我需要让 models.py 保持现在的状态。

另外,这是我尝试发布的 JSON 示例:

{“节点 ID”:“2”、“温度 (C)”:“22.6”、“湿度 (%)”:“29.67”、“Pyra (WPM)”:“118.9”、“系统时间” :“1592287220”}

这是我得到的回复:

{ “身份证”:80, “系统时间”:1592287220.0, "节点 ID": "2", “温度(C)”:22.6, “单位”:空, “值名称”:空 }

models.py

class DataValueTable(models.Model):
    timestamp = models.FloatField()
    sensorName = models.TextField(null=True)
    valueName = models.CharField(max_length=100, null=True)
    value = models.FloatField()
    units = models.CharField(max_length=100, null=True)

serializer.py

class DataValueTableSerializer(serializers.ModelSerializer):
    class Meta:
        model = DataValueTable
        fields = ['id', 'System Time', 'Node ID', 'Temp (C)', 'units', 'valueName']
        extra_kwargs = {
            "Node ID": {"source": "sensorName"},
            "System Time": {"source": "timestamp"},
            "Temp (C)": {"source": "value"},
            "Humidity(%)": {"source": "value"},
            "Pyra(WPM)": {"source": "value"},
        }

    def create(self, validated_data):
        return DataValueTable.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.timestamp = validated_data.get('timestamp', instance.timestamp)
        instance.sensorName = validated_data.get('sensorName', instance.sensorName)
        instance.valueName = validated_data.get('valueName', instance.valueName)
        instance.value = validated_data.get('value', instance.value)
        instance.units = validated_data.get('units', instance.units)
        instance.save()
        return instance

views.py

class DataValueTableList(APIView):

    parser_classes = [JSONParser]

    def get(self, request, format=None):
        info = DataValueTable.objects.all()
        serializer = DataValueTableSerializer(info, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = DataValueTableSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【问题讨论】:

  • 如果您需要在同一个字段中存储各种值,有几种方法可以做到这一点,就数据库设计而言。一种是拥有一个可以支持值列表的字段(我相信 Django 中的ArrayField),或者您可以将该字段抽象到它自己的表中,并将其与当前所在的表相关联。对于您当前的设计,您需要在表中有多个条目,每个条目都有 value 字段的唯一信息,因为该字段每个条目只接受一个值。

标签: python django django-rest-framework postman serialization


【解决方案1】:

对于其他难以发布多个值的人,请查看 bulk_create Django 方法来发布多行数据:https://docs.djangoproject.com/en/3.0/ref/models/querysets/#bulk-create

Bulk_create 并不是我最初想要做的,但它是我遇到的最佳解决方案。它还显着提高了发布速度,这是一个巨大的优势。

【讨论】:

    【解决方案2】:

    如果我理解你的问题,你想为extra_kwargs 的每个项目保存一个DataValueTable 的实例,你可以这样做:

        def create(self, validated_data):
            for key in self.extra_kwargs.keys():
                data_value = validated_data.get(key)
                if data_value:
                    DataValueTable.objects.create(valueName=key, value=data_value, **validated_data)
    

    【讨论】:

    • 是的!我想这就是我想要做的。我试过你的代码,它似乎没有改变任何东西,但它看起来就像我想要做的一样。我可能只需要玩弄它。 extra_kwargs 仅在元类中定义,因此我也必须将您的 def create 放入元类中。你认为这就是它没有改变任何东西的原因吗?
    • 是的,你需要把create方法放在元类之外,你需要找到一种方法把extra_kwargs嵌入create方法
    猜你喜欢
    • 2018-01-15
    • 2017-12-25
    • 2019-07-05
    • 2020-05-12
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多