2016-02-17 23 views
5

書き込み可能なネストされたシリアライザを作成しようとしています。私の親モデルはGameで、入れ子モデルはMeasurementsです。このデータをAJAXを使用してDRFアプリケーションに投稿しようとしています。しかし、データをポストしようとすると、ネストされたMeasurementsは空のOrderedDict()になります。ここでDjango Rest Framework複数のネストされたオブジェクトを持つ書き込み可能なネストされたシリアライザ

は私のモデルです:

ここ
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) 

は私のシリアライザは、以下のとおりです。ゲームのための

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 

私の見解は以下の通りです:

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

私は構造のためthis tutorialを追いました。私は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){}) 
}); 

このデータを掲示する上では、私はGameSerializer内に作成する方法で見つけることvalidate_data.pop(「測定」)空の3つの順序付き辞書(OrderedDict())のリストが含まれています。

UPDATE:私はinitial_dataはrequest.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'] 

は、誰もが前に、この問題が発生していますか?ありがとう!

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 

測定データが来る:私は、この(私はそれが解決策よりも回避策の詳細です信じていますが)私のMeasurementSerializerに以下を追加することで解決することができた

UPDATE#2

私はDictが必要だと思ったときにQueryDictでした。キーと値の周りに余分な括弧もいくつかあったので、それらも削除しなければなりませんでした。

これよりも優れた回答を探しています。

+1

'self.initial_data.get( 'measurements')'の内容を確認できますか?また、安全な側にあること:あなたのサーバーが受け取ったJSONを確認してください。 (あなたのAJAXコードはうまく見えますが、確かに意図したとおりにサーバーに到達しますが、よく...) – Risadinha

+0

あなたのコードを何度も見た後に見つけることができるのは、たぶんあなたのタイムスタンプがあなたのパターンに。私は自分自身のシリアライザやDRFの例と比較して、他のものを見つけることはできません。タイムスタンプはオプションなので、これらの値を使わずにテストしてみてください。しかし、それが問題ならば、なぜあなたは検証エラーを見ていないのだろうか。 – Risadinha

+0

@Risadinha initial_data構造で更新しました。その構造はQueryDictです。これはあまりよく知られていません。 日付の書式設定の問題であっても同じ問題が発生した場合に備え、タイムスタンプを作成する必要はありません。 –

答えて

0

ここでの問題はフロントエンド側です。デフォルトでは、サーバはapplication/x-www-form-urlencodedとしてデータを解釈し、それはあなたがそれをjsonを送信していることを理解するためには、あなたの$.ajaxリクエストでcontentTypeを指定する必要があります。あなたのcreate()方法で

$.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){}); 

今すぐあなたのvalidated_data.pop('measurements')GameSerializermeasurementsで3つのオブジェクトを生成する必要があります(しかし、更新#2の回避策をやり直すことを忘れないでください)。