2015-06-05 19 views
5

की validated_data में एक गैर-मॉडल क्षेत्र प्राप्त करने में असमर्थ मैं एक ItemCollection और मेरे Django मॉडल में आइटम है और मैं यूआई के माध्यम से संग्रह से आइटम को हटाने में सक्षम होना चाहता हूँ। एक REST PUT अनुरोध में मैं प्रत्येक आइटम के लिए एक अतिरिक्त बूलियन फ़ील्ड deleted जोड़ता हूं ताकि यह संकेत दिया जा सके कि कोई आइटम हटाया जाना चाहिए।एक Django बाकी फ्रेमवर्क serializer

इस संभाल करने के लिए सही तरीका Serializer की update विधि में हो रहा है। मेरे समस्या यह है कि इस गैर मॉडल deleted क्षेत्र सत्यापन के दौरान हटा दिया जाता है, इसलिए इसे अब उपलब्ध नहीं है। SerializerMethodField के रूप में deleted जोड़ने से मदद नहीं मिली। अभी के लिए मुझे initial_data सेरिअलाइज़र की विशेषता से deleted जानकारी मिलती है, लेकिन यह सही नहीं लगता है।

मेरे वर्तमान उदाहरण कोड के नीचे है। क्या कोई बेहतर दृष्टिकोण जानता है?

मॉडल:

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


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

serializers:

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) 

और PUT अनुरोध में json का एक उदाहरण:

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

यह सिर्फ नेस्टेड मॉड्यूल को हटाने की जरूरत है कि में से प्रत्येक के लिए एक अलग HTTP 'DELETE' करने के लिए स्वीकार्य होगा? यदि आप अपने धारावाहिकों के बेस क्लास के रूप में 'serializers.HyperlinkedModelSerializer' का उपयोग करना चाहते थे, तो प्रत्येक उप-आइटम में एक यूआरएल होगा जिसे आप आसानी से' हटा सकते हैं '। –

+0

यह अन्वेषण करने के लिए एक दिलचस्प कोण है। हालांकि, मुख्य समस्या यह है कि किस आइटम को हटाने की आवश्यकता है, इस बारे में जानकारी 'validated_data' में गुम है। – jjmurre

+0

मेरा मतलब यह है कि क्लाइंट पक्ष पर, उप-आइटम पर ध्वज 'हटाएं' सेट करने के बजाय, बस उस ऑब्जेक्ट में HTTP 'DELETE' करें और इसे कंटेनर से हटा दें। आप Django के अंदर से 'DELETE' नहीं करते हैं (यदि मुझे लगता है कि आप उस दृष्टिकोण को insinuating थे।) –

उत्तर

13

आप ओवरराइट करके गैर मॉडल क्षेत्रों वापस जोड़ सकते हैं 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 

फिर आप इसे संसाधित कर सकते हैं हालांकि आप create या update में चाहते हैं।

संबंधित मुद्दे