简体   繁体   English

Django Rest Framework可写嵌套序列化器,具有多个嵌套对象

[英]Django Rest Framework writable nested serializer with multiple nested objects

I'm trying to create a writable nested serializer. 我正在尝试创建一个可写的嵌套序列化程序。 My parent model is Game and the nested models are Measurements. 我的父模型是Game,嵌套模型是Measurements。 I am trying to post this data to my DRF application using AJAX. 我试图使用AJAX将此数据发布到我的DRF应用程序。 However, when try to post the data, the nested Measurements are empty OrderedDict(). 但是,当尝试发布数据时,嵌套的测量值为空OrderedDict()。

Here are my models: 这是我的模特:

class Game(models.Model):
    start_timestamp = models.DateTimeField(auto_now_add=False)
    end_timestamp = models.DateTimeField(auto_now_add=False)
    date_added = models.DateTimeField(auto_now_add=True)


class Measurement(models.Model):
    game = models.ForeignKey(Game, on_delete=models.PROTECT, related_name='measurements')
    measurement_type = models.CharField(max_length=56)
    measurement = models.CharField(max_length=56)
    timestamp = models.DateTimeField(auto_now_add=False)
    date_added = models.DateTimeField(auto_now_add=True)

Here are my serializers: 这是我的序列化器:

class MeasurementSerializer(serializers.ModelSerializer):
        timestamp = serializers.DateTimeField(input_formats=(['%Y-%m-%d %H:%M:%S.%Z', 'iso-8601']), required=False)

        class Meta:
            model = Measurement
            fields = ('measurement_type', 'measurement', 'timestamp')


class GameSerializer(serializers.ModelSerializer):
    start_timestamp = serializers.DateTimeField(input_formats=(['%Y-%m-%d %H:%M:%S.%Z', 'iso-8601']))
    end_timestamp = serializers.DateTimeField(input_formats=(['%Y-%m-%d %H:%M:%S.%Z', 'iso-8601']))
    measurements = MeasurementSerializer(many=True)

    class Meta:
        model = Game
        fields = ('id', 'start_timestamp', 'end_timestamp', 'measurements')

    def create(self, validated_data):
        measurements = validated_data.pop('measurements')
        game = Game.objects.create(**validated_data)
        for measurement in measurements:
            Measurement.objects.create(game=game, **measurement)
        return game

My view for Game is the following: 我对游戏的看法如下:

class GameList(generics.ListCreateAPIView):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

I followed this tutorial for the structure. 我按照本教程的结构。

I am trying to post to this API via AJAX, the code below: 我试图通过AJAX发布到这个API,代码如下:

 $.ajax({
         url: base_url + '/games/',
         dataType: "json",
         data: {
                "start_timestamp": "2016-02-16 14:51:43.000000",
                "end_timestamp": "2016-02-16 14:53:43.000000",
                "measurements":[
                    {'measurement_type':'type1', 'measurement':'71', 'timestamp':'2016-02-16 14:53:43.000000'},
                    {'measurement_type':'type1', 'measurement':'72', 'timestamp':'2016-02-16 14:54:43.000000'},
                    {'measurement_type':'type1', 'measurement':'73', 'timestamp':'2016-02-16 14:55:43.000000'},
                ]
                },
         type: 'POST'
     })
     .error(function(r){})
     .success(function(data){})
 });

On posting this data, I find in the create method within the GameSerializer that the validate_data.pop('measurements') contains a list of 3 ordered dictionaries (OrderedDict()) that are empty. 在发布此数据时,我在GameSerializer的create方法中发现validate_data.pop('measurements')包含一个空的3个有序字典(OrderedDict())的列表。

UPDATE: I've found that that the initial_data coming in via request.data is structured like so: 更新:我发现通过request.data进入的initial_data的结构如下:

'emotion_measurements[0][measurement_type]' (4397175560) = {list} ['type1']
'emotion_measurements[0][measurement]' (4397285512) = {list} ['71']
'emotion_measurements[0][timestamp]' (4397285600) = {list} ['2016-02-16 14:53:43.000000']
'emotion_measurements[1][measurement_type]' (4397175040) = {list} ['type1']
'emotion_measurements[1][measurement]' (4397285864) = {list} ['72']
'emotion_measurements[1][timestamp]' (4397285952) = {list} ['2016-02-16 14:54:43.000000']
'emotion_measurements[2][measurement_type]' (4397175040) = {list} ['type1']
'emotion_measurements[2][measurement]' (4397285864) = {list} ['73']
'emotion_measurements[2][timestamp]' (4397285952) = {list} ['2016-02-16 14:55:43.000000']

Has anyone encountered this issue before? 有没有人遇到过这个问题? Thanks! 谢谢!

UPDATE #2 更新#2

I was able to resolve this (although I believe it is more of a workaround than a solution) by adding the following to my MeasurementSerializer: 通过在MeasurementSerializer中添加以下内容,我能够解决这个问题(虽然我认为它更像是解决方法而不是解决方案):

def to_internal_value(self, data):
        formatted_data = json.dumps(data)
        formatted_data = formatted_data.replace("[", "").replace("]","")
        formatted_data = json.loads(formatted_data)
        return formatted_data

The Measurement data coming in was a QueryDict when I believe I needed a Dict. 当我相信我需要一个Dict时,测量数据是一个QueryDict。 There were also some extra brackets around the key and values so I had to remove those as well. 键和值周围还有一些额外的括号,所以我也必须删除它们。

Still seeking a better answer than this! 仍在寻求比这更好的答案!

The problem here is on the front-end side. 这里的问题是在前端。 By default the server interprets the data as application/x-www-form-urlencoded and in order for it to understand that you are sending it a json , you need to specify the contentType in your $.ajax request: 默认情况下,服务器将数据解释为application/x-www-form-urlencoded并且为了使其了解您正在向其发送json ,您需要在$.ajax请求中指定contentType

$.ajax({
     url: base_url + '/games/',
     dataType: "json",
     data: {...},
     contentType: 'application/json; charset=UTF-8',  // add this line
     type: 'POST'
 })
 .error(function(r){})
 .success(function(data){});

Now your validated_data.pop('measurements') in create() method of your GameSerializer should yield three objects with your measurements (but don't forget to redo your workaround from Update#2). 现在,您的GameSerializer create()方法中的validated_data.pop('measurements')应该产生三个measurements对象(但不要忘记从Update#2重做您的解决方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 django-rest-framework 中的可写嵌套序列化程序? - Writable nested serializer in django-rest-framework? 在Django Rest Framework 3中使用可写的嵌套序列化程序创建多个对象 - create multiple objects using writable nested serializers in django rest framework 3 Django Rest框架| 可写的多个嵌套关系 - Django Rest Framework | Writable multiple nested relations Django Rest Framework 可写嵌套序列化程序引发 AttributeError - Django Rest Framework writable nested serializer raises AttributeError Django rest 框架 - writable(create,update) 双嵌套序列化器 - Django rest framework- writable(create,update) double nested serializer 如何在 Django REST Framework 中创建多个模型实例而无需重复的可写嵌套序列化程序? - How to create multiple model instances without duplicated writable nested serializer in Django REST Framework? Django Rest使用可写的嵌套序列化器创建 - Django Rest Create with a Writable Nested Serializer Django Rest Framework嵌套序列化器 - Django Rest Framework nested serializer 在Django Rest Framework中使用预先存在的对象创建嵌套序列化程序的问题 - Issues creating a nested serializer in Django Rest Framework with pre existing objects Django Rest Framework 序列化程序嵌套对象内部服务器错误 500 - Django Rest Framework serializer nested objects internal server error 500
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM