简体   繁体   中英

Posting multiple values to a single field in django rest framework?

I'm using Django Rest Framework and I'm trying to post multiple value types to a single field in my serializer class. For example, I want to post values for "Temp (C)", "Humidity(%)", "Pyra(WPM)" all under the "value" field.

I'm using extra_kwargs in my serializer class to tell my "value" field to accept the different value types I post to it. However, when I try to post using Postman, only the value for the first matching field ("Temp (C)" in this case) will get posted, not all the others. I was wondering if there was a way to have all the field types posted so I don't have to make a new post request for every value type I need?

I know I could hardcode these value names into my models.py and serializer.py, but I need to keep models.py how it is right now.

Also, here is an example of the JSON I'm trying to post:

{"Node ID": "2", "Temp (C)": "22.6", "Humidity(%)": "29.67", "Pyra (WPM)": "118.9", "System Time": "1592287220"}

This is the response I get:

{ "id": 80, "System Time": 1592287220.0, "Node ID": "2", "Temp (C)": 22.6, "units": null, "valueName": null }

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)

For anybody else struggling with posting multiple values look into the bulk_create Django method to post multiple lines of data: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#bulk-create .

Bulk_create isn't exactly what I was originally trying to do but it is the best solution I have come across. It also significantly increases posting speed which is a huge plus.

If i understand you problem you want to save a instance of DataValueTable for each item of extra_kwargs , you can do something like this:

    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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM