2015-06-05 38 views
5

'un validated_data'ında model dışı bir alan elde edilemiyor Django modellerimde ItemCollection ve Öğelerim var ve Koleksiyondaki öğeleri Kullanıcı Arabirimi aracılığıyla kaldırmak istiyorum. Bir REST PUT isteğinde, bir Öğenin silinmesi gerektiğini bildirmek için her bir Öğe için deleted ek bir boole alanı ekleyin.Django Rest Framework serileştiricisi

Bunu işlemenin doğru yolu, Serializer'ın update yönteminde görünüyor. Benim sorunum, bu olmayan model deleted alanının doğrulama sırasında kaldırıldığından, artık kullanılamaz. deleted'un SerializerMethodField olarak eklenmesi işe yaramadı. Şimdilik, Serializer'ın initial_data özniteliğindeki deleted bilgilerimi aldım, ancak bu doğru hissetmiyor.

Şu andaki örnek kodum aşağıda. Daha iyi bir yaklaşım bilen var mı?

Modeller:

class ItemCollection(models.Model): 
     description = models.CharField(max_length=256) 


    class Item(models.Model): 
     collection = models.ForeignKey(ItemCollection, related_name="items") 

Serileştiriciler:

from django.shortcuts import get_object_or_404 
    from rest_framework.views import APIView 
    from rest_framework.response import Response 
    from rest_framework import serializers 
    from models import Item, ItemCollection 


    class ItemSerializer(serializers.ModelSerializer): 

     class Meta: 
      model = Item 


    class ItemCollectionSerializer(serializers.ModelSerializer): 

     items = ItemSerializer(many=True, read_only=False) 

     class Meta: 
      model = ItemCollection 

     def update(self, instance, validated_data): 
      instance.description = validated_data['description'] 
      for item, item_obj in zip(
        self.initial_data['items'], validated_data['items']): 
       if item['delete']: 
        instance.items.filter(id=item['id']).delete() 
      return instance 


    class ItemCollectionView(APIView): 

     def get(self, request, ic_id): 
      item_collection = get_object_or_404(ItemCollection, pk=ic_id) 
      serialized = ItemCollectionSerializer(item_collection).data 
      return Response(serialized) 

     def put(self, request, ic_id): 
      item_collection = get_object_or_404(ItemCollection, pk=ic_id) 
      serializer = ItemCollectionSerializer(
       item_collection, data=request.data) 
      if serializer.is_valid(raise_exception=True): 
       serializer.save() 
      return Response(serializer.data) 

Ve PUT isteğinde json bir örnek:

{ 
     "id": 2, 
     "items": [ 
      { 
       "id": 3, 
       "collection": 2, 
       "delete": true 
      } 
     ], 
     "description": "mycoll" 
    } 
+0

Silmek isteyen iç içe geçmiş modüllerin her biri için ayrı bir HTTP 'DELETE 'işlemi yapmak kabul edilebilir mi? Eğer 'serializers.HyperlinkedModelSerializer' serisini serializer'larınızın temel sınıfı olarak kullanacak olursanız, her bir alt öğe kolayca 'DELETE' yapabileceğiniz bir URL'ye sahip olacaktır. –

+0

Keşfetmek için ilginç bir açı. Ancak asıl sorun, hangi öğelerin silinmesi gerektiğiyle ilgili bilgilerin valide_data'da eksik olmasıdır. – jjmurre

+0

İstemci tarafında, alt öğe üzerinde "delete" bayrağı ayarlanmak yerine, o nesneye bir HTTP 'DELETE 'işlemi yapıp kapsayıcıdan kaldırmak yeterlidir. Django'nun içinden 'DELETE' yapmıyorsunuz (Bu yaklaşımı ima ettiğinizi varsayabilirsem.) –

cevap

13

Sen üzerine yazarak olmayan model alanlar geri ekleyebilirsiniz to_internal_value fn:

def to_internal_value(self, data): 
    internal_value = super(MySerializer, self).to_internal_value(data) 
    my_non_model_field_raw_value = data.get("my_non_model_field") 
    my_non_model_field_value = ConvertRawValueInSomeCleverWay(my_non_model_field_raw_value) 
    internal_value.update({ 
     "my_non_model_field": my_non_model_field_value 
    }) 
    return internal_value 

Ardından, create veya update numaralı telefondan istediğiniz gibi işleyebilirsiniz.

İlgili konular