2015-03-13 12 views
7

तो मैं निम्नलिखित संरचना है:Django बाकी फ्रेमवर्क नेस्ट संसाधन कुंजी "आईडी" unaccessible

एक ClientFile एक मालिक के अंतर्गत आता है (वर्ग के नाम = संपर्क)। मैं एपीआई का उपयोग कर क्लाइंटफाइल बनाने की कोशिश कर रहा हूं। अनुरोध में निम्न डेटा शामिल है:

{ 
    name: "Hello!" 
    owner: { 
    id: 1, 
    first_name: "Charlie", 
    last_name: "Watson" 
    } 
} 

मैंने अपनी संरचना के अनुसार धारावाहिक बनाया है। उम्मीद है कि यह एपीआई कॉल "हैलो!" नाम के साथ क्लाइंटफ़ाइल बनायेगा और मालिक के रूप में आईडी 1 से संपर्क करें:

class ContactSerializer(serializers.ModelSerializer): 
    class Meta: 
    model = Contact 
    fields = (
     'id', 
     'first_name', 
     'last_name', 
    ) 

class ClientfileSerializer(serializers.ModelSerializer): 

    owner = ContactSerializer(read_only=False) 

    class Meta(): 
    model = Clientfile 
    fields = (
     'id', 
     'name', 
     'owner', 
    ) 

    def create(self, validated_data): 

    owner = Contact.objects.get(pk=validated_data['owner']['id']) 

मैं निर्माण विधि में मिलता हूं। हालांकि, मुझे केवल एक फ़ील्ड (['owner']['id']) की आवश्यकता नहीं है। अगर मैं print ['owner']['first_name'] करता हूं तो यह 'चार्ली' लौटाता है। लेकिन कुछ कारणों से आईडी सुलभ प्रतीत नहीं होती है ...

ऐसा कोई कारण क्यों हो सकता है? क्या मैं कुछ भूल रहा हूँ? (मैं Django के लिए नया हूँ)


समाधान: बस पता चला कि कारण है कि आईडी पहली जगह में नहीं दिखाया जा सका क्योंकि मैं बहुत जैसे क्षेत्रों में यह घोषणा करने के लिए किया था: आशा है कि इस मदद करता है।

class ContactSerializer(serializers.ModelSerializer): 

    id = serializers.IntegerField() # ← Here 

    class Meta: 
    model = Contact 
    fields = (
     'id', 
     'first_name', 
     'last_name', 
    ) 

उत्तर

1

ठीक है इसलिए मुझे एक अलग दृष्टिकोण मिला जो काम करता है। मैंने मालिक संबंध के लिए एक इंटेगरफ़िल्ल्ड धारावाहिक जोड़ा। मुझे read_only = True पर मालिक संबंध भी सेट करना पड़ा।

यह json मैं पोस्ट के माध्यम से भेज रहा हूँ है:

{ 
    name: "Hello!" 
    owner_id: 1 
} 

यह मेरा serializer है:

class ClientfileSerializer(serializers.ModelSerializer): 

    owner_id = serializers.IntegerField() 
    owner = ContactSerializer(read_only=True) 

    class Meta(): 
    model = Clientfile 
    fields = (
     'id', 
     'owner_id', 
     'owner', 
    ) 

यह पहली बार जिस तरह से कम से कम शांत लगता है, लेकिन यह काम करता है। प्लस मैं एक नया मालिक नहीं बनाना चाहता, लेकिन केवल उस डेटाबेस का चयन करें जो पहले से ही डेटाबेस में है। तो हो सकता है कि यह केवल आईडी के लिए अधिक अर्थपूर्ण हो और जेसन के माध्यम से पोस्ट की गई जानकारी का पूरा सेट न हो।

7

Django बाकी फ्रेमवर्क में AutoField क्षेत्रों (उन है कि स्वचालित रूप से उत्पन्न कर रहे हैं) केवल पढ़ने के लिए सामान्य रूप से कर रहे हैं। the docs से:

read_only

True को यह सेट सुनिश्चित करें कि क्षेत्र जब प्रतिनिधित्व serializing प्रयोग किया जाता है, लेकिन बनाने या अक्रमांकन दौरान एक उदाहरण अपडेट करने के दौरान किया जाता है।

False

को चूक आप अपने खोल में प्रतिनिधित्व मुद्रण द्वारा inspecting your serializer द्वारा इस देख सकते हैं:

serializer = ClientfileSerializer() 
print repr(serializer) 

आप इस ओवरराइड कर सकते हैं extra_kwargs में आईडी क्षेत्र के खिलाफ read_only=False की स्थापना द्वारा:

class ContactSerializer(serializers.ModelSerializer): 
    class Meta: 
    model = Contact 
    fields = (
     'id', 
     'first_name', 
     'last_name', 
    ) 
    extra_kwargs = {'id': {'read_only': False}} 

class ClientfileSerializer(serializers.ModelSerializer): 

    owner = ContactSerializer(read_only=False) 

    class Meta(): 
    model = Clientfile 
    fields = (
     'id', 
     'name', 
     'owner', 
    ) 
    extra_kwargs = {'id': {'read_only': False}} 
+0

मैंने कोशिश की। यह समस्या को हल करता है लेकिन एक और बनाता है: अब मैं संपर्क नहीं बना सकता। यह एक त्रुटि कहता है कि आईडी फ़ील्ड आवश्यक है ... – MonsieurNinja

+0

क्या आपने क्लाइंटफ़ाइलरिएलाइज़र के लिए आईडी फ़ील्ड को केवल पढ़ने के लिए आवेदन करने का प्रयास किया है? – br3w5

+0

मुझे @MonsieurNinja के समान समस्या है, यह आईडी को मैन्युअल रूप से सेट करने की आवश्यकता है। – Sem

2

आप कुछ इस तरह की कोशिश कर सकते हैं:

class YourModelSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = YourModel 
     fields = ('id', 'field1', 'field2') 

    def to_internal_value(self, data): 
     """ 
     Dict of native values <- Dict of primitive datatypes. 
     Add instance key to values if `id` present in primitive dict 
     :param data: 
     """ 
     obj = super(YourModelSerializer, self).to_internal_value(data) 
     instance_id = data.get('id', None) 
     if instance_id: 
      obj['instance'] = YourModel.objects.get(id=instance_id) 
     return obj 

फिर serializer मान्य डेटा में आप "उदाहरण" कुंजी अगर request.data है "आईडी" कुंजी होना चाहिए।

इसके अलावा आप पूर्ण उदाहरण/ऑब्जेक्ट के बजाय बस "आईडी" जोड़ सकते हैं।

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