2016-02-17 18 views
5

Yazılabilir bir yuvalanmış seri hale getirici oluşturmaya çalışıyorum. Ebeveyn modelim Oyun ve yuvalanmış modeller Ölçümlerdir. Bu verileri AJAX kullanarak DRF uygulamasına göndermeye çalışıyorum. Ancak, verileri göndermeye çalışırken, iç içe Ölçümler boş OrderedDict(). İşte Django Rest Framework birden çok iç içe geçmiş nesnelerle birlikte yazılabilir iç içe geçmiş seri hale getirici

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) 

benim serializers şunlardır: Oyun için

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 

Benim görüş şudur:

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

Ben yapı için this tutorial takip İşte

benim modellerdir. Ben AJAX üzerinden bu API için göndermek çalışıyorum

aşağıdaki kodu:

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

bu verileri gönderme, ben GameSerializer içinde oluşturmak yöntemde bulduğunuz validate_data.pop ('ölçümleri') boş olan 3 adet sipariş edilen sözlüklerin (OrderedDict()) bir listesini içerir.

GÜNCELLEME:

'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'] 

Herkes önce bu sorunu karşılaştı: Ben request.data yoluyla gelen initial_data şöyle yapılandırılmıştır olduğunu tespit ettik? Teşekkürler!

GÜNCELLEME 2.

benim MeasurementSerializer aşağıdaki ekleyerek (Ben bir çözümden çok geçici bir çözüm daha olduğuna inanıyoruz rağmen) bu sorunu çözmek için başardı:

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 

Ölçüm verileri geliyor bir Dict'a ihtiyacım olduğuna inandığımda bir QueryDict idi. Anahtar ve değerler etrafında da bazı ekstra parantezler vardı, bu yüzden de bunları kaldırmak zorunda kaldım.

Yine de bundan daha iyi bir cevap aramak!

+1

'self.initial_data.get ('ölçümler')' içinde neler olup bittiğini kontrol edebilir misiniz? Ve ayrıca, sadece güvenli tarafta olmak için: sunucunuzun aldığı JSON'u kontrol edin. (AJAX kodunuz gayet iyi görünüyor ve kesinlikle sunucuya olduğu gibi ulaşıyor - ama iyi ...) – Risadinha

+0

Kodunuzu birkaç kez inceledikten sonra bulabildiğim tek şey, belki de (belki!) Zaman damgasını göre ayrıştırılamıyor. senin desenine. Kendi serileştiricilerimle ve DRF örneğiyle de başka bir şey bulamıyorum. Zaman damgası isteğe bağlı olduğundan, belki de emin olmak için bu değerler olmadan test edebilirsiniz.Fakat sorun buysa, doğrulama hatalarını görmemenizin nedeni budur. – Risadinha

+0

@Risadinha initial_data yapısıyla güncelledim. Yapı çok aşina olmayan bir QueryDict. Aynı zamanda bir tarih biçimlendirme sorunu olmasına karşın yine aynı sorun olduğunda aynı düşünce zaman damgasını yapmadım. –

cevap

0

Burada sorun ön taraftadır. Varsayılan olarak sunucu application/x-www-form-urlencoded olarak ve bunu anlamak için sırayla veri yorumladığı bunu bir json gönderiyor, kendi $.ajax istekte contentType belirtmek gerekir: Şimdi

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

senin validated_data.pop('measurements') arasında create() yönteminde senin GameSerializer, measurements ile üç nesne vermelidir (ancak 2 numaralı güncelleştirmeden geçici çözümünüzü yinelemeyi unutmayın).

İlgili konular